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;
1350 std::unique_ptr<const Trk::TrackParameters> returnParameters =
nullptr;
1356 unsigned int iDest = 0;
1358 const EventContext& ctx = Gaudi::Hive::currentContext();
1360 if (destVol &&
m_navigator->atVolumeBoundary(currPar, destVol, dir, nextVol,
m_tolerance) && nextVol != destVol) {
1365 if (!
cache.m_highestVolume) {
1374 cache.m_trSurfs.clear();
1379 if (!tgVol || tgVol != destVol) {
1381 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1382 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1384 dir * currPar->
momentum().normalized());
1390 cache.m_trSurfs.emplace_back(&surf, distSol.
first());
1398 cache.m_trSurfs.emplace_back(&surf, distSol.
second());
1406 if (
cache.m_parametersAtBoundary.nextParameters == currPar) {
1407 cache.m_currentStatic =
cache.m_parametersAtBoundary.nextVolume;
1411 cache.m_currentStatic =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
1413 if (!
cache.m_currentStatic ||
1414 !
cache.m_currentStatic->inside(currPar->
position() + 0.01 * dir * currPar->
momentum().normalized(), 0.)) {
1421 if (!
cache.m_currentStatic) {
1430 if (!
cache.m_currentStatic)[[
unlikely]]
return returnParameters;
1432 nextGeoID =
cache.m_currentStatic->geometrySignature();
1440 return returnParameters;
1449 cache.m_trStaticBounds.clear();
1450 const auto& bounds =
cache.m_currentStatic->boundarySurfaces();
1451 for (
unsigned int ib = 0; ib < bounds.size(); ++ib) {
1452 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1454 dir * currPar->
momentum().normalized());
1458 double dist = distSol.
first();
1470 double dist = distSol.
second();
1481 if (
cache.m_trStaticBounds.empty()) {
1483 " transportToVolumeWithPathLimit() - at " << currPar->
position() <<
", missing static volume boundary "
1484 <<
cache.m_currentStatic->volumeName() <<
1485 ": transport interrupted");
1488 "---> particle R,phi,z, momentum:" << currPar->
position().perp() <<
"," << currPar->
position().phi() <<
"," << currPar->
position().z() <<
"," <<
1500 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
1501 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
1505 "---> decomposed boundary surface position, normal, estimated distance:" << ib <<
"," << surf.
center() <<
"," <<
1508 "---> estimated distance to (first solution):boundary check:" << distSol.
numberOfSolutions() <<
"," << distSol.
first() <<
":" <<
1512 ATH_MSG_DEBUG(
"---> estimated distance to (second solution):boundary check:" << distSol.
second() <<
"," <<
1518 return returnParameters;
1524 cache.m_currentStatic =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
1526 if (
cache.m_currentStatic) {
1537 cache.m_detachedVols.clear();
1538 cache.m_denseVols.clear();
1539 cache.m_trDenseBounds.clear();
1540 cache.m_trLays.clear();
1541 cache.m_navigLays.clear();
1545 if (!detVols.empty()) {
1546 Trk::ArraySpan<const Trk::DetachedTrackingVolume* const>::iterator iTer = detVols.begin();
1547 for (; iTer != detVols.end(); ++iTer) {
1549 const Trk::Layer *layR = (*iTer)->layerRepresentation();
1556 dir * currPar->
momentum().normalized());
1561 cache.m_trLays.emplace_back(&surf, distSol.
first());
1562 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), layR);
1566 const auto& multi = (*iTer)->multilayerRepresentation();
1567 for (
const auto *i : multi) {
1570 dir * currPar->
momentum().normalized());
1575 cache.m_trLays.emplace_back(&surf, distSol.
first());
1576 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), i);
1583 (*iTer)->name().substr((*iTer)->name().size() - 4, 4) ==
"PERM") {
1586 if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
1587 ((*iTer)->trackingVolume()->confinedDenseVolumes().empty())
1588 && ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
1589 const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
1591 for (
unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
1592 const Trk::Surface &surf = (detBounds[ibb])->surfaceRepresentation();
1594 dir * currPar->
momentum().normalized());
1599 cache.m_trDenseBounds.emplace_back(&surf, distSol.
first());
1605 cache.m_denseVols.emplace_back((*iTer)->trackingVolume(), newB);
1615 const auto confinedDense =
1616 (*iTer)->trackingVolume()->confinedDenseVolumes();
1617 if (!confinedDense.empty()) {
1618 auto vIter = confinedDense.begin();
1619 for (; vIter != confinedDense.end(); ++vIter) {
1620 const auto& bounds = (*vIter)->boundarySurfaces();
1622 for (
unsigned int ibb = 0; ibb < bounds.size(); ibb++) {
1623 const Trk::Surface &surf = (bounds[ibb])->surfaceRepresentation();
1625 dir * currPar->
momentum().normalized());
1630 cache.m_trDenseBounds.emplace_back(&surf, distSol.
first());
1636 cache.m_denseVols.emplace_back((*vIter), newB);
1638 if (!(*vIter)->confinedArbitraryLayers().empty()) {
1640 " transportToVolumeWithPathLimit() - at " << currPar->
position() <<
", unresolved sublayers/subvolumes for "
1641 << (*vIter)->volumeName());
1648 if (!confLays.empty()) {
1649 for (
const Trk::Layer*
const lIt: confLays) {
1650 const Trk::Surface &surf = lIt->surfaceRepresentation();
1652 dir * currPar->
momentum().normalized());
1657 cache.m_trLays.emplace_back(&surf, distSol.
first());
1658 cache.m_navigLays.emplace_back((*iTer)->trackingVolume(), lIt);
1666 cache.m_denseResolved = std::pair<unsigned int, unsigned int> (
cache.m_denseVols.size(),
cache.m_trDenseBounds.size());
1667 cache.m_layerResolved =
cache.m_trLays.size();
1669 std::vector< Trk::DestBound >::iterator bIter =
cache.m_trStaticBounds.begin();
1670 while (bIter !=
cache.m_trStaticBounds.end()) {
1671 cache.m_trSurfs.emplace_back((*bIter).surface, (*bIter).distance);
1685 cache.m_navigBoundaries.clear();
1686 if (
cache.m_denseVols.size() >
cache.m_denseResolved.first) {
1687 cache.m_denseVols.resize(
cache.m_denseResolved.first);
1688 cache.m_trDenseBounds.resize(
cache.m_denseResolved.second);
1690 if (
cache.m_layers.size() >
cache.m_layerResolved) {
1691 cache.m_trLays.resize(
cache.m_layerResolved);
1692 cache.m_navigLays.resize(
cache.m_layerResolved);
1698 if (
cache.m_currentStatic->confinedLayers()) {
1699 std::span <Trk::Layer const * const> cLays =
cache.m_currentStatic->confinedLayers()->arrayObjects();
1700 for (
const auto *cLay : cLays) {
1701 if (cLay->layerMaterialProperties()) {
1702 const Trk::Surface &surf = cLay->surfaceRepresentation();
1704 dir * currPar->
momentum().normalized());
1709 cache.m_trLays.emplace_back(&surf, distSol.
first());
1710 cache.m_navigLays.emplace_back(
cache.m_currentStatic,
1721 if (!
cache.m_trLays.empty()) {
1724 if (!
cache.m_trDenseBounds.empty()) {
1725 cache.m_trSurfs.insert(
cache.m_trSurfs.end(),
cache.m_trDenseBounds.begin(),
cache.m_trDenseBounds.end());
1729 cache.m_currentDense =
cache.m_highestVolume;
1731 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1736 cache.m_currentDense = dVol;
1742 cache.m_currentDense =
cache.m_currentStatic;
1748 std::vector<unsigned int> sols;
1749 sols.reserve(
cache.m_trSurfs.size());
1750 for (
unsigned int i = 0; i <
cache.m_trSurfs.size(); ++i) {
1754 if (sols.size() > 1) {
1755 unsigned int itest = 1;
1756 while (itest < sols.size()) {
1757 if (
cache.m_trSurfs[sols[itest]].second <
cache.m_trSurfs[sols[itest - 1]].second) {
1758 unsigned int iex = sols[itest - 1];
1759 sols[itest - 1] = sols[itest];
1767 for (
unsigned int is = 1; is < sols.size(); is++) {
1768 if (
cache.m_trSurfs[sols[is]].second <
cache.m_trSurfs[sols[is - 1]].second) {
1769 std::cout <<
"wrong intersection ordering" << std::endl;
1783 double mom = currPar->
momentum().mag();
1784 double beta = mom / sqrt(mom * mom +
cache.m_particleMass *
cache.m_particleMass) * Gaudi::Units::c_light;
1786 ATH_MSG_DEBUG(
" [0] starting transport of neutral particle in (dense) volume " <<
cache.m_currentDense->volumeName());
1788 for (
unsigned int sol : sols) {
1789 if (
cache.m_trSurfs[sol].second == 0.) {
1793 double step =
cache.m_trSurfs[sol].second - dist;
1800 ATH_MSG_DEBUG(
" [!] WARNING: missing volume boundary for volume" <<
cache.m_currentDense->volumeName());
1802 cache.m_currentDense =
cache.m_highestVolume;
1803 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
1806 cache.m_currentDense = dVol;
1810 cache.m_currentDense =
cache.m_currentStatic;
1813 ATH_MSG_DEBUG(
" [!] new search for dense volume : " <<
cache.m_currentDense->volumeName());
1816 double tDelta = step / beta;
1818 double mDelta = (
cache.m_currentDense->zOverAtimesRho() != 0.) ? step /
cache.m_currentDense->x0() : 0.;
1823 if (step > 0 && timeLim.
tMax >
cache.m_time &&
cache.m_time + tDelta >= timeLim.
tMax) {
1824 frT = (timeLim.
tMax -
cache.m_time) * beta / step;
1829 if (mDelta > 0 &&
cache.m_path.x0Max > 0.) {
1830 if (
cache.m_path.process < 100 &&
cache.m_path.x0Collected + mDelta >
cache.m_path.x0Max) {
1831 frM = (
cache.m_path.x0Max -
cache.m_path.x0Collected) / mDelta;
1833 double mDeltaL =
cache.m_currentDense->L0 >
1834 0. ? step /
cache.m_currentDense->L0 : mDelta / 0.37 /
cache.m_currentDense->averageZ();
1835 if (
cache.m_path.l0Collected + mDeltaL >
cache.m_path.x0Max) {
1836 frM = (
cache.m_path.x0Max -
cache.m_path.l0Collected) / mDeltaL;
1841 double fr = fmin(frT, frM);
1848 cache.m_time += fr * step / beta;
1849 if (mDelta > 0 &&
cache.m_currentDense->averageZ() > 0) {
1850 cache.m_path.updateMat(fr * mDelta,
cache.m_currentDense->averageZ(), 0.);
1853 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * (dist + fr * step);
1866 if (nextPar &&
process == 121) {
1867 ATH_MSG_DEBUG(
" [!] WARNING: failed hadronic interaction, killing the input particle anyway");
1869 return returnParameters;
1873 return returnParameters;
1879 return returnParameters;
1884 dist =
cache.m_trSurfs[sol].second;
1885 if (mDelta > 0 &&
cache.m_currentDense->averageZ() > 0) {
1886 cache.m_path.updateMat(mDelta,
cache.m_currentDense->averageZ(), 0.);
1888 cache.m_time += tDelta;
1895 }
if (sol < iDest +
cache.m_trStaticBounds.size()) {
1897 const Trk::Layer *mb =
cache.m_trStaticBounds[sol - iDest].surface->materialLayer();
1899 if (mb->layerMaterialProperties() && mb->layerMaterialProperties()->fullMaterial(nextPos)) {
1905 nextPar, *mb, timeLim,
cache.m_path,
cache.m_currentStatic->geometrySignature(), dir, particle)
1910 ATH_MSG_VERBOSE(
" [+] Update may have killed neutral track - return.");
1911 cache.m_parametersAtBoundary.resetBoundaryInformation();
1912 return returnParameters;
1917 ATH_MSG_VERBOSE(
" boundary layer without material:" << mb->layerIndex());
1922 unsigned int index =
cache.m_trStaticBounds[sol - iDest].bIndex;
1924 nextVol = (
cache.m_currentStatic->boundarySurfaces())[
index]->attachedVolume(
1927 if (nextVol && !(nextVol->
inside(nextPar->
position() + 0.01 * dir * nextPar->
momentum().normalized(), 0.))) {
1929 " [!] WARNING: wrongly assigned static volume ?" <<
cache.m_currentStatic->volumeName() <<
"->" <<
1931 nextVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(
1938 if (nextVol !=
cache.m_currentStatic) {
1939 ATH_MSG_DEBUG(
" [+] StaticVol boundary reached of '" <<
cache.m_currentStatic->volumeName() <<
"'.");
1940 if (
m_navigator->atVolumeBoundary(nextPar,
cache.m_currentStatic, dir, assocVol,
1942 cache.m_currentDense =
cache.m_dense ? nextVol :
cache.m_highestVolume;
1960 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
1966 }
else if (sol < iDest +
cache.m_trStaticBounds.size() +
cache.m_trLays.size()) {
1968 unsigned int index = sol - iDest -
cache.m_trStaticBounds.size();
1977 nextPar = currentUpdator ? currentUpdator
1982 cache.m_currentStatic->geometrySignature(),
1989 ATH_MSG_VERBOSE(
" [+] Update may have killed neutral track - return.");
1990 cache.m_parametersAtBoundary.resetBoundaryInformation();
1991 return returnParameters;
1996 }
else if (sol < iDest +
cache.m_trStaticBounds.size() +
cache.m_trLays.size() +
cache.m_trDenseBounds.size()) {
1999 unsigned int index = sol - iDest -
cache.m_trStaticBounds.size() -
cache.m_trLays.size();
2000 std::vector< std::pair<const Trk::TrackingVolume *, unsigned int> >
::iterator dIter =
cache.m_denseVols.begin();
2001 while (dIter !=
cache.m_denseVols.end() &&
index >= (*dIter).second) {
2002 index -= (*dIter).second;
2005 if (dIter !=
cache.m_denseVols.end()) {
2006 currVol = (*dIter).first;
2011 cache.m_currentDense = assocVol;
2012 }
else if (currVol->
inside(nextPos + 0.002 * dir * nextPar->
momentum().normalized())) {
2013 cache.m_currentDense = currVol;
2016 cache.m_currentDense =
cache.m_highestVolume;
2018 cache.m_currentDense =
cache.m_currentStatic;
2020 for (
unsigned int i = 0; i <
cache.m_denseVols.size(); i++) {
2022 if (dVol->
inside(nextPos + 0.002 * dir * nextPar->
momentum().normalized(),
2024 cache.m_currentDense = dVol;
2041 " transportToVolumeWithPathLimit() - return from volume " <<
cache.m_currentStatic->volumeName() <<
" at position:" <<
2056 const std::string m = aliTV ? aliTV->
volumeName() :
" NULLPTR!";
2057 ATH_MSG_DEBUG(
" [0] starting transport of neutral particle in alignable volume " << m);
2066 std::vector<Trk::IdentifiedIntersection> iis;
2070 const EventContext& ctx = Gaudi::Hive::currentContext();
2072 return {
nullptr,
nullptr,
nullptr};
2096 if (
cache.m_hitVector && binIDMat) {
2098 if (binIDMat->second > 0) {
2105 unsigned int cbin = lbu->
bin(pos);
2107 std::pair<size_t, float> d2n = lbu->
distanceToNext(pos, dir * umo);
2113 if (d2n.first == cbin) {
2118 pos = pos + d2n.second * dir * umo;
2119 if (!aliTV->
inside(pos)) {
2124 if (d2n.first == cbin && fabs(d2n.second) < 0.002) {
2125 pos = pos + 0.002 * dir * umo;
2130 if (d2n.second > 0.001) {
2131 pot = pos + 0.5 * d2n.second * dir * umo;
2133 iis.emplace_back(distTot, binIDMat->second, binIDMat->first.get());
2142 cache.m_trStaticBounds.clear();
2144 for (
unsigned int ib = 0; ib < bounds.size(); ib++) {
2145 const Trk::Surface &surf = (bounds[ib])->surfaceRepresentation();
2147 dir * currPar->
momentum().normalized());
2148 double dist = distSol.
first();
2162 " [!] WARNING: wrongly assigned exit volume ?" <<
cache.m_currentStatic->volumeName() <<
"->" <<
2164 attachedVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(
2165 gp + 0.01 * dir * currPar->
momentum().normalized());
2171 if (attachedVol !=
cache.m_currentStatic) {
2172 nextVol = attachedVol;
2174 }
else if (dist > 0.001) {
2179 "gluing problem at the exit from alignable volume: " << gp.perp() <<
"," << gp.z() <<
":" <<
2180 cache.m_currentStatic->volumeName());
2185 testVol->
inside(gp + 0.01 * dir * currPar->
momentum().normalized(),
2188 "next volume resolved to:" << testVol->
volumeName() <<
" at the position(R,Z):" << gp.perp() <<
"," <<
2200 if (
cache.m_trStaticBounds.empty()) {
2202 return {
nullptr,
nullptr,
nullptr};
2203 }
if (
cache.m_trStaticBounds.size() > 1) {
2206 nextVol =
m_navigator->trackingGeometry(ctx)->lowestStaticTrackingVolume(gp);
2211 if (!iis.empty() &&
cache.m_trStaticBounds[0].distance - iis.back().distance < 0.01) {
2216 iis.emplace_back(
cache.m_trStaticBounds[0].distance, 0,
nullptr);
2221 double mom = currPar->
momentum().mag();
2222 double beta = mom / sqrt(mom * mom +
cache.m_particleMass *
cache.m_particleMass) * Gaudi::Units::c_light;
2227 for (
unsigned int is = 0; is < iis.size(); is++) {
2228 if (iis[is].distance == 0.) {
2232 double step = iis[is].distance - dist;
2234 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * iis[is].distance;
2236 double tDelta = step / beta;
2238 double mDelta = (currMat->
zOverAtimesRho() != 0.) ? step / currMat->
x0() : 0.;
2243 if (step > 0 && timeLim.
tMax >
cache.m_time &&
cache.m_time + tDelta >= timeLim.
tMax) {
2244 frT = (timeLim.
tMax -
cache.m_time) * beta / step;
2249 if (mDelta > 0 &&
cache.m_path.x0Max > 0.) {
2250 if (
cache.m_path.process < 100 &&
cache.m_path.x0Collected + mDelta >
cache.m_path.x0Max) {
2251 frM = (
cache.m_path.x0Max -
cache.m_path.x0Collected) / mDelta;
2253 double mDeltaL = currMat->
L0 > 0. ? step / currMat->
L0 : mDelta / 0.37 / currMat->
averageZ();
2254 if (
cache.m_path.l0Collected + mDeltaL >
cache.m_path.x0Max) {
2255 frM = (
cache.m_path.x0Max -
cache.m_path.l0Collected) / mDeltaL;
2260 double fr = fmin(frT, frM);
2267 cache.m_time += fr * step / beta;
2268 if (mDelta > 0 && currMat->
averageZ() > 0) {
2269 cache.m_path.updateMat(fr * mDelta, currMat->
averageZ(), 0.);
2272 nextPos = currPar->
position() + dir * currPar->
momentum().normalized() * (dist + fr * step);
2286 if (nextPar &&
process == 121) {
2287 ATH_MSG_DEBUG(
" [!] WARNING: failed hadronic interaction, killing the input particle anyway");
2288 return {
nullptr,
nullptr,
nullptr};
2292 return {
nullptr,
nullptr,
nullptr};
2297 return {
nullptr,
nullptr,
nullptr};
2302 dist = iis[is].distance;
2303 if (mDelta > 0 && currMat->
averageZ() > 0) {
2306 cache.m_time += tDelta;
2308 if (is < iis.size() - 1) {
2311 currMat = iis[is].material;
2312 currLay = iis[is].identifier;
2314 if (
cache.m_hitVector && iis[is].identifier > 0) {
2315 ATH_MSG_VERBOSE(
"active layer entry:" << currLay <<
" at R,z:" << nextPos.perp() <<
"," << nextPos.z());
2316 auto nextPar = std::make_unique<Trk::CurvilinearParameters>(nextPos, currPar->
momentum(), 0.);
2317 cache.m_hitVector->emplace_back(std::move(nextPar), timeLim.
time, iis[is].identifier, 0.);
2324 if (
cache.m_hitVector) {
2325 ATH_MSG_VERBOSE(
"active layer/volume exit:" << currLay <<
" at R,z:" << nextPos.perp() <<
"," << nextPos.z());
2326 if (binIDMat and(binIDMat->second > 0)) {
2335 ATH_MSG_DEBUG(
" [+] StaticVol boundary reached of '" <<
cache.m_currentStatic->volumeName() <<
"'.");
2347 cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
2349 return {nextPar, nextVol,
cache.m_currentStatic};