ATLAS Offline Software
EnergyLossExtrapolationValidation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // EnergyLossValidation.cxx, (c) ATLAS Detector software
8 
9 // Tracking
10 #include <cmath>
11 
22 // Validation mode - TTree includes
23 #include "TTree.h"
24 #include "GaudiKernel/ITHistSvc.h"
25 #include "GaudiKernel/MsgStream.h"
26 #include "GaudiKernel/SystemOfUnits.h"
27 // Framework
29 
30 
31 //================ Constructor =================================================
32 
34 : AthAlgorithm(name,pSvcLocator),
35  m_highestVolume(nullptr),
36  m_extrapolator("Trk::Extrapolator/AtlasExtrapolator"),
37  m_gaussDist(nullptr),
38  m_flatDist(nullptr),
39  m_materialCollectionValidation(false),
40  m_validationTree(nullptr),
41  m_validationRunTree(nullptr),
42  m_validationTreeFolder("/val/EventTreeTG"),
43  m_validationTreeName("EventTreeTG"),
44  m_validationTreeDescription("Event output of the EnergyLossExtrapolationValidation Algorithm"),
45  m_validationRunTreeFolder("/val/RunTreeTG"),
46  m_validationRunTreeName("RunTreeTG"),
47  m_validationRunTreeDescription("Run stats of the EnergyLossExtrapolationValidation Algorithm"),
48  m_maximumR(0.),
49  m_maximumZ(0.),
50  m_cylinders(6),
51  m_onion(true),
52  m_momentum(10.*Gaudi::Units::GeV),
53  m_usePt(true),
54  m_minEta(-3.),
55  m_maxEta(3.),
56  m_events(0),
57  m_totalRecordedLayers(0),
58  m_avgRecordedLayers(0.),
59  m_pdg(0),
60  m_particleType(2),
61  m_entries(0),
62  m_energy{},
63  m_energyLoss{},
64  m_parameterX0{},
65  m_radius{},
66  m_positionX{},
67  m_positionY{},
68  m_positionZ{},
69  m_parameterPhi{},
70  m_parameterEta{},
71  m_parameterTheta{},
72  m_parameterQoverP{},
73  m_parameterP{},
74  m_layer{},
75  m_triesForward(0),
76  m_breaksForward(0),
77  m_triesBack(0),
78  m_breaksBack(0),
79  m_collectedLayerForward(0),
80  m_collectedLayerBack(0),
81  m_cylinderR{},
82  m_cylinderZ{},
83  m_theCylinders(nullptr),
84  m_theDiscs1(nullptr),
85  m_theDiscs2(nullptr)
86 {
87  // used algorithms and alg tools
88  declareProperty("Extrapolator" , m_extrapolator);
89  declareProperty("UseMaterialCollection" , m_materialCollectionValidation);
90  // TTree handling
91  declareProperty("ValidationTreeName" , m_validationTreeName);
92  declareProperty("ValidationRunTreeName" , m_validationRunTreeName);
93  declareProperty("ValidationTreeDescription" , m_validationTreeDescription);
94  declareProperty("ValidationRunTreeDescription" , m_validationRunTreeDescription);
95  declareProperty("ValidationTreeFolder" , m_validationTreeFolder);
96  declareProperty("ValidationRunTreeFolder" , m_validationRunTreeFolder);
97 
98  declareProperty("StartPerigeeMinEta" , m_minEta);
99  declareProperty("StartPerigeeMaxEta" , m_maxEta);
100  declareProperty("StartPerigeeUsePt" , m_usePt);
101  declareProperty("StartPerigeeMomentum" , m_momentum);
102 
103  declareProperty("ValidationCylinders" , m_cylinders);
104  declareProperty("ValidationCylinderR" , m_cylinderVR);
105  declareProperty("ValidationCylinderZ" , m_cylinderVZ);
106  declareProperty("StrictOnionMode" , m_onion);
107 
108  declareProperty("ParticleType" , m_particleType);
109 
110 }
111 
112 //================ Destructor =================================================
113 
115 {
116  // clear random number generators
117  delete m_gaussDist;
118  delete m_flatDist;
119  // clear data vectors
120  delete m_theCylinders;
121  delete m_theDiscs1;
122  delete m_theDiscs2;
123 
124 }
125 
126 
127 //================ Initialization =================================================
128 
130 {
131  // Code entered here will be executed once at program start.
132  ATH_MSG_INFO( "initialize()" );
133  ATH_MSG_DEBUG( "initialize() m_materialCollectionValidation = " << m_materialCollectionValidation );
134 
135  // Get Extrapolator from ToolService
136  if (m_extrapolator.retrieve().isFailure()) {
137  ATH_MSG_FATAL( "initialize() Could not retrieve Tool " << m_extrapolator << ". Exiting." );
138  return StatusCode::FAILURE;
139  }
140 
141  // create the new Trees
142  m_validationTree = new TTree(m_validationTreeName.c_str(), m_validationTreeDescription.c_str());
143  m_validationRunTree = new TTree(m_validationRunTreeName.c_str(), m_validationRunTreeDescription.c_str());
144 
145  // the branches for the parameters
146  m_validationTree->Branch("Entries", &m_entries, "entries/i");
147  m_validationTree->Branch("Energy", m_energy, "energy[entries]/F");
148  m_validationTree->Branch("EnergyLoss", m_energyLoss, "eLoss[entries]/F");
149  m_validationTree->Branch("tInX0", m_parameterX0, "tinX0[entries]/F");
150  m_validationTree->Branch("Radius", m_radius, "radius[entries]/F");
151  m_validationTree->Branch("PosX", m_positionX, "posX[entries]/F");
152  m_validationTree->Branch("PosY", m_positionY, "posY[entries]/F");
153  m_validationTree->Branch("PosZ", m_positionZ, "posZ[entries]/F");
154  m_validationTree->Branch("Eta", m_parameterEta, "eta[entries]/F");
155  m_validationTree->Branch("Phi", m_parameterPhi, "phi[entries]/F");
156  m_validationTree->Branch("Layer", m_layer, "layer[entries]/i");
157 
158  m_validationRunTree->Branch("Layers", &m_cylinders, "layers/i");
159  m_validationRunTree->Branch("CylR", m_cylinderR, "cylR[layers]/F");
160  m_validationRunTree->Branch("CylZ", m_cylinderZ, "cylZ[layers]/F");
161  m_validationRunTree->Branch("Momentum",&m_momentum, "momentum/F");
162  m_validationRunTree->Branch("UsePt", &m_usePt, "usePt/O");
163  m_validationRunTree->Branch("MinEta", &m_minEta, "minEta/F");
164  m_validationRunTree->Branch("MaxEta", &m_maxEta, "maxEta/F");
165  m_validationRunTree->Branch("PDG", &m_pdg, "pdg/I");
166  m_validationRunTree->Branch("Events", &m_events, "events/i");
167  m_validationRunTree->Branch("AvgRecordedLayers", &m_avgRecordedLayers, "avgRecLayers/F");
168 
169  // now register the Trees
170  SmartIF<ITHistSvc> tHistSvc{service("THistSvc")};
171  if (!tHistSvc){
172  ATH_MSG_ERROR( "initialize() Could not find Hist Service -> Switching ValidationMode Off !" );
173  delete m_validationTree; m_validationTree = nullptr;
174  delete m_validationRunTree; m_validationRunTree = nullptr;
175  }
176  if ((tHistSvc->regTree(m_validationTreeFolder, m_validationTree)).isFailure()
177  || (tHistSvc->regTree(m_validationRunTreeFolder, m_validationRunTree)).isFailure() ) {
178  ATH_MSG_ERROR( "initialize() Could not register the validation Trees -> Switching ValidationMode Off !" );
179  delete m_validationTree; m_validationTree = nullptr;
180  delete m_validationRunTree; m_validationRunTree = nullptr;
181  }
182 
183  // initialize the random number generators
184  ATH_MSG_INFO( "initialize() RandomService = " << randSvc()->name() );
185  m_gaussDist = new Rndm::Numbers(randSvc(), Rndm::Gauss(0.,1.));
186  m_flatDist = new Rndm::Numbers(randSvc(), Rndm::Flat(0.,1.));
187 
188  // initialize cylinders if they are not set in jobOptions
189  double const s_cylInitR[TRKEXALGS_MAXPARAMETERS] = { 0.5, 34.5, 250, 550, 1120, 4250, 13000, 0, 0, 0 };
190  double const s_cylInitZ[TRKEXALGS_MAXPARAMETERS] = { 100, 10e6, 680, 2820, 3120, 6500, 22000, 0, 0, 0 };
191 
192  // output of vector from jobOptions
193  ATH_MSG_INFO( "initialize() cylinder dimensions vector from jobOptions :" );
194  for (size_t lay=0; lay<m_cylinders+1; ++lay) {
195  ATH_MSG_INFO( "initialize() m_cylinderVR[" << lay << "] = " << m_cylinderVR[lay] << "\t ... m_cylinderVZ[" << lay << "] = " << m_cylinderVZ[lay] );
196  }
197  // transform vector (from jobOptions) into array (for ROOT tree)
198  ATH_MSG_INFO( "initialize() cylinder dimensions array for algorithm and ROOT tree :" );
199  for (size_t lay=0; lay<m_cylinders+1; ++lay) {
200  m_cylinderR[lay] = m_cylinderVR[lay] > 0 ? m_cylinderVR[lay] : s_cylInitR[lay];
201  m_cylinderZ[lay] = m_cylinderVZ[lay] > 0 ? m_cylinderVZ[lay] : s_cylInitZ[lay];
202  // in "strict onion mode", constrain m_cylinders if the values don't make sense
207  if (m_onion && lay>0 && (m_cylinderR[lay] < m_cylinderR[lay-1])) {
208  ATH_MSG_WARNING( "initialize() layer " << lay << "dimensions are smaller than those of layer " << lay-1 << " - constraining m_cylinders to " << lay-1 );
209  ATH_MSG_INFO( "initialize() cutting off here :" );
210  ATH_MSG_INFO( "initialize() m_cylinderR[" << lay << "] = " << m_cylinderR[lay] << "\t ... m_cylinderZ[" << lay << "] = " << m_cylinderZ[lay] );
211  m_cylinders = lay-1;
212  break;
213  }
214  ATH_MSG_INFO( "initialize() m_cylinderR[" << lay << "] = " << m_cylinderR[lay] << "\t ... m_cylinderZ[" << lay << "] = " << m_cylinderZ[lay] );
215  }
216 
217  // fill data vector with cylinders once (in order not to create them every time)
218  m_theCylinders = new DataVector<const Trk::CylinderSurface>();
219  m_theDiscs1 = new DataVector<const Trk::DiscSurface>();
220  m_theDiscs2 = new DataVector<const Trk::DiscSurface>();
221  for (size_t lay=0; lay<m_cylinders+1; ++lay) {
222  m_theCylinders->push_back(new Trk::CylinderSurface(Amg::Transform3D(), m_cylinderR[lay], m_cylinderZ[lay]));
223  ATH_MSG_INFO( "initialize() Cylinder " << lay << ": " << *m_theCylinders->at(lay) );
224  m_theDiscs1->push_back(new Trk::DiscSurface(*createTransform(0.,0.,-m_cylinderZ[lay]), 0., m_cylinderR[lay]));
225  ATH_MSG_INFO( "initialize() Disc1 " << lay << ": " << *m_theDiscs1->at(lay) );
226  m_theDiscs2->push_back(new Trk::DiscSurface(*createTransform(0.,0., m_cylinderZ[lay]), 0., m_cylinderR[lay]));
227  ATH_MSG_INFO( "initialize() Disc2 " << lay << ": " << *m_theDiscs2->at(lay) );
228  }
229 
230  if (m_particleType==0) m_pdg = 999; // geantino
231  else if (m_particleType==1) m_pdg = 11; // electron
232  else if (m_particleType==2) m_pdg = 13; // muon-
233  else if (m_particleType==3) m_pdg = 211; // pion+
234  else if (m_particleType==4) m_pdg = 321; // kaon+
235  ATH_MSG_INFO( "initialize() ParticleType = " << m_particleType << " ... PDG = " << m_pdg );
236 
237  ATH_MSG_INFO( "initialize() successful" );
238  return StatusCode::SUCCESS;
239 }
240 
241 //================ Finalisation =================================================
242 
244 {
245  // Code entered here will be executed once at the end of the program run.
246  ATH_MSG_INFO( "finalize() ================== Output Statistics =========================" );
247  ATH_MSG_INFO( "finalize() = Navigation : " );
248  ATH_MSG_INFO( "finalize() = - breaks fwd : " << double(m_breaksForward)/double(m_triesForward)
249  << " (" << m_breaksForward << "/" << m_triesForward << ")" );
250  ATH_MSG_INFO( "finalize() = - breaks bwd : " << double(m_breaksBack)/double(m_triesBack)
251  << " (" << m_breaksBack << "/" << m_triesBack << ")" );
252  if (m_materialCollectionValidation){
253  ATH_MSG_INFO( "finalize() = Material collection : " );
254  ATH_MSG_INFO( "finalize() = - layer collected fwd : " << m_collectedLayerForward );
255  ATH_MSG_INFO( "finalize() = - layer collected bwd : " << m_collectedLayerBack );
256  }
257  ATH_MSG_INFO( "finalize() ==============================================================" );
258 
259  m_avgRecordedLayers = m_events ? (float)m_totalRecordedLayers / (float)m_events : 0;
260  ++m_cylinders;
261  if (m_validationRunTree)
262  m_validationRunTree->Fill();
263  --m_cylinders;
264 
265  return StatusCode::SUCCESS;
266 }
267 
268 //================ Execution ====================================================
269 
271 {
272  const EventContext& ctx = Gaudi::Hive::currentContext();
273  // get the overall dimensions
274  if (!m_highestVolume){
275  // get TrackingGeometry and highest volume
276  const Trk::TrackingGeometry* trackingGeometry = m_extrapolator->trackingGeometry();
277  m_highestVolume = trackingGeometry ? trackingGeometry->highestTrackingVolume() : nullptr;
278  const Trk::CylinderVolumeBounds* cylBounds = m_highestVolume ?
279  dynamic_cast<const Trk::CylinderVolumeBounds*>(&(m_highestVolume->volumeBounds())) : nullptr;
280  // bail out
281  if (!cylBounds){
282  ATH_MSG_WARNING( "execute() No highest TrackingVolume / no VolumeBounds ... pretty useless!" );
283  return StatusCode::SUCCESS;
284  }
285  // get the numbers
286  m_maximumR = cylBounds->outerRadius();
287  m_maximumZ = cylBounds->halflengthZ();
288  }
289 
290 
291  m_entries = 0;
292  for (size_t par=0; par<TRKEXALGS_MAXPARAMETERS; ++par) {
293  // -----------> start parameters
294 
295  m_parameterP[par] = 0.;
296  m_energy[par] = 0.;
297  m_energyLoss[par] = 0.;
298  m_parameterX0[par] = 0.;
299  m_radius[par] = 0.;
300  m_positionX[par] = 0.;
301  m_positionY[par] = 0.;
302  m_positionZ[par] = 0.;
303  m_parameterEta[par] = 0.;
304  m_parameterPhi[par] = 0.;
305  m_parameterTheta[par] = 0.;
306 // m_parameterQoverP[par] = 0.;
307  m_layer[par] = 0;
308  }
309 
310  // the local start parameters
311  // are adopted for planar and straight line surfaces
312  m_parameterPhi[0] = M_PI * (2 * m_flatDist->shoot() - 1);
313  m_parameterEta[0] = m_minEta + m_flatDist->shoot()*(m_maxEta-m_minEta);
314  m_parameterTheta[0] = 2.*std::atan(std::exp(-m_parameterEta[0]));
315 
316  double charge = -1.;
317  m_parameterP[0] = m_momentum;
318  // convert transverse momentum (pt) to momentum (p) if flag is set: p = pt/sin(theta)
319  if (m_usePt)
320  m_parameterP[0] /= std::sin(m_parameterTheta[0]);
321  m_parameterQoverP[0] = charge/m_parameterP[0];
322 
323  double mass = Trk::ParticleMasses::mass[m_particleType];
324 
325  double energy1 = sqrt(m_parameterP[0]*m_parameterP[0] + mass*mass);
326 
327  double newX0 = 0;
328 
329  const Trk::PerigeeSurface perigeeSurface;
330  // the initial perigee with random numbers
331  Trk::Perigee startParameters(0, // m_parameterLoc1[0],
332  0, // m_parameterLoc2[0],
333  m_parameterPhi[0],
334  m_parameterTheta[0],
335  m_parameterQoverP[0],
336  perigeeSurface);
337 
338  ATH_MSG_VERBOSE( "execute() Start Parameters : " << startParameters );
339  ATH_MSG_DEBUG( "execute() Start Parameters : [phi,eta] = [ " << startParameters.momentum().phi() << ", " << startParameters.eta() << " ]" );
340 
341  // --------------- propagate to find an intersection ---------------------
342 
343  // fill the TrackParameters vector with extrapolation from startParameters to dummy cylinder surface
344  const Trk::TrackParameters* lastParameters = nullptr;
345  const Trk::TrackParameters* newParameters = nullptr;
346 
347  if (!m_materialCollectionValidation) {
348 
349  lastParameters = m_extrapolator->extrapolate(
350  ctx,
351  startParameters,
352  *(m_theCylinders->at(0)),
354  true,
355  (Trk::ParticleHypothesis)m_particleType).release();
356 
357  } else { // material collection validation
358 
359  // get the vector of TrackStateOnSurfaces back
360  const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
361  m_extrapolator->extrapolateM(
362  ctx,
363  startParameters,
364  *(m_theCylinders->at(0)),
366  true,
367  (Trk::ParticleHypothesis)m_particleType);
368 
369  // get the last one and clone it
370  if (collectedMaterial && !collectedMaterial->empty()) {
371  // get the last track state on surface & clone the destination parameters
372  const Trk::TrackStateOnSurface* destinationState = collectedMaterial->back();
373  lastParameters = destinationState->trackParameters() ? destinationState->trackParameters()->clone() : nullptr;
374  m_collectedLayerForward += collectedMaterial->size();
375  // delete the layers / cleanup
376  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIter = collectedMaterial->begin();
377  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIterEnd = collectedMaterial->end();
378  for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
379  newX0 += (*tsosIter)->materialEffectsOnTrack() ? (*tsosIter)->materialEffectsOnTrack()->thicknessInX0() : 0;
380  delete(*tsosIter);
381  }
382  ATH_MSG_VERBOSE( "execute() newX0 = " << newX0 );
383  }
384  }
385 
386 
387  for (size_t lay = 1; lay<m_cylinders+1; ++lay) {
388 
389  if (!m_onion) newX0 = 0;
390 
391  if (m_onion) {
392  // safety check
393  if (!lastParameters) {
394  ATH_MSG_WARNING( "execute() Layer " << lay << ": start parameters for cylinder NOT found - skip event !" );
395  break;
396  }
397  ATH_MSG_VERBOSE( "execute() Layer " << lay << ": start parameters for cylinder found: " << *lastParameters );
398  }
399 
400  // trying to extrapolate to cylinder barrel
401  newParameters = nullptr;
402  if (!m_materialCollectionValidation) {
403 
404  newParameters = m_extrapolator->extrapolate(
405  ctx,
406  m_onion ? *lastParameters : startParameters,
407  *(m_theCylinders->at(lay)),
409  true,
410  (Trk::ParticleHypothesis)m_particleType).release();
411 
412  } else { // material collection validation
413 
414  // get the vector of TrackStateOnSurfaces back
415  const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
416  m_extrapolator->extrapolateM(ctx,
417  m_onion ? *lastParameters : startParameters,
418  *(m_theCylinders->at(lay)),
420  true,
421  (Trk::ParticleHypothesis)m_particleType);
422 
423  // get the last one and clone it
424  if (collectedMaterial && !collectedMaterial->empty()){
425  // get the last track state on surface & clone the destination parameters
426  const Trk::TrackStateOnSurface* destinationState = collectedMaterial->back();
427  newParameters = destinationState->trackParameters() ? destinationState->trackParameters()->clone() : nullptr;
428  if (m_onion)
429  m_collectedLayerForward += collectedMaterial->size();
430  else
431  m_collectedLayerForward = collectedMaterial->size(); // TODO: shouldn't there be something else here?
432  // delete the layers / cleanup
433  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIter = collectedMaterial->begin();
434  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIterEnd = collectedMaterial->end();
435  for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
436  newX0 += (*tsosIter)->materialEffectsOnTrack() ? (*tsosIter)->materialEffectsOnTrack()->thicknessInX0() : 0;
437  delete(*tsosIter);
438  }
439  ATH_MSG_VERBOSE( "execute() newX0 = " << newX0 );
440  }
441  }
442 
443  // no intersection with cylinder barrel, now trying disc endcaps
444  if (!newParameters) {
445 
446  if (!m_materialCollectionValidation) {
447 
448  newParameters = m_extrapolator->extrapolate(
449  ctx,
450  m_onion ? *lastParameters : startParameters,
451  (m_parameterEta[0] < 0) ? *(m_theDiscs1->at(lay))
452  : *(m_theDiscs2->at(lay)),
454  true,
455  (Trk::ParticleHypothesis)m_particleType).release();
456 
457  } else { // material collection validation
458 
459  // get the vector of TrackStateOnSurfaces back
460  const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
461  m_extrapolator->extrapolateM(ctx,
462  m_onion ? *lastParameters : startParameters,
463  (m_parameterEta[0] < 0) ? *(m_theDiscs1->at(lay)) : *(m_theDiscs2->at(lay)),
465  true,
466  (Trk::ParticleHypothesis)m_particleType);
467 
468  // get the last one and clone it
469  if (collectedMaterial && !collectedMaterial->empty()){
470  // get the last track state on surface & clone the destination parameters
471  const Trk::TrackStateOnSurface* destinationState = collectedMaterial->back();
472  newParameters = destinationState->trackParameters() ? destinationState->trackParameters()->clone() : nullptr;
473  if (m_onion)
474  m_collectedLayerForward += collectedMaterial->size();
475  else
476  m_collectedLayerForward = collectedMaterial->size(); // TODO: shouldn't there be something else here?
477  // delete the layers / cleanup
478  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIter = collectedMaterial->begin();
479  std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIterEnd = collectedMaterial->end();
480  for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
481  newX0 += (*tsosIter)->materialEffectsOnTrack() ? (*tsosIter)->materialEffectsOnTrack()->thicknessInX0() : 0;
482  delete(*tsosIter);
483  }
484  ATH_MSG_VERBOSE( "execute() newX0 = " << newX0 );
485  }
486  }
487  }
488 
489  // still no intersection
490  if (!newParameters) {
491  ATH_MSG_WARNING( "execute() Layer " << lay << " intersection did not work !" );
492  }
493 
494  else if (m_highestVolume && newParameters && !(m_highestVolume->inside(newParameters->position()))) {
495  ATH_MSG_WARNING( "execute() Layer " << lay << " intersection is outside the known world !" );
496  }
497 
498  else {
499 
500  // get the current surface intersection position
501  const Amg::Vector3D& newPosition = newParameters->position();
502  ATH_MSG_VERBOSE( "execute() Track Parameters at layer " << lay << ": " << *newParameters );
503  ATH_MSG_DEBUG( "execute() Track Parameters at layer " << lay << ": [r,z] = [ " << newPosition.perp() << ", " << newPosition.z() );
504 
505  // record the surface parameters
506  ++m_triesForward;
507  ++m_entries;
508  m_parameterPhi[m_entries] = newParameters->parameters()[Trk::phi];
509  m_parameterEta[m_entries] = newParameters->momentum().eta();
510  m_parameterTheta[m_entries] = newParameters->parameters()[Trk::theta];
511  m_parameterP[m_entries] = newParameters->momentum().mag();
512  m_parameterX0[m_entries] = (float)newX0;
513  ATH_MSG_DEBUG( "execute() Layer " << lay << ": cumulated X0 = " << m_parameterX0[m_entries] );
514 
515  // get the current energy and calculate energy loss
516  m_energy[m_entries] = sqrt(m_parameterP[m_entries]*m_parameterP[m_entries] + mass*mass);
517  m_energyLoss[m_entries] = energy1-m_energy[m_entries];
518  ATH_MSG_DEBUG( "execute() Layer " << lay << ": cumulated Energy Loss = " << m_energyLoss[m_entries] );
519 
520  // record the current layer ID
521  m_layer[m_entries] = lay;
522  // record the current position
523  m_radius[m_entries] = newPosition.perp();
524  m_positionX[m_entries] = newPosition.x();
525  m_positionY[m_entries] = newPosition.y();
526  m_positionZ[m_entries] = newPosition.z();
527 
528  }
529 
530  lastParameters = newParameters;
531 
532  }
533 
534 
535  m_totalRecordedLayers += m_entries;
536  ++m_events;
537  // increase m_entries once more before the fill (to account for the "start layer" at index 0 with initial track parameters)
538  ++m_entries;
539 
540  // fill the event tree
541  if (m_validationTree)
542  m_validationTree->Fill();
543 
544  // memory cleanup
545  ATH_MSG_DEBUG( "execute() deleting DataVector parameters ... " );
546 
547  return StatusCode::SUCCESS;
548 }
549 
550 //============================================================================================
552  double x, double y, double z, double phi, double theta, double alphaZ)
553 {
554 
555  if (phi!=0. && theta != 0.){
556  // create the Start Surface
557  Amg::Vector3D surfacePosition(x,y,z);
558  // z direction
559  Amg::Vector3D surfaceZdirection(cos(phi)*sin(theta),
560  sin(phi)*sin(theta),
561  cos(theta));
562  // the global z axis
563  Amg::Vector3D zAxis(0.,0.,1.);
564  // the y direction
565  Amg::Vector3D surfaceYdirection(zAxis.cross(surfaceZdirection));
566  // the x direction
567  Amg::Vector3D surfaceXdirection(surfaceYdirection.cross(surfaceZdirection));
568  // the rotation
569  Amg::RotationMatrix3D surfaceRotation;
570  surfaceRotation.col(0) = surfaceXdirection;
571  surfaceRotation.col(1) = surfaceYdirection;
572  surfaceRotation.col(2) = surfaceZdirection;
573  // return it
574  if (alphaZ==0.){
575  return std::make_unique<Amg::Transform3D>(surfaceRotation, surfacePosition);
576  }
577  Amg::Transform3D nominalTransform(surfaceRotation, surfacePosition);
578  return std::make_unique<Amg::Transform3D>(nominalTransform*Amg::AngleAxis3D(alphaZ,zAxis));
579 
580  }
581 
582  return std::make_unique<Amg::Transform3D>(Amg::Translation3D(x,y,z));
583 }
584 
Trk::EnergyLossExtrapolationValidation::initialize
StatusCode initialize()
standard Athena-Algorithm method
Definition: EnergyLossExtrapolationValidation.cxx:129
Trk::y
@ y
Definition: ParamDefs.h:56
Trk::TrackStateOnSurface::trackParameters
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::z
@ z
global position (cartesian)
Definition: ParamDefs.h:57
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PlotCalibFromCool.zAxis
zAxis
Definition: PlotCalibFromCool.py:76
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::EnergyLossExtrapolationValidation::createTransform
static std::unique_ptr< Amg::Transform3D > createTransform(double x, double y, double z, double phi=0., double theta=0., double alphaZ=0.)
private helper method to create a Transform
Definition: EnergyLossExtrapolationValidation.cxx:551
IExtrapolator.h
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
Trk::DiscSurface
Definition: DiscSurface.h:54
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
Trk::EnergyLossExtrapolationValidation::finalize
StatusCode finalize()
standard Athena-Algorithm method
Definition: EnergyLossExtrapolationValidation.cxx:243
CylinderVolumeBounds.h
Trk::TrackingGeometry::highestTrackingVolume
const TrackingVolume * highestTrackingVolume() const
return the world
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::theta
@ theta
Definition: ParamDefs.h:66
Trk::TrackingGeometry
Definition: TrackingGeometry.h:67
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trk::CylinderSurface
Definition: CylinderSurface.h:55
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
CylinderSurface.h
Trk::CylinderVolumeBounds::halflengthZ
double halflengthZ() const
This method returns the halflengthZ.
Definition: CylinderVolumeBounds.h:207
Trk::ParametersBase
Definition: ParametersBase.h:55
TRKEXALGS_MAXPARAMETERS
#define TRKEXALGS_MAXPARAMETERS
Definition: EnergyLossExtrapolationValidation.h:28
DataVector< const Trk::CylinderSurface >
ParticleHypothesis.h
AthAlgorithm
Definition: AthAlgorithm.h:47
Athena::Units
Definition: Units.h:45
Trk::ParticleMasses::mass
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:53
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
Trk::EnergyLossExtrapolationValidation::~EnergyLossExtrapolationValidation
~EnergyLossExtrapolationValidation()
Default Destructor.
Definition: EnergyLossExtrapolationValidation.cxx:114
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
Trk::CylinderVolumeBounds::outerRadius
double outerRadius() const
This method returns the outer radius.
Definition: CylinderVolumeBounds.h:191
charge
double charge(const T &p)
Definition: AtlasPID.h:756
EnergyLossExtrapolationValidation.h
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
TrackingVolume.h
Trk::EnergyLossExtrapolationValidation::EnergyLossExtrapolationValidation
EnergyLossExtrapolationValidation(const std::string &name, ISvcLocator *pSvcLocator)
Standard Athena-Algorithm Constructor.
Definition: EnergyLossExtrapolationValidation.cxx:33
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Amg::RotationMatrix3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Definition: GeoPrimitives.h:49
PlaneSurface.h
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
DiscSurface.h
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
TrackingGeometry.h
Amg::AngleAxis3D
Eigen::AngleAxisd AngleAxis3D
Definition: GeoPrimitives.h:45
Trk::phi
@ phi
Definition: ParamDefs.h:75
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::x
@ x
Definition: ParamDefs.h:55
readCCLHist.float
float
Definition: readCCLHist.py:83
TrackStateOnSurface.h
Trk::EnergyLossExtrapolationValidation::execute
StatusCode execute()
standard Athena-Algorithm method
Definition: EnergyLossExtrapolationValidation.cxx:270
Trk::ParametersBase::clone
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy