285 std::unique_ptr<const Trk::TrackParameters> returnParameters =
nullptr;
289 std::vector<unsigned int> solutions;
291 unsigned int iDest = 0;
292 const EventContext& ctx = Gaudi::Hive::currentContext();
295 if (destVol &&
m_navigator->atVolumeBoundary(currPar, destVol, dir, nextVol,
m_tolerance) && nextVol != destVol) {
299 if (!
cache.m_highestVolume) {
308 cache.m_navigSurfs.clear();
313 if (!tgVol || tgVol != destVol) {
315 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
316 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
317 cache.m_navigSurfs.emplace_back(&surf,
true);
319 iDest = bounds.size();
324 bool updateStatic =
false;
328 cache.m_currentStatic =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
331 if (
m_navigator->atVolumeBoundary(currPar,
cache.m_currentStatic, dir, nextVol,
339 cache.m_currentStatic = nextVol;
344 nextGeoID =
cache.m_currentStatic->geometrySignature();
354 return returnParameters;
364 cache.m_staticBoundaries.clear();
365 const auto& bounds =
cache.m_currentStatic->boundarySurfaces();
366 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
367 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
368 cache.m_staticBoundaries.emplace_back(&surf,
true);
371 cache.m_detachedVols.clear();
372 cache.m_detachedBoundaries.clear();
373 cache.m_denseVols.clear();
374 cache.m_denseBoundaries.clear();
375 cache.m_layers.clear();
376 cache.m_navigLays.clear();
398 if (!detVols.empty()) {
399 Trk::ArraySpan<const Trk::DetachedTrackingVolume* const>::iterator iTer = detVols.begin();
400 for (; iTer != detVols.end(); ++iTer) {
402 const Trk::Layer *layR = (*iTer)->layerRepresentation();
404 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
406 cache.m_detachedVols.emplace_back(*iTer,
408 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
409 const Trk::Surface &surf = (detBounds[ibb])->surfaceRepresentation();
410 cache.m_detachedBoundaries.emplace_back(&surf,
true);
412 }
else if (
cache.m_currentStatic->geometrySignature() !=
Trk::MS ||
414 (*iTer)->name().substr((*iTer)->name().size() - 4, 4) ==
421 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
422 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty())
423 && (*iTer)->trackingVolume()->confinedArbitraryLayers().empty()) {
424 cache.m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
425 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
426 const Trk::Surface &surf = (detBounds[ibb])->surfaceRepresentation();
427 cache.m_denseBoundaries.emplace_back(&surf,
true);
431 if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() || (confLays.size() > detBounds.size())) {
432 cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
433 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
434 const Trk::Surface &surf = (detBounds[ibb])->surfaceRepresentation();
435 cache.m_detachedBoundaries.emplace_back(&surf,
true);
437 }
else if (!confLays.empty()) {
438 for (
const Trk::Layer*
const lIt : confLays) {
439 cache.m_layers.emplace_back(&(lIt->surfaceRepresentation()),
441 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), lIt);
447 cache.m_denseResolved = std::pair<unsigned int, unsigned int> (
cache.m_denseVols.size(),
cache.m_denseBoundaries.size());
448 cache.m_layerResolved =
cache.m_layers.size();
451 cache.m_navigSurfs.insert(
cache.m_navigSurfs.end(),
cache.m_staticBoundaries.begin(),
cache.m_staticBoundaries.end());
459 cache.m_navigBoundaries.clear();
460 if (
cache.m_denseVols.size() >
cache.m_denseResolved.first) {
461 cache.m_denseVols.resize(
cache.m_denseResolved.first);
463 while (
cache.m_denseBoundaries.size() >
cache.m_denseResolved.second) {
464 cache.m_denseBoundaries.pop_back();
466 if (
cache.m_layers.size() >
cache.m_layerResolved) {
467 cache.m_navigLays.resize(
cache.m_layerResolved);
469 while (
cache.m_layers.size() >
cache.m_layerResolved) {
470 cache.m_layers.pop_back();
477 std::vector<std::pair<const Trk::TrackingVolume *, unsigned int> > navigVols;
480 std::vector<const Trk::DetachedTrackingVolume *> detVols =
481 m_navigator->trackingGeometry(ctx)->lowestDetachedTrackingVolumes(gp);
482 std::vector<const Trk::DetachedTrackingVolume *>::iterator dIter = detVols.begin();
483 for (; dIter != detVols.end(); ++dIter) {
484 const Trk::Layer *layR = (*dIter)->layerRepresentation();
490 m_useMuonMatApprox && (*dIter)->name().substr((*dIter)->name().size() - 4, 4) !=
"PERM") {
503 if (!
active && confinedDense.empty() && confinedLays.empty()) {
507 if (!
active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
510 if (!confinedDense.empty() || !confinedLays.empty()) {
511 navigVols.emplace_back(dVol, bounds.size());
512 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
513 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
514 cache.m_navigBoundaries.emplace_back(&surf,
true);
517 if (!confinedDense.empty()) {
518 auto vIter = confinedDense.begin();
519 for (; vIter != confinedDense.end(); ++vIter) {
520 const auto& bounds = (*vIter)->boundarySurfaces();
521 cache.m_denseVols.emplace_back(*vIter, bounds.size());
522 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
523 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
524 cache.m_denseBoundaries.emplace_back(&surf,
true);
529 if (!confinedLays.empty()) {
530 for (
const auto *confinedLay : confinedLays) {
531 cache.m_layers.emplace_back(&(confinedLay->surfaceRepresentation()),
true);
532 cache.m_navigLays.emplace_back(dVol, confinedLay);
539 for (
const auto *subvol : subvols) {
550 bool vExit =
m_navigator->atVolumeBoundary(currPar, detVol, dir, nextVol,
m_tolerance) && nextVol != detVol;
557 navigVols.emplace_back(detVol, bounds.size());
558 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
559 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
560 cache.m_navigBoundaries.emplace_back(&surf,
true);
563 cache.m_denseVols.emplace_back(detVol, bounds.size());
564 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
565 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
566 cache.m_denseBoundaries.emplace_back(&surf,
true);
573 for (
const auto *cLay : cLays) {
574 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
575 cache.m_layers.emplace_back(&(cLay->surfaceRepresentation()),
true);
576 cache.m_navigLays.emplace_back(
cache.m_currentStatic,
587 cache.m_navigLays.emplace_back(detVol, lay);
590 dir * currPar->
momentum().normalized(),
true);
591 if (nextLayer && nextLayer != lay) {
593 cache.m_navigLays.emplace_back(detVol, nextLayer);
598 for (
const auto *layer : layers) {
599 cache.m_layers.emplace_back(&(layer->surfaceRepresentation()),
true);
600 cache.m_navigLays.emplace_back(detVol, layer);
608 if (
cache.m_currentStatic->confinedLayers() && updateStatic) {
611 std::span<Trk::Layer const * const> cLays =
cache.m_currentStatic->confinedLayers()->arrayObjects();
612 for (
const auto *cLay : cLays) {
613 if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
614 cache.m_layers.emplace_back(&(cLay->surfaceRepresentation()),
616 cache.m_navigLays.emplace_back(
cache.m_currentStatic, cLay);
629 cache.m_navigLays.emplace_back(
cache.m_currentStatic, lay);
631 if (nextLayer && nextLayer != lay) {
634 cache.m_navigLays.emplace_back(
cache.m_currentStatic,
638 if (backLayer && backLayer != lay) {
641 cache.m_navigLays.emplace_back(
cache.m_currentStatic,
651 if (!
cache.m_layers.empty()) {
652 cache.m_navigSurfs.insert(
cache.m_navigSurfs.end(),
cache.m_layers.begin(),
cache.m_layers.end());
654 if (!
cache.m_denseBoundaries.empty()) {
655 cache.m_navigSurfs.insert(
cache.m_navigSurfs.end(),
cache.m_denseBoundaries.begin(),
cache.m_denseBoundaries.end());
657 if (!
cache.m_navigBoundaries.empty()) {
658 cache.m_navigSurfs.insert(
cache.m_navigSurfs.end(),
cache.m_navigBoundaries.begin(),
cache.m_navigBoundaries.end());
660 if (!
cache.m_detachedBoundaries.empty()) {
661 cache.m_navigSurfs.insert(
cache.m_navigSurfs.end(),
cache.m_detachedBoundaries.begin(),
cache.m_detachedBoundaries.end());
667 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
670 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
674 cache.m_currentDense = dVol;
681 if (
cache.m_hitVector) {
682 for (
unsigned int i = 0; i <
cache.m_navigLays.size(); i++) {
683 if (
cache.m_navigLays[i].second->layerType() > 0 &&
cache.m_navigLays[i].second->isOnLayer(currPar->
position())) {
684 if (
cache.m_navigLays[i].second->surfaceArray()) {
690 ATH_MSG_VERBOSE(
" [o] Collecting intersection with active input layer.");
703 std::vector<unsigned int> solutions;
707 <<
" (current momentum: " << currPar->
momentum().mag() <<
709 ATH_MSG_DEBUG(
" [+] " <<
cache.m_navigSurfs.size() <<
" target surfaces in '" <<
cache.m_currentDense->volumeName() <<
"'.");
731 cache.m_currentDense,
742 cache.m_parametersAtBoundary.boundaryInformation(
cache.m_currentStatic, nextPar, nextPar);
743 return returnParameters;
749 if (
cache.m_path.x0Max > 0. &&
750 ((
cache.m_path.process < 100 &&
cache.m_path.x0Collected >=
cache.m_path.x0Max) ||
751 (
cache.m_path.process > 100 &&
cache.m_path.l0Collected >=
cache.m_path.x0Max))) {
764 return returnParameters;
770 return returnParameters;
774 if (timeLim.
tMax > 0. && timeLim.
time >= timeLim.
tMax) {
783 return returnParameters;
788 return returnParameters;
795 ATH_MSG_DEBUG(
" [!] ERROR: missing volume boundary for volume" <<
cache.m_currentDense->volumeName());
799 ATH_MSG_DEBUG(
" [+] Number of intersection solutions: " << solutions.size());
801 unsigned int iSol = 0;
802 while (iSol < solutions.size()) {
803 if (solutions[iSol] < iDest) {
805 }
if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size()) {
807 const Trk::Layer *mb =
cache.m_navigSurfs[solutions[iSol]].first->materialLayer();
809 if (mb->layerMaterialProperties() && mb->layerMaterialProperties()->fullMaterial(nextPar->
position())) {
811 nextPar = currentUpdator ? currentUpdator
816 cache.m_currentStatic->geometrySignature(),
823 ATH_MSG_VERBOSE(
" [+] Update may have killed neutral track - return.");
824 cache.m_parametersAtBoundary.resetBoundaryInformation();
825 return returnParameters;
829 ATH_MSG_VERBOSE(
" boundary layer without material:" << mb->layerIndex());
834 unsigned int index = solutions[iSol] - iDest;
837 nextVol = (
cache.m_currentStatic->boundarySurfaces())[
index]->attachedVolume(
840 if (nextVol && !(nextVol->
inside(nextPar->
position() + 0.01 * dir * nextPar->
momentum().normalized(), 0.))) {
842 " [!] WARNING: wrongly assigned static volume ?" <<
cache.m_currentStatic->volumeName() <<
"->" <<
844 nextVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(
851 if (nextVol !=
cache.m_currentStatic) {
852 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
853 ATH_MSG_DEBUG(
" [+] StaticVol boundary reached of '" <<
cache.m_currentStatic->volumeName() <<
"'.");
854 if (
m_navigator->atVolumeBoundary(nextPar,
cache.m_currentStatic, dir, assocVol,
856 cache.m_currentDense =
cache.m_dense ? nextVol :
cache.m_highestVolume;
878 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size()) {
880 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size();
890 double pIn = nextPar->
momentum().mag();
891 nextPar = currentUpdator ? currentUpdator->
update(nextPar, *nextLayer, timeLim,
cache.m_path,
892 cache.m_currentStatic->geometrySignature(), dir,
893 particle).release() : nextPar;
896 cache.m_parametersAtBoundary.resetBoundaryInformation();
897 return returnParameters;
900 " Layer energy loss:" << nextPar->
momentum().mag() - pIn <<
"at position:" << nextPar->
position() <<
", current momentum:" <<
921 dir * nextPar->
momentum().normalized());
922 if (newLayer && newLayer != nextLayer) {
925 for (
unsigned int i = 0; i <
cache.m_navigLays.size(); i++) {
926 if (
cache.m_navigLays[i].second == newLayer) {
930 if (
cache.m_navigLays[i].second != nextLayer) {
947 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
cache.m_denseBoundaries.size()) {
949 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
cache.m_layers.size();
950 std::vector< std::pair<const Trk::TrackingVolume *, unsigned int> >
::iterator dIter =
cache.m_denseVols.begin();
951 while (dIter !=
cache.m_denseVols.end() &&
index >= (*dIter).second) {
952 index -= (*dIter).second;
955 if (dIter !=
cache.m_denseVols.end()) {
956 currVol = (*dIter).first;
962 if (
cache.m_dense &&
cache.m_denseVols.empty()) {
965 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
968 cache.m_currentDense = dVol;
969 ATH_MSG_DEBUG(
" [+] Next dense volume found: '" <<
cache.m_currentDense->volumeName() <<
"'.");
975 cache.m_currentDense = nextVol;
976 ATH_MSG_DEBUG(
" [+] Next dense volume: '" <<
cache.m_currentDense->volumeName() <<
"'.");
979 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
cache.m_denseBoundaries.size()
980 +
cache.m_navigBoundaries.size()) {
982 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
cache.m_layers.size() -
983 cache.m_denseBoundaries.size();
984 std::vector< std::pair<const Trk::TrackingVolume *, unsigned int> >
::iterator nIter = navigVols.begin();
985 while (nIter != navigVols.end() &&
index >= (*nIter).second) {
986 index -= (*nIter).second;
989 if (nIter != navigVols.end()) {
990 currVol = (*nIter).first;
991 nextVol = ((*nIter).first->boundarySurfaces())[
index]->attachedVolume(*nextPar, dir);
993 ATH_MSG_DEBUG(
" [+] Navigation volume boundary, leaving volume '"
1005 }
else if (solutions[iSol] < iDest +
cache.m_staticBoundaries.size() +
cache.m_layers.size() +
cache.m_denseBoundaries.size()
1006 +
cache.m_navigBoundaries.size() +
cache.m_detachedBoundaries.size()) {
1008 unsigned int index = solutions[iSol] - iDest -
cache.m_staticBoundaries.size() -
cache.m_layers.size()
1009 -
cache.m_denseBoundaries.size() -
cache.m_navigBoundaries.size();
1012 while (dIter !=
cache.m_detachedVols.end() &&
index >= (*dIter).second) {
1013 index -= (*dIter).second;
1016 if (dIter !=
cache.m_detachedVols.end()) {
1017 currVol = (*dIter).first->trackingVolume();
1019 ((*dIter).first->trackingVolume()->boundarySurfaces())[
index]->attachedVolume(*nextPar, dir);
1037 return returnParameters;
1351 std::unique_ptr<const Trk::TrackParameters> returnParameters =
nullptr;
1357 unsigned int iDest = 0;
1359 const EventContext& ctx = Gaudi::Hive::currentContext();
1361 if (destVol &&
m_navigator->atVolumeBoundary(currPar, destVol, dir, nextVol,
m_tolerance) && nextVol != destVol) {
1366 if (!
cache.m_highestVolume) {
1375 cache.m_trSurfs.clear();
1380 if (!tgVol || tgVol != destVol) {
1382 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1383 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1385 dir * currPar->
momentum().normalized());
1391 cache.m_trSurfs.emplace_back(&surf, distSol.
first());
1399 cache.m_trSurfs.emplace_back(&surf, distSol.
second());
1407 if (
cache.m_parametersAtBoundary.nextParameters == currPar) {
1408 cache.m_currentStatic =
cache.m_parametersAtBoundary.nextVolume;
1412 cache.m_currentStatic =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
1414 if (!
cache.m_currentStatic ||
1415 !
cache.m_currentStatic->inside(currPar->
position() + 0.01 * dir * currPar->
momentum().normalized(), 0.)) {
1422 if (!
cache.m_currentStatic) {
1431 nextGeoID =
cache.m_currentStatic->geometrySignature();
1439 return returnParameters;
1448 cache.m_trStaticBounds.clear();
1449 const auto& bounds =
cache.m_currentStatic->boundarySurfaces();
1450 for (
unsigned int ib = 0; ib < bounds.size(); ++ib) {
1451 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1453 dir * currPar->
momentum().normalized());
1457 double dist = distSol.
first();
1469 double dist = distSol.
second();
1480 if (
cache.m_trStaticBounds.empty()) {
1482 " transportToVolumeWithPathLimit() - at " << currPar->
position() <<
", missing static volume boundary "
1483 <<
cache.m_currentStatic->volumeName() <<
1484 ": transport interrupted");
1487 "---> particle R,phi,z, momentum:" << currPar->
position().perp() <<
"," << currPar->
position().phi() <<
"," << currPar->
position().z() <<
"," <<
1499 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1500 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1504 "---> decomposed boundary surface position, normal, estimated distance:" << ib <<
"," << surf.
center() <<
"," <<
1507 "---> estimated distance to (first solution):boundary check:" << distSol.
numberOfSolutions() <<
"," << distSol.
first() <<
":" <<
1511 ATH_MSG_DEBUG(
"---> estimated distance to (second solution):boundary check:" << distSol.
second() <<
"," <<
1517 return returnParameters;
1523 cache.m_currentStatic =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
1525 if (
cache.m_currentStatic) {
1536 cache.m_detachedVols.clear();
1537 cache.m_denseVols.clear();
1538 cache.m_trDenseBounds.clear();
1539 cache.m_trLays.clear();
1540 cache.m_navigLays.clear();
1544 if (!detVols.empty()) {
1545 Trk::ArraySpan<const Trk::DetachedTrackingVolume* const>::iterator iTer = detVols.begin();
1546 for (; iTer != detVols.end(); ++iTer) {
1548 const Trk::Layer *layR = (*iTer)->layerRepresentation();
1555 dir * currPar->
momentum().normalized());
1560 cache.m_trLays.emplace_back(&surf, distSol.
first());
1561 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), layR);
1565 const auto& multi = (*iTer)->multilayerRepresentation();
1566 for (
const auto *i : multi) {
1569 dir * currPar->
momentum().normalized());
1574 cache.m_trLays.emplace_back(&surf, distSol.
first());
1575 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), i);
1582 (*iTer)->name().substr((*iTer)->name().size() - 4, 4) ==
"PERM") {
1585 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
1586 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty())
1587 && ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
1588 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
1590 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
1591 const Trk::Surface &surf = (detBounds[ibb])->surfaceRepresentation();
1593 dir * currPar->
momentum().normalized());
1598 cache.m_trDenseBounds.emplace_back(&surf, distSol.
first());
1604 cache.m_denseVols.emplace_back((*iTer)->trackingVolume(), newB);
1614 const auto confinedDense =
1615 (*iTer)->trackingVolume()->confinedDenseVolumes();
1616 if (!confinedDense.empty()) {
1617 auto vIter = confinedDense.begin();
1618 for (; vIter != confinedDense.end(); ++vIter) {
1619 const auto& bounds = (*vIter)->boundarySurfaces();
1621 for (
unsigned int ibb = 0; ibb < bounds.size(); ibb++) {
1622 const Trk::Surface &surf = (bounds[ibb])->surfaceRepresentation();
1624 dir * currPar->
momentum().normalized());
1629 cache.m_trDenseBounds.emplace_back(&surf, distSol.
first());
1635 cache.m_denseVols.emplace_back((*vIter), newB);
1637 if (!(*vIter)->confinedArbitraryLayers().empty()) {
1639 " transportToVolumeWithPathLimit() - at " << currPar->
position() <<
", unresolved sublayers/subvolumes for "
1640 << (*vIter)->volumeName());
1647 if (!confLays.empty()) {
1648 for (
const Trk::Layer*
const lIt: confLays) {
1649 const Trk::Surface &surf = lIt->surfaceRepresentation();
1651 dir * currPar->
momentum().normalized());
1656 cache.m_trLays.emplace_back(&surf, distSol.
first());
1657 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), lIt);
1665 cache.m_denseResolved = std::pair<unsigned int, unsigned int> (
cache.m_denseVols.size(),
cache.m_trDenseBounds.size());
1666 cache.m_layerResolved =
cache.m_trLays.size();
1668 std::vector< Trk::DestBound >::iterator bIter =
cache.m_trStaticBounds.begin();
1669 while (bIter !=
cache.m_trStaticBounds.end()) {
1670 cache.m_trSurfs.emplace_back((*bIter).surface, (*bIter).distance);
1684 cache.m_navigBoundaries.clear();
1685 if (
cache.m_denseVols.size() >
cache.m_denseResolved.first) {
1686 cache.m_denseVols.resize(
cache.m_denseResolved.first);
1687 cache.m_trDenseBounds.resize(
cache.m_denseResolved.second);
1689 if (
cache.m_layers.size() >
cache.m_layerResolved) {
1690 cache.m_trLays.resize(
cache.m_layerResolved);
1691 cache.m_navigLays.resize(
cache.m_layerResolved);
1697 if (
cache.m_currentStatic->confinedLayers()) {
1698 std::span <Trk::Layer const * const> cLays =
cache.m_currentStatic->confinedLayers()->arrayObjects();
1699 for (
const auto *cLay : cLays) {
1700 if (cLay->layerMaterialProperties()) {
1701 const Trk::Surface &surf = cLay->surfaceRepresentation();
1703 dir * currPar->
momentum().normalized());
1708 cache.m_trLays.emplace_back(&surf, distSol.
first());
1709 cache.m_navigLays.emplace_back(
cache.m_currentStatic,
1720 if (!
cache.m_trLays.empty()) {
1723 if (!
cache.m_trDenseBounds.empty()) {
1724 cache.m_trSurfs.insert(
cache.m_trSurfs.end(),
cache.m_trDenseBounds.begin(),
cache.m_trDenseBounds.end());
1728 cache.m_currentDense =
cache.m_highestVolume;
1730 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1735 cache.m_currentDense = dVol;
1741 cache.m_currentDense =
cache.m_currentStatic;
1747 std::vector<unsigned int> sols;
1748 sols.reserve(
cache.m_trSurfs.size());
1749 for (
unsigned int i = 0; i <
cache.m_trSurfs.size(); ++i) {
1753 if (sols.size() > 1) {
1754 unsigned int itest = 1;
1755 while (itest < sols.size()) {
1756 if (
cache.m_trSurfs[sols[itest]].second <
cache.m_trSurfs[sols[itest - 1]].second) {
1757 unsigned int iex = sols[itest - 1];
1758 sols[itest - 1] = sols[itest];
1766 for (
unsigned int is = 1; is < sols.size(); is++) {
1767 if (
cache.m_trSurfs[sols[is]].second <
cache.m_trSurfs[sols[is - 1]].second) {
1768 std::cout <<
"wrong intersection ordering" << std::endl;
1782 double mom = currPar->
momentum().mag();
1783 double beta = mom / sqrt(mom * mom +
cache.m_particleMass *
cache.m_particleMass) * Gaudi::Units::c_light;
1785 ATH_MSG_DEBUG(
" [0] starting transport of neutral particle in (dense) volume " <<
cache.m_currentDense->volumeName());
1787 for (
unsigned int sol : sols) {
1788 if (
cache.m_trSurfs[sol].second == 0.) {
1792 double step =
cache.m_trSurfs[sol].second - dist;
1799 ATH_MSG_DEBUG(
" [!] WARNING: missing volume boundary for volume" <<
cache.m_currentDense->volumeName());
1801 cache.m_currentDense =
cache.m_highestVolume;
1802 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1805 cache.m_currentDense = dVol;
1809 cache.m_currentDense =
cache.m_currentStatic;
1812 ATH_MSG_DEBUG(
" [!] new search for dense volume : " <<
cache.m_currentDense->volumeName());
1815 double tDelta = step / beta;
1817 double mDelta = (
cache.m_currentDense->zOverAtimesRho() != 0.) ? step /
cache.m_currentDense->x0() : 0.;
1822 if (step > 0 && timeLim.
tMax >
cache.m_time &&
cache.m_time + tDelta >= timeLim.
tMax) {
1823 frT = (timeLim.
tMax -
cache.m_time) * beta / step;
1828 if (mDelta > 0 &&
cache.m_path.x0Max > 0.) {
1829 if (
cache.m_path.process < 100 &&
cache.m_path.x0Collected + mDelta >
cache.m_path.x0Max) {
1830 frM = (
cache.m_path.x0Max -
cache.m_path.x0Collected) / mDelta;
1832 double mDeltaL =
cache.m_currentDense->L0 >
1833 0. ? step /
cache.m_currentDense->L0 : mDelta / 0.37 /
cache.m_currentDense->averageZ();
1834 if (
cache.m_path.l0Collected + mDeltaL >
cache.m_path.x0Max) {
1835 frM = (
cache.m_path.x0Max -
cache.m_path.l0Collected) / mDeltaL;
1840 double fr = fmin(frT, frM);
1847 cache.m_time += fr * step / beta;
1848 if (mDelta > 0 &&
cache.m_currentDense->averageZ() > 0) {
1849 cache.m_path.updateMat(fr * mDelta,
cache.m_currentDense->averageZ(), 0.);
1852 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * (dist + fr * step);
1865 if (nextPar &&
process == 121) {
1866 ATH_MSG_DEBUG(
" [!] WARNING: failed hadronic interaction, killing the input particle anyway");
1867 return returnParameters;
1871 return returnParameters;
1877 return returnParameters;
1882 dist =
cache.m_trSurfs[sol].second;
1883 if (mDelta > 0 &&
cache.m_currentDense->averageZ() > 0) {
1884 cache.m_path.updateMat(mDelta,
cache.m_currentDense->averageZ(), 0.);
1886 cache.m_time += tDelta;
1893 }
if (sol < iDest +
cache.m_trStaticBounds.size()) {
1895 const Trk::Layer *mb =
cache.m_trStaticBounds[sol - iDest].surface->materialLayer();
1897 if (mb->layerMaterialProperties() && mb->layerMaterialProperties()->fullMaterial(nextPos)) {
1903 nextPar, *mb, timeLim,
cache.m_path,
cache.m_currentStatic->geometrySignature(), dir, particle)
1908 ATH_MSG_VERBOSE(
" [+] Update may have killed neutral track - return.");
1909 cache.m_parametersAtBoundary.resetBoundaryInformation();
1910 return returnParameters;
1915 ATH_MSG_VERBOSE(
" boundary layer without material:" << mb->layerIndex());
1920 unsigned int index =
cache.m_trStaticBounds[sol - iDest].bIndex;
1922 nextVol = (
cache.m_currentStatic->boundarySurfaces())[
index]->attachedVolume(
1925 if (nextVol && !(nextVol->
inside(nextPar->
position() + 0.01 * dir * nextPar->
momentum().normalized(), 0.))) {
1927 " [!] WARNING: wrongly assigned static volume ?" <<
cache.m_currentStatic->volumeName() <<
"->" <<
1929 nextVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(
1936 if (nextVol !=
cache.m_currentStatic) {
1937 ATH_MSG_DEBUG(
" [+] StaticVol boundary reached of '" <<
cache.m_currentStatic->volumeName() <<
"'.");
1938 if (
m_navigator->atVolumeBoundary(nextPar,
cache.m_currentStatic, dir, assocVol,
1940 cache.m_currentDense =
cache.m_dense ? nextVol :
cache.m_highestVolume;
1958 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
1964 }
else if (sol < iDest +
cache.m_trStaticBounds.size() +
cache.m_trLays.size()) {
1966 unsigned int index = sol - iDest -
cache.m_trStaticBounds.size();
1975 nextPar = currentUpdator ? currentUpdator
1980 cache.m_currentStatic->geometrySignature(),
1987 ATH_MSG_VERBOSE(
" [+] Update may have killed neutral track - return.");
1988 cache.m_parametersAtBoundary.resetBoundaryInformation();
1989 return returnParameters;
1994 }
else if (sol < iDest +
cache.m_trStaticBounds.size() +
cache.m_trLays.size() +
cache.m_trDenseBounds.size()) {
1997 unsigned int index = sol - iDest -
cache.m_trStaticBounds.size() -
cache.m_trLays.size();
1998 std::vector< std::pair<const Trk::TrackingVolume *, unsigned int> >
::iterator dIter =
cache.m_denseVols.begin();
1999 while (dIter !=
cache.m_denseVols.end() &&
index >= (*dIter).second) {
2000 index -= (*dIter).second;
2003 if (dIter !=
cache.m_denseVols.end()) {
2004 currVol = (*dIter).first;
2009 cache.m_currentDense = assocVol;
2010 }
else if (currVol->
inside(nextPos + 0.002 * dir * nextPar->
momentum().normalized())) {
2011 cache.m_currentDense = currVol;
2014 cache.m_currentDense =
cache.m_highestVolume;
2016 cache.m_currentDense =
cache.m_currentStatic;
2018 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
2020 if (dVol->
inside(nextPos + 0.002 * dir * nextPar->
momentum().normalized(),
2022 cache.m_currentDense = dVol;
2039 " transportToVolumeWithPathLimit() - return from volume " <<
cache.m_currentStatic->volumeName() <<
" at position:" <<
2054 const std::string m = aliTV ? aliTV->
volumeName() :
" NULLPTR!";
2055 ATH_MSG_DEBUG(
" [0] starting transport of neutral particle in alignable volume " << m);
2064 std::vector<Trk::IdentifiedIntersection> iis;
2068 const EventContext& ctx = Gaudi::Hive::currentContext();
2070 return {
nullptr,
nullptr,
nullptr};
2094 if (
cache.m_hitVector && binIDMat) {
2096 if (binIDMat->second > 0) {
2103 unsigned int cbin = lbu->
bin(pos);
2105 std::pair<size_t, float> d2n = lbu->
distanceToNext(pos, dir * umo);
2111 if (d2n.first == cbin) {
2116 pos = pos + d2n.second * dir * umo;
2117 if (!aliTV->
inside(pos)) {
2122 if (d2n.first == cbin && fabs(d2n.second) < 0.002) {
2123 pos = pos + 0.002 * dir * umo;
2128 if (d2n.second > 0.001) {
2129 pot = pos + 0.5 * d2n.second * dir * umo;
2131 iis.emplace_back(distTot, binIDMat->second, binIDMat->first.get());
2140 cache.m_trStaticBounds.clear();
2142 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
2143 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
2145 dir * currPar->
momentum().normalized());
2146 double dist = distSol.
first();
2160 " [!] WARNING: wrongly assigned exit volume ?" <<
cache.m_currentStatic->volumeName() <<
"->" <<
2162 attachedVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(
2163 gp + 0.01 * dir * currPar->
momentum().normalized());
2169 if (attachedVol !=
cache.m_currentStatic) {
2170 nextVol = attachedVol;
2172 }
else if (dist > 0.001) {
2177 "gluing problem at the exit from alignable volume: " << gp.perp() <<
"," << gp.z() <<
":" <<
2178 cache.m_currentStatic->volumeName());
2183 testVol->
inside(gp + 0.01 * dir * currPar->
momentum().normalized(),
2186 "next volume resolved to:" << testVol->
volumeName() <<
" at the position(R,Z):" << gp.perp() <<
"," <<
2198 if (
cache.m_trStaticBounds.empty()) {
2200 return {
nullptr,
nullptr,
nullptr};
2201 }
if (
cache.m_trStaticBounds.size() > 1) {
2204 nextVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
2209 if (!iis.empty() &&
cache.m_trStaticBounds[0].distance - iis.back().distance < 0.01) {
2214 iis.emplace_back(
cache.m_trStaticBounds[0].distance, 0,
nullptr);
2219 double mom = currPar->
momentum().mag();
2220 double beta = mom / sqrt(mom * mom +
cache.m_particleMass *
cache.m_particleMass) * Gaudi::Units::c_light;
2225 for (
unsigned int is = 0; is < iis.size(); is++) {
2226 if (iis[is].distance == 0.) {
2230 double step = iis[is].distance - dist;
2232 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * iis[is].distance;
2234 double tDelta = step / beta;
2236 double mDelta = (currMat->
zOverAtimesRho() != 0.) ? step / currMat->
x0() : 0.;
2241 if (step > 0 && timeLim.
tMax >
cache.m_time &&
cache.m_time + tDelta >= timeLim.
tMax) {
2242 frT = (timeLim.
tMax -
cache.m_time) * beta / step;
2247 if (mDelta > 0 &&
cache.m_path.x0Max > 0.) {
2248 if (
cache.m_path.process < 100 &&
cache.m_path.x0Collected + mDelta >
cache.m_path.x0Max) {
2249 frM = (
cache.m_path.x0Max -
cache.m_path.x0Collected) / mDelta;
2251 double mDeltaL = currMat->
L0 > 0. ? step / currMat->
L0 : mDelta / 0.37 / currMat->
averageZ();
2252 if (
cache.m_path.l0Collected + mDeltaL >
cache.m_path.x0Max) {
2253 frM = (
cache.m_path.x0Max -
cache.m_path.l0Collected) / mDeltaL;
2258 double fr = fmin(frT, frM);
2265 cache.m_time += fr * step / beta;
2266 if (mDelta > 0 && currMat->
averageZ() > 0) {
2267 cache.m_path.updateMat(fr * mDelta, currMat->
averageZ(), 0.);
2270 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * (dist + fr * step);
2284 if (nextPar &&
process == 121) {
2285 ATH_MSG_DEBUG(
" [!] WARNING: failed hadronic interaction, killing the input particle anyway");
2286 return {
nullptr,
nullptr,
nullptr};
2290 return {
nullptr,
nullptr,
nullptr};
2295 return {
nullptr,
nullptr,
nullptr};
2300 dist = iis[is].distance;
2301 if (mDelta > 0 && currMat->
averageZ() > 0) {
2304 cache.m_time += tDelta;
2306 if (is < iis.size() - 1) {
2309 currMat = iis[is].material;
2310 currLay = iis[is].identifier;
2312 if (
cache.m_hitVector && iis[is].identifier > 0) {
2313 ATH_MSG_VERBOSE(
"active layer entry:" << currLay <<
" at R,z:" << nextPos.perp() <<
"," << nextPos.z());
2314 auto nextPar = std::make_unique<Trk::CurvilinearParameters>(nextPos, currPar->
momentum(), 0.);
2315 cache.m_hitVector->emplace_back(std::move(nextPar), timeLim.
time, iis[is].identifier, 0.);
2322 if (
cache.m_hitVector) {
2323 ATH_MSG_VERBOSE(
"active layer/volume exit:" << currLay <<
" at R,z:" << nextPos.perp() <<
"," << nextPos.z());
2324 if (binIDMat and(binIDMat->second > 0)) {
2333 ATH_MSG_DEBUG(
" [+] StaticVol boundary reached of '" <<
cache.m_currentStatic->volumeName() <<
"'.");
2345 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
2347 return {nextPar, nextVol,
cache.m_currentStatic};