28 #include <boost/algorithm/string.hpp>
29 #include <boost/container/small_vector.hpp>
32 namespace Experimental {
72 std::shared_ptr<const Logger> _logger =
77 State makeState(
const Surface* startSurface,
78 const Surface* targetSurface)
const {
80 result.startSurface = startSurface;
81 result.targetSurface = targetSurface;
95 const Surface* currentSurface(
const State&
state)
const {
96 return state.currentSurface;
99 const TrackingVolume* currentVolume(
const State& )
const {
103 const IVolumeMaterial* currentVolumeMaterial(
const State&
state)
const {
104 return state.currentVolume->volumeMaterial();
107 const Surface* startSurface(
const State& state)
const {
108 return state.startSurface;
111 const Surface* targetSurface(
const State& state)
const {
112 return state.targetSurface;
115 bool targetReached(
const State& state)
const {
return state.targetReached; }
117 bool endOfWorldReached(State& state)
const {
118 return state.currentVolume ==
nullptr;
121 bool navigationBreak(
const State& state)
const {
122 return state.navigationBreak;
126 state.currentSurface =
surface;
129 void targetReached(State& state,
bool targetReached)
const {
130 state.targetReached = targetReached;
133 void navigationBreak(State& state,
bool navigationBreak)
const {
134 state.navigationBreak = navigationBreak;
137 void insertExternalSurface(State& ,
138 GeometryIdentifier )
const {
151 template <
typename propagator_state_t,
typename stepper_t>
155 auto&
nState = state.navigation;
178 template <
typename propagator_state_t,
typename stepper_t>
179 void preStep(propagator_state_t& state,
const stepper_t& stepper)
const {
181 <<
posInfo(state, stepper) <<
"Entering navigator::preStep.");
183 auto&
nState = state.navigation;
188 <<
posInfo(state, stepper) <<
"navigator inactive");
198 <<
posInfo(state, stepper) <<
"stepping through surface");
201 <<
posInfo(state, stepper) <<
"stepping through portal");
219 <<
" surfaces remain to try.");
223 (c.surface !=
nullptr) ? (*c.surface) : (c.portal->surface());
226 <<
"next surface candidate will be "
230 auto surfaceStatus = stepper.updateSurfaceStatus(
231 state.stepping,
surface, state.options.direction, boundaryCheck,
232 state.options.targetTolerance,
logger());
233 if (surfaceStatus == Intersection3D::Status::reachable) {
236 <<
"surface reachable, step size updated to "
237 << stepper.outputStepSize(state.stepping));
253 template <
typename propagator_state_t,
typename stepper_t>
254 void postStep(propagator_state_t& state,
const stepper_t& stepper)
const {
256 <<
posInfo(state, stepper) <<
"Entering navigator::postStep.");
258 auto&
nState = state.navigation;
263 <<
posInfo(state, stepper) <<
"navigator inactive");
275 <<
"no surface candidates - waiting for target call");
279 const Portal* nextPortal =
nullptr;
280 const Surface* nextSurface =
nullptr;
281 bool isPortal =
false;
288 nextSurface = &nextPortal->surface();
293 <<
"panic: not a surface not a portal - what is it?");
298 auto surfaceStatus = stepper.updateSurfaceStatus(
299 state.stepping, *nextSurface, state.options.direction, boundaryCheck,
300 state.options.targetTolerance,
logger());
303 if (surfaceStatus == Intersection3D::Status::onSurface) {
305 <<
posInfo(state, stepper) <<
"landed on surface");
309 <<
"this is a portal, storing it.");
314 <<
posInfo(state, stepper) <<
"current portal set to "
318 <<
"this is a surface, storing it.");
324 <<
posInfo(state, stepper) <<
"current surface set to "
336 template <
typename propagator_state_t>
338 auto&
nState = state.navigation;
344 template <
typename propagator_state_t,
typename stepper_t>
346 const stepper_t& stepper)
const {
347 std::stringstream ss;
348 ss << stepper.position(state.stepping).transpose();
360 if (
m_cfg.detector ==
nullptr) {
364 if (!
m_cfg.resolveSensitive && !
m_cfg.resolveMaterial &&
365 !
m_cfg.resolvePassive) {
389 template <
typename propagator_state_t,
typename stepper_t>
391 const stepper_t& stepper)
const {
393 <<
posInfo(state, stepper) <<
"initialize target");
395 auto&
nState = state.navigation;
403 <<
posInfo(state, stepper) <<
"switched detector volume");
409 <<
posInfo(state, stepper) <<
"panic: no current volume");
417 std::sort(nCandidates.begin(), nCandidates.end(),
418 [&](
const auto&
a,
const auto&
b) {
420 ActsScalar pathToA =
a.objectIntersection.pathLength();
421 ActsScalar pathToB =
b.objectIntersection.pathLength();
422 return pathToA < pathToB;
428 template <
typename propagator_state_t,
typename stepper_t>
431 nState.
position = stepper.position(state.stepping);
432 nState.
direction = stepper.direction(state.stepping);
433 nState.
absMomentum = stepper.absoluteMomentum(state.stepping);
434 auto fieldResult = stepper.getField(state.stepping, nState.
position);
435 if (!fieldResult.ok()) {
437 <<
"could not read from the magnetic field");