ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StandardAborters.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file StandardAborters.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 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 <limits>
12 #include <sstream>
13 #include <string>
19 
20 namespace Acts {
21 
23 struct TargetOptions {
26 
29 
31  const Surface* startObject = nullptr;
32 
35 
38 };
39 
49 template <typename propagator_state_t>
50 void targetDebugLog(propagator_state_t& state, const std::string& status,
51  const std::function<std::string()>& logAction) {
52  if (state.options.debug) {
53  std::stringstream dstream;
54  dstream << " " << status << " ";
55  dstream << std::setw(state.options.debugPfxWidth);
56  dstream << " Target "
57  << " | ";
58  dstream << std::setw(state.options.debugMsgWidth);
59  dstream << logAction() << '\n';
60  state.options.debugString += dstream.str();
61  }
62 }
63 
68 
75  template <typename propagator_state_t, typename stepper_t>
76  bool operator()(propagator_state_t& state,
77  const stepper_t& /*unused*/) const {
78  if (state.navigation.targetReached) {
79  return true;
80  }
81  // Check if the maximum allowed step size has to be updated
82  double distance = state.stepping.navDir * std::abs(internalLimit) -
83  state.stepping.pathAccumulated;
84  double tolerance = state.options.targetTolerance;
85  state.stepping.stepSize.update(distance, ConstrainedStep::aborter);
86  bool limitReached = (distance * distance < tolerance * tolerance);
87  if (limitReached) {
88  targetDebugLog(state, "x", [&] {
89  std::stringstream dstream;
90  dstream << "Path limit reached at distance " << distance;
91  return dstream.str();
92  });
93  // reaching the target means navigation break
94  state.navigation.targetReached = true;
95  } else {
96  targetDebugLog(state, "o", [&] {
97  std::stringstream dstream;
98  dstream << "Target stepSize (path limit) updated to ";
99  dstream << state.stepping.stepSize.toString();
100  return dstream.str();
101  });
102  }
103  // path limit check
104  return limitReached;
105  }
106 };
107 
111  SurfaceReached() = default;
112 
120  template <typename propagator_state_t, typename stepper_t>
121  bool operator()(propagator_state_t& state, const stepper_t& stepper) const {
122  return (*this)(state, stepper, *state.navigation.targetSurface);
123  }
124 
133  template <typename propagator_state_t, typename stepper_t>
134  bool operator()(propagator_state_t& state, const stepper_t& stepper,
135  const Surface& targetSurface) const {
136  if (state.navigation.targetReached) {
137  return true;
138  }
139  // Check if the cache filled the currentSurface - or if we are on the
140  // surface
141  // @todo - do not apply the isOnSurface check here, but handle by the
142  // intersectionEstimate
143  if ((state.navigation.currentSurface &&
144  state.navigation.currentSurface == &targetSurface)) {
145  targetDebugLog(state, "x", [&] {
146  std::string ds("Target surface reached.");
147  return ds;
148  });
149  // reaching the target calls a navigation break
150  state.navigation.targetReached = true;
151  return true;
152  }
153  // Calculate the distance to the surface
154  const double tolerance = state.options.targetTolerance;
155  const auto sIntersection = targetSurface.intersect(
156  state.geoContext, stepper.position(state.stepping),
157  state.stepping.navDir * stepper.direction(state.stepping), true);
158 
159  // The target is reached
160  bool targetReached =
161  (sIntersection.intersection.status == Intersection::Status::onSurface);
162  double distance = sIntersection.intersection.pathLength;
163 
164  // Return true if you fall below tolerance
165  if (targetReached) {
166  targetDebugLog(state, "x", [&] {
167  std::stringstream dstream;
168  dstream << "Target surface reached at distance (tolerance) ";
169  dstream << distance << " (" << tolerance << ")";
170  return dstream.str();
171  });
172  // assigning the currentSurface
173  state.navigation.currentSurface = &targetSurface;
174  targetDebugLog(state, "x", [&] {
175  std::stringstream dstream;
176  dstream << "Current surface set to target surface ";
177  dstream << state.navigation.currentSurface->geoID();
178  return dstream.str();
179  });
180  // reaching the target calls a navigation break
181  state.navigation.targetReached = true;
182  } else {
183  // Target is not reached, update the step size
184  const double overstepLimit = stepper.overstepLimit(state.stepping);
185  // Check the alternative solution
186  if (distance < overstepLimit and sIntersection.alternative) {
187  // Update the distance to the alternative solution
188  distance = sIntersection.alternative.pathLength;
189  }
190  state.stepping.stepSize.update(state.stepping.navDir * distance,
192  targetDebugLog(state, "o", [&] {
193  std::stringstream dstream;
194  dstream << "Target stepSize (surface) updated to ";
195  dstream << state.stepping.stepSize.toString();
196  return dstream.str();
197  });
198  }
199  // path limit check
200  return targetReached;
201  }
202 };
203 
207  EndOfWorldReached() = default;
208 
214  template <typename propagator_state_t, typename stepper_t>
215  bool operator()(propagator_state_t& state,
216  const stepper_t& /*unused*/) const {
217  if (state.navigation.currentVolume != nullptr) {
218  return false;
219  }
220  state.navigation.targetReached = true;
221  return true;
222  }
223 };
224 
225 } // namespace Acts