ATLAS Offline Software
Example3DSystem5.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // //
7 // Implementation of class Example3DSystem5 //
8 // //
9 // Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10 // //
11 // Initial version: June 2007 //
12 // //
14 
16 #include "ui_example5controllerform.h"
17 
18 #include "StoreGate/StoreGateSvc.h"
19 #include "TrkTrack/Track.h"
23 //#include "CLHEP/Units/SystemOfUnits.h"
24 #include "GaudiKernel/SystemOfUnits.h"
25 
26 
27 #include <Inventor/nodes/SoSeparator.h>
28 #include <Inventor/nodes/SoLineSet.h>
29 #include <Inventor/nodes/SoVertexProperty.h>
30 #include <Inventor/nodes/SoSwitch.h>
31 
34 
35 //_____________________________________________________________________________________
37  : IVP13DSystemSimple("Ex3DSys5",
38  "This is an illustration of a very basic 3D system.\n"
39  "It transforms track information found in storegate"
40  " into 3D objects, displays track information and zooms to them upon selection, "
41  "and has a controller which allows the user to set a pt cut on tracks."
42  " It also has a multiple selection mode which can be used to display the combined invariant mass of tracks",
43  "Thomas.Kittelmann@cern.ch"), m_ptcut(0*Gaudi::Units::GeV), m_multiselection(0)
44 {
45 }
46 
47 //_____________________________________________________________________________________
49 {
50  //Clear maps:
51  m_nodeToTrack.clear();
52  m_switchToPt.clear();
53 
54  //1) Try to get the collection of (InDet) tracks from storegate:
55 
56  //Sanity check:
57  if (!sg) {
58  message("Error: Got null storegate pointer");
59  return;
60  }
61 
62  const TrackCollection *trackColl;
63  std::string trackname="Tracks";
64  StatusCode status = sg->retrieve(trackColl, trackname);
65  if (status != StatusCode::SUCCESS || !trackColl) {
66  message("Error: Could not retrieve track collection (used key="+QString(trackname.c_str())+")");
67  return;
68  }
69 
70  //2) Add SoCooperativeSelection node under which we will put all the
71  //tracks. Register it and put its policy to TOGGLE (i.e. clicking
72  //adds or removes tracks from selection). In updateSelectionMode we
73  //will update its ACTIVE/INERT status depending on whether multiple
74  //selections are enabled: If ACTIVE, we get lists of selected nodes
75  //in the userChangedSelection(...) method, otherwise we get single
76  //nodes in the userPickedNode(...) method as always. We could also
77  //simply have changed its policy and gotten information about the
78  //clicks in a userSelectedSingleNode(...) method instead (the
79  //reason for the two available ways of doing this is that you might
80  //want to have several different selection nodes in your graph in
81  //the case where you have different types of physics objects
82  //displayed from the same system):
84  m_multiselection->policy = SoCooperativeSelection::TOGGLE;
85  registerSelectionNode(m_multiselection);//Always do this for SoCooperativeSelection nodes in your graph.
86  updateSelectionMode( true );//Since our controller starts with the single mode selected, we init like that also.
87 
88  //2) Loop over the tracks and construct a relevant 3D object for each of them (a SoLineSet):
89 
90  TrackCollection::const_iterator trackItr, trackItrEnd = trackColl->end();
91 
92  for ( trackItr = trackColl->begin() ; trackItr != trackItrEnd; ++trackItr) {
93  const Trk::Track *track = (*trackItr);
94  const DataVector<const Trk::TrackParameters> *params = track->trackParameters();
95 
96  //Just a sanity check (we need at least two points on the track):
97  if ( !params || params->size()<2 )
98  continue;
99 
100  //The list of points on this track should be set in a so-called
101  //SoVertexProperty (which one realises by reading the
102  //documentation for SoLineSet at http://doc.coin3d.org/Coin/):
103 
104  SoVertexProperty *vertices = new SoVertexProperty();
105 
106  int iver(0);
108  for (it = params->begin();it!=itE;++it) {
109  vertices->vertex.set1Value(iver++,(*it)->position().x(),(*it)->position().y(),(*it)->position().z());
110  }
111 
112  //Create a set of lines from these vertices:
113  SoLineSet * line = new SoLineSet();
114  line->numVertices = iver;
115  line->vertexProperty = vertices;
116 
117  //We add the line to the tree below an SoSwitch. The latter is needed to turn the track on/off:
118  SoSwitch * sw = new SoSwitch();
119 
120  // initial value of switch is based on current pt cut:
121  double pt = params->front()->pT();
122  sw->whichChild = pt > m_ptcut ? SO_SWITCH_ALL : SO_SWITCH_NONE;
123 
124  // the user might change the pt cut later, so we need a list of the switches and the pT of their corresponding tracks:
125  m_switchToPt[sw] = pt;
126 
127  sw->addChild(line);
128  m_multiselection->addChild(sw);
129 
130  //Bookkeep which track this 3D object corresponds to (we will need this to display track info when the user clicks):
132 
133  //To avoid GUI freeze-ups:
134  updateGUI();
135  }
136 
137  //Add the selection node under the root:
138  root->addChild(m_multiselection);
139 
140 }
141 
142 //_____________________________________________________________________________________
143 void Example3DSystem5::userPickedNode(SoNode* pickedNode, SoPath * /*pickedPath*/) {
144 
145  //User clicked on "pickedNode". We should know which track this belongs to:
146  if (m_nodeToTrack.find(pickedNode)==m_nodeToTrack.end()) {
147  message("Error: Does not have track information for picked node");
148  return;
149  }
150 
151  //Get parameters:
152  const DataVector<const Trk::TrackParameters> *params = m_nodeToTrack[pickedNode]->trackParameters();
153  if ( !params || params->empty() ) {
154  message("Error: Track has no trackparameters");
155  return;
156  }
157 
158  //Show some interesting information (from the first trackparameter):
159  message("===> Track info:");
160  message(" |p| = "+QString::number(params->front()->momentum().mag()/Gaudi::Units::GeV)+" GeV");
161  message(" pT = "+QString::number(params->front()->pT()/Gaudi::Units::GeV)+" GeV");
162  message(" Q = "+QString::number(params->front()->charge()));
163  message(" eta = "+QString::number(params->front()->eta()));
164 
165  //Zoom to track:
166  CamList cameras = getCameraList();
167  for (CamListItr itCam = cameras.begin(); itCam!=cameras.end(); ++itCam) {
168  VP1CameraHelper::animatedZoomToSubTree(*itCam,m_multiselection,pickedNode,2.0,1.0);
169  }
170 }
171 
172 //_____________________________________________________________________________________
173 void Example3DSystem5::userChangedSelection(SoCooperativeSelection*, QSet<SoNode*> nodes, QSet<SoPath*>)
174 {
175  //Calculate and print invariant mass.
176  if (nodes.count()<2)
177  return;
178 
179  //Loop over the nodes, find their track pointers and add up their four-momentum (assuming massless particles):
180  Amg::Vector3D total3mom(0.0, 0.0, 0.0); //This is just a three vector
181  double totalenergy(0);//for the energy part of the lorentz vector
182 
183  for (SoNode * node : nodes) {
184  //Track pointer:
185  if (m_nodeToTrack.find(node)==m_nodeToTrack.end()) {
186  message("Error: Does not have track information for all nodes");
187  return;
188  }
189  //Parameters:
191  if ( !params || params->empty() ) {
192  message("Error: Track has no trackparameters");
193  return;
194  }
195  total3mom += params->front()->momentum();
196  totalenergy += params->front()->momentum().mag();
197  }
198  //Display result:
199  double invmasssq = totalenergy*totalenergy - total3mom.mag2();
200  QString invmass_str = invmasssq>=0.0 ? QString::number(sqrt(invmasssq)/Gaudi::Units::GeV) : "sqrt(-1)*"+QString::number(sqrt(-invmasssq)/Gaudi::Units::GeV);
201  message("Invariant mass of "+QString::number(nodes.count())+" selected tracks (massless particles): "+invmass_str+" GeV");
202 }
203 
204 //_____________________________________________________________________________________
206 {
207  QWidget * controller = new QWidget(0);
208  Ui::Example5ControllerForm ui;
209  ui.setupUi(controller);
210 
211  m_ptcut = ui.doubleSpinBox_ptcut->value()*Gaudi::Units::GeV;
212  connect(ui.doubleSpinBox_ptcut,SIGNAL(valueChanged(double)),this,SLOT(ptCutChanged(double)));
213  connect(ui.radioButton_select_single,SIGNAL(toggled(bool)),this,SLOT(updateSelectionMode(bool)));
214 
215  return controller;
216 }
217 
218 //_____________________________________________________________________________________
220 {
221  //Save this value since we need it when building next event:
223 
224  //Update switches to display relevant tracks:
226  for ( it = m_switchToPt.begin(); it!=itE; ++it) {
227  it->first->whichChild = ( it->second>m_ptcut ? SO_SWITCH_ALL : SO_SWITCH_NONE );
228  }
229 }
230 
231 //_____________________________________________________________________________________
233 {
234  //If multiselection not created or if we dont need to change anything - abort:
236  return;
237 
238  //When we change selection mode we deselect everything - always a good idea to avoid hard to debug problems later:
239  deselectAll();
240 
241  if (single)
243  else
245 
246 }
Example3DSystem5::userChangedSelection
void userChangedSelection(SoCooperativeSelection *, QSet< SoNode * >, QSet< SoPath * >)
Definition: Example3DSystem5.cxx:173
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
SoCooperativeSelection::INERT
@ INERT
Definition: SoCooperativeSelection.h:41
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
checkFileSG.line
line
Definition: checkFileSG.py:75
Example3DSystem5::ptCutChanged
void ptCutChanged(double)
Definition: Example3DSystem5.cxx:219
IVP13DSystemSimple
Definition: IVP13DSystemSimple.h:24
TrackParameters.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
Example3DSystem5.h
VP1CameraHelper.h
fillPileUpNoiseLumi.connect
string connect
Definition: fillPileUpNoiseLumi.py:70
SoCooperativeSelection::activePolicy
SoSFEnum activePolicy
Definition: SoCooperativeSelection.h:49
skel.it
it
Definition: skel.GENtoEVGEN.py:396
test_pyathena.pt
pt
Definition: test_pyathena.py:11
Example3DSystem5::buildEventSceneGraph
void buildEventSceneGraph(StoreGateSvc *sg, SoSeparator *root)
Definition: Example3DSystem5.cxx:48
sendEI_SPB.root
root
Definition: sendEI_SPB.py:34
Example3DSystem5::m_ptcut
double m_ptcut
Definition: Example3DSystem5.h:48
Example3DSystem5::userPickedNode
void userPickedNode(SoNode *pickedNode, SoPath *pickedPath)
Definition: Example3DSystem5.cxx:143
Pythia8_A14_NNPDF23LO_forMGHT_EvtGen.ptcut
float ptcut
Definition: Pythia8_A14_NNPDF23LO_forMGHT_EvtGen.py:9
TruthTest.itE
itE
Definition: TruthTest.py:25
StoreGateSvc::retrieve
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
Track.h
GeoPrimitives.h
IVP13DSystem::registerSelectionNode
void registerSelectionNode(SoCooperativeSelection *)
Definition: IVP13DSystem.cxx:257
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:125
IVP13DSystem::CamList
std::set< SoCamera * > CamList
Definition: IVP13DSystem.h:90
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TrackCollection.h
IVP13DSystem::CamListItr
CamList::iterator CamListItr
Definition: IVP13DSystem.h:91
Example3DSystem5::m_switchToPt
std::map< SoSwitch *, double > m_switchToPt
Definition: Example3DSystem5.h:47
PyPoolBrowser.node
node
Definition: PyPoolBrowser.py:131
DataVector< Trk::Track >
Athena::Units
Definition: Units.h:45
SoCooperativeSelection::ACTIVE
@ ACTIVE
Definition: SoCooperativeSelection.h:41
SoCooperativeSelection.h
python.selection.number
number
Definition: selection.py:20
Example3DSystem5::updateSelectionMode
void updateSelectionMode(bool single)
Definition: Example3DSystem5.cxx:232
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Example3DSystem5::m_nodeToTrack
std::map< SoNode *, const Trk::Track * > m_nodeToTrack
Definition: Example3DSystem5.h:46
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Example3DSystem5::Example3DSystem5
Example3DSystem5()
Definition: Example3DSystem5.cxx:36
Example3DSystem5::buildController
QWidget * buildController()
Definition: Example3DSystem5.cxx:205
IVP13DSystemSimple::updateGUI
void updateGUI()
Definition: IVP13DSystemSimple.h:89
IVP13DSystem::getCameraList
CamList getCameraList()
Definition: IVP13DSystem.cxx:395
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
Example3DSystem5::m_multiselection
SoCooperativeSelection * m_multiselection
Definition: Example3DSystem5.h:49
merge.status
status
Definition: merge.py:17
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
VP1CameraHelper::animatedZoomToSubTree
static VP1CameraHelper * animatedZoomToSubTree(SoCamera *camera, SoGroup *sceneroot, SoNode *subtreeroot, double duration_in_secs=1.0, double clipVolPercent=100.0, double lastClipVolPercent=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)
Definition: VP1CameraHelper.cxx:413
StoreGateSvc.h
IVP1System::message
void message(const QString &) const
Definition: IVP1System.cxx:336
IVP13DSystem::deselectAll
virtual void deselectAll(SoCooperativeSelection *exception_sel=0)
Definition: IVP13DSystem.cxx:331
node
Definition: memory_hooks-stdcmalloc.h:74
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
SoCooperativeSelection
Definition: SoCooperativeSelection.h:29