ATLAS Offline Software
Loading...
Searching...
No Matches
TrackHandleBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class TrackHandleBase //
9// //
10// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11// Initial version: February 2008 //
12// //
14
24#include "VP1TrackSystems/SimBarCode.h"//For unknown pdg. Fixme: Use 0 for unknown pdg!
30#include "VP1Utils/VP1DetInfo.h"
31
35
38#include "VP1Base/VP1Msg.h"
40#include "VP1Base/VP1QtUtils.h"
41
42#include "TrkTrack/Track.h"
46
47#include <Inventor/C/errors/debugerror.h>
48#include <Inventor/nodes/SoLineSet.h>
49#include <Inventor/nodes/SoVertexProperty.h>
50#include <Inventor/nodes/SoSeparator.h>
51#include <Inventor/nodes/SoMaterial.h>
52#include <Inventor/nodes/SoPickStyle.h>
53#include <Inventor/nodes/SoCylinder.h>
54#include <Inventor/nodes/SoMatrixTransform.h>
55#include <Inventor/SbRotation.h>
56#include <Inventor/SbMatrix.h>
57#include <Inventor/nodes/SoTranslation.h>
58#include <Inventor/nodes/SoText2.h>
59
60#include "TrkVolumes/Volume.h"
71#include <cassert>
72#include <memory>
73
74
75//____________________________________________________________________
77public:
78 static void convertLineSetToCylinders(SoLineSet*line,SoSeparator*sep, const double& cylradius);
79 static double dist(const SbVec3f& p1,const SbVec3f& p2);
80
81 static int ntrackhandles;
82
84 chargeinit(false),
86 massinit(false),
88 line(nullptr),
89 extraRepresentation(nullptr),
90 extrapSurfaces_sep(nullptr),
91 extraRepAttached(false),
92 points_raw(nullptr), points_propagated(nullptr),
98 randommaterial(nullptr),
99 pathInfoLoaded(false),
100 pathInfo_TrkTrack(nullptr),
101 pathInfo_Points(nullptr),
102 label_sep(nullptr),
103 shownTSOSParts(TrackCommonFlags::TSOS_NoObjects),
105 m_objBrowseTree(nullptr),
106 tempMaxPropRadius(0.0){}
107
109
111 double charge;
113 double mass;
114
115 SoLineSet * line;//This represents the line(s) representing the track and its projections
116 SoSeparator * extraRepresentation;//For alternative representations (e.g. tubes for lines)
117 SoSeparator* extrapSurfaces_sep;
119
120 //For efficiency we cache parameterisations of the various track parts:
121
122 //The next two vectors://=0 when not inited, !=0 but empty means previous attempt to init failed.
123 std::vector< Amg::Vector3D > * points_raw;
124 std::vector<Amg::Vector3D > * points_propagated;
125 //The following sets://=0 when not inited, !=0 and ->front().vector.empty() means previous attempt to init failed.
130
131 void ensureInitPointsRaw();
133 void ensureInitPointsProjections_InDet( bool raw );
134 void ensureInitPointsProjections_Muon( bool raw );
135
136 void materialChanged();
137
138 void rebuild3DObjects();
139 void attach3DObjects();
140 void detach3DObjects();
141
142 mutable std::set<GeoPVConstLink> touchedmuonchambers;
144
145 void addPathToSoLineSetAndSoVertexProperty(const std::vector<Amg::Vector3D >& points,
146 int & iver, int& numlines, SoLineSet *, SoVertexProperty * ) const;
148 int & iver, int& numlines,SoLineSet *, SoVertexProperty * ) const;
149
150 SoMaterial * determineMaterial();
151 SoMaterial * randommaterial;
152
153 QList<AssociatedObjectHandleBase*> associatedObjects;
154 std::map<std::pair<int,double>,AssocObjAttachmentHandle *> attachmentHandles;
155
156 //We cache path info, but it might get invalidated (if switching off simhits for instance):
159 const std::vector< Amg::Vector3D > * pathInfo_Points;
160 SoSeparator * label_sep;
161 void ensureLoadPathInfo();
162
163 static bool isSane(const Amg::Vector3D& p)
164 {
165 if (p.x()!=p.x()||fabs(p.x())>1.0*CLHEP::km)
166 return false;
167 if (p.y()!=p.y()||fabs(p.y())>1.0*CLHEP::km)
168 return false;
169 if (p.z()!=p.z()||fabs(p.z())>1.0*CLHEP::km)
170 return false;
171 return true;
172 }
173
174
175 TrackCommonFlags::TSOSPartsFlags shownTSOSParts;
176 TrackCommonFlags::TSOSPartsFlags customColouredTSOSParts;
177 std::unique_ptr<std::vector<AssociatedObjectHandleBase*>> tsos_ascobjs;
178 AscObj_TSOS* addTSOS(const Trk::TrackStateOnSurface * tsos,unsigned index) const;
179
180 QTreeWidgetItem* m_objBrowseTree;
182};
183
184
186
187//____________________________________________________________________
189{
190 if (pathInfoLoaded)
191 return;
192 pathInfoLoaded = true;
193 pathInfo_TrkTrack = theclass->provide_pathInfoTrkTrack();
195 return;
196 pathInfo_Points = theclass->provide_pathInfoPoints();
197 if (!pathInfo_Points) {
198 theclass->collHandle()->systemBase()->message("ERROR: No path information for track in collection "+theclass->collHandle()->name());
199 }
200}
201
202//____________________________________________________________________
209
210//____________________________________________________________________
212{
213 if (m_d->extraRepresentation)
214 common()->unregisterTrack(m_d->extraRepresentation);
215
216 //FIXME: if visible, should we call detach first?
217 for(AssociatedObjectHandleBase*ao : m_d->associatedObjects)
218 delete ao;
219
220 //Delete points the following way since we might use same points for raw and propagated.
221 if (m_d->points_propagated != m_d->points_raw)
222 delete m_d->points_propagated;
223 delete m_d->points_raw;
224 if (m_d->points_propagated_id_projections != m_d->points_raw_id_projections)
225 delete m_d->points_propagated_id_projections;
226 delete m_d->points_raw_id_projections;
227 if (m_d->points_propagated_muon_projections != m_d->points_raw_muon_projections)
228 delete m_d->points_propagated_muon_projections;
229 delete m_d->points_raw_muon_projections;
230
231 clearLine();
233 m_currentmaterial->unref();
234 if (m_d->randommaterial)
235 m_d->randommaterial->unref();
236 if (m_d->label_sep)
237 m_d->label_sep->unref();
238
239 std::map<std::pair<int,double>,AssocObjAttachmentHandle *>::iterator it,itE(m_d->attachmentHandles.end());
240 for (it = m_d->attachmentHandles.begin();it!=itE;++it)
241 delete it->second;
242
243 delete m_d;
245}
246
247//____________________________________________________________________
252
253//____________________________________________________________________
255{
256 return m_collhandle->common();
257}
258
259//____________________________________________________________________
261{
262 if (!m_d->tsos_ascobjs)
263 return;
264 std::vector<AssociatedObjectHandleBase*>::iterator
265 it(m_d->tsos_ascobjs->begin()),
266 itE(m_d->tsos_ascobjs->end());
267 for (;it!=itE;++it)
268 if ((*it)->hasMeasurement())
269 (*it)->update3DObjects();
270}
271
272//____________________________________________________________________
274{
275 if (!m_d->tsos_ascobjs)
276 return;
277 std::vector<AssociatedObjectHandleBase*>::iterator
278 it(m_d->tsos_ascobjs->begin()),
279 itE(m_d->tsos_ascobjs->end());
280 for (;it!=itE;++it)
281 if ((*it)->hasError())
282 (*it)->update3DObjects();
283}
284
285//____________________________________________________________________
287{
288 if (!m_d->tsos_ascobjs)
289 return;
290 std::vector<AssociatedObjectHandleBase*>::iterator
291 it(m_d->tsos_ascobjs->begin()),
292 itE(m_d->tsos_ascobjs->end());
293 for (;it!=itE;++it)
294 if ((*it)->hasMaterialEffect())
295 (*it)->update3DObjects();
296}
297
298//____________________________________________________________________
299TrackCommonFlags::TSOSPartsFlags TrackHandleBase::shownTSOSParts() const
300{
301 return m_d->shownTSOSParts;//FIXME: inline?
302}
303
304//____________________________________________________________________
305TrackCommonFlags::TSOSPartsFlags TrackHandleBase::customColouredTSOSParts() const
306{
307 return m_d->customColouredTSOSParts;//FIXME: inline?
308}
309
310//____________________________________________________________________
311void TrackHandleBase::setShownTSOSParts(TrackCommonFlags::TSOSPartsFlags f)
312{
313 VP1Msg::messageDebug(QString("TrackHandleBase::setShownTSOSParts to ")+QString::number(f) );
314
315 if (m_d->shownTSOSParts==f){
316 VP1Msg::messageDebug(QString("->No change in shown parts. Skipping."));
317 return;
318 }
319
320 //Figure out changed bits:
321 TrackCommonFlags::TSOSPartsFlags change(m_d->shownTSOSParts ^ f);//^ is XOR
322 m_d->shownTSOSParts=f;
323 if (!m_d->tsos_ascobjs&&(m_d->shownTSOSParts==TrackCommonFlags::TSOS_NoObjects||!visible()))
324 return;
325
326 ensureInitTSOSs(m_d->tsos_ascobjs);
327 //Loop over all TSOS objects. Those with changed parts needs shape
328 //and visibility update:
329 std::vector<AssociatedObjectHandleBase*>::iterator it(m_d->tsos_ascobjs->begin()), itE(m_d->tsos_ascobjs->end());
330 for (;it!=itE;++it) {
331 const bool vis = (*it)->parts() & m_d->shownTSOSParts;
332 if (!((*it)->parts()&change)){
333 continue;
334 }
335
336 if (vis==(*it)->visible()) {
337 //Just update shape:
338 (*it)->update3DObjects();
339 continue;
340 }
341 //Need both shape and visibility updates.
342 if (vis) {
343 //update shape and then turn visible:
344 (*it)->update3DObjects();
345 (*it)->setVisible(vis);
346 } else {
347 //turn invisible and then update (i.e. invalidate) shape:
348 (*it)->setVisible(vis);
349 (*it)->update3DObjects();
350 }
351 }
352}
353
354//____________________________________________________________________
355void TrackHandleBase::setCustomColouredTSOSParts(TrackCommonFlags::TSOSPartsFlags f)
356{
357 if (m_d->customColouredTSOSParts==f)
358 return;
359 //Figure out changed bits:
360 TrackCommonFlags::TSOSPartsFlags change(m_d->customColouredTSOSParts ^ f);//^ is XOR
361 m_d->customColouredTSOSParts=f;
362
363 if (!m_d->tsos_ascobjs||m_d->shownTSOSParts==TrackCommonFlags::TSOS_NoObjects)
364 return;
365
366 TrackCommonFlags::TSOSPartsFlags changedShownParts(change & m_d->shownTSOSParts);
367
368 if (!changedShownParts)
369 return;
370
371 std::vector<AssociatedObjectHandleBase*>::iterator it(m_d->tsos_ascobjs->begin()), itE(m_d->tsos_ascobjs->end());
372 for (;it!=itE;++it) {
373 if ((*it)->parts()&changedShownParts)
374 (*it)->update3DObjects();
375 }
376}
377
378//____________________________________________________________________
379void TrackHandleBase::ensureInitTSOSs(std::unique_ptr<std::vector<AssociatedObjectHandleBase*>>& tsos_ascobjs)
380{
381 std::cout<<"TrackHandleBase::ensureInitTSOSs"<<std::endl;
382 if (tsos_ascobjs)
383 return;
384
385 tsos_ascobjs = std::make_unique<std::vector<AssociatedObjectHandleBase*>>();
386 m_d->ensureLoadPathInfo();
387
388 if (!m_d->pathInfo_TrkTrack||!m_d->pathInfo_TrkTrack->trackParameters()||m_d->pathInfo_TrkTrack->trackParameters()->empty())
389 return;
390
391 tsos_ascobjs->reserve(m_d->pathInfo_TrkTrack->trackParameters()->size());
392
393 unsigned parindex(0);
394
395 AscObj_TSOS* ascObjNeedDistToNext(nullptr);
396 Trk::TrackStates::const_iterator tsos_iter = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->begin();
397 Trk::TrackStates::const_iterator tsos_end = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->end();
398 const Trk::TrackParameters* trackParam(nullptr);
399 for (; tsos_iter != tsos_end; ++tsos_iter) {
400 trackParam = (*tsos_iter)->trackParameters();
401 if (!VP1TrackSanity::isSafe(*tsos_iter)) {
402 parindex++;
403 continue;
404 }
405 if (trackParam&&!VP1TrackSanity::isSafe(trackParam)) {
406 parindex++;
407 continue;
408 }
409 //FIXME: likewise check that we don't have a bad measurement, material effect, ...
410 if (ascObjNeedDistToNext&&trackParam) {
411 ascObjNeedDistToNext->setDistToNextPar((trackParam->position()-ascObjNeedDistToNext->approxCenter()).mag());
412 ascObjNeedDistToNext = nullptr;
413 }
414 VP1Msg::messageVerbose("Adding TSOS at index:"+QString::number(parindex));
415 ascObjNeedDistToNext = m_d->addTSOS(*tsos_iter,parindex++);
416 }
417
418}
419
420
421//____________________________________________________________________
423{
424 AscObj_TSOS* ao = new AscObj_TSOS(theclass,tsos,index);
425 theclass->registerAssocObject(ao);
426 tsos_ascobjs->push_back(ao);
427 if (ao->parts()&shownTSOSParts)
428 ao->setVisible(true);
429 return ao;
430}
431
432//____________________________________________________________________
434{
435 std::cout<<"TrackHandleBase::setVisible"<<std::endl;
436 QString tmp = (vis)?"True":"False";
437 QString tmp2 = (m_visible)?"True":"False";
438 VP1Msg::messageDebug(QString("TrackHandleBase calling setVisible with vis=")+tmp+QString(", and m_visible=")+tmp2 );
439 if (vis==m_visible)
440 return;
441 std::cout<<"TrackHandleBase::setVisible 1"<<std::endl;
442
443 m_visible=vis;
444 if (vis) {
445 m_collhandle->incrementNShownHandles();
446 if (!touchedMuonChambers().empty()) {
447 for (std::set<GeoPVConstLink>::iterator it=touchedMuonChambers().begin(); it!=touchedMuonChambers().end(); ++it)
449 }
450 if (!m_d->line)
451 m_d->rebuild3DObjects();//The call to rebuild also fixes attached state.
452 else
453 m_d->attach3DObjects();
454 } else {
455 m_collhandle->decrementNShownHandles();
456 if (!touchedMuonChambers().empty()) {
457 for (std::set<GeoPVConstLink>::iterator it=touchedMuonChambers().begin(); it!=touchedMuonChambers().end(); ++it)
459 }
460 m_d->detach3DObjects();
461 }
462
463 std::cout<<"TrackHandleBase::setVisible 2"<<std::endl;
464
465
466 bool initTSOS(false);
467 if (!m_d->tsos_ascobjs&&vis&&m_d->shownTSOSParts!=TrackCommonFlags::TSOS_NoObjects) {
468 ensureInitTSOSs(m_d->tsos_ascobjs);
469 initTSOS = true;
470 }
471 std::cout<<"m_d->tsos_ascobjs: "<<m_d->tsos_ascobjs<<std::endl;
472 std::cout<<"m_d->shownTSOSParts!=TrackCommonFlags::TSOS_NoObjects "<<(m_d->shownTSOSParts!=TrackCommonFlags::TSOS_NoObjects)<<std::endl;
473 std::cout<<"TrackHandleBase::setVisible 3"<<std::endl;
474
475 if (!initTSOS && m_d->tsos_ascobjs) {
476 std::vector<AssociatedObjectHandleBase*>::iterator
477 it(m_d->tsos_ascobjs->begin()),
478 itE(m_d->tsos_ascobjs->end());
479 if (m_d->shownTSOSParts!=TrackCommonFlags::TSOS_NoObjects) {
480 for (;it!=itE;++it) {
481 if ((*it)->visible()!=((*it)->parts() & m_d->shownTSOSParts))
482 (*it)->toggleVisible();
483 }
484 } else {
485 for (;it!=itE;++it) {
486 if ((*it)->visible())
487 (*it)->setVisible(false);
488 }
489 }
490 }
491 std::cout<<"TrackHandleBase::setVisible 4"<<std::endl;
492
494
495 std::map<std::pair<int,double>,AssocObjAttachmentHandle *>::iterator it,itE(m_d->attachmentHandles.end());
496 for (it = m_d->attachmentHandles.begin();it!=itE;++it)
497 it->second->trackVisibilityChanged();
498
499 //Label
500
501}
502
503//____________________________________________________________________
504void TrackHandleBase::update3DObjects( bool invalidatePropagatedPoints, float maxR )
505{
506 VP1Msg::messageVerbose(QString("TrackHandleBase::update3DObject with maxR set to ")+QString::number(maxR) );
507 if (maxR>0.0) {
508 m_d->tempMaxPropRadius=maxR;
509 }
510 if ( invalidatePropagatedPoints) {
511 if (m_d->points_propagated != m_d->points_raw) {
512 delete m_d->points_propagated;m_d->points_propagated = nullptr;
513 }
514 delete m_d->points_raw;m_d->points_raw = nullptr;
515 if (m_d->points_propagated_id_projections) { delete m_d->points_propagated_id_projections; m_d->points_propagated_id_projections = nullptr; }
516 if (m_d->points_propagated_muon_projections) { delete m_d->points_propagated_muon_projections; m_d->points_propagated_muon_projections = nullptr; }
517 }
518 if (m_visible) {
519 m_d->rebuild3DObjects();
520 } else {
521 //Simply clear the present 3D objects. They will only be recreated if/when the track becomes visible again.
522 clearLine();
523 }
524 m_d->tempMaxPropRadius=0.0;
525}
526
527//____________________________________________________________________
529{
530 //Invalidate points of indet projections if already calculated:
531 if (m_d->points_raw_id_projections!=m_d->points_propagated_id_projections)
532 delete m_d->points_propagated_id_projections;
533 delete m_d->points_raw_id_projections;
534 m_d->points_raw_id_projections = nullptr;
535 m_d->points_propagated_id_projections = nullptr;
536 //Rebuild 3D objects:
538}
539
540//____________________________________________________________________
542{
543 //Invalidate points of indet projections if already calculated:
544 if (m_d->points_raw_muon_projections!=m_d->points_propagated_muon_projections)
545 delete m_d->points_propagated_muon_projections;
546 delete m_d->points_raw_muon_projections;
547 m_d->points_raw_muon_projections = nullptr;
548 m_d->points_propagated_muon_projections = nullptr;
549 //Rebuild 3D objects:
551}
552
553
554//____________________________________________________________________
555void TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty(const std::vector<Amg::Vector3D >& points,
556 int & iver, int& numlines,
557 SoLineSet * line, SoVertexProperty * vertices ) const
558{
559 if (points.size()<2)
560 return;
561 if (!line) {
562 theclass->collHandle()->systemBase()->message("TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty (1) ERROR: Unexpected null SoLineSet pointer!");
563 return;
564 }
565 if (!vertices) {
566 theclass->collHandle()->systemBase()->message("TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty (1) ERROR: Unexpected null SoVertexPropery pointer!");
567 return;
568 }
569 std::vector<Amg::Vector3D >::const_iterator pointsIt, pointsItEnd(points.end());
570 unsigned npointsused(0);
571
572
573 float maxR2=theclass->common()->controller()->propMaxRadius()>0.0?theclass->common()->controller()->propMaxRadius():std::numeric_limits<float>::max();
574 if (tempMaxPropRadius>0.0){
576 theclass->collHandle()->systemBase()->messageVerbose("maxR2 is set to "+VP1Msg::str(maxR2));
577 }
578 float vertexPlanePhi = (theclass->common()->controller()->vertexProjectionAngle())*M_PI/180;// angle of plane to use for vertex projection
579 vertexPlanePhi-=M_PI; // ATLAS range is -PI to PI
580
581 // debug msgs:
582 // theclass->collHandle()->systemBase()->messageVerbose("TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty - adding "
583 // +VP1Msg::str(points.size())+" points up to R2 of "+VP1Msg::str(maxR2));
584 theclass->collHandle()->systemBase()->messageVerbose("Vertex projection is set to "+VP1Msg::str(vertexPlanePhi));
585
586 // unsigned int count=0; // for the debug msgs below
587
588 //For vertex projection
589 Amg::Vector3D tempPoint;
590
591 double trkPhi = theclass->momentum().phi(); // some tracks curve between sections otherwise.
592 double newPhi= vertexPlanePhi+M_PI;
593 if (cos(vertexPlanePhi-trkPhi)>0) newPhi=vertexPlanePhi;
594 // theclass->collHandle()->systemBase()->messageVerbose("Vertex projection is set to "+VP1Msg::str(vertexPlanePhi)+" trkPhi= "+VP1Msg::str(trkPhi)+" newPhi="+VP1Msg::str(newPhi)); // debug msg
595
596 for (pointsIt = points.begin();pointsIt!=pointsItEnd && pointsIt->mag2()<maxR2; ++pointsIt) {
597 // theclass->collHandle()->systemBase()->messageVerbose(VP1Msg::str(count++)+": point has perp2="+VP1Msg::str(pointsIt->perp2())); // debug msg
598 if (!isSane(*pointsIt)) {
599 theclass->collHandle()->systemBase()->message("WARNING: Ignoring point on track:"+VP1Msg::str( *pointsIt ) );
600 continue;
601 }
602
603 if (theclass->collHandle()->parts() & TrackCommonFlags::VertexProjections){
604 tempPoint = *pointsIt;
605 Amg::setPhi(tempPoint, newPhi);
606
607 // std::cout<<trkPhi<<"\t"<<phi<<"\t"<<r0<<"\t"<<r1<<"\t"<<r2<<"\t"<<r3<<"\t"<<rotatePhi<<"\t"<<tempPoint.getPhi()<<std::endl; // debug msg
608
609 vertices->vertex.set1Value(iver++,tempPoint.x(),tempPoint.y(),tempPoint.z());
610 } else {
611 vertices->vertex.set1Value(iver++,pointsIt->x(),pointsIt->y(),pointsIt->z());
612 }
613 ++npointsused;
614 }
615 line->numVertices.set1Value(numlines++,npointsused);
616}
617
618//____________________________________________________________________
620 int & iver, int& numlines,
621 SoLineSet * line, SoVertexProperty * vertices ) const
622{
623 if ( !paths || ( paths->size()==1 && paths->begin()->empty()) )
624 return;
625 if (!line) {
626 theclass->collHandle()->systemBase()->message("TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty (2) ERROR: Unexpected null SoLineSet pointer!");
627 return;
628 }
629 if (!vertices) {
630 theclass->collHandle()->systemBase()->message("TrackHandleBase::Imp::addPathToSoLineSetAndSoVertexProperty (2) ERROR: Unexpected null SoVertexPropery pointer!");
631 return;
632 }
633 Amg::SetVectorVector3D::const_iterator itProjPart, itProjPartEnd(paths->end());
634 for (itProjPart = paths->begin();itProjPart!=itProjPartEnd;++itProjPart)
635 addPathToSoLineSetAndSoVertexProperty(*itProjPart,iver,numlines,line,vertices);
636}
637
638//____________________________________________________________________
640{
641 if (m_d->line) {
642 common()->unregisterTrack(m_d->line);
643 m_d->line->unref();
644 m_d->line=nullptr;
645 }
646}
647
648//____________________________________________________________________
650{
651 if (m_d->line)
652 common()->registerTrack(m_d->line,this);
653}
654
655
656//____________________________________________________________________
658{
659 //Ensure we are always detached while updating.
660 if (theclass->m_visible)
662
663 // Make sure we're not going to redraw old surfaces, for this debug mode.
664 if (theclass->common()->trackPropagationHelper()->showExtrapolationSurfaces())
665 theclass->common()->trackPropagationHelper()->getExtrapolationSurfaces().clear();
666
667 Trk::IExtrapolator * propagator = theclass->collHandle()->propagator();
668
669 if (propagator)
671 else
673
674 bool id_proj = theclass->collHandle()->parts() & TrackCommonFlags::InDetProjections;
675 if (id_proj)
677
678 bool muon_proj = theclass->collHandle()->parts() & TrackCommonFlags::MuonProjections;
679 if (muon_proj)
681
682 std::vector<Amg::Vector3D > * points;
683 Amg::SetVectorVector3D *proj_id, *proj_muon;
684 if (propagator) {
685 points = points_propagated;
688 } else {
689 points = points_raw;
691 proj_muon = points_raw_muon_projections;
692 }
693
694 //Put points into an appropriate vertex property.
695 theclass->clearLine(); //FIXME: Since we are just changing shape - no need to delete line and take it
696 //out of the tree first. Just edit lineset properties instead.
697 line = new SoLineSet();
698 line->ref();
699 theclass->registerTrack();
700
701 SoVertexProperty * vertices = new SoVertexProperty();
702
703 int iver(0), numlines(0);
704
705 //Add various parts to these vertices as appropriate:
706 if (theclass->collHandle()->parts() & TrackCommonFlags::ActualPath)
707 addPathToSoLineSetAndSoVertexProperty(*points,iver,numlines,line,vertices);
708 if (id_proj)
709 addPathsToSoLineSetAndSoVertexProperty( proj_id, iver, numlines, line, vertices );
710 if (muon_proj)
711 addPathsToSoLineSetAndSoVertexProperty( proj_muon, iver, numlines, line, vertices );
712
713 line->vertexProperty = vertices;
714
716
717
718// Add debugging surfaces.
719 if (theclass->common()->trackPropagationHelper()->showExtrapolationSurfaces()){
720 std::vector<Trk::PlaneSurface>& surfaces = theclass->common()->trackPropagationHelper()->getExtrapolationSurfaces();
721 std::vector<Trk::PlaneSurface>::const_iterator surfIt=surfaces.begin(), surfEnd=surfaces.end();
722 SurfaceToSoNode surfCnv;//fixme: check if need in common()
723 extrapSurfaces_sep=new SoSeparator;
724 for (;surfIt!=surfEnd;++surfIt){
725 SoNode* theSurfSep = surfCnv.translateSurface(*surfIt);
726 if (theSurfSep) {
727 SoNode * nodeToAdd = theSurfSep;
728 extrapSurfaces_sep->addChild(nodeToAdd);
729 }
730 }
731 }
732
733// Add labels
734 if (!points->empty() && theclass->common()->controller()->doTrackLabels() ){
735
736 // should detach first? This is all fairly suboptimal I'm sure... EJWM.
737 if (!label_sep){
738 label_sep = new SoSeparator;
739 label_sep->ref();
740 }
741 label_sep->removeAllChildren ();
742
743 SoText2 *labelText = new SoText2;
744 labelText->ref();
745 QStringList text;
746 TrackSystemController::TrackLabelModes labels=theclass->common()->controller()->trackLabels();
747 if (labels&TrackSystemController::P){
748 text << "P="+VP1Msg::str(theclass->momentum().mag())+" MeV";
749 }
750
751 if (labels&TrackSystemController::Pt){
752 text << "|Pt|="+VP1Msg::str(theclass->momentum().perp())+" MeV";
753 }
754
755 if (labels&TrackSystemController::Pid){
756 int pdg = theclass->pdgCode();
757 if (pdg) {
758 bool ok;
759 QString name = VP1ParticleData::particleName(pdg,ok);
760 if (ok)
761 text << "pdg: "+QString::number(pdg)+" ["+name+"]";
762 else
763 text << "pdg: "+QString::number(pdg);
764 }
765 }
766
767 if (labels&TrackSystemController::FitQuality && theclass->getFitQuality()){
768 text << TrkObjToString::shortInfo(*theclass->getFitQuality());
769 }
770
771 if (labels&TrackSystemController::Hits){
772 text <<"Pix["+VP1Msg::str(theclass->getNPixelHits())+"], SCT["+VP1Msg::str(theclass->getNSCTHits())+"], TRT["+VP1Msg::str(theclass->getNTRTHits())+"],"
773 <<" MDT["+QString::number(theclass->getNMDTHits())+"], RPC["+QString::number(theclass->getNRPCHits())+"], TGC["+QString::number(theclass->getNTGCHits())+"], CSC["+QString::number(theclass->getNCSCHits())+"] MM["+QString::number(theclass->getNMMHits())+"], sTGC["+QString::number(theclass->getNsTGCHits())+"]";
774 }
775
777 Amg::Vector3D mom = theclass->momentum();
778 mom /= CLHEP::GeV;
779 if (mom.mag2()==0.0) {
780 text << "Momentum : 0 (undefined)";
781 } else {
782 // current SoCoin classes don't support Unincode here, apparently.
783 // text << VP1Msg::str("(")+QChar(0x03B7)+","+QChar(0x03D5)+VP1Msg::str(")=(")
784 // +VP1Msg::str(mom.pseudoRapidity())+VP1Msg::str(VP1LinAlgUtils::phiFromXY(mom.x(), mom.y() ))+VP1Msg::str(")");
785 double pseudoRapidity = mom.eta();
786 text << VP1Msg::str("(eta,phi)=(")
787 +VP1Msg::str(pseudoRapidity)+VP1Msg::str(",")+VP1Msg::str(VP1LinAlgUtils::phiFromXY(mom.x(), mom.y() ))+VP1Msg::str(")");
788 }
789 }
790
791 unsigned int row=0;
792 for(const QString& str : text){
793 QByteArray array = str.toLatin1();
794 labelText->string.set1Value(row++,array.data());
795 }
796
797 //Position
798 float labelTrackOffset = theclass->common()->controller()->trackLabelTrkOffset();
799 unsigned int point=(points->size()-1)*labelTrackOffset;
800 Amg::Vector3D labelPos = (*points)[point] ;
801
802// NOTE: those options can be used if we want different label positions:
803// if (labels&TrackSystemController::PosEndOfTrack)
804// labelPos= points->back();
805// else if (labels&TrackSystemController::PosBeginOfTrack)
806// labelPos= points->front ();
807// else if (labels&TrackSystemController::PosMidOfTrack)
808// labelPos= (*points)[points->size()/2];
809
810 SoTranslation *labelTranslate = new SoTranslation;
811 float offScale=10.0;
812 int xOffset = theclass->common()->controller()->labelXOffset() ;
813 int yOffset = theclass->common()->controller()->labelYOffset() ;
814 int zOffset = theclass->common()->controller()->labelZOffset() ;
815 labelTranslate->translation.setValue(labelPos.x()+(xOffset*offScale),labelPos.y()+(yOffset*offScale),labelPos.z()+(zOffset*offScale));
816
817 SoMaterial *sMat = new SoMaterial();
818 SoMFColor sColor;
819 sColor.setValue(SbColor(0, 0, 1));
820 sMat->diffuseColor = sColor;
821
822 label_sep->addChild(labelTranslate);
823 label_sep->addChild(labelText);
824 }
825
826 //Attach if visible:
827 if (theclass->m_visible)
829}
830
831//____________________________________________________________________
833{
834 theclass->currentMaterialChanged();
835 std::map<std::pair<int,double>,AssocObjAttachmentHandle *>::iterator it,itE(attachmentHandles.end());
836 for (it = attachmentHandles.begin();it!=itE;++it)
837 it->second->trackMaterialChanged();
838}
839
840//____________________________________________________________________
841double TrackHandleBase::Imp::dist(const SbVec3f& p1,const SbVec3f& p2)//TODO: to linalgs..
842{
843 float x1,x2,y1,y2,z1,z2;
844 p1.getValue(x1,y1,z1);
845 p2.getValue(x2,y2,z2);
846 return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
847}
848
849//____________________________________________________________________
850void TrackHandleBase::Imp::convertLineSetToCylinders(SoLineSet*line,SoSeparator*sep,const double& cylradius)
851{
852 //TODO: belongs in VP1Utils
853 SoVertexProperty *vertices = static_cast<SoVertexProperty *>(line->vertexProperty.getValue());
854 if (!vertices)
855 return;
856 int ivert(0);
857 SbMatrix lastTransf;
858 lastTransf.makeIdentity();
859
860 for (int iline=0;iline<line->numVertices.getNum();++iline) {
861 int nvert=line->numVertices[iline];
862 if (nvert<2) {
863 ivert += nvert;
864 continue;
865 }
866 for (int jvert= ivert; jvert<ivert+nvert-1;++jvert) {
867 SbVec3f p1 = vertices->vertex[jvert].getValue();
868 SbVec3f p2 = vertices->vertex[jvert+1].getValue();
869 SoCylinder * cyl = new SoCylinder;
870 cyl->radius = cylradius;
871 const double l(dist(p1,p2));
872 cyl->height = l;
873 //First translate (0,l/2,0), then rotate (0,1,0) into (p2-p1), then translate p1.:
874 SbMatrix m;
875 m.setTranslate(SbVec3f(0,0.5*l,0));
876 SbVec3f v(p2); v -= p1;
877 SbRotation rot(SbVec3f(0,1,0),v);
878 SbMatrix m2; m2.setRotate(rot);
879 m.multRight(m2);
880 SbMatrix m3;
881 m3.setTranslate(p1);
882 m.multRight(m3);
883 //m is the transform we need in front of our cylinder.
884 //However, we need to first add the inverse of all previous transforms.
885 SbMatrix mat;
886 mat = m;
887 mat.multRight(lastTransf.inverse());
888 SoMatrixTransform * mt = new SoMatrixTransform;
889 mt->matrix.setValue(mat);
890 sep->addChild(mt);
891 sep->addChild(cyl);
892 lastTransf = m;
893 }
894 ivert += nvert;
895 }
896}
897
898//____________________________________________________________________
900{
901 VP1Msg::messageDebug("TrackHandleBase::Imp::attach3DObjects() - 1");
902
903 if (!theclass->m_currentmaterial) {
904 theclass->m_currentmaterial = determineMaterial();
905 theclass->m_currentmaterial->ref();
907 }
908 if (line && theclass->m_collhandle->sephelper()) {
909 VP1Msg::messageDebug("TrackHandleBase::Imp::attach3DObjects() - 2");
910 theclass->m_collhandle->sephelper()->addNodeUnderMaterial(line,theclass->m_currentmaterial);
911 double tube_r(theclass->m_collhandle->trackTubeRadius());
912 if (tube_r) {
914 extraRepresentation->removeAllChildren();
915 } else {
916 extraRepresentation = new SoSeparator;
917 extraRepresentation->ref();
918 theclass->common()->registerTrack(extraRepresentation,theclass);
919 }
921 if (!extraRepAttached) {
922 theclass->m_collhandle->sephelper()->addNodeUnderMaterial(extraRepresentation,theclass->m_currentmaterial);
923 extraRepAttached=true;
924 }
925 }
926 }
927 if (label_sep && theclass->common()->textSep() && theclass->common()->controller()->doTrackLabels())
928 theclass->common()->textSep()->addChild(label_sep);
929
930 if (extrapSurfaces_sep) theclass->m_collhandle->sephelper()->addNodeUnderMaterial(extrapSurfaces_sep,theclass->m_currentmaterial);
931}
932
933//____________________________________________________________________
935{
936 if (!theclass->m_currentmaterial)
937 return;//Can never have been attached!
938 if (line && theclass->m_collhandle->sephelper()) {
939 theclass->m_collhandle->sephelper()->removeNodeUnderMaterial(line,theclass->m_currentmaterial);
941 theclass->m_collhandle->sephelper()->removeNodeUnderMaterial(extraRepresentation,theclass->m_currentmaterial);
942 extraRepAttached=false;
943 }
944 }
945 if (label_sep && theclass->common()->textSep())
946 theclass->common()->textSep()->removeChild(label_sep);
947
949 theclass->m_collhandle->sephelper()->removeNodeUnderMaterial(extrapSurfaces_sep,theclass->m_currentmaterial);
950}
951
952//____________________________________________________________________
954{
955 //We need to change the current material. This means we need to
956 //clear the cache. Only if we are visible do we need to do a
957 //detach->clear material->attach cycle to trigger attachment under new material.
958
960 return;//We have no material cached and is thus not attached either.
961 if (m_visible) {
962 //See if the material changed. If it did, detach, update the material, attach again.
963 SoMaterial * newmat = m_d->determineMaterial();
964 newmat->ref();
965 if (newmat!=m_currentmaterial) {
966 m_d->detach3DObjects();
967 m_currentmaterial->unref();
968 m_currentmaterial = newmat;
969 m_d->attach3DObjects();
970 m_d->materialChanged();
971 } else {
972 newmat->unref();
973 }
974 } else {
975 //Just clear material.
976 m_currentmaterial->unref();
977 m_currentmaterial = nullptr;
978 m_d->materialChanged();
979 }
980}
981
982//____________________________________________________________________
984{
985 // debug msg:
986 // theclass->collHandle()->systemBase()->message("ensureInitPointsRaw start" );
987
988 if (points_raw)
989 return;
990 points_raw = new std::vector<Amg::Vector3D >;
991
993 // Get information about this path //
995
997
998 if (pathInfo_TrkTrack) {
999 Amg::Vector3D * firstmomentum(nullptr);
1000 if (pathInfo_TrkTrack->trackParameters())
1001 points_raw->reserve(pathInfo_TrkTrack->trackParameters()->size());
1002 bool unsafeparts(false);
1003 Trk::TrackStates::const_iterator tsos_iter = pathInfo_TrkTrack->trackStateOnSurfaces()->begin();
1004 Trk::TrackStates::const_iterator tsos_end = pathInfo_TrkTrack->trackStateOnSurfaces()->end();
1005 const Trk::TrackParameters* trackParam;
1006 for (; tsos_iter != tsos_end; ++tsos_iter) {
1007 if (!VP1TrackSanity::isSafe(*tsos_iter)) {
1008 unsafeparts = true;
1009 continue;
1010 }
1011 if (theclass->collHandle()->ignoreMEOTinProp() && (*tsos_iter)->materialEffectsOnTrack())
1012 continue;
1013 trackParam = (*tsos_iter)->trackParameters();
1014 if (trackParam) {
1015 if (!VP1TrackSanity::isSafe(trackParam)) {
1016 unsafeparts = true;
1017 continue;
1018 }
1019 trackParam->position();//test
1020 points_raw->push_back( trackParam->position() );
1021 if (!firstmomentum) {
1022 firstmomentum = new Amg::Vector3D(trackParam->momentum());
1023 }
1024 }
1025 }
1026 if (unsafeparts)
1027 theclass->collHandle()->systemBase()->message("WARNING: Ignored unsafe parts of track!");
1028 if (points_raw->size()==1) {
1029 if (!firstmomentum) {
1030 theclass->collHandle()->systemBase()->message(" TrackHandleBase ERROR: Unexpected null firstmomentum!");
1031 firstmomentum = new Amg::Vector3D(0,0,0);
1032 }
1033 if (firstmomentum->mag()==0.0) {
1034 theclass->collHandle()->systemBase()->message("TrackHandleBase ERROR: Only point on track had zero momentum. Can't add second point.");
1035 points_raw->clear();
1036 } else {
1037 VP1Msg::messageVerbose("TrackHandleBase: Adding second point in direction of initial momentum.");
1038 points_raw->push_back(points_raw->front()+(*firstmomentum)*(100.0/firstmomentum->mag()));
1039 }
1040 } else if (points_raw->empty()) {
1041 theclass->collHandle()->systemBase()->message("TrackHandleBase ERROR: No points on track.");
1042 }
1043
1044 delete firstmomentum;
1045 firstmomentum = nullptr;
1046 return;
1047 }
1048 if (pathInfo_Points)
1049 std::copy(pathInfo_Points->begin(), pathInfo_Points->end(), std::back_inserter(*points_raw));
1050 if (points_raw->size()<2) {
1051 theclass->collHandle()->systemBase()->message("TrackHandleBase ERROR: Less than two points on track provided.");
1052 points_raw->clear();
1053 } else {
1054 VP1Msg::messageVerbose( "TrackHandleBase: Created raw data "
1055 + QString::number(points_raw->size())
1056 + " points for track.");
1057 }
1058}
1059
1060//____________________________________________________________________
1062{
1064 return;
1065
1067
1068 if (pathInfo_TrkTrack) {
1069 points_propagated = new std::vector<Amg::Vector3D >();
1070 bool ok (false);
1071 if (theclass->hasCharge()&&theclass->charge()!=0.0)
1072 ok = theclass->common()->trackPropagationHelper()->makePointsCharged(*points_propagated,pathInfo_TrkTrack,
1073 theclass->collHandle()->propagator(),
1074 theclass->extrapolationParticleHypothesis(),
1075 !theclass->collHandle()->ignoreMEOTinProp(),
1076 theclass->collHandle()->extendTracks() ? theclass->common()->controller()->extrapolateToThisVolume() : nullptr );
1077 else
1078 ok = theclass->common()->trackPropagationHelper()->makePointsNeutral(*points_propagated,pathInfo_TrkTrack);
1079
1080 if (!ok) {
1081 delete points_propagated;
1084 }
1085 } else {
1086 //We just use the raw points:
1089 }
1090}
1091
1092//____________________________________________________________________
1094{
1096 return;
1097
1099
1100 //First check if we use same points for raw/propagated modes:
1102 if (raw) {
1105 return;
1106 }
1107 } else {
1110 return;
1111 }
1112 }
1113 }
1114
1115 //Time for the hard work:
1116 std::vector<Amg::Vector3D > * points=nullptr;
1117 Amg::SetVectorVector3D* projections=nullptr;
1118 if (raw) {
1120 points = points_raw;
1121 projections = points_raw_id_projections;
1122 } else {
1124 points = points_propagated;
1126 }
1127
1128 if ( !points || points->empty() || points->size()<2 ) {
1129 projections->clear();
1130 projections->insert(std::vector<Amg::Vector3D >());//error signature
1131 return;
1132 }
1133
1134 bool oneok(false);
1135 if (theclass->common()->indetProjHelper_Pixel()) {
1136 theclass->common()->indetProjHelper_Pixel()->projectPath(*points,*projections);
1137 oneok = true;
1138 }
1139 if (theclass->common()->indetProjHelper_SCT()) {
1140 theclass->common()->indetProjHelper_SCT()->projectPath(*points,*projections);
1141 oneok = true;
1142 }
1143 if (theclass->common()->indetProjHelper_TRT()) {
1144 theclass->common()->indetProjHelper_TRT()->projectPath(*points,*projections);
1145 oneok = true;
1146 }
1147
1148 if (!oneok) {
1149 projections->clear();
1150 projections->insert(std::vector<Amg::Vector3D >());//error signature
1151 }
1152}
1153
1154//____________________________________________________________________
1156{
1158 return;
1159
1161
1162 //First check if we use same points for raw/propagated modes:
1164 if (raw) {
1167 return;
1168 }
1169 } else {
1172 return;
1173 }
1174 }
1175 }
1176
1177 //Time for the hard work:
1178 std::vector<Amg::Vector3D > * points;
1179 Amg::SetVectorVector3D * projections;
1180 if (raw) {
1182 points = points_raw;
1183 projections = points_raw_muon_projections;
1184 } else {
1186 points = points_propagated;
1188 }
1189
1190 MuonChamberProjectionHelper * projhelper = theclass->common()->muonChamberProjectionHelper();
1191 if ( !VP1JobConfigInfo::hasMuonGeometry() || !projhelper || !points || points->empty() ) {
1192 projections->insert(std::vector<Amg::Vector3D >());//error signature
1193 return;
1194 }
1195
1196 //Temporary variables:
1197 Amg::Vector3D firstEndWall_pointA, firstEndWall_pointB;
1198 Amg::Vector3D secondEndWall_pointA, secondEndWall_pointB;
1199 bool outsidechamber;
1200 std::vector<Amg::Vector3D > proj1, proj2;
1201
1202 //For each (MDT) chamber we try to project all line segments on "points" to the ends of that chamber.
1203 for (std::set<GeoPVConstLink>::iterator it=theclass->touchedMuonChambers().begin(); it!=theclass->touchedMuonChambers().end(); ++it){
1204
1205 //For now, only project to end of MDT chambers:
1206 if (!projhelper->isKnownMDTChamber(*it))
1207 continue;
1208
1209 proj1.clear();
1210 proj2.clear();
1211
1212 // now loop over the stored points
1213 std::vector<Amg::Vector3D >::const_iterator pointsIt=points->begin(), pointsItEnd=points->end()-1;
1214 for (;pointsIt!=pointsItEnd; ++pointsIt) {
1215
1216 // Do projections
1217 bool ok = projhelper->projectAndConstrainLineSegmentToMDTChamberEndWalls( *it, *pointsIt, *(pointsIt+1),
1218 firstEndWall_pointA, firstEndWall_pointB,
1219 secondEndWall_pointA, secondEndWall_pointB,
1220 outsidechamber );
1221
1222 if (!ok) {
1223 theclass->collHandle()->systemBase()->message("TrackHandleBase Error: "
1224 "Problems with projectAndConstrainLineSegmentToMDTChamberEndWalls(..)");
1225 // projections->clear();
1226 // projections->push_back(std::vector<Amg::Vector3D >);//error signature
1227 continue;
1228 }
1229
1230 if (!outsidechamber){
1231 if ( proj1.empty() ) {
1232 proj1.push_back(firstEndWall_pointA); proj1.push_back(firstEndWall_pointB);
1233 } else {
1234 if ( proj1[proj1.size()-1] == firstEndWall_pointA ) {
1235 proj1.push_back(firstEndWall_pointB);//Keep adding to line part
1236 } else {
1237 //Start new line.
1238 projections->insert(proj1); proj1.clear();
1239 proj1.push_back(firstEndWall_pointA); proj1.push_back(firstEndWall_pointB);
1240 }
1241 }
1242 if ( proj2.empty() ) {
1243 proj2.push_back(secondEndWall_pointA); proj2.push_back(secondEndWall_pointB);
1244 } else {
1245 // unsure about this change...coverity 16206, sroe
1246 // if ( proj2[proj2.size()-1] == firstEndWall_pointA ) {
1247 if ( proj2[proj2.size()-1] == secondEndWall_pointA ) {
1248 proj2.push_back(secondEndWall_pointB);//Keep adding to line part
1249 } else {
1250 //Start new line.
1251 projections->insert(proj2); proj2.clear();
1252 proj2.push_back(secondEndWall_pointA); proj2.push_back(secondEndWall_pointB);
1253 }
1254 }
1255 }
1256 //proj2 fixme
1257 }
1258 if ( !proj1.empty() ) {
1259 projections->insert(proj1);
1260 }
1261 if ( !proj2.empty() ) {
1262 projections->insert(proj2);
1263 }
1264 }
1265}
1266
1267//____________________________________________________________________
1268void TrackHandleBase::registerTouchedMuonChamber( const GeoPVConstLink& chamberPV ) const
1269{
1270 m_d->touchedmuonchambers.insert(chamberPV);
1271}
1272
1273//____________________________________________________________________
1274const std::set<GeoPVConstLink>& TrackHandleBase::touchedMuonChambers() const
1275{
1276 if (!m_d->inittouchedchambers) {
1279 m_d->inittouchedchambers=true;
1280 }
1281 return m_d->touchedmuonchambers;
1282}
1283
1284//____________________________________________________________________
1286{
1287 // debug msg:
1288 // theclass->collHandle()->systemBase()->message("determineMaterial with material = "+QString::number(static_cast<unsigned int>(theclass->collHandle()->colourBy()))); //too verbose. EJWM.
1289
1290 int pdgcode(0);
1291 switch(theclass->collHandle()->colourBy()) {
1292
1294 pdgcode = theclass->pdgCode();
1295 return theclass->common()->controller()->getMaterialForPDGCode(pdgcode == SimBarCode::unknownPDG ? 0 : pdgcode);
1296
1298 if (!randommaterial) {
1299 randommaterial = new SoMaterial;
1300 randommaterial->ref();
1301 theclass->rerandomiseRandomMaterial();
1302 }
1303 return randommaterial;
1304
1306 return theclass->common()->controller()->getMaterialForCharge(theclass->hasCharge()?theclass->charge():0.0);
1308 return theclass->common()->controller()->getMaterialForMomentum(theclass->momentum().mag());
1309
1311 {
1312 // debug code:
1313 // AscObjSelectionManager* selManager= theclass->common()->ascObjSelectionManager();
1314 // TrackHandleBase* handle = 0;
1315 // if ( selManager ) {
1316 // QList<AssociatedObjectHandleBase*> selection = selManager->currentSelection();
1317 // if (!selection.empty()) handle = selection[0]->trackHandle(); // Take first at the moment, but should loop and colour by all. FIXME!
1318 // else theclass->collHandle()->systemBase()->message("Empty selection!");
1319 // } else {
1320 // theclass->collHandle()->systemBase()->message("No AscObjSelectionManager");
1321 // }
1322
1323 TrackHandleBase* handle = theclass->common()->lastSelectedTrackHandle();
1324 if (handle==nullptr) {
1325 //theclass->collHandle()->systemBase()->message("No previously selected track.");
1326 return theclass->collHandle()->material(); // use collection colouring
1327 }
1328
1329 Amg::Vector3D selectedTrackMom = handle->momentum();
1330 Amg::Vector3D thisTrackMom = theclass->momentum();
1331
1332 float phiDistance = sqrt ( pow( selectedTrackMom.phi() - thisTrackMom.phi(),2) );
1333 float etaDistance = sqrt ( pow( selectedTrackMom.eta() - thisTrackMom.eta(),2) );
1334
1335 //theclass->collHandle()->systemBase()->message("Distance "+QString::number(distance)); // debug msg
1336 float colScale=std::max(0.0, std::min(1.0,phiDistance/(M_PI))); // means that min scale is reached 0.5 of total possible distance away.
1337 float brightness= std::max(0.2, 1.0-(etaDistance/5.0) );
1338 //theclass->collHandle()->systemBase()->message("Distance "+QString::number(distance)+"\t brightness "+QString::number(brightness)); // debug msg
1339
1340 SoMaterial* mat = new SoMaterial;
1341 mat->ref();
1342
1343 // get colour of collection.
1344 const SbColor& col=theclass->collHandle()->material()->diffuseColor[0];
1345 float r,g,b;
1346 col.getValue(r,g,b);
1347
1348 double r3,g3,b3;
1349 if (colScale>0.01) {
1350
1351 //Use QColor to get HSL
1352 QColor tempCol = QColor::fromRgbF( r,g,b );
1353 double h,s,v;
1354 tempCol.getHsvF(&h,&s,&v);
1355
1356 //get opposite hue for farthest away points.
1357 h+=0.5;
1358 if (h>1.0) h-=1.0;
1359 tempCol.setHsvF(h,s,v);
1360 double r2,g2,b2;
1361 tempCol.getRgbF(&r2,&g2,&b2);
1362
1363 // closest will have collection colour - far away will have opposite colour
1364 r3 = r+(r2-r)*colScale;
1365 b3 = b+(b2-b)*colScale;
1366 g3 = g+(g2-g)*colScale;
1367
1368 } else {
1369 // too close - take default values
1370 r3=r;b3=b;g3=g;
1371 }
1372
1373 VP1MaterialButton::setMaterialParameters(mat,r3*brightness,g3*brightness,b3*brightness,
1374 theclass->collHandle()->collMaterialBrightness(),
1375 theclass->collHandle()->collMaterialTransparency());
1376
1377 return mat;
1378 }
1380 {
1381 SoMaterial* mat = theclass->common()->system()->materialFromVertex(theclass);
1382 if (mat)
1383 return mat;
1384 else
1385 return theclass->collHandle()->material();
1386 }
1388 default:
1389 return theclass->collHandle()->material();
1390 }
1391}
1392
1393//____________________________________________________________________
1395{
1396 if ( !m_d->randommaterial )//We will anyway rerandomize it when we need it
1397 return;
1398
1399 double r2 = 0.3*0.3;
1400 unsigned i(0);
1401 double r,g,b;
1402 bool ok;
1403 while (true) {
1404 r = (rand() / static_cast<double>(RAND_MAX));
1405 g = (rand() / static_cast<double>(RAND_MAX));
1406 b = (rand() / static_cast<double>(RAND_MAX));
1407 ok = true;
1408 //For now we make sure that we avoid black and red. This should be updated from bgd and highlight col automatically! (fixme).
1409 // -> and we should probably also make sure that tracks close in (eta,phi) are well separated in colour-space.
1410 if ( (r-1.0)*(r-1.0)+g*g+b*b < r2*0.5 )//avoid red (distance)
1411 ok = false;
1412 else if ( r*r/(r*r+g*g+b*b) > 0.8 )//avoid red (angle)
1413 ok = false;
1414 else if ( r*r+g*g+b*b < r2*2.0 )//avoid black
1415 ok = false;
1416 if (ok)
1417 break;
1418 ++i;
1419 if (i>50 ) {
1420 r2 *= 0.99;//To avoid problem in case we add too many forbidden spheres.
1421 if (i>1000) {
1422 //Just a safety
1423 m_d->theclass->collHandle()->systemBase()->message("TrackHandleBase::rerandomiseRandomMaterial Warning: Random colour could"
1424 " not be selected such as to satisfy all separation criterias");
1425 break;
1426 }
1427 }
1428 }
1430 collHandle()->collMaterialBrightness(),
1431 collHandle()->collMaterialTransparency());
1432}
1433
1434//____________________________________________________________________
1436{
1437 if ( !m_d->randommaterial )//We will anyway set up correctly when needed.
1438 return;
1439 float r,g,b;
1440 m_d->randommaterial->diffuseColor[0].getValue(r,g,b);
1442 collHandle()->collMaterialBrightness(),
1443 collHandle()->collMaterialTransparency());
1444}
1445
1446
1447//____________________________________________________________________
1449{
1450 if (VP1Msg::verbose()) {
1451 if (m_d->associatedObjects.contains(ao)) {
1452 m_d->theclass->collHandle()->systemBase()->message("TrackHandleBase::registerAssocObject ERROR: object already registered!");
1453 return;
1454 }
1455 }
1456 //Assume ownership of this associated object:
1457 if (!ao) {
1458 m_d->theclass->collHandle()->systemBase()->message("TrackHandleBase::registerAssocObject ERROR: object is null!");
1459 return;
1460 }
1461
1462 m_d->associatedObjects << ao;
1463}
1464
1465
1466//____________________________________________________________________
1467AssocObjAttachmentHandle * TrackHandleBase::getAttachmentHandle(int regionIndex, const double&crossoverval)
1468{
1469 std::map<std::pair<int,double>,AssocObjAttachmentHandle *>::iterator
1470 it = m_d->attachmentHandles.find(std::make_pair(regionIndex,crossoverval));
1471 if (it!=m_d->attachmentHandles.end())
1472 return it->second;
1473 AssocObjAttachmentHandle *attachHandle
1474 = new AssocObjAttachmentHandle(common()->trackLODManager()->getLODHandle(regionIndex,crossoverval),this);
1475 m_d->attachmentHandles[std::make_pair(regionIndex,crossoverval)] = attachHandle;
1476 return attachHandle;
1477}
1478
1479//____________________________________________________________________
1481{
1482 //look up from pdgCode(); // valid PDG codes > 0
1483 int pdg = pdgCode();
1484 if (pdg) {
1485 bool ok;
1486 double c = VP1ParticleData::particleCharge(pdg,ok);
1487 if (ok) {
1488 VP1Msg::messageDebug("TrackHandleBase: Determined charge from pdg code "+VP1Msg::str(pdg)+": "+VP1Msg::str(c));
1489 return c;
1490 }
1491 }
1492
1493 //Attempt to look at the first trackparameter.
1494 const Trk::Track * trk = provide_pathInfoTrkTrack();
1495 if (trk&&!trk->trackParameters()->empty()) {
1496 double c = (*(trk->trackParameters()->begin()))->charge();
1497 VP1Msg::messageDebug("TrackHandleBase: Determined charge from first track parameter: "+VP1Msg::str(c));
1498 return c;
1499 }
1500 if (VP1Msg::verbose())
1501 VP1Msg::messageDebug("Failed to determine charge.");
1502
1503 return unknown();
1504}
1505
1506//____________________________________________________________________
1508{
1509 if (m_d->chargeinit)
1510 return m_d->charge;
1511 m_d->chargeinit = true;
1512 m_d->charge = calculateCharge();
1513 return m_d->charge;
1514}
1515
1516//____________________________________________________________________
1518{
1519 if (m_d->massinit)
1520 return m_d->mass;
1521 m_d->massinit = true;
1522 int pdg = pdgCode();
1523 if (pdg) {
1524 bool ok;
1525 double m = VP1ParticleData::particleMass(pdg,ok);
1526 if (ok)
1527 m_d->mass = m;
1528 }
1529 return m_d->mass;
1530}
1531
1532//____________________________________________________________________
1534{
1535 switch(abs(pdgCode())) {
1536 case 211: return Trk::pion;
1537 case 2212: return Trk::proton;
1538 case 11: return Trk::electron;
1539 case 13: return Trk::muon;
1540 case 321://k+
1541 case 323://k*+
1542 return Trk::kaon;
1543 case 0:
1544 default:
1546 }
1547}
1548
1549//____________________________________________________________________
1550QStringList TrackHandleBase::baseInfo() const
1551{
1552 QStringList l;
1553 Amg::Vector3D mom = momentum();
1554 mom /= CLHEP::GeV;
1555 if (mom.mag2()==0.0) {
1556 l << "Momentum : 0 (undefined)";
1557 } else {
1558 l << "Momentum [GeV]: "+VP1Msg::str(mom);
1559 l << "|Pt|/|P| [GeV]: "+VP1Msg::str(mom.perp())+" / " + VP1Msg::str(mom.mag());
1560 l << VP1Msg::str("(")+QChar(0x03B7)+","+QChar(0x03D5)+VP1Msg::str(")=(")
1561 +VP1Msg::str(mom.eta())+VP1Msg::str(",")+VP1Msg::str(VP1LinAlgUtils::phiFromXY(mom.x(), mom.y() ))+VP1Msg::str(")");
1562
1563 l << "Eta: "+VP1Msg::str(mom.eta());
1564 l << "Phi: "+VP1Msg::str(VP1LinAlgUtils::phiFromXY(mom.x(), mom.y() ));
1565 }
1566 l<<"Hit summary: Pix["+VP1Msg::str(getNPixelHits())+"], SCT["+VP1Msg::str(getNSCTHits())+"], TRT["+VP1Msg::str(getNTRTHits())
1567 +"], MDT["+QString::number(getNMDTHits())+"], RPC["+QString::number(getNRPCHits())+"], TGC["+QString::number(getNTGCHits())+"], CSC["+QString::number(getNCSCHits())+"] MM["+QString::number(getNMMHits())+"], sTGC["+QString::number(getNsTGCHits())+"]";
1568
1569 return l;
1583}
1584
1585//____________________________________________________________________
1586std::optional<Amg::Vector3D> TrackHandleBase::startPoint() const
1587{
1588 m_d->ensureLoadPathInfo();
1589 if (m_d->pathInfo_TrkTrack) {
1590 Trk::TrackStates::const_iterator tsos_iter = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->begin();
1591 Trk::TrackStates::const_iterator tsos_end = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->end();
1592 for (; tsos_iter != tsos_end; ++tsos_iter) {
1593 if (common()->trackSanityHelper()->isSafe(*tsos_iter)) {
1594 const Trk::TrackParameters* trackParam = (*tsos_iter)->trackParameters();
1595 if (common()->trackSanityHelper()->isSafe(trackParam))
1596 return trackParam->position();
1597 }
1598 }
1599 } else if (m_d->pathInfo_Points&&!m_d->pathInfo_Points->empty()) {
1600 return m_d->pathInfo_Points->at(0);
1601 }
1602 return {};
1603}
1604
1605//____________________________________________________________________
1606std::optional<Amg::Vector3D> TrackHandleBase::endPoint() const
1607{
1608 m_d->ensureLoadPathInfo();
1609 if (m_d->pathInfo_TrkTrack) {
1610 Trk::TrackStates::const_reverse_iterator tsos_iter = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->rend();
1611 Trk::TrackStates::const_reverse_iterator tsos_end = m_d->pathInfo_TrkTrack->trackStateOnSurfaces()->rbegin();
1612 for (; tsos_iter != tsos_end; ++tsos_iter) {
1613 if (common()->trackSanityHelper()->isSafe(*tsos_iter)) {
1614 const Trk::TrackParameters* trackParam = (*tsos_iter)->trackParameters();
1615 if (common()->trackSanityHelper()->isSafe(trackParam))
1616 return trackParam->position();
1617 }
1618 }
1619 } else if (m_d->pathInfo_Points&&!m_d->pathInfo_Points->empty()) {
1620 return m_d->pathInfo_Points->back();
1621 }
1622 return {};
1623}
1624
1626{
1627 std::optional<Amg::Vector3D> start = startPoint();
1628 if (!start) return false;
1629 return start->perp()<1100 &&fabs( start->z())<3500;
1630}
1631
1632//____________________________________________________________________
1633const QList<AssociatedObjectHandleBase*>& TrackHandleBase::getAllAscObjHandles() const
1634{
1635 return m_d->associatedObjects;
1636}
1637
1638std::vector< Amg::Vector3D > * TrackHandleBase::hackGetPointsPropagated()
1639{
1640 m_d->ensureInitPointsPropagated();
1641 return m_d->points_propagated;
1642}
1643
1644//____________________________________________________________________
1646public:
1648 : trackhandle(th),
1649 trackmat(nullptr),
1650 lodHandle(tlh),
1651 septrack_simple(nullptr),
1652 septrack_detailed(nullptr),
1654 attached(false) {}
1656 SoMaterial* trackmat;
1658 SoSeparator * septrack_simple;
1659 SoSeparator * septrack_detailed;
1660 void ensureInit();
1661 static SoPickStyle * pickStyle;
1665 {
1666 if (attached)
1667 return;
1668 attached=true;
1669 if (!septrack_detailed)
1670 return;//We attach in ensureInit in this case!
1672 }
1674 {
1675 if (!attached)
1676 return;
1677 attached=false;
1678 if (!septrack_detailed)
1679 return;
1681 }
1682 static SoMaterial * dummymaterial;
1683};
1684SoPickStyle * AssocObjAttachmentHandle::Imp::pickStyle = nullptr;
1686
1687//____________________________________________________________________
1689{
1690 bool b = m_d->trackhandle->visible();
1691 if (b&&!m_d->trackhandle->currentMaterial())
1692 VP1Msg::message("ERROR: track is visible but has not current material!!");
1693 if (b)
1694 m_d->ensureAttached();
1695 else
1696 m_d->ensureDetached();
1697}
1698
1699//____________________________________________________________________
1701 : m_d ( new Imp(tlh,th) )
1702{
1703 if (!tlh)
1704 VP1Msg::message("AssocObjAttachmentHandle ERROR: constructed with null LOD handle!");
1705 if (!Imp::dummymaterial) {
1706 Imp::dummymaterial = new SoMaterial;
1707 Imp::dummymaterial->ref();
1708 }
1709}
1710
1711//____________________________________________________________________
1713{
1714 if (VP1Msg::verbose()) {
1715 if ((m_d->septrack_detailed && m_d->pickStyleChildIdx != m_d->septrack_detailed->findChild(Imp::pickStyle))
1716 ||(m_d->septrack_simple&&m_d->pickStyleChildIdx != m_d->septrack_simple->findChild(Imp::pickStyle))) {
1717 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes detected wrong pickStyleChildIdx");
1718 return;
1719 }
1720 }
1721
1722 if (Imp::pickStyle) {
1723 Imp::pickStyle->unref();
1724 if ( Imp::pickStyle->getRefCount()==1 ) {
1725 Imp::pickStyle->unref();
1726 Imp::pickStyle = nullptr;
1727 }
1728 }
1729
1730 if (m_d->septrack_simple)
1731 m_d->septrack_simple->unref();
1732 if (m_d->septrack_detailed)
1733 m_d->septrack_detailed->unref();
1734 if (m_d->trackmat)
1735 m_d->trackmat->unref();
1736 delete m_d;
1737}
1738
1739//____________________________________________________________________
1741{
1742 SoMaterial * m = m_d->trackhandle->currentMaterial();
1743 if (m_d->trackmat==m)
1744 return;
1745 if (!m) {
1746 if (m_d->trackhandle->visible())
1747 VP1Msg::message("ERROR: track is visible but has no current material!!");
1749 }
1750 m->ref();
1751 if (m_d->trackmat) {
1752 if ( m_d->septrack_simple && m_d->septrack_simple->findChild(m_d->trackmat) > -1 )
1753 m_d->septrack_simple->replaceChild(m_d->trackmat,m);
1754 if ( m_d->septrack_detailed && m_d->septrack_detailed->findChild(m_d->trackmat) > -1 )
1755 m_d->septrack_detailed->replaceChild(m_d->trackmat,m);
1756 m_d->trackmat->unref();
1757 }
1758 m_d->trackmat = m;
1759}
1760
1761//____________________________________________________________________
1763{
1764 if (septrack_simple)
1765 return;
1766 septrack_simple = new SoSeparator;
1767 septrack_detailed = new SoSeparator;
1768 septrack_simple->ref();
1769 septrack_detailed->ref();
1770
1771 if (!pickStyle) {
1772 pickStyle = new SoPickStyle;
1773 pickStyle->style=SoPickStyle::UNPICKABLE;
1774 pickStyle->ref();
1775 }
1776 pickStyle->ref();
1777 if (attached) {
1778 attached = false;
1780 }
1781}
1782
1783//____________________________________________________________________
1784void AssocObjAttachmentHandle::attachNodes( SoNode*simple, SoNode*detailed, bool unpickable )
1785{
1786 if (!m_d->trackhandle->visible())
1787 return;
1788 m_d->ensureInit();
1789 if (!m_d->trackmat) {
1790 SoMaterial * m = m_d->trackhandle->currentMaterial();
1791 if (!m)
1792 m = Imp::dummymaterial;//For now we attach a dummy material.
1793 m_d->trackmat=m;
1794 m->ref();
1795 m_d->septrack_simple->addChild(m);
1796 m_d->septrack_detailed->addChild(m);
1797 }
1798
1799 if (VP1Msg::verbose()) {
1800 if (m_d->pickStyleChildIdx != m_d->septrack_detailed->findChild(Imp::pickStyle)
1801 ||m_d->pickStyleChildIdx != m_d->septrack_simple->findChild(Imp::pickStyle)) {
1802 VP1Msg::message("ERROR: AssocObjAttachmentHandle::attachNodes detected wrong pickStyleChildIdx");
1803 return;
1804 }
1805 if (m_d->septrack_simple->findChild(simple)>-1||m_d->septrack_detailed->findChild(detailed)>-1) {
1806 VP1Msg::message("ERROR: AssocObjAttachmentHandle::attachNodes Already attached!");
1807 return;
1808 }
1809 }
1810 if (unpickable) {
1811 if (m_d->pickStyleChildIdx==-1) {
1812 m_d->pickStyleChildIdx = m_d->septrack_simple->getNumChildren();
1813 m_d->septrack_simple->addChild(Imp::pickStyle);
1814 m_d->septrack_detailed->addChild(Imp::pickStyle);
1815 }
1816 m_d->septrack_simple->addChild(simple);
1817 m_d->septrack_detailed->addChild(detailed);
1818 } else {
1819 if (m_d->pickStyleChildIdx>-1) {
1820 m_d->septrack_simple->insertChild(simple,m_d->pickStyleChildIdx);
1821 m_d->septrack_detailed->insertChild(detailed,m_d->pickStyleChildIdx);
1822 ++(m_d->pickStyleChildIdx);
1823 } else {
1824 m_d->septrack_simple->addChild(simple);
1825 m_d->septrack_detailed->addChild(detailed);
1826 }
1827 }
1828
1829 //Should we update the overall attachment status?:
1830 if (m_d->trackhandle->visible() && m_d->septrack_simple->getNumChildren() == 2 + (m_d->pickStyleChildIdx==-1?0:1)) {
1831 m_d->ensureAttached();
1832 }
1833}
1834
1835//____________________________________________________________________
1836void AssocObjAttachmentHandle::setPickableStateOfNodes( SoNode*simple, SoNode*detailed, bool unpickable )
1837{
1838 if (VP1Msg::verbose()) {
1839 VP1Msg::messageVerbose("AssocObjAttachmentHandle::setPickableStateOfNodes called with unpickable = "
1840 +QString(unpickable?"true":"false"));
1841 if (!simple||!detailed) {
1842 VP1Msg::messageVerbose("AssocObjAttachmentHandle::setPickableStateOfNodes ERROR: Called with null pointers!");
1843 return;
1844 }
1845 }
1846 m_d->ensureInit();
1847 int isimple = m_d->septrack_simple->findChild(simple);
1848 if (VP1Msg::verbose()) {
1849 if (m_d->septrack_simple->getNumChildren()!=m_d->septrack_detailed->getNumChildren()) {
1850 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes septrack_simple->getNumChildren()"
1851 "!=m_d->septrack_detailed->getNumChildren().");
1852 return;
1853 }
1854 int idetailed = m_d->septrack_detailed->findChild(detailed);
1855 if (idetailed!=isimple) {
1856 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes"
1857 " called with simple and detailed nodes that are not at same child idx!");
1858 return;
1859 }
1860 if (m_d->pickStyleChildIdx != m_d->septrack_detailed->findChild(Imp::pickStyle)
1861 ||m_d->pickStyleChildIdx != m_d->septrack_simple->findChild(Imp::pickStyle)) {
1862 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes detected wrong pickStyleChildIdx");
1863 return;
1864 }
1865 }
1866 if (isimple<0) {
1867 VP1Msg::messageDebug( "WARNING: AssocObjAttachmentHandle::setPickableStateOfNodes"
1868 " called with nodes that are not currently children. Calling attachNodes(..)." );
1869 attachNodes(simple, detailed, unpickable);
1870 return;
1871 }
1872 if (unpickable == (m_d->pickStyleChildIdx>-1&&isimple>m_d->pickStyleChildIdx)) {
1873 VP1Msg::messageDebug("WARNING: AssocObjAttachmentHandle::setPickableStateOfNodes"
1874 " already in correct state.");
1875 return;
1876 }
1877
1878 simple->ref();//To avoid deletion upon removeChild calls.
1879 detailed->ref();
1880 if (unpickable) {
1881 m_d->septrack_simple->removeChild(simple);
1882 m_d->septrack_detailed->removeChild(detailed);
1883 if (m_d->pickStyleChildIdx==-1) {
1884 m_d->pickStyleChildIdx = m_d->septrack_simple->getNumChildren();
1885 m_d->septrack_simple->addChild(Imp::pickStyle);
1886 m_d->septrack_detailed->addChild(Imp::pickStyle);
1887 } else {
1888 --(m_d->pickStyleChildIdx);
1889 }
1890 m_d->septrack_simple->addChild(simple);
1891 m_d->septrack_detailed->addChild(detailed);
1892 } else {
1893 if (m_d->pickStyleChildIdx==-1) {
1894 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes Inconsistent logic");
1895 simple->unref();
1896 detailed->unref();
1897 return;
1898 }
1899 if (m_d->pickStyleChildIdx==isimple-1&&isimple==m_d->septrack_simple->getNumChildren()-1) {
1900 //pickStyle object no longer needed:
1901 VP1Msg::messageVerbose("AssocObjAttachmentHandle::setPickableStateOfNodes detaching pickstyle");
1902 m_d->septrack_simple->removeChild(Imp::pickStyle);
1903 m_d->septrack_detailed->removeChild(Imp::pickStyle);
1904 m_d->pickStyleChildIdx = -1;
1905 } else {
1906 //Move children left of the pickstyle object.
1907 m_d->septrack_simple->removeChild(simple);
1908 m_d->septrack_detailed->removeChild(detailed);
1909 m_d->septrack_simple->insertChild(simple,m_d->pickStyleChildIdx);
1910 m_d->septrack_detailed->insertChild(detailed,m_d->pickStyleChildIdx);
1911 ++(m_d->pickStyleChildIdx);
1912 }
1913 }
1914 simple->unref();
1915 detailed->unref();
1916}
1917
1918//____________________________________________________________________
1919void AssocObjAttachmentHandle::detachNodes( SoNode*simple, SoNode*detailed )
1920{
1921 if (!m_d->trackmat)
1922 return;
1923 int isimple = m_d->septrack_simple->findChild(simple);
1924 if (VP1Msg::verbose()) {
1925 if (!simple||!detailed) {
1926 VP1Msg::messageVerbose("AssocObjAttachmentHandle::detach ERROR: Called with null pointers!");
1927 return;
1928 }
1929 if (m_d->septrack_simple->getNumChildren()!=m_d->septrack_detailed->getNumChildren()) {
1930 VP1Msg::message("ERROR: AssocObjAttachmentHandle::detachNodes septrack_simple->getNumChildren()"
1931 "!=m_d->septrack_detailed->getNumChildren().");
1932 return;
1933 }
1934 if (m_d->pickStyleChildIdx != m_d->septrack_detailed->findChild(Imp::pickStyle)
1935 ||m_d->pickStyleChildIdx != m_d->septrack_simple->findChild(Imp::pickStyle)) {
1936 VP1Msg::message("ERROR: AssocObjAttachmentHandle::detachNodes detected wrong pickStyleChildIdx");
1937 return;
1938 }
1939 if (isimple==-1) {
1940 VP1Msg::message("ERROR: AssocObjAttachmentHandle::detachNodes Not previously attached!");
1941 return;
1942 }
1943 if (m_d->septrack_detailed->findChild(detailed)!=isimple) {
1944 VP1Msg::message("ERROR: AssocObjAttachmentHandle::setPickableStateOfNodes"
1945 " called with simple and detailed nodes that are not at same child idx!");
1946 return;
1947 }
1948 }
1949 m_d->septrack_simple->removeChild(simple);
1950 m_d->septrack_detailed->removeChild(detailed);
1951 if ( m_d->pickStyleChildIdx!=-1
1952 && isimple>m_d->pickStyleChildIdx
1953 && m_d->pickStyleChildIdx==m_d->septrack_simple->getNumChildren()-1 ) {
1954 VP1Msg::messageVerbose("AssocObjAttachmentHandle::detachNodes detaching pickstyle");
1955 m_d->septrack_simple->removeChild(Imp::pickStyle);
1956 m_d->septrack_detailed->removeChild(Imp::pickStyle);
1957 m_d->pickStyleChildIdx = -1;
1958 }
1959
1960 //Should we update the overall attachment status?:
1961 if (m_d->trackhandle->visible() && m_d->septrack_simple->getNumChildren() == 1 + (m_d->pickStyleChildIdx==-1?0:1))
1962 m_d->ensureDetached();
1963}
1964
1966 const MuonGM::MuonReadoutElement* re = nullptr;
1967 switch (TrkObjToString::type(&mb)){
1970 break;
1973 break;
1976 break;
1979 break;
1982 break;
1983 case TrkObjToString::MM:
1984 re = VP1DetInfo::muonDetMgr()->getMMReadoutElement(mb.identify());
1985 break;
1986 default:
1987 VP1Msg::message("TrackHandleBase::getReadoutElement:: Unable to find matching readoutElement");
1988 }
1989 return re;
1990 }
1991
1992
1993
1994//____________________________________________________________________
1995QList<AssociatedObjectHandleBase*> TrackHandleBase::getVisibleMeasurements() const
1996{
1997 QList<AssociatedObjectHandleBase*> l;
1998 if (!m_d->tsos_ascobjs) return l;
1999 std::vector<AssociatedObjectHandleBase*>::iterator
2000 it(m_d->tsos_ascobjs->begin()),
2001 itE(m_d->tsos_ascobjs->end());
2002 for (;it!=itE;++it)
2003 if ((*it)->hasMeasurement()&&(*it)->visible())
2004 l << (*it);
2005 return l;
2006}
2007
2008void TrackHandleBase::fillObjectBrowser( QList<QTreeWidgetItem *>& listOfItems) {
2009 VP1Msg::messageVerbose("TrackHandleBase::fillObjectBrowser");
2010
2011 assert(m_d->m_objBrowseTree==0);
2012 m_d->m_objBrowseTree = new QTreeWidgetItem();
2013
2014 QString direction = QString::fromUtf8("(\u03B7,\u03D5)=[") + QString::number(momentum().eta(),'f',2) + ","+QString::number(momentum().phi(),'f',2)+"], ";
2015 QString l = direction + shortInfo();
2016 m_d->m_objBrowseTree->setText(0, type()+QString(QString::number(listOfItems.size())) );
2017 m_d->m_objBrowseTree->setText(1, l );
2018
2019 if (!visible()) {
2020 m_d->m_objBrowseTree->setFlags(Qt::ItemFlags()); // not selectable, not enabled
2021 }
2022 listOfItems << browserTreeItem();
2023}
2024
2025QTreeWidgetItem* TrackHandleBase::browserTreeItem() const {return m_d->m_objBrowseTree;}
2026
2027//____________________________________________________________________
2029{
2030 if ( !browserTreeItem()) {
2031 VP1Msg::messageVerbose("visibleStateChanged: No m_objBrowseTree!");
2032 return;
2033 }
2034
2035 if (!visible()) {
2036 browserTreeItem()->setFlags(Qt::ItemFlags()); // not selectable, not enabled
2037 } else {
2038 browserTreeItem()->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); // selectable, enabled
2039 }
2040 QFont itemFont = browserTreeItem()->font(0);
2041 itemFont.setStrikeOut(!visible());
2042 browserTreeItem()->setFont(0, itemFont);
2043 browserTreeItem()->setFont(1, itemFont);
2044}
const boost::regex re(r_e)
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
static Double_t tc
static const Attributes_t empty
constexpr int pow(int base, int exp) noexcept
void setDistToNextPar(const double &)
virtual TrackCommonFlags::TSOSPartsFlags parts() const
Definition AscObj_TSOS.h:59
virtual void setVisible(bool)
Amg::Vector3D approxCenter() const
Imp(TrackLODHandle *tlh, TrackHandleBase *th)
void attachNodes(SoNode *simple, SoNode *detailed, bool unpickable)
AssocObjAttachmentHandle(TrackLODHandle *, TrackHandleBase *)
void setPickableStateOfNodes(SoNode *simple, SoNode *detailed, bool unpickable)
Will attach if not currently attached.
void detachNodes(SoNode *simple, SoNode *detailed)
Header file for AthHistogramAlgorithm.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition DataVector.h:847
bool isKnownMDTChamber(const GeoPVConstLink &mdtChamber)
bool projectAndConstrainLineSegmentToMDTChamberEndWalls(const GeoPVConstLink &mdtChamber, const Amg::Vector3D &pointA, const Amg::Vector3D &pointB, Amg::Vector3D &firstEndWall_pointA, Amg::Vector3D &firstEndWall_pointB, Amg::Vector3D &secondEndWall_pointA, Amg::Vector3D &secondEndWall_pointB, bool &outsidechamber)
const RpcReadoutElement * getRpcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const MMReadoutElement * getMMReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const sTgcReadoutElement * getsTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const CscReadoutElement * getCscReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Base class for the XxxReadoutElement, with Xxx = Mdt, Rpc, Tgc, Csc.
static const int unknownPDG
Definition SimBarCode.h:25
SoNode * translateSurface(const Trk::Surface &sf, const bool &simple=false) const
void decrementNumberOfObjectsForPV(const GeoPVConstLink &chamberPV)
void incrementNumberOfObjectsForPV(const GeoPVConstLink &chamberPV)
AscObj_TSOS * addTSOS(const Trk::TrackStateOnSurface *tsos, unsigned index) const
std::map< std::pair< int, double >, AssocObjAttachmentHandle * > attachmentHandles
const std::vector< Amg::Vector3D > * pathInfo_Points
Used in all other cases.
Amg::SetVectorVector3D * points_propagated_id_projections
QList< AssociatedObjectHandleBase * > associatedObjects
void addPathsToSoLineSetAndSoVertexProperty(const Amg::SetVectorVector3D *paths, int &iver, int &numlines, SoLineSet *, SoVertexProperty *) const
void ensureInitPointsProjections_Muon(bool raw)
void addPathToSoLineSetAndSoVertexProperty(const std::vector< Amg::Vector3D > &points, int &iver, int &numlines, SoLineSet *, SoVertexProperty *) const
SoMaterial * determineMaterial()
SoSeparator * extrapSurfaces_sep
for debugging.
TrackCommonFlags::TSOSPartsFlags shownTSOSParts
const Trk::Track * pathInfo_TrkTrack
Used in the case of a Trk::Track.
static double dist(const SbVec3f &p1, const SbVec3f &p2)
Amg::SetVectorVector3D * points_raw_id_projections
SoSeparator * extraRepresentation
std::unique_ptr< std::vector< AssociatedObjectHandleBase * > > tsos_ascobjs
std::set< GeoPVConstLink > touchedmuonchambers
TrackHandleBase * theclass
static bool isSane(const Amg::Vector3D &p)
static void convertLineSetToCylinders(SoLineSet *line, SoSeparator *sep, const double &cylradius)
std::vector< Amg::Vector3D > * points_propagated
std::vector< Amg::Vector3D > * points_raw
void ensureInitPointsProjections_InDet(bool raw)
QTreeWidgetItem * m_objBrowseTree
Amg::SetVectorVector3D * points_raw_muon_projections
Amg::SetVectorVector3D * points_propagated_muon_projections
Imp(TrackHandleBase *tc)
TrackCommonFlags::TSOSPartsFlags customColouredTSOSParts
void registerTouchedMuonChamber(const GeoPVConstLink &) const
If not earlier, touched muon chambers must me registered at latest when this method is invoked.
virtual QString shortInfo() const
returns mom and hit information about track
void setCustomColouredTSOSParts(TrackCommonFlags::TSOSPartsFlags f)
TrackCommonFlags::TSOSPartsFlags customColouredTSOSParts() const
QList< AssociatedObjectHandleBase * > getVisibleMeasurements() const
virtual const Trk::Track * provide_pathInfoTrkTrack() const
void updateShapes_TSOSWithMaterialEffects()
virtual int pdgCode() const
0 means unknown
const std::set< GeoPVConstLink > & touchedMuonChambers() const
virtual void fillObjectBrowser(QList< QTreeWidgetItem * > &list)
Called in child classes.
virtual double calculateCharge() const
virtual unsigned getNTRTHits() const
virtual unsigned getNMDTHits() const
virtual void visibleStateChanged()
override if need to take action in this case.
static double unknown()
QTreeWidgetItem * browserTreeItem() const
virtual unsigned getNMMHits() const
friend class TrackCollHandleBase
friend class AssociatedObjectHandleBase
AssocObjAttachmentHandle * getAttachmentHandle(int regionIndex, const double &crossoverval)
friend class AssocObjAttachmentHandle
TrackHandleBase(TrackCollHandleBase *)
void setVisible(bool)
use by the collection handle.
virtual std::optional< Amg::Vector3D > startPoint() const
returns 0 if can't find start point.
virtual void ensureTouchedMuonChambersInitialised() const
virtual Trk::ParticleHypothesis extrapolationParticleHypothesis() const
Default implementation of this next method bases hypothesis on pdgCode() and charge():
virtual unsigned getNSCTHits() const
virtual std::optional< Amg::Vector3D > endPoint() const
returns 0 if can't find start point.
virtual double mass() const
void updateShapes_TSOSWithErrors()
TrackCommonFlags::TSOSPartsFlags shownTSOSParts() const
virtual unsigned getNTGCHits() const
virtual unsigned getNCSCHits() const
virtual void ensureInitTSOSs(std::unique_ptr< std::vector< AssociatedObjectHandleBase * > > &)
Ensure that the TSOSs are initialized.
void updateShapes_TSOSWithMeasurements()
QStringList baseInfo() const
virtual const MuonGM::MuonReadoutElement * getMuonReadoutElement(const Trk::RIO_OnTrack &mb) const
virtual unsigned getNRPCHits() const
double charge() const
virtual Amg::Vector3D momentum() const
void setShownTSOSParts(TrackCommonFlags::TSOSPartsFlags f)
virtual bool isIDTrack() const
bool visible() const
virtual unsigned getNMuonHits() const
void updateRandomColourTransparencyAndBrightness()
virtual unsigned getNsTGCHits() const
TrackCollHandleBase * collHandle() const
std::vector< Amg::Vector3D > * hackGetPointsPropagated()
FIXME.
SoMaterial * m_currentmaterial
bool hasCharge() const
TrackSysCommonData * common() const
static int numberOfInstances()
virtual unsigned getNPixelHits() const
const QList< AssociatedObjectHandleBase * > & getAllAscObjHandles() const
override if need to take action in this case.
void update3DObjects(bool invalidatePropagatedPoints=false, float maxR=0.0)
virtual QString type() const
return very short word with type (maybe link with collection type?)
TrackCollHandleBase * m_collhandle
void registerAssocObject(AssociatedObjectHandleBase *)
Trackhandle assumes ownership.
void registerTrack(SoNode *, TrackHandleBase *)
TouchedMuonChamberHelper * touchedMuonChamberHelper() const
void unregisterTrack(SoNode *)
static MeasurementType type(const Trk::PrepRawData *prd)
static QString shortInfo(const Trk::MeasurementBase &mb)
Interface class for the extrapolation AlgTool, it inherits from IAlgTool Detailed information about p...
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
represents the track state (measurement, material, fit parameters and quality) at a surface.
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
static const MuonGM::MuonDetectorManager * muonDetMgr()
static bool hasMuonGeometry()
static double phiFromXY(const double &x, const double &y)
static void setMaterialParameters(SoMaterial *m, const QColor &, const double &brightness=0.0, const double &transp=0.0)
static void messageVerbose(const QString &)
Definition VP1Msg.cxx:84
static bool verbose()
Definition VP1Msg.h:31
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
static void message(const QString &, IVP1System *sys=0)
Definition VP1Msg.cxx:30
static double particleMass(const int &pdgcode, bool &ok)
static double particleCharge(const int &pdgcode, bool &ok)
static QString particleName(const int &pdgcode, bool &ok)
static QString str(const QString &s)
Definition VP1String.h:49
static bool isSafe(const Trk::TrackStateOnSurface *)
int r
Definition globals.cxx:22
std::set< std::vector< Amg::Vector3D >, VectorVector3DComparer > SetVectorVector3D
Amg::RotationMatrix3D setPhi(Amg::RotationMatrix3D mat, double angle, int convention=0)
Eigen::Matrix< double, 3, 1 > Vector3D
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1