27 #include <boost/container/small_vector.hpp>
36 template <
typename object_t>
60 double pathLimit = std::numeric_limits<double>::max();
96 boost::container::small_vector<SurfaceIntersection, 10>;
99 boost::container::small_vector<LayerIntersection, 10>;
102 boost::container::small_vector<BoundaryIntersection, 4>;
202 std::shared_ptr<const Logger> _logger =
206 State makeState(
const Surface* startSurface,
207 const Surface* targetSurface)
const {
209 result.startSurface = startSurface;
210 result.targetSurface = targetSurface;
229 state.startSurface = ssurface;
230 if (ssurface->associatedLayer() !=
nullptr) {
231 state.startLayer = ssurface->associatedLayer();
233 if (state.startLayer->trackingVolume() !=
nullptr) {
234 state.startVolume = state.startLayer->trackingVolume();
236 state.currentSurface = state.startSurface;
237 state.currentVolume = state.startVolume;
238 state.targetSurface = tsurface;
242 navOpts.resolveSensitive =
true;
243 navOpts.resolveMaterial =
true;
244 navOpts.resolvePassive =
true;
246 state.currentVolume->compatibleLayers(geoContext, pos, dir, navOpts);
249 state.navLayerIndex = 0;
252 const Surface* currentSurface(
const State& state)
const {
253 return state.currentSurface;
256 const TrackingVolume* currentVolume(
const State& state)
const {
257 return state.currentVolume;
260 const IVolumeMaterial* currentVolumeMaterial(
const State& state)
const {
261 if (state.currentVolume ==
nullptr) {
264 return state.currentVolume->volumeMaterial();
267 const Surface* startSurface(
const State& state)
const {
268 return state.startSurface;
271 const Surface* targetSurface(
const State& state)
const {
272 return state.targetSurface;
275 bool targetReached(
const State& state)
const {
return state.targetReached; }
277 bool endOfWorldReached(State& state)
const {
278 return state.currentVolume ==
nullptr;
281 bool navigationBreak(
const State& state)
const {
282 return state.navigationBreak;
286 state.currentSurface =
surface;
289 void targetReached(State& state,
bool targetReached)
const {
290 state.targetReached = targetReached;
293 void navigationBreak(State& state,
bool navigationBreak)
const {
294 state.navigationBreak = navigationBreak;
297 void insertExternalSurface(State& state, GeometryIdentifier geoid)
const {
298 state.externalSurfaces.insert(
299 std::pair<uint64_t, GeometryIdentifier>(geoid.layer(), geoid));
311 template <
typename propagator_state_t,
typename stepper_t>
317 if (not state.navigation.worldVolume) {
318 state.navigation.worldVolume =
319 m_cfg.trackingGeometry->highestTrackingVolume();
326 state.navigation.currentSurface = state.navigation.startSurface;
327 if (state.navigation.currentSurface) {
329 <<
"Current surface set to start surface "
330 << state.navigation.currentSurface->geometryId());
336 if (state.navigation.startSurface &&
337 state.navigation.startSurface->associatedLayer()) {
340 <<
"Fast start initialization through association from Surface.");
342 state.navigation.startLayer =
343 state.navigation.startSurface->associatedLayer();
344 state.navigation.startVolume =
345 state.navigation.startLayer->trackingVolume();
347 state.navigation.currentVolume = state.navigation.startVolume;
348 }
else if (state.navigation.startVolume) {
351 <<
"Fast start initialization through association from Volume.");
352 state.navigation.startLayer =
353 state.navigation.startVolume->associatedLayer(
354 state.geoContext, stepper.position(state.stepping));
356 state.navigation.currentVolume = state.navigation.startVolume;
359 <<
"Slow start initialization through search.");
362 <<
"Starting from position "
363 <<
toString(stepper.position(state.stepping))
365 <<
toString(stepper.direction(state.stepping)));
366 state.navigation.startVolume =
367 m_cfg.trackingGeometry->lowestTrackingVolume(
368 state.geoContext, stepper.position(state.stepping));
369 state.navigation.startLayer =
370 state.navigation.startVolume
371 ? state.navigation.startVolume->associatedLayer(
372 state.geoContext, stepper.position(state.stepping))
375 state.navigation.currentVolume = state.navigation.startVolume;
376 if (state.navigation.startVolume) {
377 ACTS_VERBOSE(volInfo(state) <<
"Start volume resolved.");
394 template <
typename propagator_state_t,
typename stepper_t>
395 void preStep(propagator_state_t& state,
const stepper_t& stepper)
const {
397 if (inactive(state, stepper)) {
402 ACTS_VERBOSE(volInfo(state) <<
"Entering navigator::preStep.");
405 if (state.navigation.targetSurface and not state.navigation.targetVolume) {
407 initializeTarget(state, stepper);
410 if (state.navigation.navigationStage <= Stage::surfaceTarget and
411 targetSurfaces(state, stepper)) {
412 ACTS_VERBOSE(volInfo(state) <<
"Target set to next surface.");
413 }
else if (state.navigation.navigationStage <= Stage::layerTarget and
414 targetLayers(state, stepper)) {
415 ACTS_VERBOSE(volInfo(state) <<
"Target set to next layer.");
416 }
else if (targetBoundaries(state, stepper)) {
417 ACTS_VERBOSE(volInfo(state) <<
"Target set to next boundary.");
420 <<
"No further navigation action, proceed to target.");
422 state.navigation.navigationBreak =
true;
423 stepper.releaseStepSize(state.stepping);
427 state.navigation.currentSurface =
nullptr;
449 template <
typename propagator_state_t,
typename stepper_t>
450 void postStep(propagator_state_t& state,
const stepper_t& stepper)
const {
452 if (inactive(state, stepper)) {
460 ACTS_VERBOSE(volInfo(state) <<
"Entering navigator::postStep.");
463 state.navigation.currentSurface =
nullptr;
467 if (surfaceStatus(state, stepper, state.navigation.navSurfaces,
468 state.navigation.navSurfaceIndex)) {
469 ACTS_VERBOSE(volInfo(state) <<
"Post step: in surface handling.");
470 if (state.navigation.currentSurface) {
472 <<
"On surface: switch forward or release.");
473 if (++state.navigation.navSurfaceIndex ==
474 state.navigation.navSurfaces.size()) {
476 if (!state.navigation.navLayers.empty()) {
477 ++state.navigation.navLayerIndex;
478 }
else if (state.navigation.startLayer !=
nullptr and
479 state.navigation.currentSurface->associatedLayer() ==
480 state.navigation.startLayer) {
482 state.navigation.navigationStage = Stage::layerTarget;
486 state.navigation.navigationStage = Stage::boundaryTarget;
492 state.navigation.navigationStage = Stage::surfaceTarget;
493 ACTS_VERBOSE(volInfo(state) <<
"Staying focussed on surface.");
495 }
else if (surfaceStatus(state, stepper, state.navigation.navLayers,
496 state.navigation.navLayerIndex)) {
497 ACTS_VERBOSE(volInfo(state) <<
"Post step: in layer handling.");
498 if (state.navigation.currentSurface !=
nullptr) {
499 ACTS_VERBOSE(volInfo(state) <<
"On layer: update layer information.");
500 if (resolveSurfaces(state, stepper)) {
502 state.navigation.navigationStage = Stage::surfaceTarget;
507 state.navigation.navigationStage = Stage::layerTarget;
508 ACTS_VERBOSE(volInfo(state) <<
"Staying focussed on layer.");
511 }
else if (surfaceStatus(state, stepper, state.navigation.navBoundaries,
512 state.navigation.navBoundaryIndex)) {
513 ACTS_VERBOSE(volInfo(state) <<
"Post step: in boundary handling.");
516 if (state.navigation.currentSurface !=
nullptr) {
519 <<
"On boundary: update volume information.");
521 state.navigation.navSurfaces.clear();
522 state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size();
523 state.navigation.navLayers.clear();
524 state.navigation.navLayerIndex = state.navigation.navLayers.size();
525 state.navigation.lastHierarchySurfaceReached =
false;
528 auto boundary = state.navigation.navBoundary().object();
529 state.navigation.currentVolume = boundary->attachedVolume(
530 state.geoContext, stepper.position(state.stepping),
531 stepper.direction(state.stepping), state.options.direction);
533 if (!state.navigation.currentVolume) {
536 <<
"No more volume to progress to, stopping navigation.");
538 state.navigation.navigationBreak =
true;
539 stepper.releaseStepSize(state.stepping);
544 state.navigation.navBoundaries.clear();
545 state.navigation.navBoundaryIndex =
546 state.navigation.navBoundaries.size();
550 state.navigation.navigationStage = Stage::boundaryTarget;
551 ACTS_VERBOSE(volInfo(state) <<
"Staying focussed on boundary.");
553 }
else if (state.navigation.currentVolume ==
554 state.navigation.targetVolume) {
555 if (state.navigation.targetSurface ==
nullptr) {
557 <<
"No further navigation action, proceed to "
558 "target. This is very likely an error");
561 <<
"No further navigation action, proceed to target.");
564 state.navigation.navigationBreak =
true;
565 stepper.releaseStepSize(state.stepping);
568 <<
"Status could not be determined - good luck.");
588 template <
typename propagator_state_t,
typename stepper_t,
589 typename navigation_surfaces_t>
590 bool surfaceStatus(propagator_state_t& state,
const stepper_t& stepper,
591 const navigation_surfaces_t& navSurfaces,
592 std::size_t navIndex)
const {
594 if (navSurfaces.empty() or navIndex == navSurfaces.size()) {
598 auto surface = navSurfaces.at(navIndex).representation();
602 auto surfaceStatus = stepper.updateSurfaceStatus(
603 state.stepping, *
surface, state.options.direction,
true,
604 state.options.targetTolerance,
logger());
605 if (surfaceStatus == Intersection3D::Status::onSurface) {
607 <<
"Status Surface successfully hit, storing it.");
609 state.navigation.currentSurface =
surface;
610 if (state.navigation.currentSurface) {
612 <<
"Current surface set to surface "
613 << state.navigation.currentSurface->geometryId());
632 template <
typename propagator_state_t,
typename stepper_t>
633 bool targetSurfaces(propagator_state_t& state,
634 const stepper_t& stepper)
const {
635 if (state.navigation.navigationBreak) {
639 if (state.navigation.startLayer and
640 not state.navigation.startLayerResolved) {
641 ACTS_VERBOSE(volInfo(state) <<
"Start layer to be resolved.");
643 state.navigation.startLayerResolved =
true;
645 resolveSurfaces(state, stepper, state.navigation.startLayer);
646 if (not startResolved and
647 state.navigation.startLayer == state.navigation.targetLayer) {
649 <<
"Start is target layer, nothing left to do.");
651 state.navigation.navigationBreak =
true;
652 stepper.releaseStepSize(state.stepping);
654 return startResolved;
659 if (state.navigation.navSurfaces.empty() or
660 state.navigation.navSurfaceIndex ==
661 state.navigation.navSurfaces.size()) {
663 <<
"No surfaces present, target at layer first.");
666 auto layerID = state.navigation.navSurface().object()->geometryId().layer();
667 std::pair<ExternalSurfaces::iterator, ExternalSurfaces::iterator>
668 externalSurfaceRange =
669 state.navigation.externalSurfaces.equal_range(layerID);
671 while (state.navigation.navSurfaceIndex !=
672 state.navigation.navSurfaces.size()) {
675 << (state.navigation.navSurfaces.size() -
676 state.navigation.navSurfaceIndex)
677 <<
" out of " << state.navigation.navSurfaces.size()
678 <<
" surfaces remain to try.");
680 auto surface = state.navigation.navSurface().object();
682 ACTS_VERBOSE(volInfo(state) <<
"Next surface candidate will be "
683 << surface->geometryId());
686 for (
auto it = externalSurfaceRange.first;
687 it != externalSurfaceRange.second;
it++) {
688 if (surface->geometryId() ==
it->second) {
689 boundaryCheck =
false;
693 auto surfaceStatus = stepper.updateSurfaceStatus(
694 state.stepping, *surface, state.options.direction, boundaryCheck,
695 state.options.targetTolerance,
logger());
696 if (surfaceStatus == Intersection3D::Status::reachable) {
698 <<
"Surface reachable, step size updated to "
699 << stepper.outputStepSize(state.stepping));
702 ++state.navigation.navSurfaceIndex;
707 if (state.navigation.navSurfaceIndex ==
708 state.navigation.navSurfaces.size()) {
710 state.navigation.navSurfaces.clear();
711 state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size();
713 if (state.navigation.navLayerIndex != state.navigation.navLayers.size()) {
715 <<
"Last surface on layer reached, switching layer.");
717 ++state.navigation.navLayerIndex;
720 <<
"Last surface on layer reached, and no layer.");
722 state.navigation.lastHierarchySurfaceReached =
true;
723 state.navigation.navigationBreak =
724 (state.navigation.currentVolume == state.navigation.targetVolume);
749 template <
typename propagator_state_t,
typename stepper_t>
750 bool targetLayers(propagator_state_t& state,
const stepper_t& stepper)
const {
751 using namespace UnitLiterals;
753 if (state.navigation.navigationBreak ||
754 state.navigation.lastHierarchySurfaceReached) {
759 if (state.navigation.navLayers.empty()) {
761 <<
"No layers present, resolve volume first.");
764 if (state.navigation.currentVolume->hasBoundingVolumeHierarchy()) {
767 navOpts.resolveSensitive =
m_cfg.resolveSensitive;
768 navOpts.resolveMaterial =
m_cfg.resolveMaterial;
769 navOpts.resolvePassive =
m_cfg.resolvePassive;
770 navOpts.endObject = state.navigation.targetSurface;
771 navOpts.overstepLimit = stepper.overstepLimit(state.stepping);
772 double opening_angle = 0;
804 auto protoNavSurfaces =
805 state.navigation.currentVolume->compatibleSurfacesFromHierarchy(
806 state.geoContext, stepper.position(state.stepping),
807 state.options.direction * stepper.direction(state.stepping),
808 opening_angle, navOpts);
809 if (!protoNavSurfaces.empty()) {
814 if ((state.navigation.currentSurface ==
nullptr &&
815 state.navigation.navSurfaces.empty()) ||
816 protoNavSurfaces.front().pathLength() > 1_um) {
819 state.navigation.navSurfaces.clear();
820 state.navigation.navSurfaces.insert(
821 state.navigation.navSurfaces.begin(), protoNavSurfaces.begin(),
822 protoNavSurfaces.end());
824 state.navigation.navSurfaceIndex = 0;
825 state.navigation.navLayers = {};
826 state.navigation.navLayerIndex = state.navigation.navLayers.size();
828 stepper.updateStepSize(state.stepping,
829 state.navigation.navSurface(),
830 state.options.direction,
true);
832 <<
"Navigation stepSize updated to "
833 << stepper.outputStepSize(state.stepping));
839 if (resolveLayers(state, stepper)) {
845 while (state.navigation.navLayerIndex !=
846 state.navigation.navLayers.size()) {
848 auto layerSurface = state.navigation.navLayer().representation();
850 if (state.navigation.currentSurface == layerSurface) {
851 ACTS_VERBOSE(volInfo(state) <<
"We are on a layer, resolve Surfaces.");
853 if (resolveSurfaces(state, stepper)) {
857 ++state.navigation.navLayerIndex;
862 auto layerStatus = stepper.updateSurfaceStatus(
863 state.stepping, *layerSurface, state.options.direction,
true,
864 state.options.targetTolerance,
logger());
865 if (layerStatus == Intersection3D::Status::reachable) {
866 ACTS_VERBOSE(volInfo(state) <<
"Layer reachable, step size updated to "
867 << stepper.outputStepSize(state.stepping));
871 <<
"Layer intersection not valid, skipping it.");
872 ++state.navigation.navLayerIndex;
877 if (state.navigation.currentVolume == state.navigation.targetVolume) {
878 initializeTarget(state, stepper);
882 std::ostringstream
os;
884 if (state.navigation.currentVolume == state.navigation.targetVolume) {
885 os <<
" (final volume) done, proceed to target.";
887 os <<
" done, target volume boundary.";
892 state.navigation.navigationBreak =
893 (state.navigation.currentVolume == state.navigation.targetVolume);
922 template <
typename propagator_state_t,
typename stepper_t>
923 bool targetBoundaries(propagator_state_t& state,
924 const stepper_t& stepper)
const {
925 if (state.navigation.navigationBreak) {
929 if (!state.navigation.currentVolume) {
931 <<
"No sufficient information to resolve boundary, "
932 "stopping navigation.");
933 stepper.releaseStepSize(state.stepping);
935 }
else if (state.navigation.currentVolume ==
936 state.navigation.targetVolume) {
938 <<
"In target volume: no need to resolve boundary, "
939 "stopping navigation.");
940 state.navigation.navigationBreak =
true;
941 stepper.releaseStepSize(state.stepping);
946 initializeTarget(state, stepper);
949 auto findBoundaries = [&]() ->
bool {
953 navOpts.startObject = state.navigation.currentSurface;
956 navOpts.overstepLimit = stepper.overstepLimit(state.stepping);
957 navOpts.forceIntersectBoundaries =
958 state.navigation.forceIntersectBoundaries;
961 <<
"Try to find boundaries, we are at: "
962 << stepper.position(state.stepping).transpose() <<
", dir: "
963 << stepper.direction(state.stepping).transpose());
966 state.navigation.navBoundaries =
967 state.navigation.currentVolume->compatibleBoundaries(
968 state.geoContext, stepper.position(state.stepping),
969 state.options.direction * stepper.direction(state.stepping),
973 std::ostringstream
os;
974 os << state.navigation.navBoundaries.size();
975 os <<
" boundary candidates found at path(s): ";
976 for (
auto& bc : state.navigation.navBoundaries) {
977 os << bc.pathLength() <<
" ";
982 state.navigation.navBoundaryIndex = 0;
983 if (not state.navigation.navBoundaries.empty()) {
985 stepper.updateStepSize(state.stepping, state.navigation.navBoundary(),
986 state.options.direction,
true);
987 ACTS_VERBOSE(volInfo(state) <<
"Navigation stepSize updated to "
988 << stepper.outputStepSize(state.stepping));
995 if (state.navigation.navBoundaries.empty() and findBoundaries()) {
1000 while (state.navigation.navBoundaryIndex !=
1001 state.navigation.navBoundaries.size()) {
1003 auto boundarySurface = state.navigation.navBoundary().representation();
1005 auto boundaryStatus = stepper.updateSurfaceStatus(
1006 state.stepping, *boundarySurface, state.options.direction,
true,
1007 state.options.targetTolerance,
logger());
1008 if (boundaryStatus == Intersection3D::Status::reachable) {
1010 <<
"Boundary reachable, step size updated to "
1011 << stepper.outputStepSize(state.stepping));
1015 << (state.navigation.navBoundaries.size() -
1016 state.navigation.navBoundaryIndex)
1017 <<
" out of " << state.navigation.navBoundaries.size()
1018 <<
" not reachable anymore, switching to next.");
1020 << std::tie(*boundarySurface, state.geoContext));
1023 ++state.navigation.navBoundaryIndex;
1026 state.navigation.navBoundaries.clear();
1027 ACTS_VERBOSE(volInfo(state) <<
"Boundary navigation lost, re-targetting.");
1028 state.navigation.forceIntersectBoundaries =
true;
1029 if (findBoundaries()) {
1031 state.navigation.forceIntersectBoundaries =
false;
1056 template <
typename propagator_state_t,
typename stepper_t>
1057 void initializeTarget(propagator_state_t& state,
1058 const stepper_t& stepper)
const {
1059 if (state.navigation.targetVolume and
1060 state.stepping.pathAccumulated == 0.) {
1062 <<
"Re-initialzing cancelled as it is the first step.");
1066 if (state.navigation.targetSurface &&
1067 state.navigation.targetSurface->associatedLayer() &&
1068 !state.navigation.targetVolume) {
1070 <<
"Fast target initialization through association.");
1072 <<
"Target surface set to "
1073 << state.navigation.targetSurface->geometryId());
1074 state.navigation.targetLayer =
1075 state.navigation.targetSurface->associatedLayer();
1076 state.navigation.targetVolume =
1077 state.navigation.targetLayer->trackingVolume();
1078 }
else if (state.navigation.targetSurface) {
1080 if (state.navigation.targetVolume) {
1082 <<
"Re-initialization of target volume triggered.");
1086 auto targetIntersection =
1087 state.navigation.targetSurface
1089 state.geoContext, stepper.position(state.stepping),
1090 state.options.direction * stepper.direction(state.stepping),
1091 false, state.options.targetTolerance)
1093 if (targetIntersection) {
1095 <<
"Target estimate position ("
1096 << targetIntersection.position().x() <<
", "
1097 << targetIntersection.position().y() <<
", "
1098 << targetIntersection.position().z() <<
")");
1100 auto tPosition = targetIntersection.position();
1101 state.navigation.targetVolume =
1102 m_cfg.trackingGeometry->lowestTrackingVolume(state.geoContext,
1104 state.navigation.targetLayer =
1105 state.navigation.targetVolume
1106 ? state.navigation.targetVolume->associatedLayer(
1107 state.geoContext, tPosition)
1109 if (state.navigation.targetVolume) {
1111 <<
"Target volume estimated : "
1112 << state.navigation.targetVolume->volumeName());
1128 template <
typename propagator_state_t,
typename stepper_t>
1129 bool resolveSurfaces(propagator_state_t& state,
const stepper_t& stepper,
1130 const Layer* cLayer =
nullptr)
const {
1132 auto layerSurface = cLayer ? state.navigation.startSurface
1133 : state.navigation.navLayer().representation();
1134 auto navLayer = cLayer ? cLayer : state.navigation.navLayer().object();
1136 bool onStart = (navLayer == state.navigation.startLayer);
1137 auto startSurface = onStart ? state.navigation.startSurface : layerSurface;
1140 navOpts.resolveSensitive =
m_cfg.resolveSensitive;
1141 navOpts.resolveMaterial =
m_cfg.resolveMaterial;
1142 navOpts.resolvePassive =
m_cfg.resolvePassive;
1143 navOpts.startObject = startSurface;
1144 navOpts.endObject = state.navigation.targetSurface;
1146 std::vector<GeometryIdentifier> externalSurfaces;
1147 if (!state.navigation.externalSurfaces.empty()) {
1148 auto layerID = layerSurface->geometryId().layer();
1149 auto externalSurfaceRange =
1150 state.navigation.externalSurfaces.equal_range(layerID);
1151 navOpts.externalSurfaces.reserve(
1152 state.navigation.externalSurfaces.count(layerID));
1153 for (
auto itSurface = externalSurfaceRange.first;
1154 itSurface != externalSurfaceRange.second; itSurface++) {
1155 navOpts.externalSurfaces.push_back(itSurface->second);
1162 navOpts.overstepLimit = (cLayer !=
nullptr)
1163 ? state.options.targetTolerance
1164 : stepper.overstepLimit(state.stepping);
1167 state.navigation.navSurfaces = navLayer->compatibleSurfaces(
1168 state.geoContext, stepper.position(state.stepping),
1169 state.options.direction * stepper.direction(state.stepping), navOpts);
1171 if (!state.navigation.navSurfaces.empty()) {
1173 std::ostringstream
os;
1174 os << state.navigation.navSurfaces.size();
1175 os <<
" surface candidates found at path(s): ";
1176 for (
auto& sfc : state.navigation.navSurfaces) {
1177 os << sfc.pathLength() <<
" ";
1183 state.navigation.navSurfaceIndex = 0;
1185 stepper.updateStepSize(state.stepping, state.navigation.navSurface(),
1186 state.options.direction,
true);
1187 ACTS_VERBOSE(volInfo(state) <<
"Navigation stepSize updated to "
1188 << stepper.outputStepSize(state.stepping));
1191 state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size();
1192 ACTS_VERBOSE(volInfo(state) <<
"No surface candidates found.");
1210 template <
typename propagator_state_t,
typename stepper_t>
1211 bool resolveLayers(propagator_state_t& state,
1212 const stepper_t& stepper)
const {
1213 ACTS_VERBOSE(volInfo(state) <<
"Searching for compatible layers.");
1217 (state.navigation.currentVolume == state.navigation.startVolume)
1218 ? state.navigation.startLayer
1223 navOpts.boundaryCheck =
m_cfg.boundaryCheckLayerResolving;
1224 navOpts.resolveSensitive =
m_cfg.resolveSensitive;
1225 navOpts.resolveMaterial =
m_cfg.resolveMaterial;
1226 navOpts.resolvePassive =
m_cfg.resolvePassive;
1227 navOpts.startObject = startLayer;
1229 navOpts.targetSurface = state.navigation.targetSurface;
1232 navOpts.overstepLimit = stepper.overstepLimit(state.stepping);
1234 state.navigation.navLayers =
1235 state.navigation.currentVolume->compatibleLayers(
1236 state.geoContext, stepper.position(state.stepping),
1237 state.options.direction * stepper.direction(state.stepping),
1241 if (!state.navigation.navLayers.empty()) {
1244 std::ostringstream
os;
1245 os << state.navigation.navLayers.size();
1246 os <<
" layer candidates found at path(s): ";
1247 for (
auto& lc : state.navigation.navLayers) {
1248 os << lc.pathLength() <<
" ";
1253 state.navigation.navLayerIndex = 0;
1255 if (state.navigation.startLayer &&
1256 state.navigation.navLayer().object() != state.navigation.startLayer) {
1259 stepper.updateStepSize(state.stepping, state.navigation.navLayer(),
1260 state.options.direction,
true);
1261 ACTS_VERBOSE(volInfo(state) <<
"Navigation stepSize updated to "
1262 << stepper.outputStepSize(state.stepping));
1268 state.navigation.navLayerIndex = state.navigation.navLayers.size();
1271 ACTS_VERBOSE(volInfo(state) <<
"No compatible layer candidates found.");
1273 stepper.releaseStepSize(state.stepping);
1289 template <
typename propagator_state_t,
typename stepper_t>
1290 bool inactive(propagator_state_t& state,
const stepper_t& stepper)
const {
1292 if (!
m_cfg.trackingGeometry) {
1296 if (!
m_cfg.resolveSensitive && !
m_cfg.resolveMaterial &&
1297 !
m_cfg.resolvePassive) {
1306 if (state.navigation.navigationBreak) {
1308 if (state.navigation.targetReached || !state.navigation.targetSurface) {
1311 auto targetStatus = stepper.updateSurfaceStatus(
1312 state.stepping, *state.navigation.targetSurface,
1313 state.options.direction,
true, state.options.targetTolerance,
1316 if (targetStatus == Intersection3D::Status::onSurface) {
1318 state.navigation.currentSurface = state.navigation.targetSurface;
1321 <<
"Current surface set to target surface "
1322 << state.navigation.currentSurface->geometryId());
1330 template <
typename propagator_state_t>
1331 std::string volInfo(
const propagator_state_t& state)
const {
1332 return (state.navigation.currentVolume
1333 ? state.navigation.currentVolume->volumeName()