Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:59

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Propagator/ConstrainedStep.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Intersection.hpp"
0016 #include "Acts/Utilities/Logger.hpp"
0017 
0018 #include <limits>
0019 
0020 namespace Acts {
0021 
0022 /// This is the condition that the pathLimit has been reached
0023 struct PathLimitReached {
0024   /// Boolean switch for Loop protection
0025   double internalLimit = std::numeric_limits<double>::max();
0026 
0027   /// boolean operator for abort condition without using the result
0028   ///
0029   /// @tparam propagator_state_t Type of the propagator state
0030   /// @tparam stepper_t Type of the stepper
0031   /// @tparam navigator_t Type of the navigator
0032   ///
0033   /// @param [in,out] state The propagation state object
0034   /// @param [in] stepper Stepper used for propagation
0035   /// @param [in] navigator Navigator used for propagation
0036   /// @param logger a logger instance
0037   template <typename propagator_state_t, typename stepper_t,
0038             typename navigator_t>
0039   bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0040                   const navigator_t& navigator, const Logger& logger) const {
0041     (void)navigator;
0042 
0043     // Check if the maximum allowed step size has to be updated
0044     double distance =
0045         std::abs(internalLimit) - std::abs(state.stepping.pathAccumulated);
0046     double tolerance = state.options.surfaceTolerance;
0047     bool limitReached = (std::abs(distance) < std::abs(tolerance));
0048     if (limitReached) {
0049       ACTS_VERBOSE("PathLimit aborter | " << "Path limit reached at distance "
0050                                           << distance);
0051       return true;
0052     }
0053     stepper.updateStepSize(state.stepping, distance,
0054                            ConstrainedStep::Type::Actor);
0055     ACTS_VERBOSE("PathLimit aborter | "
0056                  << "Target stepSize (path limit) updated to "
0057                  << stepper.outputStepSize(state.stepping));
0058     return false;
0059   }
0060 };
0061 
0062 /// This is the condition that the Surface has been reached it then triggers a
0063 /// propagation abort
0064 struct SurfaceReached {
0065   const Surface* surface = nullptr;
0066   BoundaryTolerance boundaryTolerance = BoundaryTolerance::None();
0067 
0068   // TODO https://github.com/acts-project/acts/issues/2738
0069   /// Distance limit to discard intersections "behind us"
0070   /// @note this is only necessary because some surfaces have more than one
0071   ///       intersection
0072   double nearLimit = -100 * UnitConstants::um;
0073 
0074   SurfaceReached() = default;
0075   explicit SurfaceReached(double nLimit) : nearLimit(nLimit) {}
0076 
0077   /// boolean operator for abort condition without using the result
0078   ///
0079   /// @tparam propagator_state_t Type of the propagator state
0080   /// @tparam stepper_t Type of the stepper
0081   /// @tparam navigator_t Type of the navigator
0082   ///
0083   /// @param [in,out] state The propagation state object
0084   /// @param [in] stepper Stepper used for propagation
0085   /// @param [in] navigator Navigator used for propagation
0086   /// @param logger a logger instance
0087   template <typename propagator_state_t, typename stepper_t,
0088             typename navigator_t>
0089   bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0090                   const navigator_t& navigator, const Logger& logger) const {
0091     if (surface == nullptr) {
0092       ACTS_VERBOSE("SurfaceReached aborter | Target surface not set.");
0093       return false;
0094     }
0095 
0096     if (navigator.currentSurface(state.navigation) == surface) {
0097       ACTS_VERBOSE("SurfaceReached aborter | Target surface reached.");
0098       return true;
0099     }
0100 
0101     // not using the stepper overstep limit here because it does not always work
0102     // for perigee surfaces
0103     // note: the near limit is necessary for surfaces with more than one
0104     // intersection in order to discard the ones which are behind us
0105     const double farLimit = std::numeric_limits<double>::max();
0106     const double tolerance = state.options.surfaceTolerance;
0107 
0108     const auto sIntersection = surface->intersect(
0109         state.geoContext, stepper.position(state.stepping),
0110         state.options.direction * stepper.direction(state.stepping),
0111         boundaryTolerance, tolerance);
0112     const auto closest = sIntersection.closest();
0113 
0114     bool reached = false;
0115 
0116     if (closest.status() == IntersectionStatus::onSurface) {
0117       const double distance = closest.pathLength();
0118       ACTS_VERBOSE(
0119           "SurfaceReached aborter | "
0120           "Target surface reached at distance (tolerance) "
0121           << distance << " (" << tolerance << ")");
0122       reached = true;
0123     }
0124 
0125     bool intersectionFound = false;
0126 
0127     for (const auto& intersection : sIntersection.split()) {
0128       if (intersection.isValid() &&
0129           detail::checkPathLength(intersection.pathLength(), nearLimit,
0130                                   farLimit, logger)) {
0131         stepper.updateStepSize(state.stepping, intersection.pathLength(),
0132                                ConstrainedStep::Type::Actor);
0133         ACTS_VERBOSE(
0134             "SurfaceReached aborter | "
0135             "Target stepSize (surface) updated to "
0136             << stepper.outputStepSize(state.stepping));
0137         intersectionFound = true;
0138         break;
0139       }
0140     }
0141 
0142     if (!intersectionFound) {
0143       ACTS_VERBOSE(
0144           "SurfaceReached aborter | "
0145           "Target intersection not found. Maybe next time?");
0146     }
0147     return reached;
0148   }
0149 };
0150 
0151 /// Similar to SurfaceReached, but with an infinite overstep limit.
0152 ///
0153 /// This can be used to force the propagation to the target surface.
0154 struct ForcedSurfaceReached : SurfaceReached {
0155   ForcedSurfaceReached()
0156       : SurfaceReached(std::numeric_limits<double>::lowest()) {}
0157 };
0158 
0159 /// This is the condition that the end of world has been reached
0160 /// it then triggers an propagation abort
0161 struct EndOfWorldReached {
0162   /// boolean operator for abort condition without using the result
0163   ///
0164   /// @tparam propagator_state_t Type of the propagator state
0165   /// @tparam navigator_t Type of the navigator
0166   ///
0167   /// @param [in,out] state The propagation state object
0168   /// @param [in] navigator The navigator object
0169   template <typename propagator_state_t, typename stepper_t,
0170             typename navigator_t>
0171   bool checkAbort(propagator_state_t& state, const stepper_t& /*stepper*/,
0172                   const navigator_t& navigator,
0173                   const Logger& /*logger*/) const {
0174     bool endOfWorld = navigator.endOfWorldReached(state.navigation);
0175     return endOfWorld;
0176   }
0177 };
0178 
0179 /// This is the condition that the end of world has been reached
0180 /// it then triggers a propagation abort
0181 struct VolumeConstraintAborter {
0182   /// boolean operator for abort condition without using the result
0183   ///
0184   /// @tparam propagator_state_t Type of the propagator state
0185   /// @tparam navigator_t Type of the navigator
0186   ///
0187   /// @param [in,out] state The propagation state object
0188   /// @param [in] navigator The navigator object
0189   /// @param logger a logger instance
0190   template <typename propagator_state_t, typename stepper_t,
0191             typename navigator_t>
0192   bool checkAbort(propagator_state_t& state, const stepper_t& /*stepper*/,
0193                   const navigator_t& navigator, const Logger& logger) const {
0194     const auto& constrainToVolumeIds = state.options.constrainToVolumeIds;
0195     const auto& endOfWorldVolumeIds = state.options.endOfWorldVolumeIds;
0196 
0197     if (constrainToVolumeIds.empty() && endOfWorldVolumeIds.empty()) {
0198       return false;
0199     }
0200     const auto* currentVolume = navigator.currentVolume(state.navigation);
0201 
0202     // We need a volume to check its ID
0203     if (currentVolume == nullptr) {
0204       return false;
0205     }
0206 
0207     const auto currentVolumeId =
0208         static_cast<std::uint32_t>(currentVolume->geometryId().volume());
0209 
0210     if (!constrainToVolumeIds.empty() &&
0211         std::find(constrainToVolumeIds.begin(), constrainToVolumeIds.end(),
0212                   currentVolumeId) == constrainToVolumeIds.end()) {
0213       ACTS_VERBOSE(
0214           "VolumeConstraintAborter aborter | Abort with volume constrain "
0215           << currentVolumeId);
0216       return true;
0217     }
0218 
0219     if (!endOfWorldVolumeIds.empty() &&
0220         std::find(endOfWorldVolumeIds.begin(), endOfWorldVolumeIds.end(),
0221                   currentVolumeId) != endOfWorldVolumeIds.end()) {
0222       ACTS_VERBOSE(
0223           "VolumeConstraintAborter aborter | Abort with additional end of "
0224           "world volume "
0225           << currentVolumeId);
0226       return true;
0227     }
0228 
0229     return false;
0230   }
0231 };
0232 
0233 /// Aborter that checks if the propagation has reached any surface
0234 struct AnySurfaceReached {
0235   template <typename propagator_state_t, typename stepper_t,
0236             typename navigator_t>
0237   bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0238                   const navigator_t& navigator, const Logger& logger) const {
0239     (void)stepper;
0240     (void)logger;
0241 
0242     const Surface* startSurface = navigator.startSurface(state.navigation);
0243     const Surface* targetSurface = navigator.targetSurface(state.navigation);
0244     const Surface* currentSurface = navigator.currentSurface(state.navigation);
0245 
0246     // `startSurface` is excluded because we want to reach a new surface
0247     // `targetSurface` is excluded because another aborter should handle it
0248     if (currentSurface != nullptr && currentSurface != startSurface &&
0249         currentSurface != targetSurface) {
0250       return true;
0251     }
0252 
0253     return false;
0254   }
0255 };
0256 
0257 }  // namespace Acts