60 class RecursionCounter {
62 RecursionCounter(std::array<unsigned short,Trk::Cache::kNRecursionValues> &the_counter)
63 : m_counter(&the_counter)
70 std::array<unsigned short,Trk::Cache::kNRecursionValues> *m_counter;
85 const double prePositionR =
pars.position().perp();
87 return (prePositionR > (
pars.position() +
dir * 0.5 * prePositionR *
88 pars.momentum().normalized())
96 std::stringstream outStream;
101 return outStream.str();
106 std::stringstream outStream;
108 outStream <<
"[eta,phi] = [ " <<
mom.eta() <<
", " <<
mom.phi() <<
" ]";
109 return outStream.str();
120 , m_numOfValidPropagators(INVALIDPROPAGATORS)
122 declareInterface<IExtrapolator>(
this);
134 m_referenceSurface = std::make_unique<Trk::PlaneSurface>(
Amg::Transform3D(Trk::s_idTransform), 0., 0.);
141 const auto numberOfSubPropagatorsGiven = m_propNames.size();
142 const auto numberOfSubMatEffUpdatersGiven = m_updatNames.size();
144 if (m_propagators.empty()) {
145 m_propagators.push_back(
"Trk::RungeKuttaPropagator/DefaultPropagator");
147 if (m_updaters.empty()) {
148 m_updaters.push_back(
"Trk::MaterialEffectsUpdator/DefaultMaterialEffectsUpdator");
152 if (!m_propagators.empty()) {
157 const unsigned int validprop = m_propagators.size();
160 ATH_MSG_WARNING(
"None of the defined propagators could be retrieved!");
163 m_numOfValidPropagators = validprop ;
164 ATH_MSG_VERBOSE(
"Number of Valid Propagators " << m_numOfValidPropagators);
171 if (m_includeMaterialEffects && not m_updaters.empty()) {
173 for (
auto&
tool : m_updaters) {
182 const unsigned int validmeuts = m_updaters.size();
183 std::vector<std::string> fullPropagatorNames(m_propagators.size());
184 std::vector<std::string> fullUpdatorNames(m_updaters.size());
185 auto extractNameFromTool = [](
const auto& toolHndl) {
return toolHndl->name(); };
187 m_propagators.begin(), m_propagators.end(), fullPropagatorNames.begin(), extractNameFromTool);
189 m_updaters.begin(), m_updaters.end(), fullUpdatorNames.begin(), extractNameFromTool);
193 if (m_propNames.empty() && not m_propagators.empty()) {
195 "Inconsistent setup of Extrapolator, no sub-propagators configured, doing it for you. ");
199 ATH_MSG_ERROR(
"Some configured propagators have same name but different owners");
206 if (m_updatNames.empty() && not m_updaters.empty()) {
207 ATH_MSG_DEBUG(
"Inconsistent setup of Extrapolator, no sub-material updaters configured, doing "
212 ATH_MSG_ERROR(
"Some configured material updaters have same name but different owners");
225 if (validprop && validmeuts) {
228 unsigned int index = 0;
229 for (
unsigned int iProp = 0; iProp < m_propagators.size(); iProp++) {
231 if (m_propNames[isign] == pname) {
236 " subPropagator:" << isign <<
" pointing to propagator: " << m_propagators[
index]->
name());
237 m_subPropagators[isign] =
241 for (
unsigned int iUp = 0; iUp < m_updaters.size(); iUp++) {
243 if (m_updatNames[isign] == uname) {
248 <<
" pointing to updator: " << m_updaters[
index]->
name());
249 m_subupdaters[isign] =
254 "Configuration Problem of Extrapolator: "
255 <<
" -- At least one IPropagator and IMaterialUpdator instance have to be given.! ");
257 const std::string propStr =
std::to_string(numberOfSubPropagatorsGiven) +
" propagator" +
258 std::string((numberOfSubPropagatorsGiven == 1) ?
"" :
"s");
259 const std::string updStr =
std::to_string(numberOfSubMatEffUpdatersGiven) +
" updater" +
260 std::string((numberOfSubMatEffUpdatersGiven == 1) ?
"" :
"s");
261 std::string msgString{
"\nThe extrapolator uses six sub-propagators and "
262 "sub-material effects updaters:\n" };
263 msgString += propStr +
" and " + updStr +
" were given in the configuration,\n";
264 msgString +=
"the extrapolator sub-tools have been defined as follows: \n";
266 msgString +=
std::to_string(
i) +
") propagator: " + m_subPropagators[
i]->name() +
267 ", updater: " + m_subupdaters[
i]->name() +
"\n";
272 return StatusCode::SUCCESS;
279 if (m_propStat.m_maxRecursionCount>0) {
280 ATH_MSG_INFO(
"ExtrapolatorStat: maximum-recursion-depth = " << m_propStat.m_maxRecursionCount);
282 if (m_propStat.m_maxPropagations>0) {
283 ATH_MSG_INFO(
"ExtrapolatorStat: maximum-number-of-propagations = " << m_propStat.m_maxPropagations);
285 if (m_propStat.m_maxMethodSequence>0) {
286 ATH_MSG_INFO(
"ExtrapolatorStat: maximum-method-sequence-number = " << m_propStat.m_maxMethodSequence);
288 if (m_navigationStatistics) {
290 ATH_MSG_INFO(
" [P] Method Statistics ------- ------------------------------------");
291 ATH_MSG_INFO(
" -> Number of extrapolate() calls : " << m_extrapolateCalls);
293 " -> Number of extrapolateBlindly() calls : " << m_extrapolateBlindlyCalls);
295 " -> Number of extrapolateDirectly() calls : " << m_extrapolateDirectlyCalls);
297 " -> Number of extrapolateStepwise() calls : " << m_extrapolateStepwiseCalls);
298 ATH_MSG_INFO(
" -> Number of layers switched in layer2layer : " << m_layerSwitched);
299 ATH_MSG_INFO(
"[P] Navigation Initialization -------------------------------------");
301 " -> Number of start associations : " << m_startThroughAssociation);
302 ATH_MSG_INFO(
" -> Number of start recalls : " << m_startThroughRecall);
304 " -> Number of start global searches : " << m_startThroughGlobalSearch);
306 " -> Number of destination associations : " << m_destinationThroughAssociation);
308 " -> Number of destination recalls : " << m_destinationThroughRecall);
309 ATH_MSG_INFO(
" -> Number of destination global searches : "
310 << m_destinationThroughGlobalSearch);
311 ATH_MSG_INFO(
"[P] Navigation Breaks ---------------------------------------------");
313 " -> Number of navigation breaks: loop : " << m_navigationBreakLoop);
315 " -> Number of navigation breaks: oscillation : " << m_navigationBreakOscillation);
317 " -> Number of navigation breaks: no volume found : " << m_navigationBreakNoVolume);
319 " -> Number of navigation breaks: dist. increase : " << m_navigationBreakDistIncrease);
320 ATH_MSG_INFO(
" -> Number of navigation breaks: dist. increase : "
321 << m_navigationBreakVolumeSignature);
322 if (m_navigationBreakDetails) {
325 <<
" loops occured in the following volumes: ");
327 <<
" oscillations occured in following volumes: ");
329 <<
" times no next volume found of volumes: ");
331 <<
" distance increases detected at volumes: ");
333 <<
" no propagator configured for volumes: ");
336 ATH_MSG_INFO(
"[P] Overlaps found ------------------------------------------------");
337 ATH_MSG_INFO(
" -> Number of overlap Surface hit : " << m_overlapSurfaceHit);
338 ATH_MSG_INFO(
" ------------------------------------------------------------------");
341 return StatusCode::SUCCESS;
345 std::unique_ptr<Trk::TrackParameters>
354 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
355 if (!currentPropagator) {
359 return extrapolateDirectlyImpl(
364 std::unique_ptr<Trk::TrackParameters>
374 Cache cache(m_propStat);
378 return cache.
m_ownedPtrs.move(extrapolateImpl(ctx, cache, clonedInput,
sf,
380 matupmode, extrapolationCache));
384 std::unique_ptr<Trk::NeutralParameters>
391 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
392 if (currentPropagator) {
410 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
411 if (currentPropagator) {
412 return extrapolateStepwiseImpl(ctx, (*currentPropagator), parm,
sf,
dir,
416 " [!] No default Propagator is configured !");
421 std::unique_ptr<Trk::TrackParameters>
423 const EventContext& ctx,
433 if (closestTrackParameters) {
435 ctx, *closestTrackParameters,
sf,
dir, bcheck,
particle, matupmode, extrapolationCache));
438 if (closestTrackParameters) {
440 ctx, *closestTrackParameters,
sf,
dir, bcheck,
particle, matupmode, extrapolationCache));
455 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
457 if (currentPropagator) {
458 Cache cache(m_propStat);
461 return extrapolateBlindlyImpl(ctx, cache, (*currentPropagator),
470 std::vector<const Trk::TrackStateOnSurface*>*
480 Cache cache(m_propStat);
485 cache.
m_matstates =
new std::vector<const Trk::TrackStateOnSurface*>;
486 if (m_dumpCache && extrapolationCache) {
487 ATH_MSG_DEBUG(
" extrapolateM pointer extrapolationCache " << extrapolationCache <<
" x0tot "
488 << extrapolationCache->
x0tot());
493 extrapolateImpl(ctx, cache, clonedInput,
sf,
dir, bcheck,
particle,
495 if (parameterAtDestination) {
496 ATH_MSG_VERBOSE(
" [+] Adding the destination surface to the TSOS vector in extrapolateM() ");
498 nullptr, cache.
m_ownedPtrs.move(parameterAtDestination),
nullptr));
500 ATH_MSG_VERBOSE(
" [-] Destination surface was not hit extrapolateM()");
503 std::vector<const Trk::TrackStateOnSurface*>* tmpMatStates = cache.
m_matstates;
510 std::unique_ptr<std::vector<std::pair<std::unique_ptr<Trk::TrackParameters>,
int>>>
512 const EventContext& ctx,
516 int destination)
const
520 Cache cache(m_propStat);
538 ctx, cache, cloneInput, -1.,
dir,
particle, boundaryVol);
540 while (subDetBounds) {
541 ATH_MSG_DEBUG(
" Identified subdetector boundary crossing saved "
542 << positionOutput(subDetBounds->position()));
544 subDetBounds->uniqueClone(),
552 subDetBounds = extrapolateToVolumeWithPathLimit(
553 ctx, cache, subDetBounds, -1.,
dir,
particle, boundaryVol);
562 std::pair<std::unique_ptr<Trk::TrackParameters>,
const Trk::Layer*>
564 const EventContext& ctx,
568 std::vector<const Trk::TrackStateOnSurface*>& material,
575 !m_subPropagators.empty() ? m_subPropagators[
Trk::MS] :
nullptr;
576 if (currentPropagator) {
577 return extrapolateToNextActiveLayerMImpl(ctx, (*currentPropagator), parm,
582 " [!] No default Propagator is configured ! Please check jobOptions.");
583 return {
nullptr,
nullptr};
587 std::unique_ptr<Trk::TrackParameters>
598 if (currentPropagator) {
599 return (extrapolateToVolumeImpl(ctx, *currentPropagator, parm, vol,
dir,
603 " [!] No default Propagator is configured ! Please check jobOptions.");
623 Cache cache(m_propStat);
625 ++m_extrapolateStepwiseCalls;
651 std::pair<std::unique_ptr<Trk::TrackParameters>,
const Trk::Layer*>
653 const EventContext& ctx,
658 std::vector<const Trk::TrackStateOnSurface*>& material,
662 Cache cache(m_propStat);
679 assocLayer =
nullptr;
681 extrapolateToNextMaterialLayer(ctx, cache, prop, currPar, destSurface,
687 nextPar->position(), bcheck, m_tolerance, m_tolerance)) {
692 << positionOutput(nextPar->position()));
701 ATH_MSG_DEBUG(
" [+] Static volume boundary: continue loop over active layers in '"
715 if (currPar && assocLayer && assocLayer->
layerType() != 0) {
722 return {cache.
m_ownedPtrs.move(currPar), assocLayer};
739 ATH_MSG_WARNING(
"Too many recursive calls of extrapolateToNextMaterialLayer: "
747 ATH_MSG_WARNING(
"Too many method sequence calls of extrapolateToNextMaterialLayer: "
766 std::vector<unsigned int> solutions;
770 bool resolveActive = destSurf ==
nullptr;
771 if (!resolveActive && m_resolveActive) {
772 resolveActive = m_resolveActive;
784 if (vol && vol->
inside(gp, m_tolerance)) {
789 if (m_navigator->atVolumeBoundary(currPar, staticVol,
dir, nextStatVol, m_tolerance) &&
790 nextStatVol != staticVol) {
791 staticVol = nextStatVol;
809 return extrapolateInAlignableTV(ctx, cache, prop, currPar, destSurf,
815 if (staticVol && (staticVol != cache.
m_currentStatic || resolveActive != m_resolveActive)) {
829 if (!detVols.empty()) {
831 for (; iTer != detVols.end(); ++iTer) {
833 const Trk::Layer* layR = (*iTer)->layerRepresentation();
835 const auto detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
839 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
840 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
844 if (!m_resolveMultilayers || (*iTer)->multilayerRepresentation().empty()) {
848 const auto&
multi = (*iTer)->multilayerRepresentation();
849 for (
const auto *
i :
multi) {
855 !m_useMuonMatApprox ||
856 (*iTer)->name().compare((*iTer)->name().size() - 4, 4,
"PERM") ==
863 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
864 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
865 ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
866 cache.
m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
868 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
869 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
874 (*iTer)->trackingVolume()->confinedArbitraryLayers();
875 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
876 (confLays.size() > detBounds.size())) {
878 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
880 (detBounds[ibb])->surfaceRepresentation();
883 }
else if (!confLays.empty()) {
884 for (
const Trk::Layer*
const lIt : confLays) {
908 ATH_MSG_DEBUG(
" [+] Starting propagation (static) at " << positionOutput(currPar->position())
920 << positionOutput(nextPar->position()));
933 const double dInX0 = std::abs(
path) / propagVol->
x0();
937 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
938 EnergyLoss const eloss = m_elossupdater->energyLoss(
939 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
941 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
953 const double dInX0 = std::abs(
path) / propagVol->
x0();
955 const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
956 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
960 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
961 EnergyLoss eloss = m_elossupdater->energyLoss(
962 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
965 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
969 nextPar->position(), nextPar->momentum(), nextPar->charge()));
982 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
983 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
986 nullptr, std::move(cvlTP), std::move(mefot)));
988 <<
"', t/X0 = " << dInX0);
992 const unsigned int isurf = destSurf ? 1 : 0;
993 if (destSurf && solutions[0] == 0) {
996 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1003 currPar->position(), currPar->momentum(),
dir);
1006 ATH_MSG_DEBUG(
" [!] World boundary at position R,z: " << currPar->position().perp() <<
","
1007 << currPar->position().z());
1044 gp = currPar->position();
1045 std::vector<const Trk::DetachedTrackingVolume*> detVols =
1048 for (; dIter != detVols.end(); ++dIter) {
1049 const Trk::Layer* layR = (*dIter)->layerRepresentation();
1051 if (
active && !resolveActive) {
1055 (*dIter)->name().compare((*dIter)->name().size() - 4, 4,
"PERM") != 0) {
1061 m_navigator->atVolumeBoundary(currPar, dVol,
dir, nextVol, m_tolerance) && !nextVol;
1069 if (!
active && confinedDense.empty() && confinedLays.empty()) {
1073 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
1076 if (!confinedDense.empty() || !confinedLays.empty()) {
1078 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
1079 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
1083 if (!confinedDense.empty()) {
1084 auto vIter = confinedDense.begin();
1085 for (; vIter != confinedDense.end(); ++vIter) {
1086 const auto bounds = (*vIter)->boundarySurfaces();
1087 cache.
m_denseVols.emplace_back(*vIter, bounds.size());
1088 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
1089 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
1095 if (!confinedLays.empty()) {
1096 for (
const auto *confinedLay : confinedLays) {
1104 for (
const auto *subvol : subvols) {
1105 if (subvol->inside(gp, m_tolerance)) {
1116 m_navigator->atVolumeBoundary(currPar, detVol,
dir, nextVol, m_tolerance) &&
1118 if (vExit && nextVol && nextVol->
inside(gp, m_tolerance)) {
1125 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
1126 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
1130 cache.
m_denseVols.emplace_back(detVol, bounds.size());
1131 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
1132 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
1145 detVol->
nextLayer(currPar->position(),
dir * currPar->momentum().unit(),
true);
1146 if (nextLayer && nextLayer != lay) {
1168 if (!m_navigator->atVolumeBoundary(currPar, dVol,
dir, nextVol, m_tolerance) ||
1182 std::vector<unsigned int> solutions;
1185 currPar->position() + 2 * m_tolerance *
dir * currPar->momentum().normalized();
1201 << positionOutput(currPar->position())
1202 <<
" (current momentum: " << currPar->momentum().mag() <<
")");
1211 << positionOutput(nextPar->position()));
1215 m_navigator->atVolumeBoundary(
1217 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
1220 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
1227 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
1237 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1239 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
1256 const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1257 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1261 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1262 EnergyLoss eloss = m_elossupdater->energyLoss(
1263 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
1266 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
1271 nextPar->position(), nextPar->momentum(), nextPar->charge()));
1286 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1287 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->
associatedSurface());
1290 nullptr, std::move(cvlTP), std::move(mefot)));
1292 ATH_MSG_DEBUG(
" [M] Collecting material from dense volume '"
1296 if (destSurf && solutions[0] == 0) {
1299 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1306 nextPar->position(), nextPar->momentum().normalized());
1308 dist = distSol.
first();
1318 if (dist *
dir < 0.) {
1323 ATH_MSG_DEBUG(
" [+] New 3D-distance to destinatiion - d3 = " << dist *
dir);
1326 int const iDest = destSurf ? 1 : 0;
1327 unsigned int iSol = 0;
1328 while (iSol < solutions.size()) {
1333 if (
mb->layerMaterialProperties() &&
1334 mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
1341 if (currentUpdator) {
1343 currentUpdator->
update(currentUpdatorCache, nextPar,
1353 const double lx0 = lmat->
x0();
1354 const double layThick =
mb->thickness();
1357 const double costr =
1358 std::abs(nextPar->momentum().normalized().dot(
mb->surfaceRepresentation().normal()));
1360 if (
mb->surfaceRepresentation().isOnSurface(
1361 mb->surfaceRepresentation().center(),
false, 0., 0.)) {
1362 thick = fmin(
mb->surfaceRepresentation().bounds().r(),
1363 layThick / std::abs(nextPar->momentum().normalized().dot(
1364 mb->surfaceRepresentation().normal())));
1366 thick = fmin(2 *
mb->thickness(), layThick / (1 - costr));
1371 const double dInX0 = thick / lx0;
1376 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1377 EnergyLoss const eloss = m_elossupdater->energyLoss(
1378 *lmat, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1391 const double dInX0 = thick / lx0;
1392 const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1393 *lmat, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1397 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1398 EnergyLoss eloss = m_elossupdater->energyLoss(
1399 *lmat, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1403 nextPar->position(), nextPar->momentum(), nextPar->charge()));
1420 std::make_unique<Trk::MaterialEffectsOnTrack>(
1422 std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
1425 nullptr, std::move(cvlTP), std::move(mefot)));
1431 const unsigned int index = solutions[iSol] - iDest;
1434 nextPar->position(), nextPar->momentum(),
dir);
1437 !(nextVol->
inside(nextPar->position() + 0.01 *
dir * nextPar->momentum().normalized(),
1439 ATH_MSG_DEBUG(
" [!] WARNING: wrongly assigned static volume ?"
1442 nextPar->position() + 0.01 * nextPar->momentum().normalized());
1452 if (m_navigator->atVolumeBoundary(
1460 << positionOutput(nextPar->position()));
1463 if (nextVol && nextPar) {
1466 << positionOutput(nextPar->position()));
1470 }
else if (solutions[iSol] <
1481 " [!] This layer is identical to the one with last material update, return layer "
1482 "without repeating the update");
1484 if (!destSurf && (nextLayer->
layerType() > 0)) {
1488 const double layThick = nextLayer->
thickness();
1489 if (
collect && layThick > 0.) {
1497 if (currentUpdator) {
1499 currentUpdator->
update(currentUpdatorCache, nextPar,
1511 const double costr = std::abs(
1517 layThick / std::abs(nextPar->momentum().normalized().dot(
1520 thick = fmin(2 * nextLayer->
thickness(), layThick / (1 - costr));
1525 const double dInX0 = thick / lx0;
1532 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1533 EnergyLoss const eloss = m_elossupdater->energyLoss(
1534 materialProperties, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1546 const double dInX0 = thick / lx0;
1549 const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1550 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1551 const double par_theta = std::abs(nextPar->parameters()[
Trk::theta]) > FLT_EPSILON
1556 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1557 EnergyLoss eloss = m_elossupdater->energyLoss(
1558 materialProperties, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1561 auto cvlTP = std::make_unique<Trk::CurvilinearParameters>(
1562 nextPar->position(), nextPar->momentum(), nextPar->charge());
1578 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1579 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->associatedSurface());
1581 nullptr, std::move(cvlTP), std::move(mefot)));
1587 if (!destSurf && nextLayer->
layerType() > 0) {
1591 if (resolveActive) {
1596 nextPar->position(),
dir * nextPar->momentum().normalized(),
true);
1608 unsigned int index =
1610 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
1613 index -= (*dIter).second;
1617 currVol = (*dIter).first;
1619 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
1622 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
1623 if (currVol->
inside(
tp, m_tolerance)) {
1625 }
else if (!nextVol || !nextVol->
inside(
tp, m_tolerance)) {
1652 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator nIter =
1655 index -= (*nIter).second;
1659 currVol = (*nIter).first;
1661 ((*nIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
1664 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
1665 if (nextVol && nextVol->
inside(
tp, 0.)) {
1666 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
1668 }
else if (currVol->
inside(
tp, 0.)) {
1670 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
1674 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, leaving volume '"
1680 return extrapolateToNextMaterialLayer(
1693 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
1696 index -= (*dIter).second;
1700 currVol = (*dIter).first->trackingVolume();
1703 ((*dIter).first->trackingVolume()->boundarySurfaces())[
index]->attachedVolume(
1706 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
1707 if (nextVol && nextVol->
inside(
tp, 0.)) {
1708 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
1710 }
else if (currVol->
inside(
tp, 0.)) {
1712 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
1716 ATH_MSG_DEBUG(
" [+] Detached volume boundary, leaving volume '"
1722 return extrapolateToNextMaterialLayer(
1766 std::vector<unsigned int> solutions;
1778 if (vol && vol->
inside(gp, m_tolerance)) {
1783 if (m_navigator->atVolumeBoundary(currPar, currVol,
dir, nextStatVol, m_tolerance) &&
1784 nextStatVol != currVol) {
1785 currVol = nextStatVol;
1787 if (currVol && currVol != vol) {
1797 ATH_MSG_DEBUG(
" [!] failing in retrieval of AlignableTV, return 0");
1806 if (binIDMat->second > 0) {
1807 std::unique_ptr<Trk::TrackParameters> identified_parm = currPar->uniqueClone();
1809 std::pair<std::unique_ptr<Trk::TrackParameters>,
int>(std::move(identified_parm), binIDMat->second));
1840 std::vector<unsigned int> solutions;
1843 << positionOutput(currPar->position())
1844 <<
" (current momentum: " << currPar->momentum().mag() <<
")");
1864 << positionOutput(nextPar->position()));
1865 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
1867 if (destSurf && solutions[0] == 0) {
1870 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1877 nextPar->position(), nextPar->momentum().normalized());
1879 dist = distSol.
first();
1889 if (dist *
dir < 0.) {
1894 ATH_MSG_DEBUG(
" [+] New 3D-distance to destinatiion - d3 = " << dist *
dir);
1897 int const iDest = destSurf ? 1 : 0;
1898 unsigned int iSol = 0;
1899 while (iSol < solutions.size()) {
1903 const unsigned int index = solutions[iSol] - iDest;
1906 nextPar->position(), nextPar->momentum(),
dir);
1909 !(nextVol->
inside(nextPar->position() + 0.01 *
dir * nextPar->momentum().normalized(),
1911 ATH_MSG_DEBUG(
" [!] WARNING: wrongly assigned static volume ?"
1914 nextPar->position() + 0.01 * nextPar->momentum().normalized());
1933 std::unique_ptr<Trk::TrackParameters> identified_parm = nextPar->uniqueClone();
1935 std::pair<std::unique_ptr<Trk::TrackParameters>,
int>(std::move(identified_parm),
1936 -binIDMat->second));
1946 if (m_navigator->atVolumeBoundary(
1954 << positionOutput(nextPar->position()));
1957 if (nextVol && nextPar) {
1960 << positionOutput(nextPar->position()));
1983 std::unique_ptr<Trk::TrackParameters>
1993 ++m_extrapolateDirectlyCalls;
1997 std::unique_ptr<Trk::TrackParameters>
2008 <<
"] extrapolateToVolume(...) to volume '" << vol.
volumeName() <<
"'.");
2009 std::unique_ptr<TrackParameters> returnParms =
nullptr;
2015 std::vector<std::pair<const Trk::Surface*, double>> surfaces;
2016 surfaces.reserve(bounds.size());
2017 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
2018 const Trk::Surface* nextSurface = &((bounds[
ib])->surfaceRepresentation());
2023 dist = distSol.
first();
2027 if (!surfaces.empty() && distSol.
numberOfSolutions() >= 0 && dist < surfaces.back().second) {
2028 std::vector<std::pair<const Trk::Surface*, double>>
::iterator sIter = surfaces.begin();
2029 while (sIter != surfaces.end()) {
2030 if (dist < (*sIter).second) {
2035 sIter = surfaces.insert(sIter, (std::pair<const Trk::Surface*, double>(nextSurface, dist)));
2037 surfaces.emplace_back(nextSurface, dist);
2043 for (std::pair<const Trk::Surface*, double>
const& a_surface : surfaces) {
2044 if (a_surface.second > 0) {
2045 Cache cache(m_propStat);
2050 extrapolateImpl(ctx, cache, prop, cloneInput, *(a_surface.first),
2052 if (returnParms.get() == &parm) {
2053 throw std::logic_error(
"Did not create new track parameters.");
2062 for (std::vector<std::pair<const Trk::Surface*, double>>::reverse_iterator rsIter =
2064 rsIter != surfaces.rend();
2066 if ((*rsIter).second < 0) {
2067 Cache cache(m_propStat);
2072 extrapolateImpl(ctx, cache, prop, cloneInput, *((*rsIter).first),
2074 if (returnParms.get() == &parm) {
2075 throw std::logic_error(
"Did not create new track parameters.");
2114 for (
unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2115 if(m_subupdaters[imueot]){
2121 ++m_extrapolateCalls;
2137 initializeNavigation(ctx, cache, prop, nextParameters,
sf,
dir,
particle,
2138 refParameters, nextLayer, nextVolume, destVolume);
2147 " [!] Navigation direction could not be resolved, switching to extrapolateDirectly()");
2151 return cache.
m_ownedPtrs.push(extrapolateDirectlyImpl(ctx, prop, *parm,
sf, navDir, bcheck,
particle));
2154 startVolume = nextVolume;
2156 bool fallback =
false;
2158 double currentDistance = 0.;
2159 double previousDistance = 0.;
2161 if (refParameters) {
2163 << positionOutput(refParameters->
position()));
2164 currentDistance = (refParameters->
position() - parm->position()).
mag();
2168 sf.straightLineDistanceEstimate(parm->position(),
dir * parm->momentum().normalized());
2176 ATH_MSG_VERBOSE(
" [+] Initial 3D-distance to destination - d3 = " << currentDistance);
2183 << ((nextVolume) ? nextVolume->
volumeName() :
"Unknown (ERROR)")
2186 :
"Unknown (blind extrapolation)"));
2188 << positionOutput(parm->position()));
2190 ATH_MSG_VERBOSE(
" [+] Starting layer determined - with " << layerRZoutput(*nextLayer));
2207 bool updateLastValid =
true;
2209 bool punchThroughDone =
false;
2211 auto navigationBreakOscillation = m_navigationBreakOscillation.buffer();
2212 auto navigationBreakNoVolume = m_navigationBreakNoVolume.buffer();
2213 auto navigationBreakDistIncrease = m_navigationBreakDistIncrease.buffer();
2214 auto navigationBreakVolumeSignature = m_navigationBreakVolumeSignature.buffer();
2216 while (nextVolume && nextVolume != destVolume && nextVolume != lastVolume && nextParameters &&
2219 currentPropagator = subPropagator(*nextVolume);
2220 if (!currentPropagator) {
2224 ATH_MSG_DEBUG(
" - Reason : No Propagator found for Volume '"
2227 ++m_navigationBreakVolumeSignature;
2235 if (updateLastValid) {
2239 previousVolume = lastVolume;
2241 lastVolume = nextVolume;
2243 lastParameters = nextParameters;
2259 m_fieldProperties,
particle,
false, previousVolume));
2267 if (nextParameters) {
2268 if (!m_stepPropagator) {
2270 "extrapolation in Calo/MS called without configured STEP propagator, aborting");
2273 resultParameters = extrapolateWithinDetachedVolumes(
2274 ctx, cache, *m_stepPropagator, nextParameters,
sf,
2277 if (resultParameters) {
2280 for (
unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2281 if(m_subupdaters[imueot]){
2286 ATH_MSG_DEBUG(
" [+] Destination surface successfully hit.");
2288 return resultParameters;
2292 ATH_MSG_DEBUG(
" [-] Destination surface could not be hit.");
2293 return resultParameters;
2300 extrapolateToVolumeBoundary(ctx,
2316 previousDistance = currentDistance;
2324 if (distParameters) {
2327 if (refParameters) {
2340 << currentDistance <<
" (from "
2342 ?
"boundary parameters"
2343 :
"last parameters within volume ")
2348 if (nextVolume == lastVolume && nextVolume) {
2350 if (nextParameters && lastParameters &&
2351 (nextParameters->position() - lastParameters->
position())
2352 .dot(lastParameters->
momentum().normalized()) *
2358 if (nextParameters && lastParameters) {
2360 "last step:" << (nextParameters->position() - lastParameters->
position()).mag());
2362 ATH_MSG_DEBUG(
"- Reason : Loop detected in TrackingVolume '"
2365 ++m_navigationBreakLoop;
2373 else if (nextVolume == previousVolume && nextVolume) {
2375 if (punchThroughDone) {
2378 ATH_MSG_DEBUG(
"- Reason : Oscillation detected in TrackingVolume '"
2381 ++navigationBreakOscillation;
2388 punchThroughDone =
true;
2389 ATH_MSG_DEBUG(
" [!] One time punch-through a volume done.");
2395 !m_stopWithUpdateZero) {
2401 ++navigationBreakNoVolume;
2411 currentDistance > s_distIncreaseTolerance + previousDistance) {
2415 << previousDistance <<
" to " << currentDistance <<
"] in TrackingVolume '"
2418 ++navigationBreakDistIncrease;
2426 else if ((!nextParameters && m_stopWithUpdateZero) || !nextVolume) {
2427 ATH_MSG_DEBUG(
" [+] Navigation stop : either the update killed the "
2428 "track, or end of detector/boundary volume reached");
2436 " [+] Navigation stop : next navigation step would lead outside given boundary volume");
2441 else if (nextVolume) {
2446 !nextVolume || currentDistance <= previousDistance;
2448 if (!nextParameters) {
2449 nextParameters = lastParameters;
2452 nextLayer =
nullptr;
2459 ATH_MSG_DEBUG(
" - Consequence : " << (m_stopWithNavigationBreak
2460 ?
"return 0 (configured) "
2461 :
"switch to extrapolateDirectly() "));
2463 if (m_stopWithNavigationBreak || m_stopWithUpdateZero) {
2467 currentPropagator = subPropagator(*lastVolume);
2469 if (!currentPropagator) {
2476 m_fieldProperties,
particle,
false, lastVolume));
2478 if (!resultParameters) {
2480 ctx, *parm,
sf,
dir, bcheck, m_fieldProperties,
particle,
false,
2483 return resultParameters;
2488 if ((&
sf) == (m_referenceSurface.get())) {
2495 ATH_MSG_DEBUG(
"create finalNextParameters " << *finalNextParameters);
2499 currentPropagator = subPropagator(*nextVolume);
2501 if (currentPropagator) {
2502 resultParameters = extrapolateInsideVolume(
2503 ctx, cache, *currentPropagator, nextParameters,
sf, nextLayer,
2509 if (!resultParameters && !m_stopWithNavigationBreak && !m_stopWithUpdateZero) {
2510 if (finalNextParameters)
2511 ATH_MSG_DEBUG(
"propagate using parameters " << *finalNextParameters);
2513 ATH_MSG_DEBUG(
"no finalNextParameters, bailing out of extrapolateDirectly");
2516 ATH_MSG_DEBUG(
" [-] Fallback to extrapolateDirectly triggered ! ");
2520 m_fieldProperties,
particle,
false, startVolume));
2523 return resultParameters;
2531 const std::vector<MaterialEffectsOnTrack>& sfMeff,
2542 <<
"] extrapolate with given MaterialEffectsOnTrack in Volume '"
2553 prop.
propagate(ctx, *currPar, a_sfMeff.associatedSurface(),
dir,
true,
2554 m_fieldProperties,
particle,
false, &tvol));
2559 return (currPar!= parm)
2571 if (currentUpdator) {
2573 currentUpdatorCache, currPar, a_sfMeff,
particle, matupmode));
2597 cache.
m_cacheEloss = extrapolationCache ? extrapolationCache->
eloss() :
nullptr;
2599 if (extrapolationCache && m_dumpCache) {
2600 ATH_MSG_DEBUG(
" In extrapolate cache pointer input: " << extrapolationCache
2601 <<
" cache.m_extrapolationCache "
2610 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
2611 if (currentPropagator) {
2612 return extrapolateImpl(ctx, cache, (*currentPropagator), parm,
sf,
dir,
2616 " [!] No default Propagator is configured ! Please check jobOptions.");
2631 ++m_extrapolateBlindlyCalls;
2643 extrapolateImpl(ctx, cache, prop, parm, *m_referenceSurface,
dir, bcheck,
particle);
2660 const Layer* assocLayer,
2669 return extrapolateWithinDetachedVolumes(
2670 ctx, cache, prop, parm,
sf, tvol,
dir, bcheck,
particle, matupmode);
2673 return insideVolumeStaticLayers(
2674 ctx, cache,
false, prop, parm, assocLayer, tvol,
dir, bcheck,
particle, matupmode);
2692 << tvol.
volumeName() <<
"' to destination surface. ");
2709 nextParameters->position(),
dir * nextParameters->momentum().normalized());
2711 dist = distSol.
first();
2716 if (destinationLayer && destinationLayer->
isOnLayer(nextParameters->position())) {
2717 ATH_MSG_DEBUG(
" [-] Already at destination layer, distance:" << dist);
2719 prop.
propagate(ctx, *nextParameters,
sf,
dir, bcheck, m_fieldProperties,
2728 prop.
propagate(ctx, *nextParameters,
sf, oppDir, bcheck,
2729 m_fieldProperties,
particle,
false, currVol));
2732 if (std::abs(dist) < m_tolerance) {
2737 bcheck, m_fieldProperties,
2743 prop.
propagate(ctx, *nextParameters,
sf, oppDir, bcheck,
2744 m_fieldProperties,
particle,
false, currVol));
2747 ATH_MSG_DEBUG(
" [!] Initial 3D-distance to the surface negative ("
2748 << dist <<
") -> skip extrapolation.");
2753 ATH_MSG_DEBUG(
" [+] Initial 3D-distance to destination - d3 = " << dist);
2764 while (nextParameters) {
2767 ctx, cache, prop, nextParameters, &
sf, currVol,
dir, bchk,
particle, matupmode);
2772 onNextLayer->position(),
dir * onNextLayer->momentum().normalized());
2776 if (currentDistance <= m_tolerance &&
2777 sf.isOnSurface(onNextLayer->position(), bchk, m_tolerance, m_tolerance)) {
2779 if (!bcheck ||
sf.isOnSurface(onNextLayer->position(), bcheck, m_tolerance, m_tolerance)) {
2780 if (
sf.type() != onNextLayer->associatedSurface().type()) {
2782 <<
static_cast<int>(
sf.type())
2783 <<
"," <<
static_cast<int>(onNextLayer->associatedSurface().type())
2784 <<
":distance to the destination surface:" << currentDistance);
2786 ctx, *onNextLayer,
sf,
dir, bchk, m_fieldProperties,
particle));
2796 nextParameters = onNextLayer;
2809 dist = distSol.
first();
2819 m_useDenseVolumeDescription))) {
2821 if (last_boundary_parameters &&
2824 " [!] Already tried parameters at boundary -> exit: pos="
2841 nextParameters = onNextLayer;
2845 ATH_MSG_DEBUG(
" [+] extrapolateWithinDetachedVolumes(...) reached static boundary, return to "
2847 return nextParameters;
2855 const Layer* assocLayer,
2865 " [!] toVolumeBoundaryDetachedVolumes(...) with confined detached volumes? This should "
2866 "not happen ! volume name and signature: "
2871 ctx, cache,
true, prop, parm, assocLayer, tvol,
dir, bcheck,
particle, matupmode));
2905 const double rPos = parm->position().perp();
2906 double rComponent = parm->momentum().normalized().perp();
2908 rComponent = rComponent < 10
e-5 ? 10
e-5 : rComponent;
2910 double rScalor = (toBoundary && tvol.
boundarySurfaces().size() == 3) ? 2. * rPos / rComponent
2911 : 0.5 * rPos / rComponent;
2912 rScalor = rScalor * rScalor < 10
e-10 ? 0.1 : rScalor;
2917 <<
"] insideVolumeStaticLayers(...) to volume boundary of '"
2921 <<
"] insideVolumeStaticLayers(...) to destination surface in '"
2926 " [+] Volume does not contain layers, just propagate to destination surface.");
2931 if (!nextParameters) {
2936 return nextParameters;
2942 " [+] Perpendicular direction of the track : " << radialDirection(*navParameters,
dir));
2944 const Trk::Layer* associatedLayer = assocLayer;
2946 const Trk::Layer* assocLayerReference = assocLayer;
2953 const Trk::Layer* destinationLayer =
nullptr;
2957 if (!destinationLayer) {
2964 if (destinationLayer) {
2966 << layerRZoutput(*destinationLayer));
2976 if (!m_skipInitialLayerUpdate && associatedLayer && associatedLayer != destinationLayer &&
2979 " [+] In starting volume: check for eventual necessary postUpdate and overlapSearch.");
2982 const Trk::Layer* parsLayer = nextParameters->associatedSurface().associatedLayer();
2983 if ((parsLayer && parsLayer == associatedLayer) ||
2991 overlapSearch(ctx, cache, prop, parm, nextParameters, *associatedLayer,
2996 ATH_MSG_VERBOSE(
" [+] Calling postUpdate on inital track parameters.");
3004 if (currentUpdator) {
3006 currentUpdatorCache, *nextParameters, *associatedLayer,
dir,
3011 addMaterialEffectsOnTrack(
3012 ctx, cache, prop, nextParameters, *associatedLayer, tvol,
dir,
particle);
3014 if (nextParameters && nextParameters != parm) {
3015 }
else if (!m_stopWithUpdateZero) {
3017 nextParameters = parm;
3026 assocLayer =
nullptr;
3033 if (!associatedLayer) {
3034 ATH_MSG_VERBOSE(
" [+] Volume switch has happened, searching for entry layers.");
3042 << layerRZoutput(*associatedLayer));
3046 auto [new_track_parm, killed] = extrapolateToIntermediateLayer(
3047 ctx, cache, prop, parm, *associatedLayer, tvol,
dir, bcheck,
particle, matupmode);
3048 nextParameters = new_track_parm;
3050 if (m_stopWithUpdateZero && killed) {
3058 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3065 if (nextParameters) {
3067 << positionOutput(nextParameters->position()));
3071 if (!nextParameters) {
3072 nextParameters = parm;
3080 if (nextParameters != parm) {
3081 navParameters = nextParameters;
3084 if (destinationLayer != assocLayerReference || toBoundary) {
3086 associatedLayer = assocLayer ? assocLayer : tvol.
associatedLayer(navParameters->position());
3090 (associatedLayer && associatedLayer == assocLayerReference)
3091 ? associatedLayer->
nextLayer(navParameters->position(),
3092 dir * rScalor * navParameters->momentum().normalized())
3096 if (associatedLayer) {
3097 ATH_MSG_VERBOSE(
" [+] Associated layer at start with " << layerRZoutput(*associatedLayer));
3101 if (destinationLayer || toBoundary) {
3103 if (associatedLayer && associatedLayer != destinationLayer) {
3106 << layerRZoutput(*associatedLayer));
3110 ctx, cache, prop, nextParameters, tvol, associatedLayer,
3111 destinationLayer, navParameters,
dir, bcheck,
particle,
3114 if (m_stopWithUpdateZero && !updateNext) {
3122 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3130 nextParameters = updateNext;
3136 nextParameters = extrapolateToDestinationLayer(
3138 *destinationLayer, tvol, assocLayerReference,
dir, bcheck,
particle,
3144 return nextParameters;
3148 }
else if (!toBoundary) {
3151 bcheck, m_fieldProperties,
particle));
3156 return nextParameters;
3160 if (!nextParameters) {
3161 nextParameters = parm;
3165 unsigned int navprop = 0;
3168 if (m_numOfValidPropagators != INVALIDPROPAGATORS) {
3170 while (navprop < m_numOfValidPropagators) {
3171 const IPropagator* navPropagator = &(*m_propagators[navprop]);
3174 const bool vetoNavParameters =
false;
3179 if (nextParameters != parm || assocLayerReference) {
3180 navParameters = nextParameters;
3188 << positionOutput(navParameters->position()));
3190 << momentumOutput(navParameters->momentum()));
3194 m_navigator->nextTrackingVolume(ctx, *navPropagator, *navParameters,
dir, tvol);
3199 bParameters = navParameters;
3209 m_navigator->nextTrackingVolume(ctx, prop, *navParameters,
dir, tvol);
3213 bParameters = navParameters;
3220 if (navParameters) {
3229 if (bParameters && bParameters->associatedSurface().materialLayer()) {
3231 if (m_includeMaterialEffects) {
3237 if (currentUpdator) {
3239 currentUpdatorCache, bParameters,
3240 *(bParameters->associatedSurface().materialLayer()),
dir,
particle,
3245 addMaterialEffectsOnTrack(
3246 ctx, cache, prop, bParameters,
3247 *(bParameters->associatedSurface().materialLayer()), tvol,
dir,
3250 navParameters = bParameters;
3256 nextVolume, nextParameters, navParameters, exitFace);
3259 return navParameters;
3270 const Layer* startLayer,
3271 const Layer* destinationLayer,
3293 bool perpCheck = radialDirection(*currPar,
dir) * radialDirection(*navParameters,
dir) > 0;
3296 unsigned int failedAttempts = 0;
3299 const unsigned int layersInVolume =
3302 const unsigned int maxAttempts =
3303 std::max(m_initialLayerAttempts.value(),
3304 static_cast<unsigned int>(layersInVolume * 0.5));
3306 ATH_MSG_VERBOSE(
" [+] Maximum number of failed layer attempts: " << maxAttempts);
3315 while (nextLayer && nextLayer != previousLayer && nextLayer != lastLayer &&
3316 nextLayer != destinationLayer && failedAttempts < maxAttempts) {
3320 :
"navigation layer with "))
3321 << layerRZoutput(*nextLayer));
3327 auto [new_track_parm, killed] = extrapolateToIntermediateLayer(
3328 ctx, cache, prop, currPar, *nextLayer, tvol,
dir, bcheck,
particle,
3329 matupmode, perpCheck);
3333 previousLayer = lastLayer;
3334 lastLayer = nextLayer;
3338 ATH_MSG_VERBOSE(
" [+] Material update killed the track parameters - return 0");
3346 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3350 ATH_MSG_VERBOSE(
" [+] Intersection successful: allowing for " << maxAttempts
3351 <<
" more failed attempt.");
3355 navParameters = nextPar;
3364 nextLayer->
nextLayer(navParameters->position(),
dir * navParameters->momentum().normalized());
3368 ATH_MSG_VERBOSE(
" [+] No next Layer provided by the previous layer -> stop of layer2layer");
3371 if (failedAttempts >= maxAttempts) {
3387 const Layer* startLayer,
3398 const bool startIsDestLayer = startLayer == (&lay);
3404 if (!destParameters) {
3416 if (currentUpdator && destParameters && !startIsDestLayer) {
3418 currentUpdatorCache, destParameters, lay,
dir,
particle, matupmode));
3420 preUpdatedParameters = destParameters;
3425 currentUpdator && !startIsDestLayer &&
3427 addMaterialEffectsOnTrack(
3428 ctx, cache, prop, preUpdatedParameters, lay, tvol,
dir,
particle);
3433 ATH_MSG_VERBOSE(
" [o] Calling overlapSearch() on destination layer.");
3435 overlapSearch(ctx, cache, prop, parm, preUpdatedParameters, lay, tvol,
dir,
3436 bcheck,
particle, startIsDestLayer);
3439 if (preUpdatedParameters) {
3444 return preUpdatedParameters;
3447 std::pair<Trk::CacheOwnedPtr<Trk::TrackParameters>,
bool>
3458 bool doPerpCheck)
const
3478 return std::make_pair(
nullptr,
false);
3482 int const rDirection = radialDirection(*parm,
dir);
3483 int const newrDirection = radialDirection(*parsOnLayer,
dir);
3484 if (newrDirection != rDirection && doPerpCheck) {
3486 ATH_MSG_DEBUG(
" [!] Perpendicular direction of track has changed -- checking");
3489 if (!radialDirectionCheck(ctx, prop, *parm, *parsOnLayer, tvol,
dir,
particle)) {
3490 ATH_MSG_DEBUG(
" [+] Perpendicular direction check cancelled this layer intersection.");
3496 << positionOutput(parsOnLayer->position()));
3498 << momentumOutput(parsOnLayer->momentum()));
3505 ATH_MSG_VERBOSE(
" [o] Calling overlapSearch() on intermediate layer.");
3506 overlapSearch(ctx, cache, prop, parm, parsOnLayer, lay, tvol,
dir, bcheck,
particle);
3511 if (lastElement >= 0 && sizeBeforeSearch < sizeAfterSearch) {
3516 throw std::logic_error(
"Invalid track parameters on det elements (lastElement)");
3522 ATH_MSG_DEBUG(
" [+] Detector element & overlapSearch successful,"
3523 <<
" call update on last parameter on this layer.");
3530 currentUpdatorCache, parsOnLayer, lay,
dir,
particle, matupmode));
3534 addMaterialEffectsOnTrack(ctx, cache, prop, parsOnLayer, lay, tvol,
dir,
particle);
3538 if (!parsOnLayer && m_stopWithUpdateZero) {
3539 return std::make_pair(
nullptr,
true);
3542 return std::make_pair(parsOnLayer,
false);
3556 bool startingLayer)
const
3559 const bool isDestinationLayer = (&parsOnLayer->associatedSurface() == cache.
m_destinationSurface);
3563 ((parm->associatedSurface()).associatedDetectorElement() && startingLayer)
3564 ? &(parm->associatedSurface())
3568 const Trk::Surface* detSurface = (parsOnLayer->associatedSurface()).associatedDetectorElement()
3569 ? &parsOnLayer->associatedSurface()
3572 ATH_MSG_VERBOSE(
" [o] OverlapSearch called " << (startSurface ?
"with " :
"w/o ") <<
"start, "
3573 << (endSurface ?
"with " :
"w/o ")
3580 detSurface = isDestinationLayer ? lay.
subSurface(parsOnLayer->localPosition())
3583 ATH_MSG_VERBOSE(
" [o] Detector surface found through subSurface() call");
3588 ATH_MSG_VERBOSE(
" [o] Detector surface found through parameter on layer association");
3592 const bool isStartLayer = (detSurface && detSurface == startSurface);
3596 bool reorderDetParametersOnLayer =
false;
3601 if (isDestinationLayer) {
3602 detParameters = parsOnLayer;
3603 }
else if (isStartLayer) {
3604 detParameters = parm;
3605 }
else if (detSurface) {
3611 bool surfaceHit =
true;
3615 if (detParameters && !isStartLayer && !isDestinationLayer) {
3616 ATH_MSG_VERBOSE(
" [o] First intersection with Detector surface: " << *detParameters);
3618 surfaceHit = detParameters && detSurface ? detSurface->isOnSurface(detParameters->position())
3621 surfaceHit = (surfaceHit && startSurface)
3622 ? ((detParameters->position() - parm->position())
3623 .dot(
dir * parm->momentum().normalized()) > 0)
3625 surfaceHit =(surfaceHit && endSurface)
3626 ? ((detParameters->position() - parsOnLayer->position())
3627 .
dot(
dir * parsOnLayer->momentum().normalized()) < 0)
3639 detParametersOnLayer.emplace_back(cache.
m_ownedPtrs.move(detParameters));
3640 }
else if (detParameters) {
3643 " [-] Detector surface hit cancelled through bounds check or start/end surface check.");
3648 if (track_parm_for_overlap) {
3650 std::vector<Trk::SurfaceIntersection> cSurfaces;
3651 size_t const ncSurfaces =
3656 ATH_MSG_VERBOSE(
"found " << ncSurfaces <<
" candidate sensitive surfaces to test.");
3660 auto overlapSurfaceHit = m_overlapSurfaceHit.buffer();
3661 for (
auto& csf : cSurfaces) {
3668 if (overlapParameters) {
3669 ATH_MSG_VERBOSE(
" [+] Overlap surface was hit, checking start/end surface condition.");
3672 surfaceHit = (startSurface) ? ((overlapParameters->position() - parm->position())
3673 .dot(
dir * parm->momentum().normalized()) > 0)
3676 surfaceHit = (surfaceHit && endSurface)
3677 ? ((overlapParameters->position() - parsOnLayer->position())
3678 .
dot(
dir * parsOnLayer->momentum().normalized()) < 0)
3684 ++overlapSurfaceHit;
3686 reorderDetParametersOnLayer =
true;
3688 detParametersOnLayer.emplace_back(cache.
m_ownedPtrs.move(overlapParameters));
3692 " [-] Detector surface hit cancelled through start/end surface check.");
3701 if (reorderDetParametersOnLayer) {
3704 sort(detParametersOnLayer.begin(), detParametersOnLayer.end(), parameterSorter);
3710 std::move(detParametersOnLayer.begin(), detParametersOnLayer.end(),
3725 const Layer*& associatedLayer,
3732 ATH_MSG_DEBUG(
" [I] initializeNaviagtion() -------------------------- ");
3735 ATH_MSG_DEBUG(
" [I] (re)initializeNaviagtion() ---------------------- ");
3742 " [I] Starting with Start Layer/Volume search: ------------------------------");
3749 const char* startSearchType =
"association";
3753 const Trk::Surface* associatedSurface = &parm->associatedSurface();
3754 associatedLayer = (associatedSurface) ? associatedSurface->
associatedLayer() : associatedLayer;
3759 if (!associatedVolume && associatedSurface && associatedSurface == cache.
m_recallSurface &&
3762 ++m_startThroughRecall;
3766 startSearchType =
"recall";
3767 }
else if (!associatedVolume) {
3769 ++m_startThroughGlobalSearch;
3772 associatedVolume = cache.
volume(ctx,parm->position());
3775 (associatedVolume) ? associatedVolume->
associatedLayer(parm->position()) :
nullptr;
3778 startSearchType =
"global search";
3785 if (lowestStaticVol && lowestStaticVol != associatedVolume) {
3786 associatedVolume = lowestStaticVol;
3790 ++m_startThroughAssociation;
3796 if (m_navigator->atVolumeBoundary(parm, associatedVolume,
dir, nextAssVol,
3798 nextAssVol != associatedVolume) {
3800 associatedVolume = nextAssVol;
3803 << associatedVolume->
volumeName() <<
" no action taken");
3810 " [I] 'AnyDirection' has been chosen: approaching direction must be determined.");
3814 ctx, *parm,
sf,
dir,
false, m_fieldProperties,
particle,
false,
3817 if (refParameters) {
3819 const Amg::Vector3D surfaceDir(refParameters->position() - parm->position());
3820 if (surfaceDir.dot(parm->momentum()) > 0.) {
3828 << ((navigationDirection < 0) ?
"oppositeMomentum." :
"alongMomentum"));
3831 " [+] Approaching direction could not be determined, they remain: anyDirection.");
3834 ATH_MSG_VERBOSE(
" [I] Starting Information gathered through : " << startSearchType <<
".");
3840 ATH_MSG_VERBOSE(
" [I] Starting with destination Volume search: -----------------------------");
3842 if ((&
sf) != (m_referenceSurface.get())) {
3844 destVolume = (
sf.associatedLayer()) ?
sf.associatedLayer()->enclosingTrackingVolume() :
nullptr;
3846 std::string destinationSearchType =
"association";
3848 ++m_destinationThroughAssociation;
3854 destinationSearchType =
"recall";
3856 ++m_destinationThroughRecall;
3857 }
else if (!destVolume) {
3859 destinationSearchType =
"global search";
3860 ++m_destinationThroughGlobalSearch;
3863 if (!refParameters && associatedVolume) {
3865 ctx, *parm,
sf,
dir,
false, m_fieldProperties,
particle,
false,
3869 if (refParameters) {
3870 destVolume = cache.
volume(ctx,refParameters->position());
3877 destVolume = cache.
volume(ctx,
sf.globalReferencePoint());
3880 ATH_MSG_VERBOSE(
" [I] Destination Information gathered through : " << destinationSearchType
3886 << (associatedVolume ?
"ok." :
"failed."));
3888 << (associatedLayer ?
"ok." :
"failed."));
3889 ATH_MSG_VERBOSE(
" [+] Destinaiton Volume search ...... " << (destVolume ?
"ok." :
"failed."));
3891 if (destVolume == associatedVolume) {
3894 const std::string navDirString =
3895 ((navigationDirection < 0) ?
"oppositeMomentum"
3896 : (navigationDirection > 0) ?
"alongMomentum" :
"undefined");
3898 ATH_MSG_VERBOSE(
" [I] initializeNaviagtion() end ---------------------- ");
3902 return navigationDirection;
3919 const double distToLayer = (startPosition - onLayerPosition).
mag();
3924 if (boundarySurfaces.size() == 4) {
3929 std::unique_ptr<const Trk::TrackParameters>
const parsOnInsideSurface(prop.
propagateParameters(
3930 ctx, startParm, insideSurface,
dir,
true, m_fieldProperties,
particle));
3932 const double distToInsideSurface =
3933 parsOnInsideSurface ? (startPosition - (parsOnInsideSurface->
position())).mag() : 10e10;
3935 ATH_MSG_VERBOSE(
" [+] Radial direction check start - at " << positionOutput(startPosition));
3936 ATH_MSG_VERBOSE(
" [+] Radial direction check layer - at " << positionOutput(onLayerPosition));
3937 if (parsOnInsideSurface) {
3939 << positionOutput(parsOnInsideSurface->
position()));
3943 ATH_MSG_VERBOSE(
" [+] Check radial direction: distance layer / boundary = "
3944 << distToLayer <<
" / " << distToInsideSurface);
3946 return distToLayer < distToInsideSurface;
3954 std::stringstream outStream;
3956 if (m_printRzOutput) {
3957 outStream <<
"[r,phi,z] = [ " <<
pos.perp() <<
", " <<
pos.phi() <<
", " <<
pos.z() <<
" ]";
3959 outStream <<
"[xyz] = [ " <<
pos.x() <<
", " <<
pos.y() <<
", " <<
pos.z() <<
" ]";
3961 return outStream.str();
3975 ATH_MSG_VERBOSE(
" [+] addMaterialEffectsOnTrack() - at " << positionOutput(parms->position()));
3978 double pathCorrection = 0.;
3986 parsOnLayer = parms;
3993 pathCorrection = pathCorrection > 0. ? pathCorrection
3995 parsOnLayer->position(), parsOnLayer->momentum());
3998 if (!materialProperties) {
4002 if (!materialProperties) {
4003 ATH_MSG_DEBUG(
" [!] No MaterialProperties on Layer after intersection.");
4009 const double tInX0 = pathCorrection * materialProperties->
thicknessInX0();
4014 const double currentQoP = parsOnLayer->parameters()[
Trk::qOverP];
4016 *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir,
particle));
4025 ATH_MSG_VERBOSE(
" [V] Validation mode: MaterialProperties found on this layer.");
4028 const double tInX0 = pathCorrection * materialProperties->
thicknessInX0();
4030 const double currentQoP = parsOnLayer->parameters()[
Trk::qOverP];
4031 auto energyLoss = m_elossupdater->energyLoss(
4032 *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir,
4035 const double sigmaMS = std::sqrt(m_msupdater->sigmaSquare(
4036 *materialProperties, std::abs(1. / currentQoP), pathCorrection,
particle));
4042 if (energyLoss.meanIoni() == 0. && tInX0 > 0.) {
4044 "because the ElossUpdator is wrongly configured: "
4045 "switch joboption DetailedEloss on ");
4052 energyLoss.sigmaIoni(),
4053 energyLoss.meanRad(),
4054 energyLoss.sigmaRad());
4059 auto meot = std::make_unique<Trk::MaterialEffectsOnTrack>(
4060 tInX0, scatAngles, std::make_unique<Trk::EnergyLoss>(std::move(energyLoss)),
4064 nullptr, cache.
m_ownedPtrs.move(parsOnLayer), std::move(meot)));
4087 unsigned int iDest = 0;
4092 if (destVol && m_navigator->atVolumeBoundary(currPar, destVol,
dir, nextVol, m_tolerance) &&
4093 nextVol != destVol) {
4098 const bool resolveActive =
true;
4113 if (!tgVol || tgVol != destVol) {
4115 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4116 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4119 iDest = bounds.size();
4124 bool updateStatic =
false;
4128 updateStatic =
true;
4133 bool navigDone =
false;
4142 updateStatic =
true;
4148 m_navigator->atVolumeBoundary(
4154 << positionOutput(currPar->position()));
4161 updateStatic =
true;
4170 ctx, cache, *m_stepPropagator, currPar,
nullptr, alignTV,
dir,
particle));
4172 return extrapolateToVolumeWithPathLimit(
4173 ctx, cache, nextPar, pathLim,
dir,
particle, destVol, matupmod);
4194 if (!detVols.empty()) {
4196 for (; iTer != detVols.end(); ++iTer) {
4198 const Trk::Layer* layR = (*iTer)->layerRepresentation();
4200 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
4203 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4204 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4208 !m_useMuonMatApprox ||
4209 (*iTer)->name().compare((*iTer)->name().size() - 4, 4,
"PERM") ==
4213 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
4214 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
4215 ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
4216 cache.
m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
4217 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4218 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4223 (*iTer)->trackingVolume()->confinedArbitraryLayers();
4224 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
4225 (confLays.size() > detBounds.size())) {
4227 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4228 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4231 }
else if (!confLays.empty()) {
4232 for (
const Trk::Layer*
const lIt : confLays) {
4273 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>> navigVols;
4275 gp = currPar->position();
4276 std::vector<const Trk::DetachedTrackingVolume*> detVols =
4279 for (; dIter != detVols.end(); ++dIter) {
4280 const Trk::Layer* layR = (*dIter)->layerRepresentation();
4282 if (
active && !resolveActive) {
4286 (*dIter)->name().compare((*dIter)->name().size() - 4, 4,
"PERM") != 0) {
4292 m_navigator->atVolumeBoundary(currPar, dVol,
dir, nextVol, m_tolerance) && !nextVol;
4300 if (!
active && confinedDense.empty() && confinedLays.empty()) {
4304 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
4307 if (!confinedDense.empty() || !confinedLays.empty()) {
4308 navigVols.emplace_back(dVol, bounds.size());
4309 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4310 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4314 if (!confinedDense.empty()) {
4315 auto vIter = confinedDense.begin();
4316 for (; vIter != confinedDense.end(); ++vIter) {
4317 const auto& bounds = (*vIter)->boundarySurfaces();
4318 cache.
m_denseVols.emplace_back(*vIter, bounds.size());
4319 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4320 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4326 if (!confinedLays.empty()) {
4327 for (
const auto *confinedLay : confinedLays) {
4335 for (
const auto *subvol : subvols) {
4336 if (subvol->inside(gp, m_tolerance)) {
4347 m_navigator->atVolumeBoundary(currPar, detVol,
dir, nextVol, m_tolerance) &&
4349 if (vExit && nextVol && nextVol->
inside(gp, m_tolerance)) {
4355 navigVols.emplace_back(detVol, bounds.size());
4356 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4357 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4361 cache.
m_denseVols.emplace_back(detVol, bounds.size());
4362 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4363 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4370 for (
const auto* cLay : cLays) {
4371 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4388 for (
const auto* cLay : cLays) {
4389 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4404 if (!m_navigator->atVolumeBoundary(currPar, dVol,
dir, nextVol, m_tolerance) ||
4423 std::vector<unsigned int> solutions;
4425 << positionOutput(currPar->position())
4426 <<
" (current momentum: " << currPar->momentum().mag() <<
")");
4431 <<
" with path limit" << pathLim
4434 <<
" in the direction" <<
dir <<
".");
4436 m_navigator->atVolumeBoundary(
4446 << positionOutput(nextPar->position()));
4447 ATH_MSG_DEBUG(
" [+] Momentum after propagation - " << nextPar->momentum());
4450 if (pathLim > 0. && cache.
m_path +
path >= pathLim) {
4456 m_navigator->atVolumeBoundary(
4458 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
4461 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
4477 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
4482 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
4484 const EnergyLoss eloss = (m_elossupdater->energyLoss(
4485 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle));
4497 unsigned int iSol = 0;
4498 while (iSol < solutions.size()) {
4499 if (solutions[iSol] < iDest) {
4505 if (
mb->layerMaterialProperties() &&
4506 mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
4507 const double pIn = nextPar->momentum().mag();
4512 if (currentUpdator) {
4515 currentUpdatorCache, nextPar, *
mb,
dir,
particle, matupmod));
4522 ATH_MSG_VERBOSE(
" Updated energy loss:" << nextPar->momentum().mag() - pIn
4523 <<
"at position:" << nextPar->position());
4528 const unsigned int index = solutions[iSol] - iDest;
4531 nextPar->position(), nextPar->momentum(),
dir);
4538 if (m_navigator->atVolumeBoundary(
4546 << positionOutput(nextPar->position()));
4558 << positionOutput(nextPar->position()));
4565 return extrapolateToVolumeWithPathLimit(
4566 ctx, cache, nextPar, pathLim,
dir,
particle, destVol, matupmod);
4568 }
else if (solutions[iSol] <
4575 m_includeMaterialEffects && nextLayer->
isOnLayer(nextPar->position());
4584 const double pIn = nextPar->momentum().mag();
4585 if (currentUpdator) {
4588 currentUpdatorCache, nextPar, *nextLayer,
dir,
particle, matupmod));
4596 << nextPar->momentum().mag() - pIn <<
"at position:"
4597 << nextPar->position() <<
", current momentum:" << nextPar->momentum());
4604 overlapSearch(ctx, cache, *m_subPropagators[0], currPar, nextPar,
4607 }
else if (nextLayer->
layerType() > 0 &&
4608 nextLayer->
isOnLayer(nextPar->position())) {
4618 if (postFactor > 0.1) {
4619 const double pIn = nextPar->momentum().mag();
4620 if (currentUpdator) {
4622 currentUpdatorCache, *nextPar, *nextLayer,
dir,
particle,
4631 ATH_MSG_VERBOSE(
" Post-update energy loss:" << nextPar->momentum().mag() - pIn
4633 << nextPar->position());
4637 const double pIn = nextPar->momentum().mag();
4638 if (currentUpdator) {
4640 currentUpdator->
update(currentUpdatorCache, nextPar,
4648 ATH_MSG_VERBOSE(
" Update energy loss:" << nextPar->momentum().mag() - pIn
4649 <<
"at position:" << nextPar->position());
4657 unsigned int index =
4659 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
4662 index -= (*dIter).second;
4666 currVol = (*dIter).first;
4668 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
4671 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
4674 }
else if (!nextVol || !nextVol->
inside(
tp, 0.)) {
4701 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator nIter =
4703 while (nIter != navigVols.end() &&
index >= (*nIter).second) {
4704 index -= (*nIter).second;
4707 if (nIter != navigVols.end()) {
4708 currVol = (*nIter).first;
4710 ((*nIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
4713 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
4714 if (nextVol && nextVol->
inside(
tp, 0.)) {
4715 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
4717 }
else if (currVol->
inside(
tp, 0.)) {
4719 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
4723 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, leaving volume '"
4729 return extrapolateToVolumeWithPathLimit(
4730 ctx, cache, nextPar, pathLim,
dir,
particle, destVol, matupmod);
4742 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
4745 index -= (*dIter).second;
4749 currVol = (*dIter).first->trackingVolume();
4751 ((*dIter).first->trackingVolume()->boundarySurfaces())[
index]->attachedVolume(
4755 nextPar->position() + 2 * m_tolerance *
dir * nextPar->momentum().normalized();
4756 if (nextVol && nextVol->
inside(
tp, 0.)) {
4757 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
4759 }
else if (currVol->
inside(
tp, 0.)) {
4761 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
4765 ATH_MSG_DEBUG(
" [+] Detached volume boundary, leaving volume '"
4770 return extrapolateToVolumeWithPathLimit(
4771 ctx, cache, nextPar, pathLim,
dir,
particle, destVol, matupmod);