ATLAS Offline Software
Loading...
Searching...
No Matches
VP1PrepRawDataSystem.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//Fixme: cleanup includes.
25
32
33#include <QBuffer>
34#include <QByteArray>
35
36#include <Inventor/nodes/SoSeparator.h>
37#include <Inventor/nodes/SoComplexity.h>
38#include <Inventor/nodes/SoTransform.h>
39#include <Inventor/nodes/SoMaterial.h>
40#include <Inventor/nodes/SoDrawStyle.h>
41#include <Inventor/nodes/SoSwitch.h>
42#include <Inventor/nodes/SoLineSet.h>
43#include <Inventor/nodes/SoPickStyle.h>
44#include <Inventor/nodes/SoVertexProperty.h>
45#include <Inventor/SoPath.h>
46
47#include <map>
48
49//Fixme: Update visuals if any detail level changes!
50
51//____________________________________________________________________
53public:
59
60 InDetProjFlags::InDetProjPartsFlags idprojflags_pixel;
61 InDetProjFlags::InDetProjPartsFlags idprojflags_sct;
62 InDetProjFlags::InDetProjPartsFlags idprojflags_trt;
64
65 SoSeparator * multisel_sep = nullptr;
67 while (multisel_sep&&multisel_sep->getNumChildren()>2)
68 multisel_sep->removeChild(2);
69 }
70
71 QList<PRDHandleBase*> currentlySelectedHandles;
72 QList<const Trk::PrepRawData*> lastEmittedPRDList;
74 currentlySelectedHandles.removeAll(0);//just to be sure
76
77 //Proper highlighting:
79 selNode_highlight->deselectAll();
81 // theclass->messageDebug("Highlighting handle...");
82 SoSeparator* target = handle->collHandle()->simpleDetailLevel() ? handle->sepSimple() : handle->sepDetailed();
83 SoPath * path = new SoPath(selNode_highlight);
84 path->ref();
85 // theclass->messageDebug("Attempting to highlight sep="+str(target));
87 theclass->message("ERROR: Failed to relocate picked node.");
88 path->unref();
89 continue;
90 }
91 selNode_highlight->select(path);
92 path->unref();
93 }
94 selNode_highlight->touch();
95 if (multisel_sep&&currentlySelectedHandles.count()>1&&controller->showSelectionLine()) {
96 SoLineSet * line = new SoLineSet;
97 SoVertexProperty * vertices = new SoVertexProperty;
98 line->vertexProperty = vertices;
99 line->numVertices.set1Value(0,currentlySelectedHandles.count());
100 int i(0);
102 Amg::Vector3D pos(handle->center());
103 vertices->vertex.set1Value(i++,pos.x(),pos.y(),pos.z());
104 }
105 multisel_sep->addChild(line);
106 //Fixme: make this unpickable!!
107
108 }
109 }
110
111 //emit signal if appropriate:
112 QList<const Trk::PrepRawData*> currentPRDs;
113 for(int i = 0; i < currentlySelectedHandles.count(); ++i) {
115 const Trk::PrepRawData* prd1 = handle->getPRD();
116 const Trk::PrepRawData* prd2 = handle->getSecondPRD();
117 if (prd1&&currentPRDs.contains(prd1)) prd1 = 0;
118 if (prd2&&currentPRDs.contains(prd2)) prd2 = 0;
119 if (!prd2) {
120 if (!prd1)
121 continue;
122 currentPRDs << prd1;
123 } else {
124 //both prd1 and prd2 are non-zero and not in the list
125 //already. Which should be first? We order them by distance to
126 //the preceding or following prd.
127
128 Amg::Vector3D p1(handle->positionPRD());
129 Amg::Vector3D p2(handle->positionSecondPRD());
130
131 if (i>0) {
132 Amg::Vector3D prevpos = currentlySelectedHandles.at(i-1)->center();
133 if ((p1-prevpos).mag2()>(p2-prevpos).mag2()) {
134 //prd2 before prd1
135 currentPRDs << prd2;
136 currentPRDs << prd1;
137 } else {
138 //prd1 before prd2
139 currentPRDs << prd1;
140 currentPRDs << prd2;
141 }
142 } else {
143 if (i+1<currentlySelectedHandles.count()) {
144 Amg::Vector3D nextpos = currentlySelectedHandles.at(i+1)->center();
145 if ((p1-nextpos).mag2()>(p2-nextpos).mag2()) {
146 //prd1 before prd2
147 currentPRDs << prd1;
148 currentPRDs << prd2;
149 } else {
150 //prd2 before prd1
151 currentPRDs << prd2;
152 currentPRDs << prd1;
153 }
154 } else {
155 //Only this one. Just add them:
156 currentPRDs << prd1;
157 currentPRDs << prd2;
158 }
159 }
160 }
161 }
162 if (currentPRDs!=lastEmittedPRDList) {
163 lastEmittedPRDList = currentPRDs;
164 theclass->messageVerbose("Emitting list of "+str(lastEmittedPRDList.count())+" selected PRDs");
165 emit theclass->selectedPRDsChanged(lastEmittedPRDList);
166 }
167 }
168
169 template <class T>
170 QList<PRDCollHandleBase*> createSpecificCollections() {
171 QList<PRDCollHandleBase*> l;
172 for (const QString& name : T::availableCollections(theclass)) {
173 T * col = new T(common,name);
174 col->init();
175 l << col;
176 }
177 return l;
178 }
179 QList<PRDCollHandleBase*> createCollections() {
180 QList<PRDCollHandleBase*> l;
181 l << createSpecificCollections<PRDCollHandle_Pixel>();
182 l << createSpecificCollections<PRDCollHandle_SCT>();
183 l << createSpecificCollections<PRDCollHandle_TRT>();
184 l << createSpecificCollections<PRDCollHandle_SpacePoints>();
185 l << createSpecificCollections<PRDCollHandle_CSC>();
186 l << createSpecificCollections<PRDCollHandle_CSC_Strip>();
187 l << createSpecificCollections<PRDCollHandle_MDT>();
188 l << createSpecificCollections<PRDCollHandle_MM>();
189 l << createSpecificCollections<PRDCollHandle_RPC>();
190 l << createSpecificCollections<PRDCollHandle_TGC>();
191 l << createSpecificCollections<PRDCollHandle_sTGC>();
192 return l;
193 }
194
196 if (!common) {
197 theclass->ensureBuildController();
199 }
200 }
201};
202
203//_____________________________________________________________________________________
205: IVP13DSystemSimple("Hits",
206 "System showing tracking hits (PRD's)",
207 "Edward.Moyse@cern.ch, Thomas.Kittelmann@cern.ch"), m_d(new Imp)
208{
209 m_d->theclass = this;
210 m_d->common = 0;
211 m_d->controller = 0;
212 m_d->idprojflags_pixel = InDetProjFlags::NoProjections;
213 m_d->idprojflags_sct = InDetProjFlags::NoProjections;
214 m_d->idprojflags_trt = InDetProjFlags::NoProjections;
215 m_d->appropriatemdtprojection = 0;
216 m_d->selNode_click = 0;
217 m_d->selNode_highlight = 0;
218 m_d->multisel_sep = 0;
219
220}
221
222//_____________________________________________________________________________________
227
228//_____________________________________________________________________________________
230{
231 messageVerbose("systemcreate");
233 message("Error: Can't retrieve MuonDetectorManager. Expect reduced performance and functionality.");//Fixme: Only if any muon collections are present!
234 m_d->ensureInitCommonData();
235}
236
237//_____________________________________________________________________________________
239{
240 if (m_d->multisel_sep) {
241 m_d->multisel_sep->unref();
242 m_d->multisel_sep=0;
243 }
244
245 delete m_d->common; m_d->common = 0;
246 m_d->controller = 0;
247}
248
249//_____________________________________________________________________________________
251{
252 messageVerbose("systemerase");
253
254 deselectAll();
255
256 m_d->common->controller()->collWidget()->clear();
257
258 m_d->common->clearEventData();
259
260 if (m_d->selNode_click) {
261 unregisterSelectionNode(m_d->selNode_click);
262 unregisterSelectionNode(m_d->selNode_highlight);
263 m_d->selNode_click->unref();
264 m_d->selNode_click=0;
265 m_d->selNode_highlight->unref();
266 m_d->selNode_highlight=0;
267 }
268
269 m_d->clearMultiSelLine();
270
271}
272
273//_____________________________________________________________________________________
274void VP1PrepRawDataSystem::buildPermanentSceneGraph(StoreGateSvc* /*detstore*/, SoSeparator * /*root*/)
275{
276 messageVerbose("buildPermanentSceneGraph (does not do anything)");
277}
278
279//_____________________________________________________________________________________
281{
282 messageVerbose("buildEventSceneGraph");
283
284 // set complexity to a lower value, so that e.g. the straws are manageable
285 SoComplexity * complexity = new SoComplexity;
286 complexity->value.setValue(0.3f);//Fixme: Hardcoded here and elsewhere
287 root->addChild(complexity);
288
289 // //Point sizes and line widths:
290 // root->addChild(m_d->controller->prdDrawStyle());
291
292 //Create collection list based on contents of event store, inform
293 //about projections, populate gui and apply states:
294 QList<PRDCollHandleBase*> cols = m_d->createCollections();
295
296 //Inform about appropriate projects:
297 for (PRDCollHandleBase* col : cols) {
298
299 connect(col,SIGNAL(detailLevelChanged()),this,SLOT(updateSelectionVisualsAndPossiblyEmitPRDList()));
300
301 PRDCollHandle_MDT* mdtcol = dynamic_cast<PRDCollHandle_MDT*>(col);
302 if (mdtcol) {
303 mdtcol->setAppropriateProjection( m_d->appropriatemdtprojection );
304 continue;
305 }
306
307 PRDCollHandle_TRT* trtcol = dynamic_cast<PRDCollHandle_TRT*>(col);
308 if (trtcol) {
309 trtcol->setAppropriateProjection(m_d->idprojflags_trt);//NB: Add for pixel/sct as well once supported!
310 continue;
311 }
312
313 }
314
315 m_d->controller->collWidget()->setCollections(cols);
316
317
318 //Add collections to event scenegraph:
319 m_d->selNode_click = new SoCooperativeSelection;
320 m_d->selNode_click->ref();
321 m_d->selNode_highlight = new SoCooperativeSelection;
322 m_d->selNode_highlight->ref();
323 m_d->selNode_click->activePolicy = SoCooperativeSelection::ACTIVE;
324 m_d->selNode_highlight->activePolicy = SoCooperativeSelection::INERT;
325 m_d->selNode_click->policy = SoCooperativeSelection::SINGLE;
326 m_d->selNode_highlight->policy = SoCooperativeSelection::SINGLE;
327
328 for (VP1StdCollection* col : m_d->controller->collWidget()->collections<VP1StdCollection>())
329 m_d->selNode_click->addChild(col->collSwitch());
330 m_d->selNode_highlight->addChild(m_d->selNode_click);
331 root->addChild(m_d->selNode_highlight);
332
333 registerSelectionNode(m_d->selNode_click);
334 registerSelectionNode(m_d->selNode_highlight);
335
336 if (!m_d->multisel_sep) {
337 m_d->multisel_sep = new SoSeparator;
338 m_d->multisel_sep->ref();
339 SoPickStyle * ps = new SoPickStyle;
340 ps->style= SoPickStyle::UNPICKABLE;
341 m_d->multisel_sep->addChild(ps);
342 m_d->multisel_sep->addChild(m_d->controller->getMultiSelectionLineMaterial());
343 }
344 root->addChild(m_d->multisel_sep);
345
346
347 messageVerbose("buildEventSceneGraph done");
348
349}
350
351
352//_____________________________________________________________________________________
354{
355 if (exception_sel)
356 message("WARNING: The PRD system always deselects all registered nodes/");
358 m_d->currentlySelectedHandles.clear();
359 m_d->selectionChanged();
360}
361
362//_____________________________________________________________________________________
364{
365 m_d->selectionChanged();
366}
367
368//_____________________________________________________________________________________
370{
371 messageVerbose("clearSelection");
372 deselectAll();
373}
374
375//_____________________________________________________________________________________
377{
378 messageVerbose("selectionModeChanged");
379 deselectAll();
380}
381
382//_____________________________________________________________________________________
384{
385 messageVerbose("updateSelectionVisualsAndPossiblyEmitPRDList");
386 m_d->selectionChanged();
387}
388
389//_____________________________________________________________________________________
391{
392 messageVerbose("userPickedNode");
393}
394
395//_____________________________________________________________________________________
397{
398 if (m_d->selNode_highlight==sel)
399 return;
400 messageVerbose("userSelectedSingleNode");
401 PRDHandleBase * handle = m_d->common->pickedPathToHandle(pickedPath);//This also pops the path, so that all shape nodes
402 //making up the whole shape will be highlighted
403 sel->deselectAll();
404
405 if (!handle) {
406 deselectAll();
407 message("Error: Could not identify picked node");
408 return;
409 }
410
411 if (!m_d->controller->selectionModeMultiple()) {
412 if (m_d->currentlySelectedHandles.count()==1&&*(m_d->currentlySelectedHandles.begin())==handle)
413 return;
414 m_d->currentlySelectedHandles.clear();
415 m_d->currentlySelectedHandles<<handle;
416 if (handle->inMuonChamber()&&m_d->controller->muonOrientToChambersOnClick()) {
417 messageVerbose("emits prdInMuonChamberSelected");
419 } else if (m_d->controller->zoomOnClick()) {
420 std::set<SoCamera*> cameras(getCameraList());
421 std::set<SoCamera*>::iterator it,itE = cameras.end();
422 for (it=cameras.begin();it!=itE;++it)
423 VP1CameraHelper::animatedZoomToPath(*it,handle->collHandle()->collSep(),pickedPath,2.0,1.0);
424 }
425 if (m_d->controller->printInfoOnClick()) {
426 for (const QString& line : handle->clicked())
427 message(line);
428 }
429 } else {
430 if (m_d->currentlySelectedHandles.contains(handle)) {
431 m_d->currentlySelectedHandles.removeAll(handle);
432 } else {
433 m_d->currentlySelectedHandles << handle;
434 }
435 }
436
437 m_d->selectionChanged();
438
439}
440
441//_____________________________________________________________________________________
443{
444 if (m_d->selNode_highlight==sel)
445 return;
446 // messageVerbose("userDeselectedSingleNode");
447}
448
449//_____________________________________________________________________________________
451{
452 if (m_d->selNode_highlight==sel)
453 return;
454 messageVerbose("userChangedSelection");
455}
456
457//_____________________________________________________________________________________
459{
460 messageVerbose("userClickedOnBgd");
461 if (!m_d->controller->selectionModeMultiple()) {
462 m_d->currentlySelectedHandles.clear();
463 m_d->selectionChanged();
464 }
465}
466
467
468//_____________________________________________________________________________________
470{
471 messageVerbose("buildController");
472 m_d->controller = new PRDSystemController(this);
473
474 messageVerbose("Passing ID projection settings on to collWidget");
475
476 connect(m_d->controller,SIGNAL(selectionModeMultipleChanged(bool)),this,SLOT(selectionModeChanged()));
477 connect(m_d->controller,SIGNAL(showSelectionLineChanged(bool)),this,SLOT(selectionVisualsChanged()));
478 connect(m_d->controller,SIGNAL(clearSelection()),this,SLOT(clearSelection()));
479
480 connect(m_d->controller,SIGNAL(inDetPartsUsingProjectionsChanged(InDetProjFlags::DetTypeFlags)),
481 this,SLOT(emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags)));
482 InDetProjFlags::DetTypeFlags f = m_d->controller->inDetPartsUsingProjections();
483 if ( f != InDetProjFlags::NoDet)
484 emitUsedIDProjectionsChanged(f);//Fixme: Check that this is actually sufficiently late for the guideline sys!!!
485
486 return m_d->controller;
487}
488
489//_____________________________________________________________________________________
491
492 VP1Serialise serialise(0/*version*/,this);
493 serialise.save(IVP13DSystemSimple::saveState());
494
496
497 serialise.save(m_d->controller->saveSettings());
498 serialise.save(m_d->controller->collWidget());
499
500 serialise.disableUnsavedChecks();//We do the testing in the controller
501 return serialise.result();
502}
503
504//_____________________________________________________________________________________
506 //Version & base state:
507 VP1Deserialise state(ba,this);
508 if (state.version()!=0) {
509 message("Warning: State data in .vp1 file is in wrong format - ignoring!");
510 return;
511 }
513
515
516 m_d->controller->restoreSettings(state.restoreByteArray());
517 state.restore(m_d->controller->collWidget());//We do the testing in the controller
518
519 state.disableUnrestoredChecks();//We do the testing in the controller
520}
521
522//_____________________________________________________________________________________
523void VP1PrepRawDataSystem::visibleTracksChanged(const std::vector< std::pair<const Trk::Track*, const SoMaterial*> >& tracks)
524{
525 m_d->ensureInitCommonData();
526 if (!m_d->common)
527 return;//for signals received after uncreate
528 m_d->common->trackAndSegmentHelper()->visibleTracksChanged(tracks);
530}
531
532//_____________________________________________________________________________________
533void VP1PrepRawDataSystem::visibleSegmentsChanged(const std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >& segments)
534{
535 m_d->ensureInitCommonData();
536 if (!m_d->common)
537 return;//for signals received after uncreate
538 m_d->common->trackAndSegmentHelper()->visibleSegmentsChanged(segments);
540}
541
542//_____________________________________________________________________________________
543void VP1PrepRawDataSystem::emitTouchedMuonChambersChanged(const std::set<GeoPVConstLink>& s)
544{
545 messageVerbose("emits touchedMuonChambersChanged (ntouchedchambers="+QString::number(s.size())+")");
547}
548
549//_____________________________________________________________________________________
550void VP1PrepRawDataSystem::emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags f)
551{
552 messageVerbose("emits usedIDProjectionsChanged");
554}
555
556//_____________________________________________________________________________________
558{
559 if (m_d->appropriatemdtprojection==iproj)
560 return;
561 m_d->appropriatemdtprojection = iproj;
562 if (!m_d->controller)
563 return;//applied upon creation of collections instead
564 for (PRDCollHandle_MDT* mdtcol : m_d->controller->collWidget()->collections<PRDCollHandle_MDT>())
565 mdtcol->setAppropriateProjection( m_d->appropriatemdtprojection );
566
567}
568
569//_____________________________________________________________________________________
570void VP1PrepRawDataSystem::setApplicableIDProjections( InDetProjFlags::InDetProjPartsFlags pixel,
571 InDetProjFlags::InDetProjPartsFlags sct,
572 InDetProjFlags::InDetProjPartsFlags trt )
573{
574 messageVerbose("Signal received in setApplicableProjections (from "
575 +QString(sender()?sender()->objectName():"NULL sender")+")");
576 if (m_d->idprojflags_pixel==pixel&&m_d->idprojflags_sct==sct&&m_d->idprojflags_trt==trt) {
577 return;
578 }
579
580 m_d->idprojflags_pixel = pixel;
581 m_d->idprojflags_trt = trt;
582 m_d->idprojflags_sct = sct;
583
584 if (!m_d->controller)
585 return;//applied upon creation of collections instead
586
587 for (PRDCollHandle_TRT* trtcol : m_d->controller->collWidget()->collections<PRDCollHandle_TRT>())
588 trtcol->setAppropriateProjection(m_d->idprojflags_trt);
589
590 //NB: Add for pixel/sct as well once supported!
591
592}
593
594//_____________________________________________________________________________________
595void VP1PrepRawDataSystem::muonChambersWithTracksChanged(const std::set<GeoPVConstLink>& chambers)
596{
597 messageVerbose("muonChambersWithTracksChanged : received "+str(chambers.size())+" chambers.");
598
599 // //Update map of touched chamber lists:
600 // bool listChanged(m_d->sender2ChamberList.find(sender())!=m_d->sender2ChamberList.end()?
601 // (chambers != m_d->sender2ChamberList[sender()]):true);
602 // m_d->sender2ChamberList[sender()] = chambers;
603
604 //Trigger update if list changed and in auto mode:
605 // if ( listChanged && m_d->controller->limitToActiveChambers() )
606 // message("Limittoactivechambers - not yet implemented");
607 m_d->ensureInitCommonData();
608 if (m_d->common && m_d->common->touchedMuonChamberHelper())
609 m_d->common->touchedMuonChamberHelper()->updateTouchedByTracks(chambers);
610 else
611 message("muonChambersWithTracksChanged - helpers not yet created!");
612}
Scalar mag2() const
mag2 method - forward to squaredNorm()
IVP13DSystemSimple(const QString &name, const QString &information, const QString &contact_info)
void unregisterSelectionNode(SoCooperativeSelection *)
virtual void deselectAll(SoCooperativeSelection *exception_sel=0)
void registerSelectionNode(SoCooperativeSelection *)
CamList getCameraList()
void messageVerbose(const QString &) const
virtual void restoreFromState(QByteArray)
const QString & name() const
State state() const
void message(const QString &) const
virtual QByteArray saveState()
void setAppropriateProjection(InDetProjFlags::InDetProjPartsFlags)
virtual const Trk::PrepRawData * getSecondPRD() const
virtual const Trk::PrepRawData * getPRD() const =0
Amg::Vector3D positionPRD() const
virtual QStringList clicked() const
virtual bool inMuonChamber() const
PRDCollHandleBase * collHandle() const
virtual GeoPVConstLink parentMuonChamberPV() const
Amg::Vector3D positionSecondPRD() const
The Athena Transient Store API.
static VP1CameraHelper * animatedZoomToPath(SoCamera *camera, SoGroup *sceneroot, SoPath *path, double duration_in_secs=1.0, double clipVolPercent=100.0, double slack=1.0, const SbVec3f &lookat=SbVec3f(999, 999, 999), const SbVec3f &upvec=SbVec3f(999, 999, 999), bool varySpeed=true, bool forceCircular=false)
static const MuonGM::MuonDetectorManager * muonDetMgr()
static bool hasMuonGeometry()
SoCooperativeSelection * selNode_highlight
InDetProjFlags::InDetProjPartsFlags idprojflags_sct
QList< PRDCollHandleBase * > createSpecificCollections()
QList< PRDHandleBase * > currentlySelectedHandles
PRDSystemController * controller
QList< PRDCollHandleBase * > createCollections()
InDetProjFlags::InDetProjPartsFlags idprojflags_pixel
SoCooperativeSelection * selNode_click
InDetProjFlags::InDetProjPartsFlags idprojflags_trt
VP1PrepRawDataSystem * theclass
QList< const Trk::PrepRawData * > lastEmittedPRDList
void systemcreate(StoreGateSvc *detstore)
void userPickedNode(SoNode *pickedNode, SoPath *pickedPath)
void touchedMuonChambersChanged(const std::set< GeoPVConstLink > &)
void emitTouchedMuonChambersChanged(const std::set< GeoPVConstLink > &)
void buildEventSceneGraph(StoreGateSvc *sg, SoSeparator *root)
virtual QWidget * buildController()
void visibleSegmentsChanged(const std::vector< std::pair< const Trk::Segment *, const SoMaterial * > > &)
void userChangedSelection(SoCooperativeSelection *, const QSet< SoNode * > &, QSet< SoPath * >)
void buildPermanentSceneGraph(StoreGateSvc *detstore, SoSeparator *root)
void visibleTracksChanged(const std::vector< std::pair< const Trk::Track *, const SoMaterial * > > &)
void emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags)
void restoreFromState(QByteArray)
void userSelectedSingleNode(SoCooperativeSelection *, SoNode *, SoPath *)
void prdInMuonChamberSelected(const GeoPVConstLink &chamberPV)
void usedIDProjectionsChanged(InDetProjFlags::DetTypeFlags)
void setApplicableIDProjections(InDetProjFlags::InDetProjPartsFlags pixel, InDetProjFlags::InDetProjPartsFlags sct, InDetProjFlags::InDetProjPartsFlags trt)
virtual void deselectAll(SoCooperativeSelection *exception_sel=0)
void muonChambersWithTracksChanged(const std::set< GeoPVConstLink > &)
void userDeselectedSingleNode(SoCooperativeSelection *, SoNode *, SoPath *)
static bool changePathTail(SoPath *path, SoNode *commonBranchPoint, SoNode *newtail)
SoSeparator * collSep() const
All 3D objects from this coll.
Eigen::Matrix< double, 3, 1 > Vector3D