ECCE @ 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 
11 #include <boost/algorithm/string.hpp>
12 #include <iomanip>
13 #include <iterator>
14 #include <sstream>
15 #include <string>
17 #include "Acts/Geometry/Layer.hpp"
23 
24 namespace Acts {
25 
34  public:
36  using SurfaceSequence = std::vector<const Surface*>;
37  using SurfaceIter = std::vector<const Surface*>::iterator;
38 
40  DirectNavigator() = default;
41 
44 
49  struct Initializer {
52 
54  struct this_result {
55  bool initialized = false;
56  };
58 
60  Initializer() = default;
61 
68  template <typename propagator_state_t, typename stepper_t>
69  void operator()(propagator_state_t& state, const stepper_t& /*unused*/,
70  result_type& r) const {
71  // Only act once
72  if (not r.initialized) {
73  // Initialize the surface sequence
74  state.navigation.surfaceSequence = surfaceSequence;
75  state.navigation.nextSurfaceIter =
76  state.navigation.surfaceSequence.begin();
77  r.initialized = true;
78  }
79  }
80 
82  template <typename propagator_state_t, typename stepper_t>
83  void operator()(propagator_state_t& /*unused*/,
84  const stepper_t& /*unused*/) const {}
85  };
86 
92  struct State {
96 
99 
101  const Surface* startSurface = nullptr;
103  const Surface* currentSurface = nullptr;
105  const Surface* targetSurface = nullptr;
107  const TrackingVolume* startVolume = nullptr;
109  const TrackingVolume* currentVolume = nullptr;
111  const TrackingVolume* targetVolume = nullptr;
112 
114  bool targetReached = false;
116  bool navigationBreak = false;
117  };
118 
126  template <typename propagator_state_t, typename stepper_t>
127  void status(propagator_state_t& state, const stepper_t& stepper) const {
128  // Screen output
129  debugLog(state, [&] { return std::string("Entering navigator::status."); });
130 
131  // Navigator status always resets the current surface
132  state.navigation.currentSurface = nullptr;
133  // Output the position in the sequence
134  debugLog(state, [&] {
135  std::stringstream dstream;
136  dstream << std::distance(state.navigation.nextSurfaceIter,
137  state.navigation.surfaceSequence.end());
138  dstream << " out of " << state.navigation.surfaceSequence.size();
139  dstream << " surfaces remain to try.";
140  return dstream.str();
141  });
142  // Check if we are on surface
143  if (state.navigation.nextSurfaceIter !=
144  state.navigation.surfaceSequence.end()) {
145  // Establish the surface status
146  auto surfaceStatus = stepper.updateSurfaceStatus(
147  state.stepping, **state.navigation.nextSurfaceIter, false);
148  if (surfaceStatus == Intersection::Status::onSurface) {
149  // Set the current surface
150  state.navigation.currentSurface = *state.navigation.nextSurfaceIter;
151  debugLog(state, [&] {
152  std::stringstream dstream;
153  dstream << "Current surface set to "
154  << state.navigation.currentSurface->geoID();
155  return dstream.str();
156  });
157  // Move the sequence to the next surface
158  ++state.navigation.nextSurfaceIter;
159  if (state.navigation.nextSurfaceIter !=
160  state.navigation.surfaceSequence.end()) {
161  debugLog(state, [&] {
162  std::stringstream dstream;
163  dstream << "Next surface candidate is "
164  << (*state.navigation.nextSurfaceIter)->geoID();
165  return dstream.str();
166  });
167  stepper.releaseStepSize(state.stepping);
168  }
169  } else if (surfaceStatus == Intersection::Status::reachable) {
170  debugLog(state, [&] {
171  std::stringstream dstream;
172  dstream << "Next surface reachable at distance "
173  << stepper.outputStepSize(state.stepping);
174  return dstream.str();
175  });
176  }
177  }
178  }
179 
187  template <typename propagator_state_t, typename stepper_t>
188  void target(propagator_state_t& state, const stepper_t& stepper) const {
189  // Screen output
190  debugLog(state, [&] { return std::string("Entering navigator::target."); });
191 
192  // Navigator target always resets the current surface
193  state.navigation.currentSurface = nullptr;
194  // Output the position in the sequence
195  debugLog(state, [&] {
196  std::stringstream dstream;
197  dstream << std::distance(state.navigation.nextSurfaceIter,
198  state.navigation.surfaceSequence.end());
199  dstream << " out of " << state.navigation.surfaceSequence.size();
200  dstream << " surfaces remain to try.";
201  return dstream.str();
202  });
203  if (state.navigation.nextSurfaceIter !=
204  state.navigation.surfaceSequence.end()) {
205  // Establish & update the surface status
206  auto surfaceStatus = stepper.updateSurfaceStatus(
207  state.stepping, **state.navigation.nextSurfaceIter, false);
208  if (surfaceStatus == Intersection::Status::unreachable) {
209  debugLog(state, [&] {
210  std::stringstream dstream;
211  dstream << "Surface not reachable anymore, switching to next one in "
212  "sequence";
213  return dstream.str();
214  });
215  // Move the sequence to the next surface
216  ++state.navigation.nextSurfaceIter;
217  } else {
218  debugLog(state, [&] {
219  std::stringstream dstream;
220  dstream << "Navigation stepSize set to ";
221  dstream << stepper.outputStepSize(state.stepping);
222  return dstream.str();
223  });
224  }
225  } else {
226  // Set the navigation break
227  state.navigation.navigationBreak = true;
228  // If no externally provided target is given, the target is reached
229  if (state.navigation.targetSurface == nullptr) {
230  state.navigation.targetReached = true;
231  // Announce it then
232  debugLog(state,
233  [&] { return std::string("No target Surface, job done."); });
234  }
235  }
236  }
237 
238  private:
251  template <typename propagator_state_t>
252  void debugLog(propagator_state_t& state,
253  const std::function<std::string()>& logAction) const {
254  if (state.options.debug) {
255  std::string vName = "Direct Navigator";
256  std::vector<std::string> lines;
257  std::string input = logAction();
258  boost::split(lines, input, boost::is_any_of("\n"));
259  for (const auto& line : lines) {
260  std::stringstream dstream;
261  dstream << ">>>" << std::setw(state.options.debugPfxWidth) << vName
262  << " | ";
263  dstream << std::setw(state.options.debugMsgWidth) << line << '\n';
264  state.options.debugString += dstream.str();
265  }
266  }
267  }
268 };
269 
270 } // namespace Acts