24 #include "GaudiKernel/ITHistSvc.h"
25 #include "GaudiKernel/SystemOfUnits.h"
32 m_highestVolume(nullptr),
33 m_extrapolator(
"Trk::Extrapolator/AtlasExtrapolator"),
36 m_materialCollectionValidation(true),
38 m_validationTree(nullptr),
39 m_validationTreeName(
"ExtrapolationValidation"),
40 m_validationTreeDescription(
"Output of the ExtrapolationValidation Algorithm"),
41 m_validationTreeFolder(
"/val/ExtrapolationValidation"),
64 m_covarianceDeterminant{},
65 m_destinationSurfaceType(0),
83 m_collectedLayerFront(0),
84 m_collectedLayerBack(0)
87 declareProperty(
"Extrapolator", m_extrapolator);
88 declareProperty(
"ValidateMaterialCollection", m_materialCollectionValidation);
89 declareProperty(
"ExtrapolateDirectly", m_direct);
91 declareProperty(
"ValidationTreeName", m_validationTreeName);
92 declareProperty(
"ValidationTreeDescription", m_validationTreeDescription);
93 declareProperty(
"ValidationTreeFolder", m_validationTreeFolder);
95 declareProperty(
"StartPerigeeSigmaLoc" , m_sigmaLoc);
96 declareProperty(
"StartPerigeeSigmaR" , m_sigmaR);
97 declareProperty(
"StartPerigeeSigmaZ" , m_sigmaZ);
98 declareProperty(
"StartPerigeeMinEta" , m_minEta);
99 declareProperty(
"StartPerigeeMaxEta" , m_maxEta);
100 declareProperty(
"StartPerigeeMinP" , m_minP);
101 declareProperty(
"StartPerigeeMaxP" , m_maxP);
102 declareProperty(
"ParticleType" , m_particleType);
127 m_validationTree =
new TTree(m_validationTreeName.c_str(), m_validationTreeDescription.c_str());
130 m_validationTree->Branch(
"Parameters", &m_parameters,
"params/I");
131 m_validationTree->Branch(
"ParametersLoc1", m_parameterLoc1,
"paramLoc1[params]/F");
132 m_validationTree->Branch(
"ParametersLoc2", m_parameterLoc2,
"paramLoc2[params]/F");
133 m_validationTree->Branch(
"ParametersPhi", m_parameterPhi,
"paramPhi[params]/F");
134 m_validationTree->Branch(
"ParametersTheta", m_parameterTheta,
"paramTheta[params]/F");
135 m_validationTree->Branch(
"ParametersEta", m_parameterEta,
"paramEta[params]/F");
136 m_validationTree->Branch(
"ParametersQoverP", m_parameterQoverP,
"paramQoverP[params]/F");
138 m_validationTree->Branch(
"CovarianceLoc1", m_covarianceLoc1,
"covLoc1[params]/F");
139 m_validationTree->Branch(
"CovarianceLoc2", m_covarianceLoc2,
"covLoc2[params]/F");
140 m_validationTree->Branch(
"CovariancePhi", m_covariancePhi,
"covPhi[params]/F");
141 m_validationTree->Branch(
"CovarianceTheta", m_covarianceTheta,
"covTheta[params]/F");
142 m_validationTree->Branch(
"CovarianceQoverP", m_covarianceQoverP,
"covQoverP[params]/F");
143 m_validationTree->Branch(
"CovarianceDeterminant", m_covarianceDeterminant,
"covDet[params]/F");
145 m_validationTree->Branch(
"StartMomentum", &m_startP,
"startP/F");
147 m_validationTree->Branch(
"StartSurfaceX", &m_startX,
"startX/F");
148 m_validationTree->Branch(
"StartSurfaceY", &m_startY,
"startY/F");
149 m_validationTree->Branch(
"StartSurfaceR", &m_startR,
"startR/F");
150 m_validationTree->Branch(
"StartSurfaceZ", &m_startZ,
"startZ/F");
152 m_validationTree->Branch(
"EstimationSurfaceX", &m_estimationX,
"estimateX/F");
153 m_validationTree->Branch(
"EstimationSurfaceY", &m_estimationY,
"estimateY/F");
154 m_validationTree->Branch(
"EstimationSurfaceR", &m_estimationR,
"estimateR/F");
155 m_validationTree->Branch(
"EstimationSurfaceZ", &m_estimationZ,
"estimateZ/F");
157 m_validationTree->Branch(
"DestinationSurfaceType", &m_destinationSurfaceType,
"surfaceType/I");
158 m_validationTree->Branch(
"DestinationSurfaceX", &m_destinationX,
"surfaceX/F");
159 m_validationTree->Branch(
"DestinationSurfaceY", &m_destinationY,
"surfaceY/F");
160 m_validationTree->Branch(
"DestinationSurfaceR", &m_destinationR,
"surfaceR/F");
161 m_validationTree->Branch(
"DestinationSurfaceZ", &m_destinationZ,
"surfaceZ/F");
164 SmartIF<ITHistSvc> tHistSvc{service(
"THistSvc")};
166 ATH_MSG_ERROR(
"initialize() Could not find Hist Service -> Switching ValidationMode Off !" );
167 delete m_validationTree; m_validationTree =
nullptr;
169 if ((tHistSvc->regTree(m_validationTreeFolder, m_validationTree)).isFailure()) {
170 ATH_MSG_ERROR(
"initialize() Could not register the validation Tree -> Switching ValidationMode Off !" );
171 delete m_validationTree; m_validationTree =
nullptr;
175 m_gaussDist =
new Rndm::Numbers(randSvc(), Rndm::Gauss(0.,1.));
176 m_flatDist =
new Rndm::Numbers(randSvc(), Rndm::Flat(0.,1.));
179 return StatusCode::SUCCESS;
187 ATH_MSG_INFO(
"================== Output Statistics =========================");
189 ATH_MSG_INFO(
"= - breaks fwd : " <<
double(m_breaksFront)/
double(m_triesFront)
190 <<
" (" << m_breaksFront <<
"/" << m_triesFront <<
")");
191 ATH_MSG_INFO(
"= - breaks bwd : " <<
double(m_breaksBack)/
double(m_triesBack)
192 <<
" (" << m_breaksBack <<
"/" << m_triesBack <<
")");
193 if (m_materialCollectionValidation){
195 ATH_MSG_INFO(
"= - layer collected fwd : " << m_collectedLayerFront );
196 ATH_MSG_INFO(
"= - layer collected bwd : " << m_collectedLayerBack );
199 ATH_MSG_INFO(
"==============================================================");
201 return StatusCode::SUCCESS;
208 const EventContext& ctx = Gaudi::Hive::currentContext();
210 if (!m_highestVolume){
218 ATH_MSG_WARNING(
"No highest TrackingVolume / no VolumeBounds ... pretty useless! ");
219 return StatusCode::SUCCESS;
228 m_destinationSurfaceType = 0;
246 m_parameterLoc1[m_parameters] = m_sigmaLoc * m_gaussDist->shoot();
247 m_parameterLoc2[m_parameters] = m_sigmaLoc * m_gaussDist->shoot();
249 m_parameterPhi[m_parameters] =
M_PI * m_flatDist->shoot();
250 m_parameterPhi[m_parameters] *= (m_flatDist->shoot() > 0.5 ) ? -1. : 1.;
251 m_parameterEta[m_parameters] = m_minEta + m_flatDist->shoot()*(m_maxEta-m_minEta);
252 m_parameterTheta[m_parameters] = 2.*
std::atan(
std::exp(-m_parameterEta[m_parameters]));
255 m_covarianceLoc1[m_parameters] = fabs( m_parameterLoc1[m_parameters] * 0.1);
256 m_covarianceLoc2[m_parameters] = fabs( m_parameterLoc2[m_parameters] * 0.1);
257 m_covariancePhi[m_parameters] = fabs( m_parameterPhi[m_parameters] * 0.1);
258 m_covarianceTheta[m_parameters] = fabs(m_parameterTheta[m_parameters] * 0.1);
261 double p = m_minP + m_flatDist->shoot()*(m_maxP-m_minP);
262 double charge = (m_flatDist->shoot() > 0.5 ) ? -1. : 1.;
263 m_parameterQoverP[m_parameters] =
charge/
p;
265 m_covarianceQoverP[m_parameters] = fabs(m_parameterQoverP[m_parameters] * 0.1);
271 m_startR = fabs(m_sigmaR * m_gaussDist->shoot());
272 double surfacePhi =
M_PI * m_flatDist->shoot();
273 surfacePhi *= (m_flatDist->shoot() > 0.5 ) ? -1. : 1.;
274 m_startX = m_startR*
cos(surfacePhi);
275 m_startY = m_startR*
sin(surfacePhi);
276 m_startZ = m_sigmaZ * m_gaussDist->shoot();
279 double alphaZ =
M_PI * m_flatDist->shoot();
280 alphaZ *= (m_flatDist->shoot() > 0.5 ) ? -1. : 1.;
286 m_parameterPhi[m_parameters],
287 m_parameterTheta[m_parameters],
294 covariance.setZero();
296 covariance(0,0) = m_covarianceLoc1[m_parameters];
298 covariance(1,1) = m_covarianceLoc2[m_parameters];
300 covariance(2,2) = m_covariancePhi[m_parameters];
302 covariance(3,3) = m_covarianceTheta[m_parameters];
304 covariance(4,4) = m_covarianceQoverP[m_parameters];
308 m_covarianceDeterminant[m_parameters] = covariance.determinant();
312 m_parameterLoc2[m_parameters],
313 m_parameterPhi[m_parameters],
314 m_parameterTheta[m_parameters],
315 m_parameterQoverP[m_parameters],
317 std::move(covariance));
320 if(startParameters.covariance())
ATH_MSG_VERBOSE(
"Start Covariance : \n" << *startParameters.covariance() );
324 m_estimationR = m_maximumR * m_flatDist->shoot();
328 CylTrf.setIdentity();
335 if (!estimationParameters) {
336 ATH_MSG_VERBOSE(
"Estimation of intersection did not work - skip event !" );
337 return StatusCode::SUCCESS;
339 else if (m_highestVolume && estimationParameters && !(m_highestVolume->inside(estimationParameters->
position()))){
340 ATH_MSG_VERBOSE(
"Estimation of intersection is outside the known world - skip event !" );
341 delete estimationParameters;
342 return StatusCode::SUCCESS;
350 m_parameterLoc1[m_parameters] = estimationParameters->parameters()[
Trk::loc1];
351 m_parameterLoc2[m_parameters] = estimationParameters->parameters()[
Trk::loc2];
352 m_parameterPhi[m_parameters] = estimationParameters->parameters()[
Trk::phi];
353 m_parameterEta[m_parameters] = estimationParameters->
eta();
354 m_parameterTheta[m_parameters] = estimationParameters->parameters()[
Trk::theta];
355 m_parameterQoverP[m_parameters] = estimationParameters->parameters()[
Trk::qOverP];
356 if(estimationParameters->covariance()){
357 m_covarianceLoc1[m_parameters] = (*estimationParameters->covariance())(0,0);
358 m_covarianceLoc2[m_parameters] = (*estimationParameters->covariance())(1,1);
359 m_covariancePhi[m_parameters] = (*estimationParameters->covariance())(2,2);
360 m_covarianceTheta[m_parameters] = (*estimationParameters->covariance())(3,3);
361 m_covarianceQoverP[m_parameters] = (*estimationParameters->covariance())(4,4);
362 m_covarianceDeterminant[m_parameters] = (estimationParameters->covariance())->determinant();
365 m_covarianceLoc1[m_parameters] = 0;
366 m_covarianceLoc2[m_parameters] = 0;
367 m_covariancePhi[m_parameters] = 0;
368 m_covarianceTheta[m_parameters] = 0;
369 m_covarianceQoverP[m_parameters] = 0;
370 m_covarianceDeterminant[m_parameters] = 0;
377 m_estimationX = estimatedPosition.x();
378 m_estimationY = estimatedPosition.y();
379 m_estimationZ = estimatedPosition.z();
382 delete estimationParameters; estimationParameters =
nullptr;
388 m_parameterPhi[m_parameters],
389 m_parameterTheta[m_parameters]), 10e5 , 10e5);
392 ATH_MSG_VERBOSE(
"Extrapolation to Destination Surface: " << destinationSurface );
397 if (!m_materialCollectionValidation && !m_direct)
398 destParameters = m_extrapolator->extrapolate(ctx,
406 const std::vector<const Trk::TrackStateOnSurface*>*
407 collectedMaterial = m_extrapolator->extrapolateM(ctx,
415 if (collectedMaterial && !collectedMaterial->empty()){
419 m_collectedLayerFront += collectedMaterial->size();
421 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIter = collectedMaterial->begin();
422 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIterEnd = collectedMaterial->end();
423 for ( ; tsosIter != tsosIterEnd;
delete(*tsosIter), ++tsosIter);
428 destParameters = m_extrapolator->extrapolateDirectly(ctx,
442 m_parameterLoc1[m_parameters] = destParameters->parameters()[
Trk::loc1];
443 m_parameterLoc2[m_parameters] = destParameters->parameters()[
Trk::loc2];
444 m_parameterPhi[m_parameters] = destParameters->parameters()[
Trk::phi];
445 m_parameterEta[m_parameters] = destParameters->
eta();
446 m_parameterTheta[m_parameters] = destParameters->parameters()[
Trk::theta];
447 m_parameterQoverP[m_parameters] = destParameters->parameters()[
Trk::qOverP];
448 if(destParameters->covariance()){
449 m_covarianceLoc1[m_parameters] = (*destParameters->covariance())(0,0);
450 m_covarianceLoc2[m_parameters] = (*destParameters->covariance())(1,1);
451 m_covariancePhi[m_parameters] = (*destParameters->covariance())(2,2);
452 m_covarianceTheta[m_parameters] = (*destParameters->covariance())(3,3);
453 m_covarianceQoverP[m_parameters] = (*destParameters->covariance())(4,4);
454 m_covarianceDeterminant[m_parameters] = (destParameters->covariance())->determinant();
457 m_covarianceLoc1[m_parameters] = 0;
458 m_covarianceLoc2[m_parameters] = 0;
459 m_covariancePhi[m_parameters] = 0;
460 m_covarianceTheta[m_parameters] = 0;
461 m_covarianceQoverP[m_parameters] = 0;
462 m_covarianceDeterminant[m_parameters] = 0;
466 m_destinationX = destinationPosition.x();
467 m_destinationY = destinationPosition.y();
468 m_destinationZ = destinationPosition.z();
469 m_destinationR = destinationPosition.perp();
474 if (!m_materialCollectionValidation && !m_direct)
475 backParameters = m_extrapolator->extrapolate(ctx,
483 const std::vector<const Trk::TrackStateOnSurface*>*
484 collectedBackMaterial = m_extrapolator->extrapolateM(ctx,
491 if (collectedBackMaterial && !collectedBackMaterial->empty()){
496 m_collectedLayerBack += collectedBackMaterial->size();
498 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIter = collectedBackMaterial->begin();
499 std::vector<const Trk::TrackStateOnSurface*>::const_iterator tsosIterEnd = collectedBackMaterial->end();
500 for ( ; tsosIter != tsosIterEnd;
delete(*tsosIter), ++tsosIter);
505 backParameters = m_extrapolator->extrapolateDirectly(ctx,
520 m_parameterLoc1[m_parameters] = backParameters->parameters()[
Trk::loc1];
521 m_parameterLoc2[m_parameters] = backParameters->parameters()[
Trk::loc2];
522 m_parameterPhi[m_parameters] = backParameters->parameters()[
Trk::phi];
523 m_parameterEta[m_parameters] = backParameters->
eta();
524 m_parameterTheta[m_parameters] = backParameters->parameters()[
Trk::theta];
525 m_parameterQoverP[m_parameters] = backParameters->parameters()[
Trk::qOverP];
526 if(backParameters->covariance()){
527 m_covarianceLoc1[m_parameters] = (*backParameters->covariance())(0,0);
528 m_covarianceLoc2[m_parameters] = (*backParameters->covariance())(1,1);
529 m_covariancePhi[m_parameters] = (*backParameters->covariance())(2,2);
530 m_covarianceTheta[m_parameters] = (*backParameters->covariance())(3,3);
531 m_covarianceQoverP[m_parameters] = (*backParameters->covariance())(4,4);
532 m_covarianceDeterminant[m_parameters] = (backParameters->covariance())->determinant();
535 m_covarianceLoc1[m_parameters] = 0;
536 m_covarianceLoc2[m_parameters] = 0;
537 m_covariancePhi[m_parameters] = 0;
538 m_covarianceTheta[m_parameters] = 0;
539 m_covarianceQoverP[m_parameters] = 0;
540 m_covarianceDeterminant[m_parameters] = 0;
543 delete backParameters;
547 delete destParameters;
554 if (m_validationTree)
555 m_validationTree->Fill();
561 return StatusCode::SUCCESS;
581 Amg::Vector3D surfaceXdirection(surfaceYdirection.cross(surfaceZdirection));
583 double nx = 1./sqrt(surfaceXdirection[0]*surfaceXdirection[0]+surfaceXdirection[1]*surfaceXdirection[1]+surfaceXdirection[2]*surfaceXdirection[2]);
584 double ny = 1./sqrt(surfaceYdirection[0]*surfaceYdirection[0]+surfaceYdirection[1]*surfaceYdirection[1]+surfaceYdirection[2]*surfaceYdirection[2]);
585 surfaceXdirection[0]*=nx;
586 surfaceXdirection[1]*=nx;
587 surfaceXdirection[2]*=nx;
589 surfaceYdirection[0]*=ny;
590 surfaceYdirection[1]*=ny;
591 surfaceYdirection[2]*=ny;
594 surfaceRotation.col(0) = surfaceXdirection;
595 surfaceRotation.col(1) = surfaceYdirection;
596 surfaceRotation.col(2) = surfaceZdirection;