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);