65 return (p_ptr ? p_ptr->
clone() :
nullptr);
72 return (p_ptr ? p_ptr->
clone() :
nullptr);
87 double prePositionR =
pars.position().perp();
89 return (prePositionR > (
pars.position() +
dir * 0.5 * prePositionR *
90 pars.momentum().normalized())
98 std::stringstream outStream;
103 return outStream.str();
108 std::stringstream outStream;
110 outStream <<
"[eta,phi] = [ " <<
mom.eta() <<
", " <<
mom.phi() <<
" ]";
111 return outStream.str();
124 , m_includeMaterialEffects(true)
125 , m_requireMaterialDestinationHit(false)
126 , m_stopWithNavigationBreak(false)
127 , m_stopWithUpdateZero(false)
128 , m_subSurfaceLevel(true)
129 , m_skipInitialLayerUpdate(false)
130 , m_extendedLayerSearch(true)
131 , m_robustSampling(true)
132 , m_referenceMaterial(false)
133 , m_resolveMultilayers(true)
134 , m_cacheLastMatLayer(false)
135 , m_returnPassiveLayers(false)
137 , m_numOfValidPropagators(INVALIDPROPAGATORS)
138 , m_initialLayerAttempts(3)
139 , m_successiveLayerAttempts(1)
140 , m_maxMethodSequence(2000)
142 , m_activeOverlap(false)
143 , m_useMuonMatApprox(false)
144 , m_useDenseVolumeDescription(true)
145 , m_checkForCompundLayers(false)
146 , m_maxNavigSurf{ 1000 }
147 , m_maxNavigVol{ 50 }
150 , m_referenceSurface{
nullptr }
151 , m_printRzOutput(
true)
152 , m_navigationStatistics(
false)
153 , m_navigationBreakDetails(
false)
154 , m_materialEffectsOnTrackValidation(
false)
155 , m_extrapolateCalls{}
156 , m_extrapolateBlindlyCalls{}
157 , m_extrapolateDirectlyCalls{}
158 , m_extrapolateStepwiseCalls{}
159 , m_startThroughAssociation{}
160 , m_startThroughRecall{}
161 , m_startThroughGlobalSearch{}
162 , m_destinationThroughAssociation{}
163 , m_destinationThroughRecall{}
164 , m_destinationThroughGlobalSearch{}
166 , m_navigationBreakLoop{}
167 , m_navigationBreakOscillation{}
168 , m_navigationBreakNoVolume{}
169 , m_navigationBreakDistIncrease{}
170 , m_navigationBreakVolumeSignature{}
171 , m_overlapSurfaceHit{}
172 , m_meotSearchCallsFw{}
173 , m_meotSearchCallsBw{}
174 , m_meotSearchSuccessfulFw{}
175 , m_meotSearchSuccessfulBw{}
177 declareInterface<IExtrapolator>(
this);
180 declareProperty(
"StopWithNavigationBreak", m_stopWithNavigationBreak);
181 declareProperty(
"StopWithUpdateKill", m_stopWithUpdateZero);
182 declareProperty(
"SkipInitialPostUpdate", m_skipInitialLayerUpdate);
183 declareProperty(
"MaximalMethodSequence", m_maxMethodSequence);
185 declareProperty(
"SubPropagators", m_propNames);
187 declareProperty(
"ApplyMaterialEffects", m_includeMaterialEffects);
188 declareProperty(
"RequireMaterialDestinationHit", m_requireMaterialDestinationHit);
189 declareProperty(
"SubMEUpdators", m_updatNames);
190 declareProperty(
"CacheLastMaterialLayer", m_cacheLastMatLayer);
192 declareProperty(
"UseMuonMatApproximation", m_useMuonMatApprox);
193 declareProperty(
"UseDenseVolumeDescription", m_useDenseVolumeDescription);
194 declareProperty(
"CheckForCompoundLayers", m_checkForCompundLayers);
195 declareProperty(
"ResolveMuonStation", m_resolveActive =
false);
196 declareProperty(
"ResolveMultilayers", m_resolveMultilayers);
197 declareProperty(
"ConsiderMuonStationOverlaps", m_activeOverlap);
198 declareProperty(
"RobustSampling", m_robustSampling);
200 declareProperty(
"MaterialEffectsOnTrackProviderIndex", m_meotpIndex);
201 declareProperty(
"MaterialEffectsOnTrackValidation", m_materialEffectsOnTrackValidation);
202 declareProperty(
"ReferenceMaterial", m_referenceMaterial);
203 declareProperty(
"ExtendedLayerSearch", m_extendedLayerSearch);
204 declareProperty(
"InitialLayerAttempts", m_initialLayerAttempts);
205 declareProperty(
"SuccessiveLayerAttempts", m_successiveLayerAttempts);
207 declareProperty(
"positionOutput", m_printRzOutput);
208 declareProperty(
"NavigationStatisticsOutput", m_navigationStatistics);
209 declareProperty(
"DetailedNavigationOutput", m_navigationBreakDetails);
210 declareProperty(
"Tolerance", m_tolerance);
212 declareProperty(
"DumpCache", m_dumpCache);
213 declareProperty(
"MagneticFieldProperties", m_fastField);
225 m_referenceSurface = std::make_unique<Trk::PlaneSurface>(
Amg::Transform3D(Trk::s_idTransform), 0., 0.);
232 const auto numberOfSubPropagatorsGiven = m_propNames.size();
233 const auto numberOfSubMatEffUpdatersGiven = m_updatNames.size();
235 if (m_propagators.empty()) {
236 m_propagators.push_back(
"Trk::RungeKuttaPropagator/DefaultPropagator");
238 if (m_updaters.empty()) {
239 m_updaters.push_back(
"Trk::MaterialEffectsUpdator/DefaultMaterialEffectsUpdator");
243 if (!m_propagators.empty()) {
248 unsigned int validprop = m_propagators.size();
251 ATH_MSG_WARNING(
"None of the defined propagators could be retrieved!");
254 m_numOfValidPropagators = validprop ;
255 ATH_MSG_VERBOSE(
"Number of Valid Propagators " << m_numOfValidPropagators);
262 if (m_includeMaterialEffects && not m_updaters.empty()) {
264 for (
auto&
tool : m_updaters) {
273 unsigned int validmeuts = m_updaters.size();
274 std::vector<std::string> fullPropagatorNames(m_propagators.size());
275 std::vector<std::string> fullUpdatorNames(m_updaters.size());
276 auto extractNameFromTool = [](
const auto& toolHndl) {
return toolHndl->name(); };
278 m_propagators.begin(), m_propagators.end(), fullPropagatorNames.begin(), extractNameFromTool);
280 m_updaters.begin(), m_updaters.end(), fullUpdatorNames.begin(), extractNameFromTool);
284 if (m_propNames.empty() && not m_propagators.empty()) {
286 "Inconsistent setup of Extrapolator, no sub-propagators configured, doing it for you. ");
290 ATH_MSG_ERROR(
"Some configured propagators have same name but different owners");
297 if (m_updatNames.empty() && not m_updaters.empty()) {
298 ATH_MSG_DEBUG(
"Inconsistent setup of Extrapolator, no sub-material updaters configured, doing "
303 ATH_MSG_ERROR(
"Some configured material updaters have same name but different owners");
316 if (validprop && validmeuts) {
319 unsigned int index = 0;
320 for (
unsigned int iProp = 0; iProp < m_propagators.size(); iProp++) {
322 if (m_propNames[isign] == pname) {
327 " subPropagator:" << isign <<
" pointing to propagator: " << m_propagators[
index]->
name());
328 m_subPropagators[isign] =
332 for (
unsigned int iUp = 0; iUp < m_updaters.size(); iUp++) {
334 if (m_updatNames[isign] == uname) {
339 <<
" pointing to updator: " << m_updaters[
index]->
name());
340 m_subupdaters[isign] =
345 "Configuration Problem of Extrapolator: "
346 <<
" -- At least one IPropagator and IMaterialUpdator instance have to be given.! ");
348 const std::string propStr =
std::to_string(numberOfSubPropagatorsGiven) +
" propagator" +
349 std::string((numberOfSubPropagatorsGiven == 1) ?
"" :
"s");
350 const std::string updStr =
std::to_string(numberOfSubMatEffUpdatersGiven) +
" updater" +
351 std::string((numberOfSubMatEffUpdatersGiven == 1) ?
"" :
"s");
352 std::string msgString{
"\nThe extrapolator uses six sub-propagators and "
353 "sub-material effects updaters:\n" };
354 msgString += propStr +
" and " + updStr +
" were given in the configuration,\n";
355 msgString +=
"the extrapolator sub-tools have been defined as follows: \n";
357 msgString +=
std::to_string(
i) +
") propagator: " + m_subPropagators[
i]->name() +
358 ", updater: " + m_subupdaters[
i]->name() +
"\n";
363 return StatusCode::SUCCESS;
370 if (m_navigationStatistics) {
372 ATH_MSG_INFO(
" [P] Method Statistics ------- ------------------------------------");
373 ATH_MSG_INFO(
" -> Number of extrapolate() calls : " << m_extrapolateCalls);
375 " -> Number of extrapolateBlindly() calls : " << m_extrapolateBlindlyCalls);
377 " -> Number of extrapolateDirectly() calls : " << m_extrapolateDirectlyCalls);
379 " -> Number of extrapolateStepwise() calls : " << m_extrapolateStepwiseCalls);
380 ATH_MSG_INFO(
" -> Number of layers switched in layer2layer : " << m_layerSwitched);
381 ATH_MSG_INFO(
"[P] Navigation Initialization -------------------------------------");
383 " -> Number of start associations : " << m_startThroughAssociation);
384 ATH_MSG_INFO(
" -> Number of start recalls : " << m_startThroughRecall);
386 " -> Number of start global searches : " << m_startThroughGlobalSearch);
388 " -> Number of destination associations : " << m_destinationThroughAssociation);
390 " -> Number of destination recalls : " << m_destinationThroughRecall);
391 ATH_MSG_INFO(
" -> Number of destination global searches : "
392 << m_destinationThroughGlobalSearch);
393 ATH_MSG_INFO(
"[P] Navigation Breaks ---------------------------------------------");
395 " -> Number of navigation breaks: loop : " << m_navigationBreakLoop);
397 " -> Number of navigation breaks: oscillation : " << m_navigationBreakOscillation);
399 " -> Number of navigation breaks: no volume found : " << m_navigationBreakNoVolume);
401 " -> Number of navigation breaks: dist. increase : " << m_navigationBreakDistIncrease);
402 ATH_MSG_INFO(
" -> Number of navigation breaks: dist. increase : "
403 << m_navigationBreakVolumeSignature);
404 if (m_navigationBreakDetails) {
407 <<
" loops occured in the following volumes: ");
409 <<
" oscillations occured in following volumes: ");
411 <<
" times no next volume found of volumes: ");
413 <<
" distance increases detected at volumes: ");
415 <<
" no propagator configured for volumes: ");
418 ATH_MSG_INFO(
"[P] Overlaps found ------------------------------------------------");
419 ATH_MSG_INFO(
" -> Number of overlap Surface hit : " << m_overlapSurfaceHit);
420 ATH_MSG_INFO(
" ------------------------------------------------------------------");
422 if (m_materialEffectsOnTrackValidation) {
423 ATH_MSG_INFO(
"[P] MaterialEffectsOnTrack collection -----------------------------");
425 << m_meotSearchSuccessfulFw <<
"/" << m_meotSearchCallsFw <<
" ("
426 <<
double(m_meotSearchSuccessfulFw.value()) / m_meotSearchCallsFw.value()
429 << m_meotSearchSuccessfulBw <<
"/" << m_meotSearchCallsBw <<
" ("
430 <<
double(m_meotSearchSuccessfulBw.value()) / m_meotSearchCallsBw.value()
432 ATH_MSG_INFO(
" ------------------------------------------------------------------");
436 return StatusCode::SUCCESS;
439 std::unique_ptr<Trk::NeutralParameters>
446 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
447 if (currentPropagator) {
451 " [!] No default Propagator is configured ! Please check jobOptions.");
466 ++m_extrapolateStepwiseCalls;
468 ATH_MSG_DEBUG(
"F-[" << cache.m_methodSequence <<
"] extrapolateStepwise(...) ");
473 cache.m_parametersOnDetElements = &
tmp;
475 cache.populateMatEffUpdatorCache(m_subupdaters);
477 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
480 ctx, cache, prop, cache.manage(std::move(cloneInput)).index(),
sf,
dir, bcheck,
particle));
488 cache.m_parametersOnDetElements =
nullptr;
492 std::pair<std::unique_ptr<Trk::TrackParameters>,
const Trk::Layer*>
494 const EventContext& ctx,
499 std::vector<const Trk::TrackStateOnSurface*>& material,
505 ATH_MSG_DEBUG(
"M-[" << cache.m_methodSequence <<
"] extrapolateToNextActiveLayerM(...) ");
507 cache.populateMatEffUpdatorCache(m_subupdaters);
509 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
516 cache.m_matstates = &material;
519 assocLayer =
nullptr;
521 ctx, cache, prop, currPar.
index(), destSurface, staticVol,
dir, bcheck,
particle, matupmode));
523 if (cache.m_lastMaterialLayer &&
524 cache.m_lastMaterialLayer->surfaceRepresentation().isOnSurface(
525 nextPar->
position(), bcheck, m_tolerance, m_tolerance)) {
526 assocLayer = cache.m_lastMaterialLayer;
530 << positionOutput(nextPar->
position()));
534 if (cache.m_parametersAtBoundary.nextParameters && cache.m_parametersAtBoundary.nextVolume) {
535 if (cache.m_parametersAtBoundary.nextVolume->geometrySignature() ==
Trk::MS ||
536 (cache.m_parametersAtBoundary.nextVolume->geometrySignature() ==
Trk::Calo &&
537 m_useDenseVolumeDescription)) {
538 staticVol = cache.m_parametersAtBoundary.
nextVolume;
539 nextPar = cache.m_parametersAtBoundary.nextParameters;
540 ATH_MSG_DEBUG(
" [+] Static volume boundary: continue loop over active layers in '"
543 nextPar = std::move(cache.m_parametersAtBoundary.nextParameters);
544 cache.m_parametersAtBoundary.resetBoundaryInformation();
547 }
else if (cache.m_parametersAtBoundary.nextParameters) {
548 nextPar = std::move(cache.m_parametersAtBoundary.nextParameters);
549 cache.m_parametersAtBoundary.resetBoundaryInformation();
553 currPar = std::move(nextPar);
554 if (currPar && assocLayer && assocLayer->
layerType() != 0) {
559 cache.m_parametersAtBoundary.resetBoundaryInformation();
560 cache.m_matstates =
nullptr;
561 return {currPar.
to_unique(), assocLayer};
593 std::vector<unsigned int> solutions;
597 bool resolveActive = destSurf ==
nullptr;
598 if (!resolveActive && m_resolveActive) {
599 resolveActive = m_resolveActive;
611 if (vol && vol->
inside(gp, m_tolerance)) {
616 if (m_navigator->atVolumeBoundary(currPar.
get(), staticVol,
dir, nextStatVol, m_tolerance) &&
617 nextStatVol != staticVol) {
618 staticVol = nextStatVol;
636 return extrapolateInAlignableTV(
642 if (staticVol && (staticVol != cache.
m_currentStatic || resolveActive != m_resolveActive)) {
656 if (!detVols.empty()) {
658 for (; iTer != detVols.end(); ++iTer) {
660 const Trk::Layer* layR = (*iTer)->layerRepresentation();
662 const auto detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
666 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
667 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
671 if (!m_resolveMultilayers || (*iTer)->multilayerRepresentation().empty()) {
675 const auto&
multi = (*iTer)->multilayerRepresentation();
676 for (
const auto *
i :
multi) {
682 !m_useMuonMatApprox ||
683 (*iTer)->name().compare((*iTer)->name().size() - 4, 4,
"PERM") ==
690 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
691 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
692 ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
693 cache.
m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
695 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
696 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
701 (*iTer)->trackingVolume()->confinedArbitraryLayers();
702 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
703 (confLays.size() > detBounds.size())) {
705 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
707 (detBounds[ibb])->surfaceRepresentation();
710 }
else if (!confLays.empty()) {
711 for (
const Trk::Layer*
const lIt : confLays) {
746 << positionOutput(nextPar->
position()));
759 double dInX0 = std::abs(
path) / propagVol->
x0();
763 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
764 EnergyLoss eloss = m_elossupdater->energyLoss(
765 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
779 double dInX0 = std::abs(
path) / propagVol->
x0();
781 double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
782 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
786 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
787 EnergyLoss eloss = m_elossupdater->energyLoss(
788 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
808 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
809 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
812 nullptr, std::move(cvlTP), std::move(mefot)));
814 <<
"', t/X0 = " << dInX0);
817 currPar = std::move(nextPar);
818 unsigned int isurf = destSurf ? 1 : 0;
819 if (destSurf && solutions[0] == 0) {
822 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
871 std::vector<const Trk::DetachedTrackingVolume*> detVols =
874 for (; dIter != detVols.end(); ++dIter) {
875 const Trk::Layer* layR = (*dIter)->layerRepresentation();
877 if (
active && !resolveActive) {
881 (*dIter)->name().compare((*dIter)->name().size() - 4, 4,
"PERM") != 0) {
887 m_navigator->atVolumeBoundary(currPar.
get(), dVol,
dir, nextVol, m_tolerance) && !nextVol;
895 if (!
active && confinedDense.empty() && confinedLays.empty()) {
899 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
902 if (!confinedDense.empty() || !confinedLays.empty()) {
904 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
909 if (!confinedDense.empty()) {
910 auto vIter = confinedDense.begin();
911 for (; vIter != confinedDense.end(); ++vIter) {
912 const auto bounds = (*vIter)->boundarySurfaces();
913 cache.
m_denseVols.emplace_back(*vIter, bounds.size());
914 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
921 if (!confinedLays.empty()) {
922 for (
const auto *confinedLay : confinedLays) {
930 for (
const auto *subvol : subvols) {
931 if (subvol->inside(gp, m_tolerance)) {
942 m_navigator->atVolumeBoundary(currPar.
get(), detVol,
dir, nextVol, m_tolerance) &&
944 if (vExit && nextVol && nextVol->inside(gp, m_tolerance)) {
951 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
956 cache.
m_denseVols.emplace_back(detVol, bounds.size());
957 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
972 if (nextLayer && nextLayer != lay) {
994 if (!m_navigator->atVolumeBoundary(currPar.
get(), dVol,
dir, nextVol, m_tolerance) ||
1010 std::vector<unsigned int> solutions;
1029 << positionOutput(currPar->
position())
1030 <<
" (current momentum: " << currPar->
momentum().mag() <<
")");
1047 << positionOutput(nextPar->
position()));
1051 m_navigator->atVolumeBoundary(
1053 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
1056 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
1063 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
1073 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1075 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
1092 double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1093 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1097 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1098 EnergyLoss eloss = m_elossupdater->energyLoss(
1099 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
1122 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1123 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->
associatedSurface());
1126 nullptr, std::move(cvlTP), std::move(mefot)));
1128 ATH_MSG_DEBUG(
" [M] Collecting material from dense volume '"
1132 if (destSurf && solutions[0] == 0) {
1135 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1144 dist = distSol.
first();
1154 if (dist *
dir < 0.) {
1159 ATH_MSG_DEBUG(
" [+] New 3D-distance to destinatiion - d3 = " << dist *
dir);
1162 int iDest = destSurf ? 1 : 0;
1163 unsigned int iSol = 0;
1164 while (iSol < solutions.size()) {
1169 if (
mb->layerMaterialProperties() &&
1170 mb->layerMaterialProperties()->fullMaterial(nextPar->
position())) {
1177 if (currentUpdator) {
1179 currentUpdator->
update(currentUpdatorCache,
1193 double lx0 = lmat->
x0();
1194 double layThick =
mb->thickness();
1198 std::abs(nextPar->
momentum().normalized().dot(
mb->surfaceRepresentation().normal()));
1200 if (
mb->surfaceRepresentation().isOnSurface(
1201 mb->surfaceRepresentation().center(),
false, 0., 0.)) {
1202 thick = fmin(
mb->surfaceRepresentation().bounds().r(),
1203 layThick / std::abs(nextPar->
momentum().normalized().dot(
1204 mb->surfaceRepresentation().normal())));
1206 thick = fmin(2 *
mb->thickness(), layThick / (1 - costr));
1211 double dInX0 = thick / lx0;
1216 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1217 EnergyLoss eloss = m_elossupdater->energyLoss(
1218 *lmat, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1231 double dInX0 = thick / lx0;
1232 double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1233 *lmat, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1237 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1238 EnergyLoss eloss = m_elossupdater->energyLoss(
1239 *lmat, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1260 std::make_unique<Trk::MaterialEffectsOnTrack>(
1262 std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
1265 nullptr, std::move(cvlTP), std::move(mefot)));
1271 unsigned int index = solutions[iSol] - iDest;
1279 ATH_MSG_DEBUG(
" [!] WARNING: wrongly assigned static volume ?"
1292 if (m_navigator->atVolumeBoundary(
1300 << positionOutput(nextPar->
position()));
1303 if (nextVol && nextPar) {
1306 << positionOutput(nextPar->
position()));
1310 }
else if (solutions[iSol] <
1321 " [!] This layer is identical to the one with last material update, return layer "
1322 "without repeating the update");
1324 if (!destSurf && (nextLayer->
layerType() > 0 || m_returnPassiveLayers)) {
1328 double layThick = nextLayer->
thickness();
1329 if (
collect && layThick > 0.) {
1337 if (currentUpdator) {
1339 currentUpdator->
update(currentUpdatorCache,
1355 double costr = std::abs(
1361 layThick / std::abs(nextPar->
momentum().normalized().dot(
1364 thick = fmin(2 * nextLayer->
thickness(), layThick / (1 - costr));
1369 double dInX0 = thick / lx0;
1376 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1377 EnergyLoss eloss = m_elossupdater->energyLoss(
1378 materialProperties, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1390 double dInX0 = thick / lx0;
1393 double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1394 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
1395 const double par_theta = std::abs(nextPar->parameters()[
Trk::theta]) > FLT_EPSILON
1400 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
1401 EnergyLoss eloss = m_elossupdater->energyLoss(
1402 materialProperties, std::abs(1. / currentqoverp), 1. / costr,
dir,
particle);
1405 auto cvlTP = std::make_unique<Trk::CurvilinearParameters>(
1422 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1423 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->associatedSurface());
1425 nullptr, std::move(cvlTP), std::move(mefot)));
1428 if (m_cacheLastMatLayer) {
1431 if (!destSurf && (nextLayer->
layerType() > 0 || m_returnPassiveLayers)) {
1435 if (resolveActive) {
1452 unsigned int index =
1454 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
1457 index -= (*dIter).second;
1461 currVol = (*dIter).first;
1463 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
1467 if (currVol->
inside(
tp, m_tolerance)) {
1469 }
else if (!nextVol || !nextVol->
inside(
tp, m_tolerance)) {
1496 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator nIter =
1499 index -= (*nIter).second;
1503 currVol = (*nIter).first;
1505 ((*nIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
1509 if (nextVol && nextVol->
inside(
tp, 0.)) {
1510 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
1512 }
else if (currVol->
inside(
tp, 0.)) {
1514 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
1518 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, leaving volume '"
1524 return extrapolateToNextMaterialLayer(ctx,
1544 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
1547 index -= (*dIter).second;
1551 currVol = (*dIter).first->trackingVolume();
1554 ((*dIter).first->trackingVolume()->boundarySurfaces())[
index]->attachedVolume(
1558 if (nextVol && nextVol->
inside(
tp, 0.)) {
1559 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
1561 }
else if (currVol->
inside(
tp, 0.)) {
1563 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
1567 ATH_MSG_DEBUG(
" [+] Detached volume boundary, leaving volume '"
1573 return extrapolateToNextMaterialLayer(ctx,
1593 currPar = std::move(nextPar);
1625 std::vector<unsigned int> solutions;
1637 if (vol && vol->
inside(gp, m_tolerance)) {
1642 if (m_navigator->atVolumeBoundary(currPar.
get(), currVol,
dir, nextStatVol, m_tolerance) &&
1643 nextStatVol != currVol) {
1644 currVol = nextStatVol;
1646 if (currVol && currVol != vol) {
1656 ATH_MSG_DEBUG(
" [!] failing in retrieval of AlignableTV, return 0");
1668 if (binIDMat->second > 0) {
1672 std::pair<std::unique_ptr<Trk::TrackParameters>,
int>(identified_parm.
release(), binIDMat->second));
1703 std::vector<unsigned int> solutions;
1706 << positionOutput(currPar->
position())
1707 <<
" (current momentum: " << currPar->
momentum().mag() <<
")");
1741 << positionOutput(nextPar->
position()));
1742 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
1744 if (destSurf && solutions[0] == 0) {
1747 if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1756 dist = distSol.
first();
1766 if (dist *
dir < 0.) {
1771 ATH_MSG_DEBUG(
" [+] New 3D-distance to destinatiion - d3 = " << dist *
dir);
1774 int iDest = destSurf ? 1 : 0;
1775 unsigned int iSol = 0;
1776 while (iSol < solutions.size()) {
1780 unsigned int index = solutions[iSol] - iDest;
1788 ATH_MSG_DEBUG(
" [!] WARNING: wrongly assigned static volume ?"
1813 std::pair<std::unique_ptr<Trk::TrackParameters>,
int>(identified_parm.
release(),
1814 -binIDMat->second));
1824 if (m_navigator->atVolumeBoundary(
1832 << positionOutput(nextPar->
position()));
1835 if (nextVol && nextPar) {
1838 << positionOutput(nextPar->
position()));
1855 currPar = std::move(nextPar);
1861 std::unique_ptr<Trk::TrackParameters>
1871 ++m_extrapolateDirectlyCalls;
1875 std::unique_ptr<Trk::TrackParameters>
1886 <<
"] extrapolateToVolume(...) to volume '" << vol.
volumeName() <<
"'.");
1887 std::unique_ptr<TrackParameters> returnParms =
nullptr;
1893 std::vector<std::pair<const Trk::Surface*, double>> surfaces;
1894 surfaces.reserve(bounds.size());
1895 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
1896 const Trk::Surface* nextSurface = &((bounds[
ib])->surfaceRepresentation());
1901 dist = distSol.
first();
1905 if (!surfaces.empty() && distSol.
numberOfSolutions() >= 0 && dist < surfaces.back().second) {
1906 std::vector<std::pair<const Trk::Surface*, double>>
::iterator sIter = surfaces.begin();
1907 while (sIter != surfaces.end()) {
1908 if (dist < (*sIter).second) {
1913 sIter = surfaces.insert(sIter, (std::pair<const Trk::Surface*, double>(nextSurface, dist)));
1915 surfaces.emplace_back(nextSurface, dist);
1921 for (std::pair<const Trk::Surface*, double>& a_surface : surfaces) {
1922 if (a_surface.second > 0) {
1925 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
1927 cache.populateMatEffUpdatorCache(m_subupdaters);
1928 returnParms = extrapolateImpl(ctx,
1931 cache.manage(std::move(cloneInput)).index(),
1937 if (returnParms.get() == &parm) {
1938 throw std::logic_error(
"Did not create new track parameters.");
1947 for (std::vector<std::pair<const Trk::Surface*, double>>::reverse_iterator rsIter =
1949 rsIter != surfaces.rend();
1951 if ((*rsIter).second < 0) {
1954 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
1956 cache.populateMatEffUpdatorCache(m_subupdaters);
1957 returnParms = extrapolateImpl(ctx,
1960 cache.manage(std::move(cloneInput)).index(),
1965 if (returnParms.get() == &parm) {
1966 throw std::logic_error(
"Did not create new track parameters.");
1982 std::unique_ptr<Trk::TrackParameters>
1995 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
1996 cache.populateMatEffUpdatorCache(m_subupdaters);
1997 return extrapolateImpl(ctx,
1999 cache.manage(std::move(cloneInput)).index(),
2005 extrapolationCache).to_unique();
2018 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
2019 if (currentPropagator) {
2020 return extrapolateStepwiseImpl(ctx, (*currentPropagator), parm,
sf,
dir,
2024 " [!] No default Propagator is configured ! Please check jobOptions.");
2028 std::unique_ptr<Trk::TrackParameters>
2030 const EventContext& ctx,
2040 m_navigator->closestParameters(trk,
sf);
2041 if (closestTrackParameters) {
2043 ctx, *closestTrackParameters,
sf,
dir, bcheck,
particle, matupmode, extrapolationCache));
2046 if (closestTrackParameters) {
2048 ctx, *closestTrackParameters,
sf,
dir, bcheck,
particle, matupmode, extrapolationCache));
2063 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
2065 if (currentPropagator) {
2068 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
2070 cache.populateMatEffUpdatorCache(m_subupdaters);
2071 return extrapolateBlindlyImpl(ctx, cache, (*currentPropagator),
2072 cache.manage(std::move(cloneInput)).index(),
2076 " [!] No default Propagator is configured ! Please check jobOptions.");
2080 std::unique_ptr<Trk::TrackParameters>
2090 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
2092 if (!currentPropagator) {
2094 " [!] No default Propagator is configured ! Please check jobOptions.");
2097 return extrapolateDirectlyImpl(
2098 ctx, (*currentPropagator), parm,
sf,
dir, bcheck,
particle);
2101 std::pair<std::unique_ptr<Trk::TrackParameters>,
const Trk::Layer*>
2103 const EventContext& ctx,
2107 std::vector<const Trk::TrackStateOnSurface*>& material,
2115 !m_subPropagators.empty() ? m_subPropagators[
Trk::MS] :
nullptr;
2116 if (currentPropagator) {
2117 return extrapolateToNextActiveLayerMImpl(ctx, (*currentPropagator), parm,
2122 " [!] No default Propagator is configured ! Please check jobOptions.");
2123 return {
nullptr,
nullptr};
2126 std::unique_ptr<Trk::TrackParameters>
2138 if (currentPropagator) {
2139 return (extrapolateToVolumeImpl(ctx, *currentPropagator, parm, vol,
dir,
2143 " [!] No default Propagator is configured ! Please check jobOptions.");
2147 std::vector<const Trk::TrackStateOnSurface*>*
2160 ATH_MSG_DEBUG(
"C-[" << cache.m_methodSequence <<
"] extrapolateM()");
2162 cache.m_matstates =
new std::vector<const Trk::TrackStateOnSurface*>;
2163 if (m_dumpCache && extrapolationCache) {
2164 ATH_MSG_DEBUG(
" extrapolateM pointer extrapolationCache " << extrapolationCache <<
" x0tot "
2165 << extrapolationCache->
x0tot());
2170 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
2173 cache.manage(std::move(cloneInput)).index(),
2179 extrapolationCache));
2181 if (!parameterAtDestination && m_requireMaterialDestinationHit) {
2182 ATH_MSG_VERBOSE(
" [!] Destination surface for extrapolateM has not been hit (required through "
2183 "configuration). Return 0");
2187 for (; tsosIter != tsosIterEnd; ++tsosIter) {
2190 delete cache.m_matstates;
2191 cache.m_matstates =
nullptr;
2195 if (parameterAtDestination) {
2196 ATH_MSG_VERBOSE(
" [+] Adding the destination surface to the TSOS vector in extrapolateM() ");
2197 cache.m_matstates->push_back(
2200 ATH_MSG_VERBOSE(
" [-] Destination surface was not hit extrapolateM(), but not required "
2201 "through configuration.");
2204 std::vector<const Trk::TrackStateOnSurface*>* tmpMatStates = cache.m_matstates;
2205 cache.m_matstates =
nullptr;
2207 return tmpMatStates;
2242 extrapolateDirectlyImpl(ctx, prop, *parm,
sf,
dir, bcheck,
particle));
2246 for (
unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2247 if(m_subupdaters[imueot]){
2253 ++m_extrapolateCalls;
2272 nextParameters.
index(),
2288 " [!] Navigation direction could not be resolved, switching to extrapolateDirectly()");
2293 extrapolateDirectlyImpl(ctx, prop, *parm,
sf, navDir, bcheck,
particle));
2296 startVolume = nextVolume;
2298 bool fallback =
false;
2300 double currentDistance = 0.;
2301 double previousDistance = 0.;
2303 if (refParameters) {
2305 << positionOutput(refParameters->
position()));
2318 ATH_MSG_VERBOSE(
" [+] Initial 3D-distance to destination - d3 = " << currentDistance);
2325 << ((nextVolume) ? nextVolume->
volumeName() :
"Unknown (ERROR)")
2328 :
"Unknown (blind extrapolation)"));
2330 << positionOutput(parm->
position()));
2332 ATH_MSG_VERBOSE(
" [+] Starting layer determined - with " << layerRZoutput(*nextLayer));
2349 bool updateLastValid =
true;
2351 bool punchThroughDone =
false;
2353 auto navigationBreakOscillation = m_navigationBreakOscillation.buffer();
2354 auto navigationBreakNoVolume = m_navigationBreakNoVolume.buffer();
2355 auto navigationBreakDistIncrease = m_navigationBreakDistIncrease.buffer();
2356 auto navigationBreakVolumeSignature = m_navigationBreakVolumeSignature.buffer();
2358 while (nextVolume && nextVolume != destVolume && nextVolume != lastVolume && nextParameters &&
2361 currentPropagator = subPropagator(*nextVolume);
2362 if (!currentPropagator) {
2366 ATH_MSG_DEBUG(
" - Reason : No Propagator found for Volume '"
2369 ++m_navigationBreakVolumeSignature;
2377 if (updateLastValid) {
2382 dir = initializeNavigation(ctx,
2385 nextParameters.
index(),
2395 previousVolume = lastVolume;
2397 lastVolume = nextVolume;
2428 if (nextParameters) {
2429 if (!m_stepPropagator) {
2431 "extrapolation in Calo/MS called without configured STEP propagator, aborting");
2434 resultParameters = extrapolateWithinDetachedVolumes(ctx,
2437 nextParameters.
index(),
2445 if (resultParameters) {
2448 for (
unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2449 if(m_subupdaters[imueot]){
2454 ATH_MSG_DEBUG(
" [+] Destination surface successfully hit.");
2456 return resultParameters;
2459 ATH_MSG_DEBUG(
" [-] Destination surface could not be hit.");
2460 return resultParameters;
2467 extrapolateToVolumeBoundary(ctx,
2470 nextParameters.
index(),
2483 previousDistance = currentDistance;
2489 : nextParameters.
get();
2491 if (distParameters) {
2494 if (refParameters) {
2507 << currentDistance <<
" (from "
2509 ?
"boundary parameters"
2510 :
"last parameters within volume ")
2515 if (nextVolume == lastVolume && nextVolume) {
2517 if (nextParameters && lastParameters &&
2519 .dot(lastParameters->
momentum().normalized()) *
2525 if (nextParameters && lastParameters) {
2527 "last step:" << (nextParameters->
position() - lastParameters->
position()).mag());
2529 ATH_MSG_DEBUG(
"- Reason : Loop detected in TrackingVolume '"
2532 ++m_navigationBreakLoop;
2540 else if (nextVolume == previousVolume && nextVolume) {
2542 if (punchThroughDone) {
2545 ATH_MSG_DEBUG(
"- Reason : Oscillation detected in TrackingVolume '"
2548 ++navigationBreakOscillation;
2555 punchThroughDone =
true;
2556 ATH_MSG_DEBUG(
" [!] One time punch-through a volume done.");
2562 !m_stopWithUpdateZero) {
2568 ++navigationBreakNoVolume;
2578 currentDistance > s_distIncreaseTolerance + previousDistance) {
2582 << previousDistance <<
" to " << currentDistance <<
"] in TrackingVolume '"
2585 ++navigationBreakDistIncrease;
2593 else if ((!nextParameters && m_stopWithUpdateZero) || !nextVolume) {
2594 ATH_MSG_DEBUG(
" [+] Navigation stop : either the update killed the "
2595 "track, or end of detector/boundary volume reached");
2603 " [+] Navigation stop : next navigation step would lead outside given boundary volume");
2608 else if (nextVolume) {
2613 !nextVolume || currentDistance <= previousDistance;
2615 if (!nextParameters) {
2616 nextParameters = std::move(lastParameters);
2619 nextLayer =
nullptr;
2626 ATH_MSG_DEBUG(
" - Consequence : " << (m_stopWithNavigationBreak
2627 ?
"return 0 (configured) "
2628 :
"switch to extrapolateDirectly() "));
2630 if (m_stopWithNavigationBreak || m_stopWithUpdateZero) {
2634 currentPropagator = subPropagator(*lastVolume);
2636 if (!currentPropagator) {
2651 if (!resultParameters) {
2652 resultParameters = cache.
manage(
2663 return resultParameters;
2668 if ((&
sf) == (m_referenceSurface.get())) {
2675 ATH_MSG_DEBUG(
"create finalNextParameters " << *finalNextParameters.
get());
2679 currentPropagator = subPropagator(*nextVolume);
2681 if (currentPropagator) {
2682 resultParameters = extrapolateInsideVolume(ctx,
2685 nextParameters.
index(),
2697 if (!resultParameters && !m_stopWithNavigationBreak && !m_stopWithUpdateZero) {
2698 if (finalNextParameters)
2699 ATH_MSG_DEBUG(
"propagate using parameters " << *finalNextParameters.
get());
2701 ATH_MSG_DEBUG(
"no finalNextParameters, bailing out of extrapolateDirectly");
2704 ATH_MSG_DEBUG(
" [-] Fallback to extrapolateDirectly triggered ! ");
2707 *finalNextParameters,
2718 return resultParameters;
2726 const std::vector<MaterialEffectsOnTrack>& sfMeff,
2737 <<
"] extrapolate with given MaterialEffectsOnTrack in Volume '"
2750 a_sfMeff.associatedSurface(),
2759 return (currPar.
index() != parm)
2764 currPar = std::move(nextPar);
2772 if (currentUpdator) {
2774 currentUpdatorCache, currPar.
get(), a_sfMeff,
particle, matupmode));
2781 currPar = std::move(upNext);
2798 cache.
m_cacheEloss = extrapolationCache ? extrapolationCache->
eloss() :
nullptr;
2800 if (extrapolationCache && m_dumpCache) {
2801 ATH_MSG_DEBUG(
" In extrapolate cache pointer input: " << extrapolationCache
2802 <<
" cache.m_extrapolationCache "
2811 !m_subPropagators.empty() ? m_subPropagators[
Trk::Global] :
nullptr;
2812 if (currentPropagator) {
2813 return extrapolateImpl(ctx, cache, (*currentPropagator), parm,
sf,
dir,
2817 " [!] No default Propagator is configured ! Please check jobOptions.");
2832 ++m_extrapolateBlindlyCalls;
2845 extrapolateImpl(ctx, cache, prop, parm, *m_referenceSurface,
dir, bcheck,
particle));
2862 const Layer* assLayer,
2871 return extrapolateWithinDetachedVolumes(
2872 ctx, cache, prop, parm,
sf, tvol,
dir, bcheck,
particle, matupmode);
2875 return insideVolumeStaticLayers(
2876 ctx, cache,
false, prop, parm, assLayer, tvol,
dir, bcheck,
particle, matupmode);
2894 << tvol.
volumeName() <<
"' to destination surface. ");
2916 dist = distSol.
first();
2921 if (destinationLayer && destinationLayer->
isOnLayer(nextParameters->
position())) {
2922 ATH_MSG_DEBUG(
" [-] Already at destination layer, distance:" << dist);
2950 if (std::abs(dist) < m_tolerance) {
2977 ATH_MSG_DEBUG(
" [!] Initial 3D-distance to the surface negative ("
2978 << dist <<
") -> skip extrapolation.");
2983 ATH_MSG_DEBUG(
" [+] Initial 3D-distance to destination - d3 = " << dist);
2993 while (nextParameters) {
2996 ctx, cache, prop, nextParameters.
index(), &
sf, currVol,
dir, bchk,
particle, matupmode));
3005 if (currentDistance <= m_tolerance &&
3006 sf.isOnSurface(onNextLayer->
position(), bchk, m_tolerance, m_tolerance)) {
3008 if (!bcheck ||
sf.isOnSurface(onNextLayer->
position(), bcheck, m_tolerance, m_tolerance)) {
3011 <<
static_cast<int>(
sf.type())
3013 <<
":distance to the destination surface:" << currentDistance);
3032 nextParameters = std::move(onNextLayer);
3044 dist = distSol.
first();
3054 m_useDenseVolumeDescription))) {
3057 if (last_boundary_parameters &&
3060 " [!] Already tried parameters at boundary -> exit: pos="
3077 nextParameters = std::move(onNextLayer);
3081 ATH_MSG_DEBUG(
" [+] extrapolateWithinDetachedVolumes(...) reached static boundary, return to "
3083 return nextParameters;
3091 const Layer* assLayer,
3101 " [!] toVolumeBoundaryDetachedVolumes(...) with confined detached volumes? This should "
3102 "not happen ! volume name and signature: "
3107 ctx, cache,
true, prop, parm, assLayer, tvol,
dir, bcheck,
particle, matupmode));
3142 double rPos = parm->
position().perp();
3143 double rComponent = parm->
momentum().normalized().perp();
3145 rComponent = rComponent < 10
e-5 ? 10
e-5 : rComponent;
3147 double rScalor = (toBoundary && tvol.
boundarySurfaces().size() == 3) ? 2. * rPos / rComponent
3148 : 0.5 * rPos / rComponent;
3149 rScalor = rScalor * rScalor < 10
e-10 ? 0.1 : rScalor;
3154 <<
"] insideVolumeStaticLayers(...) to volume boundary of '"
3158 <<
"] insideVolumeStaticLayers(...) to destination surface in '"
3163 " [+] Volume does not contain layers, just propagate to destination surface.");
3173 if (!nextParameters) {
3174 nextParameters = cache.
manage(
3183 return nextParameters;
3189 " [+] Perpendicular direction of the track : " << radialDirection(*navParameters,
dir));
3191 const Trk::Layer* associatedLayer = assLayer;
3193 const Trk::Layer* assLayerReference = assLayer;
3200 const Trk::Layer* destinationLayer =
nullptr;
3204 if (!destinationLayer) {
3211 if (destinationLayer) {
3213 << layerRZoutput(*destinationLayer));
3223 if (!m_skipInitialLayerUpdate && associatedLayer && associatedLayer != destinationLayer &&
3226 " [+] In starting volume: check for eventual necessary postUpdate and overlapSearch.");
3230 if ((parsLayer && parsLayer == associatedLayer) ||
3242 nextParameters.
index(),
3252 ATH_MSG_VERBOSE(
" [+] Calling postUpdate on inital track parameters.");
3260 if (currentUpdator) {
3261 nextParameters = cache.
manage(
3262 currentUpdator->
postUpdate(currentUpdatorCache,
3270 if (nextParameters && (cache.
m_matstates || m_materialEffectsOnTrackValidation)) {
3271 addMaterialEffectsOnTrack(
3272 ctx, cache, prop, nextParameters.
index(), *associatedLayer, tvol,
dir,
particle);
3274 if (nextParameters && nextParameters.
get() != parm.
get()) {
3275 }
else if (!m_stopWithUpdateZero) {
3277 nextParameters = parm;
3293 if (!associatedLayer) {
3294 ATH_MSG_VERBOSE(
" [+] Volume switch has happened, searching for entry layers.");
3302 << layerRZoutput(*associatedLayer));
3306 auto [new_track_parm, killed] = extrapolateToIntermediateLayer(
3307 ctx, cache, prop, parm.
index(), *associatedLayer, tvol,
dir, bcheck,
particle, matupmode);
3308 nextParameters = std::move(new_track_parm);
3310 if (m_stopWithUpdateZero && killed) {
3318 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3325 if (nextParameters) {
3327 << positionOutput(nextParameters->
position()));
3331 if (!nextParameters) {
3332 nextParameters = parm;
3340 if (nextParameters.
get() != parm.
get()) {
3341 navParameters = nextParameters;
3344 if (destinationLayer != assLayerReference || toBoundary) {
3350 (associatedLayer && associatedLayer == assLayerReference)
3352 dir * rScalor * navParameters->
momentum().normalized())
3356 if (associatedLayer) {
3357 ATH_MSG_VERBOSE(
" [+] Associated layer at start with " << layerRZoutput(*associatedLayer));
3361 if (destinationLayer || toBoundary) {
3363 if (associatedLayer && associatedLayer != destinationLayer) {
3366 << layerRZoutput(*associatedLayer));
3372 nextParameters.
index(),
3376 navParameters.
index(),
3382 if (m_stopWithUpdateZero && !updateNext) {
3390 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3398 nextParameters = std::move(updateNext);
3404 nextParameters = extrapolateToDestinationLayer(ctx,
3407 nextParameters.
index(),
3420 return nextParameters;
3424 }
else if (!toBoundary) {
3437 return nextParameters;
3441 if (!nextParameters) {
3442 nextParameters = parm;
3446 unsigned int navprop = 0;
3450 if (m_numOfValidPropagators != INVALIDPROPAGATORS) {
3452 while (navprop < m_numOfValidPropagators) {
3453 const IPropagator* navPropagator = &(*m_propagators[navprop]);
3456 bool vetoNavParameters =
false;
3461 if (nextParameters.
get() != parm.
get() || assLayerReference) {
3462 navParameters = nextParameters;
3470 << positionOutput(navParameters->
position()));
3472 << momentumOutput(navParameters->
momentum()));
3476 m_navigator->nextTrackingVolume(ctx, *navPropagator, *navParameters,
dir, tvol);
3479 navParameters = cache.
manage(
3482 bParameters = navParameters;
3492 m_navigator->nextTrackingVolume(ctx, prop, *navParameters,
dir, tvol);
3498 bParameters = navParameters;
3505 if (navParameters) {
3516 if (m_includeMaterialEffects) {
3522 if (currentUpdator) {
3524 currentUpdatorCache,
3532 if (bParameters && (cache.
m_matstates || m_materialEffectsOnTrackValidation)) {
3533 addMaterialEffectsOnTrack(ctx,
3536 bParameters.
index(),
3544 navParameters = std::move(bParameters);
3550 nextVolume, nextParameters, navParameters, exitFace);
3553 return navParameters;
3564 const Layer* startLayer,
3565 const Layer* destinationLayer,
3587 bool perpCheck = radialDirection(*currPar,
dir) * radialDirection(*navParameters,
dir) > 0;
3590 unsigned int failedAttempts = 0;
3594 unsigned int layersInVolume =
3598 :
int(layersInVolume * 0.5);
3601 maxAttempts = (maxAttempts < m_initialLayerAttempts) ? m_initialLayerAttempts : maxAttempts;
3603 ATH_MSG_VERBOSE(
" [+] Maximum number of failed layer attempts: " << maxAttempts);
3612 while (nextLayer && nextLayer != previousLayer && nextLayer != lastLayer &&
3613 nextLayer != destinationLayer && failedAttempts < maxAttempts) {
3617 :
"navigation layer with "))
3618 << layerRZoutput(*nextLayer));
3624 auto [new_track_parm, killed] = extrapolateToIntermediateLayer(ctx,
3637 previousLayer = lastLayer;
3638 lastLayer = nextLayer;
3642 ATH_MSG_VERBOSE(
" [+] Material update killed the track parameters - return 0");
3650 ATH_MSG_VERBOSE(
" [+] Parameter outside the given boundary/world stopping loop.");
3654 ATH_MSG_VERBOSE(
" [+] Intersection successful: allowing for " << maxAttempts
3655 <<
" more failed attempt.");
3659 navParameters = nextPar;
3660 currPar = std::move(nextPar);
3672 ATH_MSG_VERBOSE(
" [+] No next Layer provided by the previous layer -> stop of layer2layer");
3675 if (failedAttempts >= maxAttempts) {
3691 const Layer* startLayer,
3702 bool startIsDestLayer = startLayer == (&lay);
3710 if (!destParameters) {
3722 if (currentUpdator && destParameters && !startIsDestLayer) {
3723 preUpdatedParameters = cache.
manage(
3724 currentUpdator->
preUpdate(currentUpdatorCache,
3725 destParameters.
get(),
3731 preUpdatedParameters = destParameters;
3735 if ((cache.
m_matstates || m_materialEffectsOnTrackValidation) && preUpdatedParameters &&
3736 currentUpdator && !startIsDestLayer &&
3738 addMaterialEffectsOnTrack(
3744 m_subSurfaceLevel) {
3745 ATH_MSG_VERBOSE(
" [o] Calling overlapSearch() on destination layer.");
3751 preUpdatedParameters.
index(),
3760 if (preUpdatedParameters) {
3765 return preUpdatedParameters;
3768 std::pair<Trk::ManagedTrackParmPtr, bool>
3779 bool doPerpCheck)
const
3794 if (m_checkForCompundLayers) {
3798 const std::vector<const Surface*> cs =
cl->constituentSurfaces();
3799 for (
const auto *
c : cs) {
3801 ctx, *parm, *
c,
dir,
true, m_fieldProperties,
particle));
3807 parsOnLayer = cache.
manage(
3812 parsOnLayer = cache.
manage(
3823 int rDirection = radialDirection(*parm,
dir);
3824 int newrDirection = radialDirection(*parsOnLayer,
dir);
3825 if (newrDirection != rDirection && doPerpCheck) {
3827 ATH_MSG_DEBUG(
" [!] Perpendicular direction of track has changed -- checking");
3830 if (!radialDirectionCheck(ctx, prop, *parm, *parsOnLayer, tvol,
dir,
particle)) {
3831 ATH_MSG_DEBUG(
" [+] Perpendicular direction check cancelled this layer intersection.");
3837 << positionOutput(parsOnLayer->
position()));
3839 << momentumOutput(parsOnLayer->
momentum()));
3846 ATH_MSG_VERBOSE(
" [o] Calling overlapSearch() on intermediate layer.");
3853 if (lastElement >= 0 && sizeBeforeSearch < sizeAfterSearch) {
3858 throw std::logic_error(
"Invalid track parameters on det elements (lastElement)");
3864 ? cache.
manage(std::move(cloneInput))
3866 ATH_MSG_DEBUG(
" [+] Detector element & overlapSearch successful,"
3867 <<
" call update on last parameter on this layer.");
3873 parsOnLayer = cache.
manage(
3875 currentUpdatorCache, parsOnLayer.
get(), lay,
dir,
particle, matupmode));
3879 (cache.
m_matstates || m_materialEffectsOnTrackValidation)) {
3880 addMaterialEffectsOnTrack(ctx, cache, prop, parsOnLayer.
index(), lay, tvol,
dir,
particle);
3884 if (!parsOnLayer && m_stopWithUpdateZero) {
3889 return std::make_pair(parsOnLayer,
false);
3903 bool startingLayer)
const
3921 ATH_MSG_VERBOSE(
" [o] OverlapSearch called " << (startSurface ?
"with " :
"w/o ") <<
"start, "
3922 << (endSurface ?
"with " :
"w/o ")
3932 ATH_MSG_VERBOSE(
" [o] Detector surface found through subSurface() call");
3937 ATH_MSG_VERBOSE(
" [o] Detector surface found through parameter on layer association");
3941 bool isStartLayer = (detSurface && detSurface == startSurface);
3945 bool reorderDetParametersOnLayer =
false;
3950 if (isDestinationLayer) {
3951 detParameters = parsOnLayer;
3952 }
else if (isStartLayer) {
3953 detParameters = parm;
3954 }
else if (detSurface) {
3955 detParameters = cache.
manage(
3960 bool surfaceHit =
true;
3964 if (detParameters && !isStartLayer && !isDestinationLayer) {
3965 ATH_MSG_VERBOSE(
" [o] First intersection with Detector surface: " << *detParameters);
3967 surfaceHit = detParameters && detSurface ? detSurface->isOnSurface(detParameters->
position())
3971 (surfaceHit && startSurface)
3975 surfaceHit = (surfaceHit && endSurface)
3988 detParametersOnLayer.emplace_back(detParameters.
release());
3989 }
else if (detParameters) {
3992 " [-] Detector surface hit cancelled through bounds check or start/end surface check.");
3997 if (track_parm_for_overlap) {
3999 std::vector<Trk::SurfaceIntersection> cSurfaces;
4005 ATH_MSG_VERBOSE(
"found " << ncSurfaces <<
" candidate sensitive surfaces to test.");
4009 auto overlapSurfaceHit = m_overlapSurfaceHit.buffer();
4010 for (
auto& csf : cSurfaces) {
4017 if (overlapParameters) {
4018 ATH_MSG_VERBOSE(
" [+] Overlap surface was hit, checking start/end surface condition.");
4021 surfaceHit = (startSurface) ? ((overlapParameters->
position() - parm->
position())
4025 surfaceHit = (surfaceHit && endSurface)
4033 ++overlapSurfaceHit;
4035 reorderDetParametersOnLayer =
true;
4037 detParametersOnLayer.emplace_back(overlapParameters.
release());
4041 " [-] Detector surface hit cancelled through start/end surface check.");
4050 if (reorderDetParametersOnLayer) {
4053 sort(detParametersOnLayer.begin(), detParametersOnLayer.end(), parameterSorter);
4059 std::move(detParametersOnLayer.begin(), detParametersOnLayer.end(),
4074 const Layer*& associatedLayer,
4083 ATH_MSG_DEBUG(
" [I] initializeNaviagtion() -------------------------- ");
4086 ATH_MSG_DEBUG(
" [I] (re)initializeNaviagtion() ---------------------- ");
4093 " [I] Starting with Start Layer/Volume search: ------------------------------");
4100 const char* startSearchType =
"association";
4105 associatedLayer = (associatedSurface) ? associatedSurface->
associatedLayer() : associatedLayer;
4110 if (!associatedVolume && associatedSurface && associatedSurface == cache.
m_recallSurface &&
4113 ++m_startThroughRecall;
4117 startSearchType =
"recall";
4118 }
else if (!associatedVolume) {
4120 ++m_startThroughGlobalSearch;
4129 startSearchType =
"global search";
4136 if (lowestStaticVol && lowestStaticVol != associatedVolume) {
4137 associatedVolume = lowestStaticVol;
4141 ++m_startThroughAssociation;
4147 if (m_navigator->atVolumeBoundary(
4148 parm.
get(), associatedVolume,
dir, nextAssVol, m_tolerance) &&
4149 nextAssVol != associatedVolume) {
4151 associatedVolume = nextAssVol;
4154 << associatedVolume->
volumeName() <<
" no action taken");
4161 " [I] 'AnyDirection' has been chosen: approaching direction must be determined.");
4164 refParameters = cache.
manage(
4166 ctx, *parm,
sf,
dir,
false, m_fieldProperties,
particle,
false, associatedVolume));
4168 if (refParameters) {
4171 if (surfaceDir.dot(parm->
momentum()) > 0.) {
4179 << ((navigationDirection < 0) ?
"oppositeMomentum." :
"alongMomentum"));
4182 " [+] Approaching direction could not be determined, they remain: anyDirection.");
4185 ATH_MSG_VERBOSE(
" [I] Starting Information gathered through : " << startSearchType <<
".");
4191 ATH_MSG_VERBOSE(
" [I] Starting with destination Volume search: -----------------------------");
4193 if ((&
sf) != (m_referenceSurface.get())) {
4195 destVolume = (
sf.associatedLayer()) ?
sf.associatedLayer()->enclosingTrackingVolume() :
nullptr;
4197 std::string destinationSearchType =
"association";
4199 ++m_destinationThroughAssociation;
4205 destinationSearchType =
"recall";
4207 ++m_destinationThroughRecall;
4208 }
else if (!destVolume) {
4210 destinationSearchType =
"global search";
4211 ++m_destinationThroughGlobalSearch;
4214 if (!refParameters && associatedVolume) {
4215 refParameters = cache.
manage(
4217 ctx, *parm,
sf,
dir,
false, m_fieldProperties,
particle,
false, associatedVolume));
4220 if (refParameters) {
4228 destVolume = cache.
volume(ctx,
sf.globalReferencePoint());
4231 ATH_MSG_VERBOSE(
" [I] Destination Information gathered through : " << destinationSearchType
4237 << (associatedVolume ?
"ok." :
"failed."));
4239 << (associatedLayer ?
"ok." :
"failed."));
4240 ATH_MSG_VERBOSE(
" [+] Destinaiton Volume search ...... " << (destVolume ?
"ok." :
"failed."));
4242 if (destVolume == associatedVolume) {
4245 std::string navDirString =
4246 ((navigationDirection < 0) ?
"oppositeMomentum"
4247 : (navigationDirection > 0) ?
"alongMomentum" :
"undefined");
4249 ATH_MSG_VERBOSE(
" [I] initializeNaviagtion() end ---------------------- ");
4253 return navigationDirection;
4270 double distToLayer = (startPosition - onLayerPosition).
mag();
4275 if (boundarySurfaces.size() == 4) {
4281 ctx, startParm, insideSurface,
dir,
true, m_fieldProperties,
particle));
4283 double distToInsideSurface =
4284 parsOnInsideSurface ? (startPosition - (parsOnInsideSurface->
position())).mag() : 10e10;
4286 ATH_MSG_VERBOSE(
" [+] Radial direction check start - at " << positionOutput(startPosition));
4287 ATH_MSG_VERBOSE(
" [+] Radial direction check layer - at " << positionOutput(onLayerPosition));
4288 if (parsOnInsideSurface) {
4290 << positionOutput(parsOnInsideSurface->
position()));
4294 ATH_MSG_VERBOSE(
" [+] Check radial direction: distance layer / boundary = "
4295 << distToLayer <<
" / " << distToInsideSurface);
4297 return distToLayer < distToInsideSurface;
4305 std::stringstream outStream;
4307 if (m_printRzOutput) {
4308 outStream <<
"[r,phi,z] = [ " <<
pos.perp() <<
", " <<
pos.phi() <<
", " <<
pos.z() <<
" ]";
4310 outStream <<
"[xyz] = [ " <<
pos.x() <<
", " <<
pos.y() <<
", " <<
pos.z() <<
" ]";
4312 return outStream.str();
4330 ++m_meotSearchCallsFw;
4332 ++m_meotSearchCallsBw;
4336 double pathCorrection = 0.;
4340 if (m_checkForCompundLayers) {
4344 const std::vector<const Surface*> cs =
cl->constituentSurfaces();
4345 for (
const auto *
c : cs) {
4346 parsOnLayer = cache.
manage(
4354 parsOnLayer = cache.
manage(
4359 parsOnLayer = cache.
manage(
4364 parsOnLayer = parms;
4371 pathCorrection = pathCorrection > 0. ? pathCorrection
4376 if (!materialProperties) {
4380 if (!materialProperties) {
4381 ATH_MSG_DEBUG(
" [!] No MaterialProperties on Layer after intersection.");
4386 ++m_meotSearchSuccessfulFw;
4388 ++m_meotSearchSuccessfulBw;
4393 double tInX0 = pathCorrection * materialProperties->
thicknessInX0();
4398 double currentQoP = parsOnLayer->parameters()[
Trk::qOverP];
4400 *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir,
particle));
4409 ATH_MSG_VERBOSE(
" [V] Validation mode: MaterialProperties found on this layer.");
4412 double tInX0 = pathCorrection * materialProperties->
thicknessInX0();
4414 double currentQoP = parsOnLayer->parameters()[
Trk::qOverP];
4415 auto energyLoss = m_elossupdater->energyLoss(
4416 *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir,
4419 double sigmaMS = std::sqrt(m_msupdater->sigmaSquare(
4420 *materialProperties, std::abs(1. / currentQoP), pathCorrection,
particle));
4426 if (energyLoss.meanIoni() == 0. && tInX0 > 0.) {
4428 "because the ElossUpdator is wrongly configured: "
4429 "switch joboption DetailedEloss on ");
4436 energyLoss.sigmaIoni(),
4437 energyLoss.meanRad(),
4438 energyLoss.sigmaRad());
4443 auto meot = std::make_unique<Trk::MaterialEffectsOnTrack>(
4444 tInX0, scatAngles, std::make_unique<Trk::EnergyLoss>(std::move(energyLoss)),
4456 std::unique_ptr<std::vector<std::pair<std::unique_ptr<Trk::TrackParameters>,
int>>>
4458 const EventContext& ctx,
4462 std::vector<const Trk::TrackStateOnSurface*>*& material,
4463 int destination)
const
4470 ATH_MSG_DEBUG(
"M-[" << cache.m_methodSequence <<
"] extrapolate(through active volumes), from "
4475 cache.m_identifiedParameters = std::make_unique<identifiedParameters_t>();
4477 cache.m_matstates = material;
4479 cache.m_currentStatic =
nullptr;
4482 cache.m_parametersAtBoundary.resetBoundaryInformation();
4484 cache.populateMatEffUpdatorCache(m_subupdaters);
4487 auto cloneInput = std::unique_ptr<Trk::TrackParameters>(parm.
clone());
4489 ctx, cache, cache.manage(std::move(cloneInput)).index(), -1.,
dir,
particle, boundaryVol));
4491 while (subDetBounds) {
4492 ATH_MSG_DEBUG(
" Identified subdetector boundary crossing saved "
4493 << positionOutput(subDetBounds->
position()));
4495 cache.m_identifiedParameters->push_back(std::pair<std::unique_ptr<Trk::TrackParameters>,
int>(
4497 cache.m_currentStatic ? cache.m_currentStatic->geometrySignature() : 0));
4498 if (cache.m_currentStatic && cache.m_currentStatic->geometrySignature() == destination) {
4502 if (!cache.m_parametersAtBoundary.nextVolume) {
4505 subDetBounds = extrapolateToVolumeWithPathLimit(
4508 if (cache.m_identifiedParameters->empty()) {
4511 return std::move(cache.m_identifiedParameters);
4533 std::vector<unsigned int> solutions;
4535 unsigned int iDest = 0;
4541 if (destVol && m_navigator->atVolumeBoundary(currPar.
get(), destVol,
dir, nextVol, m_tolerance) &&
4542 nextVol != destVol) {
4547 bool resolveActive =
true;
4565 if (!tgVol || tgVol != destVol) {
4567 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4568 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4571 iDest = bounds.size();
4576 bool updateStatic =
false;
4580 updateStatic =
true;
4585 bool navigDone =
false;
4594 updateStatic =
true;
4600 m_navigator->atVolumeBoundary(
4606 << positionOutput(currPar->
position()));
4614 updateStatic =
true;
4623 ctx, cache, *m_stepPropagator, currPar.
index(),
nullptr, alignTV,
dir,
particle));
4625 return extrapolateToVolumeWithPathLimit(
4647 if (!detVols.empty()) {
4649 for (; iTer != detVols.end(); ++iTer) {
4651 const Trk::Layer* layR = (*iTer)->layerRepresentation();
4653 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
4656 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4657 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4661 !m_useMuonMatApprox ||
4662 (*iTer)->name().compare((*iTer)->name().size() - 4, 4,
"PERM") ==
4666 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
4667 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
4668 ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
4669 cache.
m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
4670 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4671 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4676 (*iTer)->trackingVolume()->confinedArbitraryLayers();
4677 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
4678 (confLays.size() > detBounds.size())) {
4680 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4681 const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4684 }
else if (!confLays.empty()) {
4685 for (
const Trk::Layer*
const lIt : confLays) {
4726 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>> navigVols;
4729 std::vector<const Trk::DetachedTrackingVolume*> detVols =
4732 for (; dIter != detVols.end(); ++dIter) {
4733 const Trk::Layer* layR = (*dIter)->layerRepresentation();
4735 if (
active && !resolveActive) {
4739 (*dIter)->name().compare((*dIter)->name().size() - 4, 4,
"PERM") != 0) {
4745 m_navigator->atVolumeBoundary(currPar.
get(), dVol,
dir, nextVol, m_tolerance) && !nextVol;
4753 if (!
active && confinedDense.empty() && confinedLays.empty()) {
4757 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
4760 if (!confinedDense.empty() || !confinedLays.empty()) {
4761 navigVols.emplace_back(dVol, bounds.size());
4762 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4763 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4767 if (!confinedDense.empty()) {
4768 auto vIter = confinedDense.begin();
4769 for (; vIter != confinedDense.end(); ++vIter) {
4770 const auto& bounds = (*vIter)->boundarySurfaces();
4771 cache.
m_denseVols.emplace_back(*vIter, bounds.size());
4772 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4773 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4779 if (!confinedLays.empty()) {
4780 for (
const auto *confinedLay : confinedLays) {
4788 for (
const auto *subvol : subvols) {
4789 if (subvol->inside(gp, m_tolerance)) {
4800 m_navigator->atVolumeBoundary(currPar.
get(), detVol,
dir, nextVol, m_tolerance) &&
4802 if (vExit && nextVol && nextVol->inside(gp, m_tolerance)) {
4808 navigVols.emplace_back(detVol, bounds.size());
4809 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4810 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4814 cache.
m_denseVols.emplace_back(detVol, bounds.size());
4815 for (
unsigned int ib = 0;
ib < bounds.size();
ib++) {
4816 const Trk::Surface& surf = (bounds[
ib])->surfaceRepresentation();
4824 for (
const auto *cLay : cLays) {
4825 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4836 if (nextLayer && nextLayer != lay) {
4855 for (
const auto *cLay : cLays) {
4856 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4864 static constexpr
bool boundsCheck{
false};
4868 if (nextLayer && nextLayer != lay) {
4873 if (backLayer && backLayer != lay) {
4889 if (!m_navigator->atVolumeBoundary(currPar.
get(), dVol,
dir, nextVol, m_tolerance) ||
4908 std::vector<unsigned int> solutions;
4910 << positionOutput(currPar->
position())
4911 <<
" (current momentum: " << currPar->
momentum().mag() <<
")");
4916 <<
" with path limit" << pathLim
4919 <<
" in the direction" <<
dir <<
".");
4921 m_navigator->atVolumeBoundary(
4926 m_stepPropagator->propagate(ctx,
4939 << positionOutput(nextPar->
position()));
4943 if (pathLim > 0. && cache.
m_path +
path >= pathLim) {
4949 m_navigator->atVolumeBoundary(
4951 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume"
4954 ATH_MSG_DEBUG(
" [!] ERROR: trying to recover: repeat the propagation step in"
4970 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
4975 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
4977 EnergyLoss eloss = (m_elossupdater->energyLoss(
4978 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle));
4992 double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
4993 materialProperties, 1. / std::abs(nextPar->parameters()[
qOverP]), 1.,
particle));
4997 double currentqoverp = nextPar->parameters()[
Trk::qOverP];
4998 EnergyLoss eloss = m_elossupdater->energyLoss(
4999 materialProperties, std::abs(1. / currentqoverp), 1.,
dir,
particle);
5016 auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
5017 dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
5023 ATH_MSG_DEBUG(
" [M] Collecting material from dense volume '"
5028 unsigned int iSol = 0;
5029 while (iSol < solutions.size()) {
5030 if (solutions[iSol] < iDest) {
5036 if (
mb->layerMaterialProperties() &&
5037 mb->layerMaterialProperties()->fullMaterial(nextPar->
position())) {
5038 double pIn = nextPar->
momentum().mag();
5043 if (currentUpdator) {
5054 <<
"at position:" << nextPar->
position());
5056 addMaterialEffectsOnTrack(ctx,
5070 unsigned int index = solutions[iSol] - iDest;
5080 if (m_navigator->atVolumeBoundary(
5088 << positionOutput(nextPar->
position()));
5097 << nextVol->volumeName()
5098 <<
"', next geoID: " << nextVol->geometrySignature());
5100 << positionOutput(nextPar->
position()));
5107 return extrapolateToVolumeWithPathLimit(
5110 }
else if (solutions[iSol] <
5133 double pIn = nextPar->
momentum().mag();
5134 if (currentUpdator) {
5137 currentUpdatorCache, nextPar.
get(), *nextLayer,
dir,
particle, matupmod));
5145 << nextPar->
momentum().mag() - pIn <<
"at position:"
5155 *m_subPropagators[0],
5173 if (postFactor > 0.1) {
5174 double pIn = nextPar->
momentum().mag();
5175 if (currentUpdator) {
5177 currentUpdator->
postUpdate(currentUpdatorCache,
5197 double pIn = nextPar->
momentum().mag();
5198 if (currentUpdator) {
5200 currentUpdator->
update(currentUpdatorCache,
5213 <<
"at position:" << nextPar->
position());
5217 addMaterialEffectsOnTrack(ctx,
5226 if (m_cacheLastMatLayer) {
5235 if (newLayer && newLayer != nextLayer) {
5254 return extrapolateToVolumeWithPathLimit(
5265 unsigned int index =
5267 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator dIter =
5270 index -= (*dIter).second;
5274 currVol = (*dIter).first;
5276 ((*dIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
5282 }
else if (!nextVol || !nextVol->inside(
tp, 0.)) {
5309 std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>
::iterator nIter =
5311 while (nIter != navigVols.end() &&
index >= (*nIter).second) {
5312 index -= (*nIter).second;
5315 if (nIter != navigVols.end()) {
5316 currVol = (*nIter).first;
5318 ((*nIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar,
dir);
5322 if (nextVol && nextVol->inside(
tp, 0.)) {
5323 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
5324 << nextVol->volumeName() <<
"'.");
5325 }
else if (currVol->
inside(
tp, 0.)) {
5327 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, entering volume '"
5328 << nextVol->volumeName() <<
"'.");
5331 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, leaving volume '"
5337 return extrapolateToVolumeWithPathLimit(
5350 std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>
::iterator dIter =
5353 index -= (*dIter).second;
5357 currVol = (*dIter).first->trackingVolume();
5359 ((*dIter).first->trackingVolume()->boundarySurfaces())[
index]->attachedVolume(
5364 if (nextVol && nextVol->inside(
tp, 0.)) {
5365 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
5366 << nextVol->volumeName() <<
"'.");
5367 }
else if (currVol->
inside(
tp, 0.)) {
5369 ATH_MSG_DEBUG(
" [+] Detached volume boundary, entering volume '"
5370 << nextVol->volumeName() <<
"'.");
5373 ATH_MSG_DEBUG(
" [+] Detached volume boundary, leaving volume '"
5378 return extrapolateToVolumeWithPathLimit(
5386 currPar = std::move(nextPar);