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 
17 
18 #include <limits>
19 #include <sstream>
20 #include <string>
21 
22 namespace Acts {
23 
25 struct TargetOptions {
28 
31 
33  const Surface* startObject = nullptr;
34 
37 
40 };
41 
46 
53  template <typename propagator_state_t, typename stepper_t>
54  bool operator()(propagator_state_t& state,
55  const stepper_t& /*unused*/) const {
56  const auto& logger = state.options.logger;
57  if (state.navigation.targetReached) {
58  return true;
59  }
60  // Check if the maximum allowed step size has to be updated
61  double distance = state.stepping.navDir * std::abs(internalLimit) -
62  state.stepping.pathAccumulated;
63  double tolerance = state.options.targetTolerance;
64  state.stepping.stepSize.update(distance, ConstrainedStep::aborter);
65  bool limitReached = (distance * distance < tolerance * tolerance);
66  if (limitReached) {
67  ACTS_VERBOSE("Target: x | "
68  << "Path limit reached at distance " << distance);
69  // reaching the target means navigation break
70  state.navigation.targetReached = true;
71  } else {
72  ACTS_VERBOSE("Target: 0 | "
73  << "Target stepSize (path limit) updated to "
74  << state.stepping.stepSize.toString());
75  }
76  // path limit check
77  return limitReached;
78  }
79 };
80 
84  SurfaceReached() = default;
85 
93  template <typename propagator_state_t, typename stepper_t>
94  bool operator()(propagator_state_t& state, const stepper_t& stepper) const {
95  return (*this)(state, stepper, *state.navigation.targetSurface);
96  }
97 
106  template <typename propagator_state_t, typename stepper_t>
107  bool operator()(propagator_state_t& state, const stepper_t& stepper,
108  const Surface& targetSurface) const {
109  const auto& logger = state.options.logger;
110  if (state.navigation.targetReached) {
111  return true;
112  }
113  // Check if the cache filled the currentSurface - or if we are on the
114  // surface
115  if ((state.navigation.currentSurface &&
116  state.navigation.currentSurface == &targetSurface)) {
117  ACTS_VERBOSE("Target: x | "
118  << "Target surface reached.");
119  // reaching the target calls a navigation break
120  state.navigation.targetReached = true;
121  return true;
122  }
123  // Calculate the distance to the surface
124  const double tolerance = state.options.targetTolerance;
125  const auto sIntersection = targetSurface.intersect(
126  state.geoContext, stepper.position(state.stepping),
127  state.stepping.navDir * stepper.direction(state.stepping), true);
128 
129  // The target is reached
130  bool targetReached = (sIntersection.intersection.status ==
131  Intersection3D::Status::onSurface);
132  double distance = sIntersection.intersection.pathLength;
133 
134  // Return true if you fall below tolerance
135  if (targetReached) {
136  ACTS_VERBOSE("Target: x | "
137  << "Target surface reached at distance (tolerance) "
138  << distance << " (" << tolerance << ")");
139  // assigning the currentSurface
140  state.navigation.currentSurface = &targetSurface;
141  ACTS_VERBOSE("Target: x | "
142  << "Current surface set to target surface "
143  << state.navigation.currentSurface->geometryId());
144 
145  // reaching the target calls a navigation break
146  state.navigation.targetReached = true;
147  } else {
148  // Target is not reached, update the step size
149  const double overstepLimit = stepper.overstepLimit(state.stepping);
150  // Check the alternative solution
151  if (distance < overstepLimit and sIntersection.alternative) {
152  // Update the distance to the alternative solution
153  distance = sIntersection.alternative.pathLength;
154  }
155  state.stepping.stepSize.update(state.stepping.navDir * distance,
157  ACTS_VERBOSE("Target: 0 | "
158  << "Target stepSize (surface) updated to "
159  << state.stepping.stepSize.toString());
160  }
161  // path limit check
162  return targetReached;
163  }
164 };
165 
169  EndOfWorldReached() = default;
170 
176  template <typename propagator_state_t, typename stepper_t>
177  bool operator()(propagator_state_t& state,
178  const stepper_t& /*unused*/) const {
179  if (state.navigation.currentVolume != nullptr) {
180  return false;
181  }
182  state.navigation.targetReached = true;
183  return true;
184  }
185 };
186 
187 } // namespace Acts