2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 ///////////////////////////////////////////////////////////////////
6 // StepEngine.icc, (c) ATLAS Detector software
7 ///////////////////////////////////////////////////////////////////
9 #include "TrkExInterfaces/IMaterialEffectsEngine.h"
10 #include "TrkExInterfaces/INavigationEngine.h"
11 #include "TrkSurfaces/Surface.h"
12 #include "TrkGeometry/TrackingGeometry.h"
13 #include "TrkGeometry/TrackingVolume.h"
14 #include "TrkGeometry/Layer.h"
18 template<class T> Trk::ExtrapolationCode Trk::StepEngine::targetSurfacesT(Trk::ExtrapolationCell<T>& eCell,
19 Trk::TargetSurfaceVector& ts,
20 bool trueOrderedIntersections,
21 const Trk::Surface* sf,
22 const Trk::BoundaryCheck& bcheck ) const
24 // evaluate the initial distance and save for the propagator/transport step
25 Amg::Vector3D gp = eCell.leadParameters->position();
26 Amg::Vector3D mom = eCell.leadParameters->momentum().normalized();
27 Trk::PropDirection dir = eCell.propDirection;
29 // destination surface
31 Trk::TargetSurface tt(sf,bcheck,Trk::SurfNavigType::Target,0,0,Trk::TVNavigType::Unknown);
32 evaluateDistance(tt,gp,mom*dir,ts,trueOrderedIntersections);
33 // abort if no valid intersection
34 if (!ts.size()) return Trk::ExtrapolationCode::FailureDestination;
37 // static frame boundaries
38 const auto &bounds = eCell.leadVolume->boundarySurfaces();
39 // count number of non-trivial solutions
41 for (unsigned int ib=0; ib< bounds.size(); ib++ ){
42 const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
43 Trk::TargetSurface bb(&surf,true,Trk::SurfNavigType::BoundaryFrame,ib,eCell.leadVolume,Trk::TVNavigType::Frame);
44 evaluateDistance(bb,gp,mom*dir,ts,trueOrderedIntersections);
45 if (ts.size() && ts.back().surf==&surf && ts.back().distanceAlongPath>m_tolerance) iInt++;
47 if (iInt==0 ) { // navigation problem : frame volume not resolved : trigger return && catch inf loop
48 return Trk::ExtrapolationCode::FailureLoop;
53 // order intersections
54 if ( ts.size()>1 && trueOrderedIntersections ) {
56 std::vector<unsigned int> sols(ts.size());
57 for (unsigned int i=0;i<ts.size(); i++) { sols[i]=i; }
60 while ( itest<sols.size() ) {
61 if ( ts[sols[itest]].distanceAlongPath < ts[sols[itest-1]].distanceAlongPath ) {
62 unsigned int iex = sols[itest-1];
63 sols[itest-1]=sols[itest];
69 Trk::TargetSurfaceVector tsOrd ;
70 for (unsigned int i=0;i<ts.size(); i++) tsOrd.push_back(ts[sols[i]]);
71 for (unsigned int i=0;i<ts.size(); i++) ts[i]=tsOrd[i];
74 return Trk::ExtrapolationCode::InProgress;
77 template<class T> Trk::ExtrapolationCode Trk::StepEngine::resolveFrameBoundaryT(Trk::ExtrapolationCell<T>& eCell, Amg::Vector3D gp,
78 unsigned int bIndex ) const
80 const auto &bounds = eCell.leadVolume->boundarySurfaces();
82 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "","current lead volume:"<<eCell.leadVolume->volumeName());
84 const Trk::TrackingVolume* nextVolume = bounds[bIndex]->attachedVolume(gp,
85 eCell.leadParameters->momentum(),
88 if (nextVolume) EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "resolveFrameBoundary:"<< nextVolume->volumeName()
89 <<" at position:"<< eCell.leadParameters->position().perp() <<","<<eCell.leadParameters->position().z()
90 << ","<<eCell.leadParameters->momentum().normalized()<<","<<eCell.propDirection);
92 if (!nextVolume) return Trk::ExtrapolationCode::SuccessBoundaryReached;
94 // - geometrySignature change and configuration to stop then triggers a Success
95 bool stopAtThisBoundary = eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopAtBoundary)
96 && (nextVolume->geometrySignature() != eCell.leadVolume->geometrySignature());
98 if (stopAtThisBoundary) {
99 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "geometry signature change from " <<
100 eCell.leadVolume->geometrySignature() << " to " << nextVolume->geometrySignature());
101 eCell.nextGeometrySignature = nextVolume->geometrySignature();
102 // return the boundary reached
103 return Trk::ExtrapolationCode::SuccessBoundaryReached;
105 // fill the boundary into the cache if successfully hit boundary surface
106 eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectBoundary);
108 // loop protection - relaxed for the cases where you start from the boundary
109 if (eCell.leadVolume == nextVolume ) {
110 // the start parameters where on the boundary already give a relaxed return code
111 // if (&bSurface == eCell.lastBoundarySurface) return Trk::ExtrapolationCode::Unset;
112 // give some screen output as of why this happens
113 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "",
114 "loop detected while trying to leave TrackingVolume '" << nextVolume->volumeName() << ".");
116 // can be a precision problem
117 if ((eCell.leadParameters->position()-eCell.lastBoundaryParameters->position()).mag()>0
118 && nextVolume->inside(gp+0.01*eCell.leadParameters->momentum().normalized()*eCell.propDirection,0.001) )
119 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "",
120 "recovered, continue propagation in " << nextVolume->volumeName() << ".");
121 else return Trk::ExtrapolationCode::FailureLoop;
123 // remember the last boundary surface for loop protection
124 // ecNeutral.lastBoundarySurface = &bounds[index];
125 eCell.lastBoundaryParameters = eCell.leadParameters;
127 eCell.leadVolume = nextVolume;
129 // retrieve frame boundary surfaces, check early exit
130 if ( !m_targetSurfaces.initFrameVolume(eCell.leadParameters->position(),
131 eCell.leadParameters->momentum().normalized()*eCell.propDirection,
132 eCell.leadVolume ) ) {
133 // problem detected in the update of tracking surfaces: probably exit from the frame volume within tolerance range
134 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "","early exit detected at boundary index:"<< m_targetSurfaces.nextSf());
135 Amg::Vector3D gp = eCell.leadParameters->position()+
136 eCell.leadParameters->momentum().normalized()*eCell.propDirection*m_targetSurfaces.distanceToNext();
137 return resolveFrameBoundaryT(eCell,gp,m_targetSurfaces.nextSf());
141 EX_MSG_VERBOSE(eCell.navigationStep, "navigation", ""," frame volume resolved :"<< eCell.leadVolume->volumeName());
143 return Trk::ExtrapolationCode::InProgress;