EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DirectNavigator.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DirectNavigator.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
12 #include "Acts/Geometry/Layer.hpp"
18 
19 #include <iomanip>
20 #include <iterator>
21 #include <sstream>
22 #include <string>
23 
24 #include <boost/algorithm/string.hpp>
25 
26 namespace Acts {
27 
36  public:
38  using SurfaceSequence = std::vector<const Surface*>;
39  using SurfaceIter = std::vector<const Surface*>::iterator;
40 
42  DirectNavigator() = default;
43 
46 
51  struct Initializer {
54 
56  struct this_result {
57  bool initialized = false;
58  };
60 
62  Initializer() = default;
63 
70  template <typename propagator_state_t, typename stepper_t>
71  void operator()(propagator_state_t& state, const stepper_t& /*unused*/,
72  result_type& r) const {
73  // Only act once
74  if (not r.initialized) {
75  // Initialize the surface sequence
76  state.navigation.navSurfaces = navSurfaces;
77  state.navigation.navSurfaceIter =
78  state.navigation.navSurfaces.begin();
79  r.initialized = true;
80  }
81  }
82 
84  template <typename propagator_state_t, typename stepper_t>
85  void operator()(propagator_state_t& /*unused*/,
86  const stepper_t& /*unused*/) const {}
87  };
88 
94  struct State {
98 
101 
103  const Surface* startSurface = nullptr;
105  const Surface* currentSurface = nullptr;
107  const Surface* targetSurface = nullptr;
109  const Layer* startLayer = nullptr;
111  const Layer* targetLayer = nullptr;
113  const TrackingVolume* startVolume = nullptr;
115  const TrackingVolume* currentVolume = nullptr;
117  const TrackingVolume* targetVolume = nullptr;
118 
120  bool targetReached = false;
122  bool navigationBreak = false;
123  };
124 
132  template <typename propagator_state_t, typename stepper_t>
133  void status(propagator_state_t& state, const stepper_t& stepper) const {
134  const auto& logger = state.options.logger;
135  // Screen output
136  ACTS_VERBOSE("Entering navigator::status.");
137 
138  // Navigator status always resets the current surface
139  state.navigation.currentSurface = nullptr;
140  // Output the position in the sequence
141  ACTS_VERBOSE(std::distance(state.navigation.navSurfaceIter,
142  state.navigation.navSurfaces.end())
143  << " out of " << state.navigation.navSurfaces.size()
144  << " surfaces remain to try.");
145 
146  // Check if we are on surface
147  if (state.navigation.navSurfaceIter !=
148  state.navigation.navSurfaces.end()) {
149  // Establish the surface status
150  auto surfaceStatus = stepper.updateSurfaceStatus(
151  state.stepping, **state.navigation.navSurfaceIter, false);
152  if (surfaceStatus == Intersection3D::Status::onSurface) {
153  // Set the current surface
154  state.navigation.currentSurface = *state.navigation.navSurfaceIter;
155  ACTS_VERBOSE("Current surface set to "
156  << state.navigation.currentSurface->geometryId())
157  // Move the sequence to the next surface
158  ++state.navigation.navSurfaceIter;
159  if (state.navigation.navSurfaceIter !=
160  state.navigation.navSurfaces.end()) {
161  ACTS_VERBOSE("Next surface candidate is "
162  << (*state.navigation.navSurfaceIter)->geometryId());
163  stepper.releaseStepSize(state.stepping);
164  }
165  } else if (surfaceStatus == Intersection3D::Status::reachable) {
166  ACTS_VERBOSE("Next surface reachable at distance "
167  << stepper.outputStepSize(state.stepping));
168  }
169  }
170  }
171 
179  template <typename propagator_state_t, typename stepper_t>
180  void target(propagator_state_t& state, const stepper_t& stepper) const {
181  const auto& logger = state.options.logger;
182  // Screen output
183  ACTS_VERBOSE("Entering navigator::target.");
184 
185  // Navigator target always resets the current surface
186  state.navigation.currentSurface = nullptr;
187  // Output the position in the sequence
188  ACTS_VERBOSE(std::distance(state.navigation.navSurfaceIter,
189  state.navigation.navSurfaces.end())
190  << " out of " << state.navigation.navSurfaces.size()
191  << " surfaces remain to try.");
192 
193  if (state.navigation.navSurfaceIter !=
194  state.navigation.navSurfaces.end()) {
195  // Establish & update the surface status
196  auto surfaceStatus = stepper.updateSurfaceStatus(
197  state.stepping, **state.navigation.navSurfaceIter, false);
198  if (surfaceStatus == Intersection3D::Status::unreachable) {
199  ACTS_VERBOSE(
200  "Surface not reachable anymore, switching to next one in "
201  "sequence");
202  // Move the sequence to the next surface
203  ++state.navigation.navSurfaceIter;
204  } else {
205  ACTS_VERBOSE("Navigation stepSize set to "
206  << stepper.outputStepSize(state.stepping));
207  }
208  } else {
209  // Set the navigation break
210  state.navigation.navigationBreak = true;
211  // If no externally provided target is given, the target is reached
212  if (state.navigation.targetSurface == nullptr) {
213  state.navigation.targetReached = true;
214  // Announce it then
215  ACTS_VERBOSE("No target Surface, job done.");
216  }
217  }
218  }
219 };
220 
221 } // namespace Acts