24 #include "GaudiKernel/ITHistSvc.h"
25 #include "GaudiKernel/MsgStream.h"
41 delete m_theCylinders;
54 ATH_MSG_DEBUG(
"initialize() m_materialCollectionValidation = " << m_materialCollectionValidation );
57 if (m_extrapolator.retrieve().isFailure()) {
58 ATH_MSG_FATAL(
"initialize() Could not retrieve Tool " << m_extrapolator <<
". Exiting." );
59 return StatusCode::FAILURE;
63 m_validationTree =
new TTree(m_validationTreeName.value().c_str(),
64 m_validationTreeDescription.value().c_str());
65 m_validationRunTree =
new TTree(m_validationRunTreeName.value().c_str(),
66 m_validationRunTreeDescription.value().c_str());
69 m_validationTree->Branch(
"Entries", &m_entries,
"entries/i");
70 m_validationTree->Branch(
"Energy", m_energy,
"energy[entries]/F");
71 m_validationTree->Branch(
"EnergyLoss", m_energyLoss,
"eLoss[entries]/F");
72 m_validationTree->Branch(
"tInX0", m_parameterX0,
"tinX0[entries]/F");
73 m_validationTree->Branch(
"Radius", m_radius,
"radius[entries]/F");
74 m_validationTree->Branch(
"PosX", m_positionX,
"posX[entries]/F");
75 m_validationTree->Branch(
"PosY", m_positionY,
"posY[entries]/F");
76 m_validationTree->Branch(
"PosZ", m_positionZ,
"posZ[entries]/F");
77 m_validationTree->Branch(
"Eta", m_parameterEta,
"eta[entries]/F");
78 m_validationTree->Branch(
"Phi", m_parameterPhi,
"phi[entries]/F");
79 m_validationTree->Branch(
"Layer", m_layer,
"layer[entries]/i");
81 m_validationRunTree->Branch(
"Layers", &m_cylinders,
"layers/i");
82 m_validationRunTree->Branch(
"CylR", m_cylinderR,
"cylR[layers]/F");
83 m_validationRunTree->Branch(
"CylZ", m_cylinderZ,
"cylZ[layers]/F");
84 m_validationRunTree->Branch(
"Momentum",&m_momentum,
"momentum/F");
85 m_validationRunTree->Branch(
"UsePt", &m_usePt,
"usePt/O");
86 m_validationRunTree->Branch(
"MinEta", &m_minEta,
"minEta/F");
87 m_validationRunTree->Branch(
"MaxEta", &m_maxEta,
"maxEta/F");
88 m_validationRunTree->Branch(
"PDG", &m_pdg,
"pdg/I");
89 m_validationRunTree->Branch(
"Events", &m_events,
"events/i");
90 m_validationRunTree->Branch(
"AvgRecordedLayers", &m_avgRecordedLayers,
"avgRecLayers/F");
93 SmartIF<ITHistSvc> tHistSvc{service(
"THistSvc")};
95 ATH_MSG_ERROR(
"initialize() Could not find Hist Service -> Switching ValidationMode Off !" );
96 delete m_validationTree; m_validationTree =
nullptr;
97 delete m_validationRunTree; m_validationRunTree =
nullptr;
99 if ((tHistSvc->regTree(m_validationTreeFolder, m_validationTree)).isFailure()
100 || (tHistSvc->regTree(m_validationRunTreeFolder, m_validationRunTree)).isFailure() ) {
101 ATH_MSG_ERROR(
"initialize() Could not register the validation Trees -> Switching ValidationMode Off !" );
102 delete m_validationTree; m_validationTree =
nullptr;
103 delete m_validationRunTree; m_validationRunTree =
nullptr;
108 m_gaussDist =
new Rndm::Numbers(randSvc(), Rndm::Gauss(0.,1.));
109 m_flatDist =
new Rndm::Numbers(randSvc(), Rndm::Flat(0.,1.));
116 ATH_MSG_INFO(
"initialize() cylinder dimensions vector from jobOptions :" );
117 for (
size_t lay=0; lay<m_cylinders+1; ++lay) {
118 ATH_MSG_INFO(
"initialize() m_cylinderVR[" << lay <<
"] = " << m_cylinderVR[lay] <<
"\t ... m_cylinderVZ[" << lay <<
"] = " << m_cylinderVZ[lay] );
121 ATH_MSG_INFO(
"initialize() cylinder dimensions array for algorithm and ROOT tree :" );
122 for (
size_t lay=0; lay<m_cylinders+1; ++lay) {
123 m_cylinderR[lay] = m_cylinderVR[lay] > 0 ? m_cylinderVR[lay] : s_cylInitR[lay];
124 m_cylinderZ[lay] = m_cylinderVZ[lay] > 0 ? m_cylinderVZ[lay] : s_cylInitZ[lay];
126 if (m_onion && lay>0 && (m_cylinderR[lay] < m_cylinderR[lay-1])) {
127 ATH_MSG_WARNING(
"initialize() layer " << lay <<
"dimensions are smaller than those of layer " << lay-1 <<
" - constraining m_cylinders to " << lay-1 );
129 ATH_MSG_INFO(
"initialize() m_cylinderR[" << lay <<
"] = " << m_cylinderR[lay] <<
"\t ... m_cylinderZ[" << lay <<
"] = " << m_cylinderZ[lay] );
133 ATH_MSG_INFO(
"initialize() m_cylinderR[" << lay <<
"] = " << m_cylinderR[lay] <<
"\t ... m_cylinderZ[" << lay <<
"] = " << m_cylinderZ[lay] );
140 for (
size_t lay=0; lay<m_cylinders+1; ++lay) {
142 ATH_MSG_INFO(
"initialize() Cylinder " << lay <<
": " << *m_theCylinders->at(lay) );
143 m_theDiscs1->push_back(
new Trk::DiscSurface(*createTransform(0.,0.,-m_cylinderZ[lay]), 0., m_cylinderR[lay]));
144 ATH_MSG_INFO(
"initialize() Disc1 " << lay <<
": " << *m_theDiscs1->at(lay) );
145 m_theDiscs2->push_back(
new Trk::DiscSurface(*createTransform(0.,0., m_cylinderZ[lay]), 0., m_cylinderR[lay]));
146 ATH_MSG_INFO(
"initialize() Disc2 " << lay <<
": " << *m_theDiscs2->at(lay) );
149 if (m_particleType==0) m_pdg = 999;
150 else if (m_particleType==1) m_pdg = 11;
151 else if (m_particleType==2) m_pdg = 13;
152 else if (m_particleType==3) m_pdg = 211;
153 else if (m_particleType==4) m_pdg = 321;
154 ATH_MSG_INFO(
"initialize() ParticleType = " << m_particleType <<
" ... PDG = " << m_pdg );
157 return StatusCode::SUCCESS;
165 ATH_MSG_INFO(
"finalize() ================== Output Statistics =========================" );
167 ATH_MSG_INFO(
"finalize() = - breaks fwd : " <<
static_cast<double>(m_breaksForward)/
static_cast<double>(m_triesForward)
168 <<
" (" << m_breaksForward <<
"/" << m_triesForward <<
")" );
169 ATH_MSG_INFO(
"finalize() = - breaks bwd : " <<
static_cast<double>(m_breaksBack)/
static_cast<double>(m_triesBack)
170 <<
" (" << m_breaksBack <<
"/" << m_triesBack <<
")" );
171 if (m_materialCollectionValidation){
173 ATH_MSG_INFO(
"finalize() = - layer collected fwd : " << m_collectedLayerForward );
174 ATH_MSG_INFO(
"finalize() = - layer collected bwd : " << m_collectedLayerBack );
176 ATH_MSG_INFO(
"finalize() ==============================================================" );
178 m_avgRecordedLayers = m_events ?
static_cast<float>(m_totalRecordedLayers) /
static_cast<float>(m_events) : 0;
180 if (m_validationRunTree)
181 m_validationRunTree->Fill();
184 return StatusCode::SUCCESS;
191 const EventContext& ctx = Gaudi::Hive::currentContext();
193 if (!m_highestVolume){
201 ATH_MSG_WARNING(
"execute() No highest TrackingVolume / no VolumeBounds ... pretty useless!" );
202 return StatusCode::SUCCESS;
211 m_parameterP[
par] = 0.;
213 m_energyLoss[
par] = 0.;
214 m_parameterX0[
par] = 0.;
216 m_positionX[
par] = 0.;
217 m_positionY[
par] = 0.;
218 m_positionZ[
par] = 0.;
219 m_parameterEta[
par] = 0.;
220 m_parameterPhi[
par] = 0.;
221 m_parameterTheta[
par] = 0.;
227 m_parameterPhi[0] =
M_PI * (2 * m_flatDist->shoot() - 1);
228 m_parameterEta[0] = m_minEta + m_flatDist->shoot()*(m_maxEta-m_minEta);
232 m_parameterP[0] = m_momentum;
235 m_parameterP[0] /=
std::sin(m_parameterTheta[0]);
236 m_parameterQoverP[0] =
charge/m_parameterP[0];
240 double energy1 = sqrt(m_parameterP[0]*m_parameterP[0] +
mass*
mass);
250 m_parameterQoverP[0],
254 ATH_MSG_DEBUG(
"execute() Start Parameters : [phi,eta] = [ " << startParameters.momentum().phi() <<
", " << startParameters.eta() <<
" ]" );
262 if (!m_materialCollectionValidation) {
264 lastParameters = m_extrapolator->extrapolate(
267 *(m_theCylinders->at(0)),
275 const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
276 m_extrapolator->extrapolateM(
279 *(m_theCylinders->at(0)),
285 if (collectedMaterial && !collectedMaterial->empty()) {
289 m_collectedLayerForward += collectedMaterial->size();
291 for (
const auto* tsos : *collectedMaterial) {
292 newX0 += tsos->materialEffectsOnTrack() ? tsos->materialEffectsOnTrack()->thicknessInX0() : 0;
300 for (
size_t lay = 1; lay<m_cylinders+1; ++lay) {
302 if (!m_onion) newX0 = 0;
306 if (!lastParameters) {
307 ATH_MSG_WARNING(
"execute() Layer " << lay <<
": start parameters for cylinder NOT found - skip event !" );
310 ATH_MSG_VERBOSE(
"execute() Layer " << lay <<
": start parameters for cylinder found: " << *lastParameters );
314 newParameters =
nullptr;
315 if (!m_materialCollectionValidation) {
317 newParameters = m_extrapolator->extrapolate(
319 m_onion ? *lastParameters : startParameters,
320 *(m_theCylinders->at(lay)),
328 const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
329 m_extrapolator->extrapolateM(ctx,
330 m_onion ? *lastParameters : startParameters,
331 *(m_theCylinders->at(lay)),
337 if (collectedMaterial && !collectedMaterial->empty()){
342 m_collectedLayerForward += collectedMaterial->size();
344 m_collectedLayerForward = collectedMaterial->size();
346 for (
const auto* tsos : *collectedMaterial) {
347 newX0 += tsos->materialEffectsOnTrack() ? tsos->materialEffectsOnTrack()->thicknessInX0() : 0;
355 if (!newParameters) {
357 if (!m_materialCollectionValidation) {
359 newParameters = m_extrapolator->extrapolate(
361 m_onion ? *lastParameters : startParameters,
362 (m_parameterEta[0] < 0) ? *(m_theDiscs1->at(lay))
363 : *(m_theDiscs2->at(lay)),
371 const std::vector<const Trk::TrackStateOnSurface*>* collectedMaterial =
372 m_extrapolator->extrapolateM(ctx,
373 m_onion ? *lastParameters : startParameters,
374 (m_parameterEta[0] < 0) ? *(m_theDiscs1->at(lay)) : *(m_theDiscs2->at(lay)),
380 if (collectedMaterial && !collectedMaterial->empty()){
385 m_collectedLayerForward += collectedMaterial->size();
387 m_collectedLayerForward = collectedMaterial->size();
389 for (
const auto* tsos : *collectedMaterial) {
390 newX0 += tsos->materialEffectsOnTrack() ? tsos->materialEffectsOnTrack()->thicknessInX0() : 0;
399 if (!newParameters) {
400 ATH_MSG_WARNING(
"execute() Layer " << lay <<
" intersection did not work !" );
403 else if (m_highestVolume && newParameters && !(m_highestVolume->inside(newParameters->
position()))) {
404 ATH_MSG_WARNING(
"execute() Layer " << lay <<
" intersection is outside the known world !" );
411 ATH_MSG_VERBOSE(
"execute() Track Parameters at layer " << lay <<
": " << *newParameters );
412 ATH_MSG_DEBUG(
"execute() Track Parameters at layer " << lay <<
": [r,z] = [ " << newPosition.perp() <<
", " << newPosition.z() );
417 m_parameterPhi[m_entries] = newParameters->parameters()[
Trk::phi];
418 m_parameterEta[m_entries] = newParameters->
momentum().eta();
419 m_parameterTheta[m_entries] = newParameters->parameters()[
Trk::theta];
420 m_parameterP[m_entries] = newParameters->
momentum().mag();
421 m_parameterX0[m_entries] = (
float)newX0;
422 ATH_MSG_DEBUG(
"execute() Layer " << lay <<
": cumulated X0 = " << m_parameterX0[m_entries] );
425 m_energy[m_entries] = sqrt(m_parameterP[m_entries]*m_parameterP[m_entries] +
mass*
mass);
426 m_energyLoss[m_entries] = energy1-m_energy[m_entries];
427 ATH_MSG_DEBUG(
"execute() Layer " << lay <<
": cumulated Energy Loss = " << m_energyLoss[m_entries] );
430 m_layer[m_entries] = lay;
432 m_radius[m_entries] = newPosition.perp();
433 m_positionX[m_entries] = newPosition.x();
434 m_positionY[m_entries] = newPosition.y();
435 m_positionZ[m_entries] = newPosition.z();
439 lastParameters = newParameters;
444 m_totalRecordedLayers += m_entries;
450 if (m_validationTree)
451 m_validationTree->Fill();
454 ATH_MSG_DEBUG(
"execute() deleting DataVector parameters ... " );
456 return StatusCode::SUCCESS;
461 double x,
double y,
double z,
double phi,
double theta,
double alphaZ)
476 Amg::Vector3D surfaceXdirection(surfaceYdirection.cross(surfaceZdirection));
479 surfaceRotation.col(0) = surfaceXdirection;
480 surfaceRotation.col(1) = surfaceYdirection;
481 surfaceRotation.col(2) = surfaceZdirection;
484 return std::make_unique<Amg::Transform3D>(surfaceRotation, surfacePosition);