Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:46

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2017-2023 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Propagator/ConstrainedStep.hpp"
0015 #include "Acts/Surfaces/BoundaryCheck.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Intersection.hpp"
0018 #include "Acts/Utilities/Logger.hpp"
0019 
0020 #include <limits>
0021 #include <optional>
0022 #include <sstream>
0023 #include <string>
0024 
0025 namespace Acts {
0026 
0027 /// This is the condition that the pathLimit has been reached
0028 struct PathLimitReached {
0029   /// Boolean switch for Loop protection
0030   double internalLimit = std::numeric_limits<double>::max();
0031 
0032   /// boolean operator for abort condition without using the result
0033   ///
0034   /// @tparam propagator_state_t Type of the propagator state
0035   /// @tparam stepper_t Type of the stepper
0036   /// @tparam navigator_t Type of the navigator
0037   ///
0038   /// @param [in,out] state The propagation state object
0039   /// @param [in] stepper Stepper used for propagation
0040   /// @param [in] navigator Navigator used for propagation
0041   /// @param logger a logger instance
0042   template <typename propagator_state_t, typename stepper_t,
0043             typename navigator_t>
0044   bool operator()(propagator_state_t& state, const stepper_t& stepper,
0045                   const navigator_t& navigator, const Logger& logger) const {
0046     (void)navigator;
0047 
0048     // Check if the maximum allowed step size has to be updated
0049     double distance =
0050         std::abs(internalLimit) - std::abs(state.stepping.pathAccumulated);
0051     double tolerance = state.options.surfaceTolerance;
0052     bool limitReached = (std::abs(distance) < std::abs(tolerance));
0053     if (limitReached) {
0054       ACTS_VERBOSE("PathLimit aborter | "
0055                    << "Path limit reached at distance " << distance);
0056       return true;
0057     }
0058     stepper.updateStepSize(state.stepping, distance, ConstrainedStep::aborter,
0059                            false);
0060     ACTS_VERBOSE("PathLimit aborter | "
0061                  << "Target stepSize (path limit) updated to "
0062                  << stepper.outputStepSize(state.stepping));
0063     return false;
0064   }
0065 };
0066 
0067 /// This is the condition that the Surface has been reached it then triggers a
0068 /// propagation abort
0069 struct SurfaceReached {
0070   const Surface* surface = nullptr;
0071   BoundaryCheck boundaryCheck = BoundaryCheck(true);
0072 
0073   // TODO https://github.com/acts-project/acts/issues/2738
0074   /// Distance limit to discard intersections "behind us"
0075   /// @note this is only necessary because some surfaces have more than one
0076   ///       intersection
0077   double nearLimit = -100 * UnitConstants::um;
0078 
0079   SurfaceReached() = default;
0080   SurfaceReached(double nLimit) : nearLimit(nLimit) {}
0081 
0082   /// boolean operator for abort condition without using the result
0083   ///
0084   /// @tparam propagator_state_t Type of the propagator state
0085   /// @tparam stepper_t Type of the stepper
0086   /// @tparam navigator_t Type of the navigator
0087   ///
0088   /// @param [in,out] state The propagation state object
0089   /// @param [in] stepper Stepper used for propagation
0090   /// @param [in] navigator Navigator used for propagation
0091   /// @param logger a logger instance
0092   template <typename propagator_state_t, typename stepper_t,
0093             typename navigator_t>
0094   bool operator()(propagator_state_t& state, const stepper_t& stepper,
0095                   const navigator_t& navigator, const Logger& logger) const {
0096     if (surface == nullptr) {
0097       ACTS_VERBOSE("SurfaceReached aborter | Target surface not set.");
0098       return false;
0099     }
0100 
0101     if (navigator.currentSurface(state.navigation) == surface) {
0102       ACTS_VERBOSE("SurfaceReached aborter | Target surface reached.");
0103       return true;
0104     }
0105 
0106     // not using the stepper overstep limit here because it does not always work
0107     // for perigee surfaces
0108     // note: the near limit is necessary for surfaces with more than one
0109     // intersection in order to discard the ones which are behind us
0110     const double farLimit = std::numeric_limits<double>::max();
0111     const double tolerance = state.options.surfaceTolerance;
0112 
0113     const auto sIntersection = surface->intersect(
0114         state.geoContext, stepper.position(state.stepping),
0115         state.options.direction * stepper.direction(state.stepping),
0116         boundaryCheck, tolerance);
0117     const auto closest = sIntersection.closest();
0118 
0119     bool reached = false;
0120 
0121     if (closest.status() == Intersection3D::Status::onSurface) {
0122       const double distance = closest.pathLength();
0123       ACTS_VERBOSE(
0124           "SurfaceReached aborter | "
0125           "Target surface reached at distance (tolerance) "
0126           << distance << " (" << tolerance << ")");
0127       reached = true;
0128     }
0129 
0130     bool intersectionFound = false;
0131 
0132     for (const auto& intersection : sIntersection.split()) {
0133       if (intersection &&
0134           detail::checkIntersection(intersection.intersection(), nearLimit,
0135                                     farLimit, logger)) {
0136         stepper.updateStepSize(state.stepping, intersection.pathLength(),
0137                                ConstrainedStep::aborter, false);
0138         ACTS_VERBOSE(
0139             "SurfaceReached aborter | "
0140             "Target stepSize (surface) updated to "
0141             << stepper.outputStepSize(state.stepping));
0142         intersectionFound = true;
0143         break;
0144       }
0145     }
0146 
0147     if (!intersectionFound) {
0148       ACTS_VERBOSE(
0149           "SurfaceReached aborter | "
0150           "Target intersection not found. Maybe next time?");
0151     }
0152     return reached;
0153   }
0154 };
0155 
0156 /// Similar to SurfaceReached, but with an infinite overstep limit.
0157 ///
0158 /// This can be used to force the propagation to the target surface.
0159 struct ForcedSurfaceReached : SurfaceReached {
0160   ForcedSurfaceReached()
0161       : SurfaceReached(std::numeric_limits<double>::lowest()) {}
0162 };
0163 
0164 /// This is the condition that the end of World has been reached
0165 /// it then triggers an propagation abort
0166 struct EndOfWorldReached {
0167   EndOfWorldReached() = default;
0168 
0169   /// boolean operator for abort condition without using the result
0170   ///
0171   /// @tparam propagator_state_t Type of the propagator state
0172   /// @tparam navigator_t Type of the navigator
0173   ///
0174   /// @param [in,out] state The propagation state object
0175   /// @param [in] navigator The navigator object
0176   template <typename propagator_state_t, typename stepper_t,
0177             typename navigator_t>
0178   bool operator()(propagator_state_t& state, const stepper_t& /*stepper*/,
0179                   const navigator_t& navigator,
0180                   const Logger& /*logger*/) const {
0181     bool endOfWorld = navigator.endOfWorldReached(state.navigation);
0182     return endOfWorld;
0183   }
0184 };
0185 
0186 /// Aborter that checks if the propagation has reached any surface
0187 struct AnySurfaceReached {
0188   template <typename propagator_state_t, typename stepper_t,
0189             typename navigator_t>
0190   bool operator()(propagator_state_t& state, const stepper_t& stepper,
0191                   const navigator_t& navigator, const Logger& logger) const {
0192     (void)stepper;
0193     (void)logger;
0194 
0195     const Surface* startSurface = navigator.startSurface(state.navigation);
0196     const Surface* targetSurface = navigator.targetSurface(state.navigation);
0197     const Surface* currentSurface = navigator.currentSurface(state.navigation);
0198 
0199     // `startSurface` is excluded because we want to reach a new surface
0200     // `targetSurface` is excluded because another aborter should handle it
0201     if (currentSurface != nullptr && currentSurface != startSurface &&
0202         currentSurface != targetSurface) {
0203       return true;
0204     }
0205 
0206     return false;
0207   }
0208 };
0209 
0210 }  // namespace Acts