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