737 RecursionCounter counter(
cache.m_recursionCount);
739 ATH_MSG_WARNING(
"Too many recursive calls of extrapolateToNextMaterialLayer: "
744 ++
cache.m_methodSequence;
745 ATH_MSG_DEBUG(
"M-[" <<
cache.m_methodSequence <<
"] extrapolateToNextMaterialLayer(...) ");
747 ATH_MSG_WARNING(
"Too many method sequence calls of extrapolateToNextMaterialLayer: "
748 <<
cache.m_methodSequence);
766 std::vector<unsigned int> solutions;
770 bool resolveActive = destSurf ==
nullptr;
774 if (
cache.m_lastMaterialLayer && !
cache.m_lastMaterialLayer->isOnLayer(parm->position())) {
775 cache.m_lastMaterialLayer =
nullptr;
779 if (!
cache.m_highestVolume) {
780 cache.m_highestVolume =
cache.m_trackingGeometry->highestTrackingVolume();
787 staticVol =
cache.m_trackingGeometry->lowestStaticTrackingVolume(gp);
790 nextStatVol != staticVol) {
791 staticVol = nextStatVol;
799 cache.m_navigSurfs.clear();
801 cache.m_navigSurfs.emplace_back(destSurf,
false);
808 cache.m_identifiedParameters.reset();
810 alignTV, dir, particle);
817 cache.m_currentStatic = staticVol;
818 cache.retrieveBoundaries();
820 cache.m_detachedVols.clear();
821 cache.m_detachedBoundaries.clear();
822 cache.m_denseVols.clear();
823 cache.m_denseBoundaries.clear();
824 cache.m_layers.clear();
825 cache.m_navigLays.clear();
829 if (!detVols.empty()) {
830 Trk::ArraySpan<const Trk::DetachedTrackingVolume* const>::iterator iTer = detVols.begin();
831 for (; iTer != detVols.end(); ++iTer) {
833 const Trk::Layer* layR = (*iTer)->layerRepresentation();
835 const auto detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
838 cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
839 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
840 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
841 cache.m_detachedBoundaries.emplace_back(&surf,
true);
845 cache.addOneNavigationLayer((*iTer)->trackingVolume(), layR);
848 const auto& multi = (*iTer)->multilayerRepresentation();
849 for (
const auto *i : multi) {
850 cache.addOneNavigationLayer((*iTer)->trackingVolume(), i);
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();
870 cache.m_denseBoundaries.emplace_back(&surf,
true);
874 (*iTer)->trackingVolume()->confinedArbitraryLayers();
875 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
876 (confLays.size() > detBounds.size())) {
877 cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
878 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
880 (detBounds[ibb])->surfaceRepresentation();
881 cache.m_detachedBoundaries.emplace_back(&surf,
true);
883 }
else if (!confLays.empty()) {
884 for (
const Trk::Layer*
const lIt : confLays) {
885 cache.addOneNavigationLayer((*iTer)->trackingVolume(), (lIt));
891 cache.m_denseResolved = std::pair<unsigned int, unsigned int>(
cache.m_denseVols.size(),
892 cache.m_denseBoundaries.size());
893 cache.m_layerResolved =
cache.m_layers.size();
896 cache.m_navigSurfs.insert(
897 cache.m_navigSurfs.end(),
cache.m_staticBoundaries.begin(),
cache.m_staticBoundaries.end());
913 std::unique_ptr<Trk::TrackParameters> pNextPar = prop.
propagate(ctx,*currPar,
cache.m_navigSurfs,
918 ++
cache.m_nPropagations;
923 cache.m_parametersAtBoundary.resetBoundaryInformation();
929 if (not
cache.elossPointerOverwritten()) {
933 const double dInX0 = std::abs(path) / propagVol->
x0();
935 cache.m_extrapolationCache->updateX0(dInX0);
937 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
939 materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
941 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
943 cache.m_extrapolationCache->updateEloss(
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));
958 0, 0, scatsigma / std::sin(nextPar->parameters()[
Trk::theta]), scatsigma);
960 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
962 materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
965 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
969 nextPar->position(), nextPar->momentum(), nextPar->charge()));
971 if (
cache.m_extrapolationCache) {
975 cache.m_extrapolationCache->updateX0(dInX0);
976 cache.m_extrapolationCache->updateEloss(
982 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
983 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
984 cvlTP->associatedSurface());
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) {
999 if (solutions[0] <= isurf +
cache.m_staticBoundaries.size()) {
1002 cache.m_currentStatic->boundarySurfaces()[solutions[0] - isurf]->attachedVolume(
1003 currPar->position(), currPar->momentum(), dir);
1004 cache.m_parametersAtBoundary.boundaryInformation(nextVol, currPar, currPar);
1006 ATH_MSG_DEBUG(
" [!] World boundary at position R,z: " << currPar->position().perp() <<
","
1007 << currPar->position().z());
1021 cache.m_navigBoundaries.clear();
1022 if (
cache.m_denseVols.size() >
cache.m_denseResolved.first) {
1023 cache.m_denseVols.resize(
cache.m_denseResolved.first);
1025 while (
cache.m_denseBoundaries.size() >
cache.m_denseResolved.second) {
1026 cache.m_denseBoundaries.pop_back();
1028 if (
cache.m_layers.size() >
cache.m_layerResolved) {
1029 cache.m_navigLays.resize(
cache.m_layerResolved);
1031 while (
cache.m_layers.size() >
cache.m_layerResolved) {
1032 cache.m_layers.pop_back();
1042 cache.m_navigVolsInt.clear();
1044 gp = currPar->position();
1045 std::vector<const Trk::DetachedTrackingVolume*> detVols =
1046 cache.m_trackingGeometry->lowestDetachedTrackingVolumes(gp);
1047 std::vector<const Trk::DetachedTrackingVolume*>::iterator dIter = detVols.begin();
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) {
1069 if (!
active && confinedDense.empty() && confinedLays.empty()) {
1073 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
1076 if (!confinedDense.empty() || !confinedLays.empty()) {
1077 cache.m_navigVolsInt.emplace_back(dVol, bounds.size());
1078 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1079 const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1080 cache.m_navigBoundaries.emplace_back(&surf,
true);
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();
1090 cache.m_denseBoundaries.emplace_back(&surf,
true);
1095 if (!confinedLays.empty()) {
1096 for (
const auto *confinedLay : confinedLays) {
1097 cache.addOneNavigationLayer(dVol, confinedLay);
1104 for (
const auto *subvol : subvols) {
1124 cache.m_navigVolsInt.emplace_back(detVol, bounds.size());
1125 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1126 const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1127 cache.m_navigBoundaries.emplace_back(&surf,
true);
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();
1133 cache.m_denseBoundaries.emplace_back(&surf,
true);
1141 cache.addOneNavigationLayer(detVol, lay);
1145 detVol->
nextLayer(currPar->position(), dir * currPar->momentum().unit(),
true);
1146 if (nextLayer && nextLayer != lay) {
1147 cache.addOneNavigationLayer(detVol, nextLayer);
1151 for (
const auto *layer : layers) {
1152 cache.addOneNavigationLayer(detVol, layer);
1158 cache.copyToNavigationSurfaces();
1161 cache.m_currentDense =
cache.m_highestVolume;
1162 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
1163 cache.m_currentDense =
cache.m_currentStatic;
1165 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1170 cache.m_currentDense = dVol;
1182 std::vector<unsigned int> solutions;
1185 currPar->position() + 2 *
m_tolerance * dir * currPar->momentum().normalized();
1186 if (!(
cache.m_currentDense->inside(tp, 0.))) {
1187 cache.m_currentDense =
cache.m_highestVolume;
1188 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
1189 cache.m_currentDense =
cache.m_currentStatic;
1191 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1194 cache.m_currentDense = dVol;
1202 <<
" (current momentum: " << currPar->momentum().mag() <<
")");
1204 <<
cache.m_currentDense->volumeName() <<
"'.");
1207 solutions, path,
false,
false,
cache.m_currentDense));
1209 ++
cache.m_nPropagations;
1214 if (nextPar && !(
cache.m_currentDense->inside(nextPar->position(),
m_tolerance) ||
1217 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
1218 <<
cache.m_currentDense->volumeName());
1219 if (
cache.m_currentDense->zOverAtimesRho() != 0.) {
1220 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
1221 <<
cache.m_highestVolume->volumeName());
1222 cache.m_currentDense =
cache.m_highestVolume;
1227 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
1228 if (
cache.m_currentDense->zOverAtimesRho() != 0. && !
cache.m_matstates &&
1229 cache.m_extrapolationCache) {
1230 if (not
cache.elossPointerOverwritten()) {
1234 const double dInX0 = std::abs(path) /
cache.m_currentDense->x0();
1235 cache.m_extrapolationCache->updateX0(dInX0);
1237 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1239 materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
1240 cache.m_extrapolationCache->updateEloss(
1250 if (
cache.m_currentDense->zOverAtimesRho() != 0. &&
cache.m_matstates) {
1251 const double dInX0 = std::abs(path) /
cache.m_currentDense->x0();
1252 if (path * dir < 0.) {
1256 const double scatsigma = std::sqrt(
m_msupdater->sigmaSquare(
1257 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1., particle));
1259 0, 0, scatsigma / std::sin(nextPar->parameters()[
Trk::theta]), scatsigma);
1261 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1263 materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
1266 << nextPar->momentum().mag() - currPar->momentum().mag() <<
","
1271 nextPar->position(), nextPar->momentum(), nextPar->charge()));
1273 if (
cache.m_extrapolationCache) {
1277 cache.m_extrapolationCache->updateX0(dInX0);
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 '"
1293 <<
cache.m_currentDense->volumeName() <<
"', t/X0 = " << dInX0);
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.) {
1319 ATH_MSG_DEBUG(
" [+] Destination surface missed ? " << dist <<
"," << dir);
1320 cache.m_parametersAtBoundary.resetBoundaryInformation();
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()) {
1329 if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size()) {
1331 const Trk::Layer* mb =
cache.m_navigSurfs[solutions[iSol]].first->materialLayer();
1333 if (mb->layerMaterialProperties() &&
1334 mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
1339 cache.subMaterialEffectsUpdatorCache();
1341 if (currentUpdator) {
1342 nextPar =
cache.m_ownedPtrs.push(
1343 currentUpdator->
update(currentUpdatorCache, nextPar,
1344 *mb, dir, particle, matupmode));
1347 cache.m_parametersAtBoundary.resetBoundaryInformation();
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));
1369 if (!
cache.m_matstates &&
cache.m_extrapolationCache) {
1370 if (not
cache.elossPointerOverwritten()) {
1371 const double dInX0 = thick / lx0;
1375 cache.m_extrapolationCache->updateX0(dInX0);
1376 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1378 *lmat, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1379 cache.m_extrapolationCache->updateEloss(
1390 if (
cache.m_matstates) {
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));
1395 0, 0, scatsigma / std::sin(nextPar->parameters()[
Trk::theta]), scatsigma);
1397 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1399 *lmat, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1403 nextPar->position(), nextPar->momentum(), nextPar->charge()));
1404 if (
cache.m_extrapolationCache) {
1405 if (not
cache.elossPointerOverwritten()) {
1409 cache.m_extrapolationCache->updateX0(dInX0);
1410 cache.m_extrapolationCache->updateEloss(
1420 std::make_unique<Trk::MaterialEffectsOnTrack>(
1422 std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
1423 cvlTP->associatedSurface());
1425 nullptr, std::move(cvlTP), std::move(mefot)));
1431 const unsigned int index = solutions[iSol] - iDest;
1433 nextVol = (
cache.m_currentStatic->boundarySurfaces())[
index]->attachedVolume(
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 ?"
1440 <<
cache.m_currentStatic->volumeName() <<
"->" << nextVol->
volumeName());
1441 nextVol =
cache.m_trackingGeometry->lowestStaticTrackingVolume(
1442 nextPar->position() + 0.01 * nextPar->momentum().normalized());
1448 if (nextVol !=
cache.m_currentStatic) {
1449 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
1451 <<
cache.m_currentStatic->volumeName() <<
"'.");
1454 assocVol !=
cache.m_currentStatic) {
1463 if (nextVol && nextPar) {
1470 }
else if (solutions[iSol] <
1471 iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size()) {
1473 const unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size();
1477 bool collect =
true;
1478 if (nextLayer ==
cache.m_lastMaterialLayer &&
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.) {
1495 cache.subMaterialEffectsUpdatorCache();
1497 if (currentUpdator) {
1498 nextPar =
cache.m_ownedPtrs.push(
1499 currentUpdator->
update(currentUpdatorCache, nextPar,
1500 *nextLayer, dir, particle, matupmode));
1503 cache.m_parametersAtBoundary.resetBoundaryInformation();
1511 const double costr = std::abs(
1517 layThick / std::abs(nextPar->momentum().normalized().dot(
1520 thick = fmin(2 * nextLayer->
thickness(), layThick / (1 - costr));
1523 if (!
cache.m_matstates &&
cache.m_extrapolationCache) {
1524 if (not
cache.elossPointerOverwritten()) {
1525 const double dInX0 = thick / lx0;
1529 cache.m_extrapolationCache->updateX0(dInX0);
1532 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1534 materialProperties, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1535 cache.m_extrapolationCache->updateEloss(
1545 if (
cache.m_matstates) {
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];
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());
1563 if (
cache.m_extrapolationCache) {
1564 if (not
cache.elossPointerOverwritten()) {
1568 cache.m_extrapolationCache->updateX0(dInX0);
1569 cache.m_extrapolationCache->updateEloss(
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)));
1584 if (
cache.m_cacheLastMatLayer) {
1585 cache.m_lastMaterialLayer = nextLayer;
1587 if (!destSurf && nextLayer->
layerType() > 0) {
1591 if (resolveActive) {
1594 cache.m_navigLays[
index].first->confinedLayers()) {
1596 nextPar->position(), dir * nextPar->momentum().normalized(),
true);
1605 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
1606 cache.m_layers.size() +
cache.m_denseBoundaries.size()) {
1608 unsigned int index =
1609 solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
cache.m_layers.size();
1610 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
1611 cache.m_denseVols.begin();
1612 while (dIter !=
cache.m_denseVols.end() &&
index >= (*dIter).second) {
1613 index -= (*dIter).second;
1616 if (dIter !=
cache.m_denseVols.end()) {
1617 currVol = (*dIter).first;
1619 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar, dir);
1622 nextPar->position() + 2 *
m_tolerance * dir * nextPar->momentum().normalized();
1624 cache.m_currentDense = currVol;
1626 cache.m_currentDense =
cache.m_highestVolume;
1627 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
1628 cache.m_currentDense =
cache.m_currentStatic;
1630 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1633 cache.m_currentDense = dVol;
1635 <<
cache.m_currentDense->volumeName() <<
"'.");
1641 cache.m_currentDense = nextVol;
1646 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
1647 cache.m_layers.size() +
cache.m_denseBoundaries.size() +
1648 cache.m_navigBoundaries.size()) {
1650 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
1651 cache.m_layers.size() -
cache.m_denseBoundaries.size();
1652 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator nIter =
1653 cache.m_navigVolsInt.begin();
1654 while (nIter !=
cache.m_navigVolsInt.end() &&
index >= (*nIter).second) {
1655 index -= (*nIter).second;
1658 if (nIter !=
cache.m_navigVolsInt.end()) {
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 '"
1681 ctx,
cache, prop, nextPar, destSurf,
cache.m_currentStatic,
1682 dir, bcheck, particle, matupmode);
1685 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
1686 cache.m_layers.size() +
cache.m_denseBoundaries.size() +
1687 cache.m_navigBoundaries.size() +
1688 cache.m_detachedBoundaries.size()) {
1690 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
1691 cache.m_layers.size() -
cache.m_denseBoundaries.size() -
1692 cache.m_navigBoundaries.size();
1693 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
1694 cache.m_detachedVols.begin();
1695 while (dIter !=
cache.m_detachedVols.end() &&
index >= (*dIter).second) {
1696 index -= (*dIter).second;
1699 if (dIter !=
cache.m_detachedVols.end()) {
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 '"
1723 ctx,
cache, prop, nextPar, destSurf,
cache.m_currentStatic,
1724 dir, bcheck, particle, matupmode);
1732 cache.m_parametersAtBoundary.boundaryInformation(
cache.m_currentStatic, nextPar, nextPar);
2102 cache.m_destinationSurface =
nullptr;
2103 cache.m_lastValidParameters =
nullptr;
2106 if (
cache.m_methodSequence) {
2107 ++
cache.m_methodSequence;
2114 for (
unsigned int imueot = 0; imueot <
m_subupdaters.size(); ++imueot) {
2122 ++
cache.m_methodSequence;
2138 refParameters, nextLayer, nextVolume, destVolume);
2147 " [!] Navigation direction could not be resolved, switching to extrapolateDirectly()");
2149 ++
cache.m_methodSequence;
2154 startVolume = nextVolume;
2156 bool fallback =
false;
2158 double currentDistance = 0.;
2159 double previousDistance = 0.;
2161 if (refParameters) {
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);
2182 " [" <<
cache.m_methodSequence <<
"] extrapolate() "
2183 << ((nextVolume) ? nextVolume->
volumeName() :
"Unknown (ERROR)")
2186 :
"Unknown (blind extrapolation)"));
2190 ATH_MSG_VERBOSE(
" [+] Starting layer determined - with " << layerRZoutput(*nextLayer));
2207 bool updateLastValid =
true;
2209 bool punchThroughDone =
false;
2216 while (nextVolume && nextVolume != destVolume && nextVolume != lastVolume && nextParameters &&
2220 if (!currentPropagator) {
2224 ATH_MSG_DEBUG(
" - Reason : No Propagator found for Volume '"
2235 if (updateLastValid) {
2236 cache.m_lastValidParameters = nextParameters;
2239 previousVolume = lastVolume;
2241 lastVolume = nextVolume;
2243 lastParameters = nextParameters;
2249 if (
cache.m_parametersAtBoundary.navParameters &&
2250 cache.m_parametersAtBoundary.navParameters !=
2251 cache.m_parametersAtBoundary.nextParameters) {
2255 ctx, *
cache.m_parametersAtBoundary.nextParameters,
2256 cache.m_parametersAtBoundary.navParameters->associatedSurface(),
2261 cache.m_parametersAtBoundary.boundaryInformation(nextVolume, nextPar, nextPar);
2262 nextParameters =
cache.m_parametersAtBoundary.nextParameters;
2263 navParameters =
cache.m_parametersAtBoundary.navParameters;
2267 if (nextParameters) {
2270 "extrapolation in Calo/MS called without configured STEP propagator, aborting");
2275 *nextVolume, dir, bcheck, particle, matupmode);
2277 if (resultParameters) {
2280 for (
unsigned int imueot = 0; imueot <
m_subupdaters.size(); ++imueot) {
2286 ATH_MSG_DEBUG(
" [+] Destination surface successfully hit.");
2288 return resultParameters;
2289 }
if (!
cache.m_parametersAtBoundary.nextParameters ||
2290 !
cache.m_parametersAtBoundary.nextVolume ||
2292 ATH_MSG_DEBUG(
" [-] Destination surface could not be hit.");
2293 return resultParameters;
2312 nextVolume =
cache.m_parametersAtBoundary.nextVolume;
2313 nextParameters =
cache.m_parametersAtBoundary.nextParameters;
2314 navParameters =
cache.m_parametersAtBoundary.navParameters;
2316 previousDistance = currentDistance;
2320 cache.m_parametersAtBoundary.navParameters
2321 ?
cache.m_parametersAtBoundary.navParameters
2324 if (distParameters) {
2327 if (refParameters) {
2328 currentDistance = (refParameters->
position() - distParameters->
position()).mag();
2332 distParameters->
position(), dir * distParameters->
momentum().normalized());
2340 << currentDistance <<
" (from "
2341 << (
cache.m_parametersAtBoundary.navParameters
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 '"
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.");
2394 else if (!nextVolume && !
cache.m_parametersOnDetElements && lastVolume &&
2401 ++navigationBreakNoVolume;
2410 else if (nextParameters && !
cache.m_parametersOnDetElements && navParameters && nextVolume &&
2411 currentDistance > s_distIncreaseTolerance + previousDistance) {
2415 << previousDistance <<
" to " << currentDistance <<
"] in TrackingVolume '"
2418 ++navigationBreakDistIncrease;
2427 ATH_MSG_DEBUG(
" [+] Navigation stop : either the update killed the "
2428 "track, or end of detector/boundary volume reached");
2433 else if (
cache.m_boundaryVolume && navParameters &&
2434 !(
cache.m_boundaryVolume->inside(navParameters->
position()))) {
2436 " [+] Navigation stop : next navigation step would lead outside given boundary volume");
2441 else if (nextVolume) {
2445 updateLastValid = !nextParameters ||
cache.m_parametersOnDetElements || !navParameters ||
2446 !nextVolume || currentDistance <= previousDistance;
2448 if (!nextParameters) {
2449 nextParameters = lastParameters;
2452 nextLayer =
nullptr;
2460 ?
"return 0 (configured) "
2461 :
"switch to extrapolateDirectly() "));
2466 if (
cache.m_lastValidParameters && lastVolume) {
2469 if (!currentPropagator) {
2478 if (!resultParameters) {
2479 resultParameters =
cache.m_ownedPtrs.push(currentPropagator->
propagate(
2483 return resultParameters;
2495 ATH_MSG_DEBUG(
"create finalNextParameters " << *finalNextParameters);
2501 if (currentPropagator) {
2503 ctx,
cache, *currentPropagator, nextParameters, sf, nextLayer,
2504 *nextVolume, dir, bcheck, particle, matupmode);
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 ! ");
2517 resultParameters =
cache.m_ownedPtrs.push(
2518 prop.
propagate(ctx, *finalNextParameters, sf, dir, bcheck,
2523 return resultParameters;
2892 ++
cache.m_methodSequence;
2901 ?
cache.m_parametersAtBoundary.navParameters
2905 const double rPos = parm->position().perp();
2906 double rComponent = parm->momentum().normalized().perp();
2908 rComponent = rComponent < 10e-5 ? 10e-5 : rComponent;
2911 : 0.5 * rPos / rComponent;
2912 rScalor = rScalor * rScalor < 10e-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.");
2928 nextParameters =
cache.m_ownedPtrs.push(
2929 prop.
propagate(ctx, *parm, *
cache.m_destinationSurface, dir, bcheck,
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;
2956 destinationLayer =
cache.m_destinationSurface->associatedLayer();
2957 if (!destinationLayer) {
2959 (
cache.m_recallSurface ==
cache.m_destinationSurface &&
2960 cache.m_destinationSurface->associatedDetectorElement())
2961 ?
cache.m_recallLayer
2964 if (destinationLayer) {
2966 << layerRZoutput(*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) ||
2992 tvol, dir, bcheck, particle,
true);
2996 ATH_MSG_VERBOSE(
" [+] Calling postUpdate on inital track parameters.");
3002 cache.subMaterialEffectsUpdatorCache(tvol);
3004 if (currentUpdator) {
3006 currentUpdatorCache, *nextParameters, *associatedLayer, dir,
3007 particle, matupmode));
3010 if (nextParameters &&
cache.m_matstates) {
3012 ctx,
cache, prop, nextParameters, *associatedLayer, tvol, dir, particle);
3014 if (nextParameters && nextParameters != parm) {
3017 nextParameters = parm;
3020 cache.m_parametersAtBoundary.resetBoundaryInformation();
3021 cache.resetRecallInformation();
3026 assocLayer =
nullptr;
3033 if (!associatedLayer) {
3034 ATH_MSG_VERBOSE(
" [+] Volume switch has happened, searching for entry layers.");
3036 exitFace =
cache.m_parametersAtBoundary.exitFace;
3042 << layerRZoutput(*associatedLayer));
3047 ctx,
cache, prop, parm, *associatedLayer, tvol, dir, bcheck, particle, matupmode);
3048 nextParameters = new_track_parm;
3053 cache.m_parametersAtBoundary.resetBoundaryInformation();
3054 cache.resetRecallInformation();
3056 }
if (
cache.m_boundaryVolume && nextParameters &&
3057 !
cache.m_boundaryVolume->inside(nextParameters->position())) {
3058 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3060 cache.m_parametersAtBoundary.resetBoundaryInformation();
3061 cache.resetRecallInformation();
3065 if (nextParameters) {
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,
3117 cache.m_parametersAtBoundary.resetBoundaryInformation();
3118 cache.resetRecallInformation();
3120 }
if (
cache.m_boundaryVolume && updateNext &&
3121 !
cache.m_boundaryVolume->inside(updateNext->position())) {
3122 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3124 cache.m_parametersAtBoundary.resetBoundaryInformation();
3125 cache.resetRecallInformation();
3130 nextParameters = updateNext;
3137 ctx,
cache, prop, nextParameters, *
cache.m_destinationSurface,
3138 *destinationLayer, tvol, assocLayerReference, dir, bcheck, particle,
3142 cache.setRecallInformation( *
cache.m_destinationSurface, *destinationLayer, tvol);
3144 return nextParameters;
3148 }
else if (!toBoundary) {
3149 nextParameters =
cache.m_ownedPtrs.push(
3150 prop.
propagate(ctx, *nextParameters, *
cache.m_destinationSurface, dir,
3154 cache.resetRecallInformation();
3156 return nextParameters;
3160 if (!nextParameters) {
3161 nextParameters = parm;
3165 unsigned int navprop = 0;
3174 const bool vetoNavParameters =
false;
3179 if (nextParameters != parm || assocLayerReference) {
3180 navParameters = nextParameters;
3182 navParameters = (
cache.m_parametersAtBoundary.navParameters && !vetoNavParameters)
3183 ?
cache.m_parametersAtBoundary.navParameters
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;
3218 if (!nextVolume && !
cache.m_parametersOnDetElements) {
3220 if (navParameters) {
3226 cache.resetRecallInformation();
3229 if (bParameters && bParameters->associatedSurface().materialLayer()) {
3235 cache.subMaterialEffectsUpdatorCache(tvol);
3237 if (currentUpdator) {
3238 bParameters =
cache.m_ownedPtrs.push(currentUpdator->
update(
3239 currentUpdatorCache, bParameters,
3240 *(bParameters->associatedSurface().materialLayer()), dir, particle,
3244 if (bParameters &&
cache.m_matstates) {
3246 ctx,
cache, prop, bParameters,
3247 *(bParameters->associatedSurface().materialLayer()), tvol, dir,
3250 navParameters = bParameters;
3255 cache.m_parametersAtBoundary.boundaryInformation(
3256 nextVolume, nextParameters, navParameters, exitFace);
3259 return navParameters;
4087 unsigned int iDest = 0;
4093 nextVol != destVol) {
4094 pathLim =
cache.m_path;
4098 const bool resolveActive =
true;
4099 if (!
cache.m_highestVolume) {
4100 cache.m_highestVolume =
cache.m_trackingGeometry->highestTrackingVolume();
4107 cache.m_navigSurfs.clear();
4113 if (!tgVol || tgVol != destVol) {
4115 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
4116 const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4117 cache.m_navigSurfs.emplace_back(&surf,
true);
4119 iDest = bounds.size();
4124 bool updateStatic =
false;
4127 cache.m_currentStatic =
cache.m_trackingGeometry->lowestStaticTrackingVolume(gp);
4128 updateStatic =
true;
4133 bool navigDone =
false;
4134 if (
cache.m_parametersAtBoundary.nextParameters &&
cache.m_parametersAtBoundary.nextVolume) {
4135 if ((
cache.m_parametersAtBoundary.nextParameters->position() - currPar->position()).mag() <
4137 cache.m_parametersAtBoundary.nextParameters->momentum().dot(currPar->momentum()) > 0.001) {
4138 nextVol =
cache.m_parametersAtBoundary.nextVolume;
4140 if (nextVol !=
cache.m_currentStatic) {
4141 cache.m_currentStatic = nextVol;
4142 updateStatic =
true;
4150 nextVol !=
cache.m_currentStatic) {
4156 pathLim =
cache.m_path;
4160 cache.m_currentStatic = nextVol;
4161 updateStatic =
true;
4166 if (
cache.m_currentStatic->isAlignable()) {
4173 ctx,
cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4182 cache.retrieveBoundaries();
4184 cache.m_detachedVols.clear();
4185 cache.m_detachedBoundaries.clear();
4186 cache.m_denseVols.clear();
4187 cache.m_denseBoundaries.clear();
4188 cache.m_layers.clear();
4189 cache.m_navigLays.clear();
4193 cache.m_currentStatic->confinedDetachedVolumes();
4194 if (!detVols.empty()) {
4195 Trk::ArraySpan<const Trk::DetachedTrackingVolume* const>::iterator iTer = detVols.begin();
4196 for (; iTer != detVols.end(); ++iTer) {
4198 const Trk::Layer* layR = (*iTer)->layerRepresentation();
4200 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
4202 cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
4203 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4204 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4205 cache.m_detachedBoundaries.emplace_back(&surf,
true);
4207 }
else if (
cache.m_currentStatic->geometrySignature() !=
Trk::MS ||
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();
4219 cache.m_denseBoundaries.emplace_back(&surf,
true);
4223 (*iTer)->trackingVolume()->confinedArbitraryLayers();
4224 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
4225 (confLays.size() > detBounds.size())) {
4226 cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
4227 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4228 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4229 cache.m_detachedBoundaries.emplace_back(&surf,
true);
4231 }
else if (!confLays.empty()) {
4232 for (
const Trk::Layer*
const lIt : confLays) {
4233 cache.addOneNavigationLayer((*iTer)->trackingVolume(), lIt);
4239 cache.m_denseResolved = std::pair<unsigned int, unsigned int>(
cache.m_denseVols.size(),
4240 cache.m_denseBoundaries.size());
4241 cache.m_layerResolved =
cache.m_layers.size();
4244 cache.m_navigSurfs.insert(
4245 cache.m_navigSurfs.end(),
cache.m_staticBoundaries.begin(),
cache.m_staticBoundaries.end());
4254 cache.m_navigBoundaries.clear();
4255 if (
cache.m_denseVols.size() >
cache.m_denseResolved.first) {
4256 cache.m_denseVols.resize(
cache.m_denseResolved.first);
4258 while (
cache.m_denseBoundaries.size() >
cache.m_denseResolved.second) {
4259 cache.m_denseBoundaries.pop_back();
4262 if (
cache.m_layers.size() >
cache.m_layerResolved) {
4263 cache.m_navigLays.resize(
cache.m_layerResolved);
4265 while (
cache.m_layers.size() >
cache.m_layerResolved) {
4266 cache.m_layers.pop_back();
4273 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>> navigVols;
4275 gp = currPar->position();
4276 std::vector<const Trk::DetachedTrackingVolume*> detVols =
4277 cache.m_trackingGeometry->lowestDetachedTrackingVolumes(gp);
4278 std::vector<const Trk::DetachedTrackingVolume*>::iterator dIter = detVols.begin();
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) {
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();
4311 cache.m_navigBoundaries.emplace_back(&surf,
true);
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();
4321 cache.m_denseBoundaries.emplace_back(&surf,
true);
4326 if (!confinedLays.empty()) {
4327 for (
const auto *confinedLay : confinedLays) {
4328 cache.addOneNavigationLayer(dVol, confinedLay);
4335 for (
const auto *subvol : subvols) {
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();
4358 cache.m_navigBoundaries.emplace_back(&surf,
true);
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();
4364 cache.m_denseBoundaries.emplace_back(&surf,
true);
4370 for (
const auto* cLay : cLays) {
4371 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4372 cache.addOneNavigationLayer(cLay);
4377 cache.addOneNavigationLayer(detVol, pThisLayer);
4385 if (
cache.m_currentStatic->confinedLayers() && updateStatic) {
4387 std::span<Trk::Layer const* const>
const cLays =
cache.m_currentStatic->confinedLayers()->arrayObjects();
4388 for (
const auto* cLay : cLays) {
4389 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4390 cache.addOneNavigationLayer(cLay);
4394 cache.copyToNavigationSurfaces();
4397 cache.m_currentDense =
cache.m_highestVolume;
4398 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
4399 cache.m_currentDense =
cache.m_currentStatic;
4401 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
4406 cache.m_currentDense = dVol;
4423 std::vector<unsigned int> solutions;
4426 <<
" (current momentum: " << currPar->momentum().mag() <<
")");
4428 <<
cache.m_currentDense->volumeName()
4431 <<
" with path limit" << pathLim
4434 <<
" in the direction" << dir <<
".");
4438 cache.m_currentDense =
cache.m_highestVolume;
4442 solutions, path,
true,
false,
cache.m_currentDense));
4444 ++
cache.m_nPropagations;
4447 ATH_MSG_DEBUG(
" [+] Momentum after propagation - " << nextPar->momentum());
4450 if (pathLim > 0. &&
cache.m_path + path >= pathLim) {
4451 cache.m_path += path;
4455 if (nextPar && !(
cache.m_currentDense->inside(nextPar->position(),
m_tolerance) ||
4458 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
4459 <<
cache.m_currentDense->volumeName());
4460 if (
cache.m_currentDense->zOverAtimesRho() != 0.) {
4461 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
4462 <<
cache.m_highestVolume->volumeName());
4463 cache.m_currentDense =
cache.m_highestVolume;
4469 cache.m_parametersAtBoundary.boundaryInformation(
cache.m_currentStatic, nextPar, nextPar);
4473 cache.m_path += path;
4477 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
4479 if (
cache.m_currentDense->zOverAtimesRho() != 0.&&
4480 cache.m_extrapolationCache) {
4481 const double dInX0 = std::abs(path) /
cache.m_currentDense->x0();
4482 const double currentqoverp = nextPar->parameters()[
Trk::qOverP];
4485 materialProperties, std::abs(1. / currentqoverp), 1., dir, particle));
4489 cache.m_extrapolationCache->updateX0(dInX0);
4490 cache.m_extrapolationCache->updateEloss(
4497 unsigned int iSol = 0;
4498 while (iSol < solutions.size()) {
4499 if (solutions[iSol] < iDest) {
4501 }
if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size()) {
4503 const Trk::Layer* mb =
cache.m_navigSurfs[solutions[iSol]].first->materialLayer();
4505 if (mb->layerMaterialProperties() &&
4506 mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
4507 const double pIn = nextPar->momentum().mag();
4511 cache.subMaterialEffectsUpdatorCache();
4512 if (currentUpdator) {
4513 nextPar =
cache.m_ownedPtrs.push(
4515 currentUpdatorCache, nextPar, *mb, dir, particle, matupmod));
4519 cache.m_parametersAtBoundary.resetBoundaryInformation();
4522 ATH_MSG_VERBOSE(
" Updated energy loss:" << nextPar->momentum().mag() - pIn
4523 <<
"at position:" << nextPar->position());
4528 const unsigned int index = solutions[iSol] - iDest;
4530 nextVol = (
cache.m_currentStatic->boundarySurfaces())[
index]->attachedVolume(
4531 nextPar->position(), nextPar->momentum(), dir);
4532 if (nextVol !=
cache.m_currentStatic) {
4533 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
4535 <<
cache.m_currentStatic->volumeName()
4536 <<
"', geoID: " <<
cache.m_currentStatic->geometrySignature());
4540 assocVol !=
cache.m_currentStatic) {
4541 cache.m_currentDense =
cache.m_dense ? nextVol :
cache.m_highestVolume;
4548 pathLim =
cache.m_path;
4561 pathLim =
cache.m_path;
4566 ctx,
cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4568 }
else if (solutions[iSol] <
4569 iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size()) {
4571 const unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size();
4581 cache.subMaterialEffectsUpdatorCache();
4584 const double pIn = nextPar->momentum().mag();
4585 if (currentUpdator) {
4586 nextPar =
cache.m_ownedPtrs.push(
4588 currentUpdatorCache, nextPar, *nextLayer, dir, particle, matupmod));
4592 cache.m_parametersAtBoundary.resetBoundaryInformation();
4596 << nextPar->momentum().mag() - pIn <<
"at position:"
4597 << nextPar->position() <<
", current momentum:" << nextPar->momentum());
4605 *nextLayer, *
cache.m_currentStatic, dir,
true,
4607 }
else if (nextLayer->
layerType() > 0 &&
4608 nextLayer->
isOnLayer(nextPar->position())) {
4610 cache.m_parametersOnDetElements->emplace_back(nextPar->uniqueClone());
4618 if (postFactor > 0.1) {
4619 const double pIn = nextPar->momentum().mag();
4620 if (currentUpdator) {
4622 currentUpdatorCache, *nextPar, *nextLayer, dir, particle,
4628 cache.m_parametersAtBoundary.resetBoundaryInformation();
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) {
4639 nextPar =
cache.m_ownedPtrs.push(
4640 currentUpdator->
update(currentUpdatorCache, nextPar,
4641 *nextLayer, dir, particle, matupmod));
4645 cache.m_parametersAtBoundary.resetBoundaryInformation();
4648 ATH_MSG_VERBOSE(
" Update energy loss:" << nextPar->momentum().mag() - pIn
4649 <<
"at position:" << nextPar->position());
4654 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
4655 cache.m_denseBoundaries.size()) {
4657 unsigned int index =
4658 solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
cache.m_layers.size();
4659 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
4660 cache.m_denseVols.begin();
4661 while (dIter !=
cache.m_denseVols.end() &&
index >= (*dIter).second) {
4662 index -= (*dIter).second;
4665 if (dIter !=
cache.m_denseVols.end()) {
4666 currVol = (*dIter).first;
4668 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar, dir);
4671 nextPar->position() + 2 *
m_tolerance * dir * nextPar->momentum().normalized();
4672 if (currVol->
inside(tp, 0.)) {
4673 cache.m_currentDense = currVol;
4674 }
else if (!nextVol || !nextVol->
inside(tp, 0.)) {
4675 cache.m_currentDense =
cache.m_highestVolume;
4676 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
4677 cache.m_currentDense =
cache.m_currentStatic;
4679 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
4682 cache.m_currentDense = dVol;
4684 <<
cache.m_currentDense->volumeName() <<
"'.");
4690 cache.m_currentDense = nextVol;
4695 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
4696 cache.m_denseBoundaries.size() +
4697 cache.m_navigBoundaries.size()) {
4699 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
4700 cache.m_layers.size() -
cache.m_denseBoundaries.size();
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 '"
4730 ctx,
cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4734 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
4735 cache.m_denseBoundaries.size() +
4736 cache.m_navigBoundaries.size() +
4737 cache.m_detachedBoundaries.size()) {
4739 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
4740 cache.m_layers.size() -
cache.m_denseBoundaries.size() -
4741 cache.m_navigBoundaries.size();
4742 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
4743 cache.m_detachedVols.begin();
4744 while (dIter !=
cache.m_detachedVols.end() &&
index >= (*dIter).second) {
4745 index -= (*dIter).second;
4748 if (dIter !=
cache.m_detachedVols.end()) {
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 '"
4771 ctx,
cache, nextPar, pathLim, dir, particle, destVol, matupmod);