Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:19

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-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 // clang-format off
0012 // Workaround for building on clang+libstdc++. Must be the first include.
0013 #include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp"
0014 // clang-format on
0015 
0016 #include "Acts/Definitions/Algebra.hpp"
0017 #include "Acts/Definitions/PdgParticle.hpp"
0018 #include "Acts/Definitions/Units.hpp"
0019 #include "Acts/EventData/TrackParameters.hpp"
0020 #include "Acts/EventData/TrackParametersConcept.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Propagator/AbortList.hpp"
0024 #include "Acts/Propagator/ActionList.hpp"
0025 #include "Acts/Propagator/PropagatorTraits.hpp"
0026 #include "Acts/Propagator/StandardAborters.hpp"
0027 #include "Acts/Propagator/StepperConcept.hpp"
0028 #include "Acts/Propagator/VoidNavigator.hpp"
0029 #include "Acts/Propagator/detail/ParameterTraits.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031 #include "Acts/Utilities/Result.hpp"
0032 
0033 #include <optional>
0034 
0035 namespace Acts {
0036 
0037 /// @brief Different stages during propagation
0038 enum class PropagatorStage {
0039   invalid,          ///< Invalid stage
0040   prePropagation,   ///< Before the propagation
0041   postPropagation,  ///< After the propagation
0042   preStep,          ///< Before a step
0043   postStep,         ///< After a step
0044 };
0045 
0046 /// @brief Simple class holding result of propagation call
0047 ///
0048 /// @tparam parameters_t Type of final track parameters
0049 /// @tparam result_list  Result pack for additional propagation
0050 ///                      quantities
0051 template <typename parameters_t, typename... result_list>
0052 struct PropagatorResult : private detail::Extendable<result_list...> {
0053   using detail::Extendable<result_list...>::get;
0054   using detail::Extendable<result_list...>::tuple;
0055 
0056   /// Final track parameters
0057   std::optional<parameters_t> endParameters = std::nullopt;
0058 
0059   /// Full transport jacobian
0060   std::optional<BoundMatrix> transportJacobian = std::nullopt;
0061 
0062   /// Number of propagation steps that were carried out
0063   unsigned int steps = 0;
0064 
0065   /// Signed distance over which the parameters were propagated
0066   double pathLength = 0.;
0067 };
0068 
0069 /// @brief Class holding the trivial options in propagator options
0070 ///
0071 struct PropagatorPlainOptions {
0072   /// Propagation direction
0073   Direction direction = Direction::Forward;
0074 
0075   /// Maximum number of steps for one propagate call
0076   unsigned int maxSteps = 1000;
0077 
0078   /// Absolute maximum path length
0079   double pathLimit = std::numeric_limits<double>::max();
0080 
0081   /// Required tolerance to reach surface
0082   double surfaceTolerance = s_onSurfaceTolerance;
0083 
0084   /// Loop protection step, it adapts the pathLimit
0085   bool loopProtection = true;
0086   double loopFraction = 0.5;  ///< Allowed loop fraction, 1 is a full loop
0087 
0088   // Configurations for Stepper
0089 
0090   /// Tolerance for the error of the integration
0091   double stepTolerance = 1e-4;
0092 
0093   /// Cut-off value for the step size
0094   double stepSizeCutOff = 0.;
0095 
0096   /// Absolute maximum step size
0097   double maxStepSize = std::numeric_limits<double>::max();
0098 
0099   /// Maximum number of Runge-Kutta steps for the stepper step call
0100   unsigned int maxRungeKuttaStepTrials = 10000;
0101 };
0102 
0103 /// @brief Options for propagate() call
0104 ///
0105 /// @tparam action_list_t List of action types called after each
0106 ///    propagation step with the current propagation and stepper state
0107 ///
0108 /// @tparam aborter_list_t List of abort conditions tested after each
0109 ///    propagation step using the current propagation and stepper state
0110 ///
0111 template <typename action_list_t = ActionList<>,
0112           typename aborter_list_t = AbortList<>>
0113 struct PropagatorOptions : public PropagatorPlainOptions {
0114   using action_list_type = action_list_t;
0115   using aborter_list_type = aborter_list_t;
0116 
0117   /// Delete default constructor
0118   PropagatorOptions() = delete;
0119 
0120   /// PropagatorOptions copy constructor
0121   PropagatorOptions(
0122       const PropagatorOptions<action_list_t, aborter_list_t>& po) = default;
0123 
0124   /// PropagatorOptions with context
0125   PropagatorOptions(const GeometryContext& gctx,
0126                     const MagneticFieldContext& mctx)
0127       : geoContext(gctx), magFieldContext(mctx) {}
0128 
0129   /// @brief Expand the Options with extended aborters
0130   ///
0131   /// @tparam extended_aborter_list_t Type of the new aborter list
0132   ///
0133   /// @param aborters The new aborter list to be used (internally)
0134   template <typename extended_aborter_list_t>
0135   PropagatorOptions<action_list_t, extended_aborter_list_t> extend(
0136       extended_aborter_list_t aborters) const {
0137     PropagatorOptions<action_list_t, extended_aborter_list_t> eoptions(
0138         geoContext, magFieldContext);
0139 
0140     // Copy the options over
0141     eoptions.setPlainOptions(*this);
0142 
0143     // Action / abort list
0144     eoptions.actionList = std::move(actionList);
0145     eoptions.abortList = std::move(aborters);
0146 
0147     // And return the options
0148     return eoptions;
0149   }
0150 
0151   /// @brief Set the plain options
0152   ///
0153   /// @param pOptions The plain options
0154   void setPlainOptions(const PropagatorPlainOptions& pOptions) {
0155     // Copy the options over
0156     direction = pOptions.direction;
0157     maxSteps = pOptions.maxSteps;
0158     surfaceTolerance = pOptions.surfaceTolerance;
0159     pathLimit = direction * std::abs(pOptions.pathLimit);
0160     loopProtection = pOptions.loopProtection;
0161     loopFraction = pOptions.loopFraction;
0162 
0163     // Stepper options
0164     stepTolerance = pOptions.stepTolerance;
0165     stepSizeCutOff = pOptions.stepSizeCutOff;
0166     maxStepSize = pOptions.maxStepSize;
0167     maxRungeKuttaStepTrials = pOptions.maxRungeKuttaStepTrials;
0168   }
0169 
0170   /// List of actions
0171   action_list_t actionList;
0172 
0173   /// List of abort conditions
0174   aborter_list_t abortList;
0175 
0176   /// The context object for the geometry
0177   std::reference_wrapper<const GeometryContext> geoContext;
0178 
0179   /// The context object for the magnetic field
0180   std::reference_wrapper<const MagneticFieldContext> magFieldContext;
0181 };
0182 
0183 /// Common simplified base interface for propagators.
0184 ///
0185 /// This class only supports propagation from start bound parameters to a target
0186 /// surface and returns only the end bound parameters.
0187 /// Navigation is performed if the underlying propagator is configured with an
0188 /// appropriate navigator. No custom actors or aborters are supported.
0189 class BasePropagator {
0190  public:
0191   /// Base propagator options
0192   using Options = PropagatorOptions<>;
0193 
0194   /// Method to propagate start bound track parameters to a target surface.
0195   /// @param start The start bound track parameters.
0196   /// @param target The target surface.
0197   /// @param options The propagation options.
0198   /// @return The end bound track parameters.
0199   virtual Result<BoundTrackParameters> propagateToSurface(
0200       const BoundTrackParameters& start, const Surface& target,
0201       const Options& options) const = 0;
0202 
0203   virtual ~BasePropagator() = default;
0204 };
0205 
0206 namespace detail {
0207 class PropagatorStub {};
0208 
0209 template <typename derived_t>
0210 class BasePropagatorHelper : public BasePropagator {
0211  public:
0212   Result<BoundTrackParameters> propagateToSurface(
0213       const BoundTrackParameters& start, const Surface& target,
0214       const Options& options) const override;
0215 };
0216 }  // namespace detail
0217 
0218 /// @brief Propagator for particles (optionally in a magnetic field)
0219 ///
0220 /// The Propagator works with a state objects given at function call
0221 /// This state object contains the thread local state objects
0222 ///  - Navigator::state_type for object navigation and screen output
0223 ///  - Stepper::state_type state for the actual transport caching
0224 ///  (pos,dir,field)
0225 ///
0226 /// @tparam stepper_t Type of stepper implementation of the propagation
0227 /// @tparam naviagor_t Type of the navigator (optional)
0228 ///
0229 /// This Propagator class serves as high-level steering code for propagating
0230 /// track parameters. The actual implementation of the propagation has to be
0231 /// implemented in the stepper_t object, which has to provide the following:
0232 ///
0233 /// - a function for performing a single propagation step
0234 /// - a type mapping for: initial track parameter type -> type of final track
0235 ///   parameters
0236 /// - a type mapping for: (initial track parameter type and destination
0237 ///   surface type) -> type of final track parameters
0238 /// - a type mapping for: initial track parameter type -> type of internal
0239 ///   state object
0240 /// - a type mapping for: (initial track parameter type and destination
0241 ///   surface type) -> type of internal state object
0242 ///
0243 template <typename stepper_t, typename navigator_t = VoidNavigator>
0244 class Propagator final
0245     : public std::conditional_t<
0246           SupportsBoundParameters_v<stepper_t, navigator_t>,
0247           detail::BasePropagatorHelper<Propagator<stepper_t, navigator_t>>,
0248           detail::PropagatorStub> {
0249   /// Re-define bound track parameters dependent on the stepper
0250   using StepperBoundTrackParameters =
0251       detail::stepper_bound_parameters_type_t<stepper_t>;
0252   static_assert(
0253       Concepts::BoundTrackParametersConcept<StepperBoundTrackParameters>,
0254       "Stepper bound track parameters do not fulfill bound "
0255       "parameters concept.");
0256 
0257   /// Re-define curvilinear track parameters dependent on the stepper
0258   using StepperCurvilinearTrackParameters =
0259       detail::stepper_curvilinear_parameters_type_t<stepper_t>;
0260   static_assert(
0261       Concepts::BoundTrackParametersConcept<StepperCurvilinearTrackParameters>,
0262       "Stepper bound track parameters do not fulfill bound "
0263       "parameters concept.");
0264 
0265   using Jacobian = BoundMatrix;
0266   using BoundState = std::tuple<StepperBoundTrackParameters, Jacobian, double>;
0267   using CurvilinearState =
0268       std::tuple<StepperCurvilinearTrackParameters, Jacobian, double>;
0269 
0270   static_assert(StepperStateConcept<typename stepper_t::State>,
0271                 "Stepper does not fulfill stepper concept.");
0272   static_assert(StepperConcept<stepper_t>,
0273                 "Stepper does not fulfill stepper concept.");
0274 
0275  public:
0276   /// Type of the stepper in use for public scope
0277   using Stepper = stepper_t;
0278 
0279   /// Type of the navigator in use for public scope
0280   using Navigator = navigator_t;
0281 
0282   /// Type of state object used by the propagation implementation
0283   using StepperState = typename Stepper::State;
0284 
0285   /// Typedef the navigator state
0286   using NavigatorState = typename navigator_t::State;
0287 
0288   /// Constructor from implementation object
0289   ///
0290   /// @param stepper The stepper implementation is moved to a private member
0291   /// @param navigator The navigator implementation, moved to a private member
0292   /// @param _logger a logger instance
0293   explicit Propagator(stepper_t stepper, navigator_t navigator = navigator_t(),
0294                       std::shared_ptr<const Logger> _logger =
0295                           getDefaultLogger("Propagator", Acts::Logging::INFO))
0296       : m_stepper(std::move(stepper)),
0297         m_navigator(std::move(navigator)),
0298         m_logger{std::move(_logger)} {}
0299 
0300   /// @brief private Propagator state for navigation and debugging
0301   ///
0302   /// @tparam propagator_options_t Type of the Objections object
0303   ///
0304   /// This struct holds the common state information for propagating
0305   /// which is independent of the actual stepper implementation.
0306   template <typename propagator_options_t, typename... extension_state_t>
0307   struct State : private detail::Extendable<extension_state_t...> {
0308     using options_type = propagator_options_t;
0309 
0310     /// Create the propagator state from the options
0311     ///
0312     /// @tparam propagator_options_t the type of the propagator options
0313     ///
0314     /// @param topts The options handed over by the propagate call
0315     /// @param steppingIn Stepper state instance to begin with
0316     /// @param navigationIn Navigator state instance to begin with
0317     State(const propagator_options_t& topts, StepperState steppingIn,
0318           NavigatorState navigationIn)
0319         : options(topts),
0320           stepping{std::move(steppingIn)},
0321           navigation{std::move(navigationIn)},
0322           geoContext(topts.geoContext) {}
0323 
0324     using detail::Extendable<extension_state_t...>::get;
0325     using detail::Extendable<extension_state_t...>::tuple;
0326 
0327     /// Propagation stage
0328     PropagatorStage stage = PropagatorStage::invalid;
0329 
0330     /// These are the options - provided for each propagation step
0331     propagator_options_t options;
0332 
0333     /// Stepper state - internal state of the Stepper
0334     StepperState stepping;
0335 
0336     /// Navigation state - internal state of the Navigator
0337     NavigatorState navigation;
0338 
0339     /// Context object for the geometry
0340     std::reference_wrapper<const GeometryContext> geoContext;
0341 
0342     /// Number of propagation steps that were carried out
0343     unsigned int steps = 0;
0344 
0345     /// Signed distance over which the parameters were propagated
0346     double pathLength = 0.;
0347   };
0348 
0349  private:
0350   /// @brief Helper struct determining the state's type
0351   ///
0352   /// @tparam propagator_options_t Propagator options type
0353   /// @tparam action_list_t List of propagation action types
0354   ///
0355   /// This helper struct provides type definitions to extract the correct
0356   /// propagation state type from a given TrackParameter type and an
0357   /// ActionList.
0358   ///
0359   template <typename propagator_options_t, typename action_list_t>
0360   struct state_type_helper {
0361     /// @brief Propagation state type for an arbitrary list of additional
0362     ///        propagation states
0363     ///
0364     /// @tparam args Parameter pack specifying additional propagation states
0365     ///
0366     template <typename... args>
0367     using this_state_type = State<propagator_options_t, args...>;
0368 
0369     /// @brief Propagation result type derived from a given action list
0370     using type = typename action_list_t::template result_type<this_state_type>;
0371   };
0372 
0373   /// @brief Helper struct determining the result's type
0374   ///
0375   /// @tparam parameters_t Type of final track parameters
0376   /// @tparam action_list_t List of propagation action types
0377   ///
0378   /// This helper struct provides type definitions to extract the correct
0379   /// propagation result type from a given TrackParameter type and an
0380   /// ActionList.
0381   ///
0382   template <typename parameters_t, typename action_list_t>
0383   struct result_type_helper {
0384     /// @brief Propagation result type for an arbitrary list of additional
0385     ///        propagation results
0386     ///
0387     /// @tparam args Parameter pack specifying additional propagation results
0388     ///
0389     template <typename... args>
0390     using this_result_type = PropagatorResult<parameters_t, args...>;
0391 
0392     /// @brief Propagation result type derived from a given action list
0393     using type = typename action_list_t::template result_type<this_result_type>;
0394   };
0395 
0396  public:
0397   /// @brief Short-hand type definition for propagation state derived from
0398   ///        an action list
0399   ///
0400   /// @tparam action_list_t List of propagation action types
0401   ///
0402   template <typename propagator_options_t, typename action_list_t>
0403   using action_list_t_state_t =
0404       typename state_type_helper<propagator_options_t, action_list_t>::type;
0405 
0406   /// @brief Short-hand type definition for propagation result derived from
0407   ///        an action list
0408   ///
0409   /// @tparam parameters_t Type of the final track parameters
0410   /// @tparam action_list_t List of propagation action types
0411   ///
0412   template <typename parameters_t, typename action_list_t>
0413   using action_list_t_result_t =
0414       typename result_type_helper<parameters_t, action_list_t>::type;
0415 
0416  public:
0417   /// @brief Propagate track parameters
0418   ///
0419   /// This function performs the propagation of the track parameters using the
0420   /// internal stepper implementation, until at least one abort condition is
0421   /// fulfilled or the maximum number of steps/path length provided in the
0422   /// propagation options is reached.
0423   ///
0424   /// @tparam parameters_t Type of initial track parameters to propagate
0425   /// @tparam propagator_options_t Type of the propagator options
0426   /// @tparam path_aborter_t The path aborter type to be added
0427   ///
0428   /// @param [in] start initial track parameters to propagate
0429   /// @param [in] options Propagation options, type Options<,>
0430   /// @param [in] makeCurvilinear Produce curvilinear parameters at the end of the propagation
0431   ///
0432   /// @return Propagation result containing the propagation status, final
0433   ///         track parameters, and output of actions (if they produce any)
0434   ///
0435   template <typename parameters_t, typename propagator_options_t,
0436             typename path_aborter_t = PathLimitReached>
0437   Result<
0438       action_list_t_result_t<StepperCurvilinearTrackParameters,
0439                              typename propagator_options_t::action_list_type>>
0440   propagate(const parameters_t& start, const propagator_options_t& options,
0441             bool makeCurvilinear = true) const;
0442 
0443   /// @brief Propagate track parameters - User method
0444   ///
0445   /// This function performs the propagation of the track parameters according
0446   /// to the internal implementation object until at least one abort condition
0447   /// is fulfilled, the destination surface is hit or the maximum number of
0448   /// steps/path length as given in the propagation options is reached.
0449   ///
0450   /// @tparam parameters_t Type of initial track parameters to propagate
0451   /// @tparam propagator_options_t Type of the propagator options
0452   /// @tparam target_aborter_t The target aborter type to be added
0453   /// @tparam path_aborter_t The path aborter type to be added
0454   ///
0455   /// @param [in] start Initial track parameters to propagate
0456   /// @param [in] target Target surface of to propagate to
0457   /// @param [in] options Propagation options
0458   ///
0459   /// @return Propagation result containing the propagation status, final
0460   ///         track parameters, and output of actions (if they produce any)
0461   template <typename parameters_t, typename propagator_options_t,
0462             typename target_aborter_t = SurfaceReached,
0463             typename path_aborter_t = PathLimitReached>
0464   Result<
0465       action_list_t_result_t<StepperBoundTrackParameters,
0466                              typename propagator_options_t::action_list_type>>
0467   propagate(const parameters_t& start, const Surface& target,
0468             const propagator_options_t& options) const;
0469 
0470   /// @brief Propagate track parameters
0471   ///
0472   /// This function performs the propagation of the track parameters according
0473   /// to the internal implementation object until at least one abort condition
0474   /// is fulfilled, the destination surface is hit or the maximum number of
0475   /// steps/path length as given in the propagation options is reached.
0476   ///
0477   /// @note Does not (yet) convert into the return_type of the propagation
0478   ///
0479   /// @tparam propagator_state_t Type of the propagator state with options
0480   ///
0481   /// @param [in,out] state the propagator state object
0482   ///
0483   /// @return Propagation result
0484   template <typename propagator_state_t>
0485   Result<void> propagate(propagator_state_t& state) const;
0486 
0487   template <typename parameters_t, typename propagator_options_t,
0488             typename path_aborter_t = PathLimitReached>
0489   auto makeState(const parameters_t& start,
0490                  const propagator_options_t& options) const;
0491 
0492   template <typename parameters_t, typename propagator_options_t,
0493             typename target_aborter_t = SurfaceReached,
0494             typename path_aborter_t = PathLimitReached>
0495   auto makeState(const parameters_t& start, const Surface& target,
0496                  const propagator_options_t& options) const;
0497 
0498   template <typename propagator_state_t, typename propagator_options_t>
0499   Result<
0500       action_list_t_result_t<StepperCurvilinearTrackParameters,
0501                              typename propagator_options_t::action_list_type>>
0502   makeResult(propagator_state_t state, Result<void> result,
0503              const propagator_options_t& options, bool makeCurvilinear) const;
0504 
0505   template <typename propagator_state_t, typename propagator_options_t>
0506   Result<
0507       action_list_t_result_t<StepperBoundTrackParameters,
0508                              typename propagator_options_t::action_list_type>>
0509   makeResult(propagator_state_t state, Result<void> result,
0510              const Surface& target, const propagator_options_t& options) const;
0511 
0512   const stepper_t& stepper() const { return m_stepper; }
0513 
0514   const navigator_t& navigator() const { return m_navigator; }
0515 
0516  private:
0517   const Logger& logger() const { return *m_logger; }
0518 
0519   template <typename propagator_state_t, typename result_t>
0520   void moveStateToResult(propagator_state_t& state, result_t& result) const;
0521 
0522   /// Implementation of propagation algorithm
0523   stepper_t m_stepper;
0524 
0525   /// Implementation of navigator
0526   navigator_t m_navigator;
0527 
0528   std::shared_ptr<const Logger> m_logger;
0529 };
0530 
0531 }  // namespace Acts
0532 
0533 #include "Acts/Propagator/Propagator.ipp"