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) 2019 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 #include "Acts/EventData/TrackParametersConcept.hpp"
0010 #include "Acts/Propagator/ActionList.hpp"
0011 #include "Acts/Propagator/ConstrainedStep.hpp"
0012 #include "Acts/Propagator/PropagatorError.hpp"
0013 #include "Acts/Propagator/StandardAborters.hpp"
0014 #include "Acts/Propagator/detail/LoopProtection.hpp"
0015 
0016 #include <type_traits>
0017 
0018 template <typename S, typename N>
0019 template <typename propagator_state_t>
0020 auto Acts::Propagator<S, N>::propagate(propagator_state_t& state) const
0021     -> Result<void> {
0022   // Pre-stepping call to the navigator and action list
0023   ACTS_VERBOSE("Entering propagation.");
0024 
0025   state.stage = PropagatorStage::prePropagation;
0026 
0027   // Navigator initialize state call
0028   m_navigator.initialize(state, m_stepper);
0029   // Pre-Stepping call to the action list
0030   state.options.actionList(state, m_stepper, m_navigator, logger());
0031   // assume negative outcome, only set to true later if we actually have
0032   // a positive outcome.
0033 
0034   // start at true, if we don't begin the stepping loop we're fine.
0035   bool terminatedNormally = true;
0036 
0037   // Pre-Stepping: abort condition check
0038   if (!state.options.abortList(state, m_stepper, m_navigator, logger())) {
0039     // Stepping loop
0040     ACTS_VERBOSE("Starting stepping loop.");
0041 
0042     terminatedNormally = false;  // priming error condition
0043 
0044     // Propagation loop : stepping
0045     for (; state.steps < state.options.maxSteps; ++state.steps) {
0046       // Pre-Stepping: target setting
0047       state.stage = PropagatorStage::preStep;
0048       m_navigator.preStep(state, m_stepper);
0049       // Perform a propagation step - it takes the propagation state
0050       Result<double> res = m_stepper.step(state, m_navigator);
0051       if (res.ok()) {
0052         // Accumulate the path length
0053         double s = *res;
0054         state.pathLength += s;
0055         ACTS_VERBOSE("Step with size = " << s << " performed");
0056       } else {
0057         ACTS_ERROR("Step failed with " << res.error() << ": "
0058                                        << res.error().message());
0059         // pass error to caller
0060         return res.error();
0061       }
0062       // release actor and aborter constrains after step was performed
0063       m_stepper.releaseStepSize(state.stepping, ConstrainedStep::actor);
0064       m_stepper.releaseStepSize(state.stepping, ConstrainedStep::aborter);
0065       // Post-stepping:
0066       // navigator post step call - action list - aborter list
0067       state.stage = PropagatorStage::postStep;
0068       m_navigator.postStep(state, m_stepper);
0069       state.options.actionList(state, m_stepper, m_navigator, logger());
0070       if (state.options.abortList(state, m_stepper, m_navigator, logger())) {
0071         terminatedNormally = true;
0072         break;
0073       }
0074     }
0075   } else {
0076     ACTS_VERBOSE("Propagation terminated without going into stepping loop.");
0077   }
0078 
0079   state.stage = PropagatorStage::postPropagation;
0080 
0081   // if we didn't terminate normally (via aborters) set navigation break.
0082   // this will trigger error output in the lines below
0083   if (!terminatedNormally) {
0084     m_navigator.navigationBreak(state.navigation, true);
0085     ACTS_ERROR("Propagation reached the step count limit of "
0086                << state.options.maxSteps << " (did " << state.steps
0087                << " steps)");
0088     return PropagatorError::StepCountLimitReached;
0089   }
0090 
0091   // Post-stepping call to the action list
0092   ACTS_VERBOSE("Stepping loop done.");
0093   state.options.actionList(state, m_stepper, m_navigator, logger());
0094 
0095   // return progress flag here, decide on SUCCESS later
0096   return Result<void>::success();
0097 }
0098 
0099 template <typename S, typename N>
0100 template <typename parameters_t, typename propagator_options_t,
0101           typename path_aborter_t>
0102 auto Acts::Propagator<S, N>::propagate(const parameters_t& start,
0103                                        const propagator_options_t& options,
0104                                        bool makeCurvilinear) const
0105     -> Result<action_list_t_result_t<
0106         StepperCurvilinearTrackParameters,
0107         typename propagator_options_t::action_list_type>> {
0108   static_assert(
0109       std::is_copy_constructible<StepperCurvilinearTrackParameters>::value,
0110       "return track parameter type must be copy-constructible");
0111 
0112   auto state = makeState(start, options);
0113 
0114   // Perform the actual propagation
0115   auto propagationResult = propagate(state);
0116 
0117   return makeResult(std::move(state), propagationResult, options,
0118                     makeCurvilinear);
0119 }
0120 
0121 template <typename S, typename N>
0122 template <typename parameters_t, typename propagator_options_t,
0123           typename target_aborter_t, typename path_aborter_t>
0124 auto Acts::Propagator<S, N>::propagate(
0125     const parameters_t& start, const Surface& target,
0126     const propagator_options_t& options) const
0127     -> Result<action_list_t_result_t<
0128         StepperBoundTrackParameters,
0129         typename propagator_options_t::action_list_type>> {
0130   static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0131                 "Parameters do not fulfill bound parameters concept.");
0132 
0133   auto state = makeState<parameters_t, propagator_options_t, target_aborter_t,
0134                          path_aborter_t>(start, target, options);
0135 
0136   // Perform the actual propagation
0137   auto propagationResult = propagate(state);
0138 
0139   return makeResult(std::move(state), propagationResult, target, options);
0140 }
0141 
0142 template <typename S, typename N>
0143 template <typename parameters_t, typename propagator_options_t,
0144           typename path_aborter_t>
0145 auto Acts::Propagator<S, N>::makeState(
0146     const parameters_t& start, const propagator_options_t& options) const {
0147   static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0148                 "Parameters do not fulfill bound parameters concept.");
0149 
0150   // Type of track parameters produced by the propagation
0151   using ReturnParameterType = StepperCurvilinearTrackParameters;
0152 
0153   static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0154                 "return track parameter type must be copy-constructible");
0155 
0156   // Expand the abort list with a path aborter
0157   path_aborter_t pathAborter;
0158   pathAborter.internalLimit = options.pathLimit;
0159 
0160   auto abortList = options.abortList.append(pathAborter);
0161 
0162   // The expanded options (including path limit)
0163   auto eOptions = options.extend(abortList);
0164   using OptionsType = decltype(eOptions);
0165   // Initialize the internal propagator state
0166   using StateType =
0167       action_list_t_state_t<OptionsType,
0168                             typename propagator_options_t::action_list_type>;
0169   StateType state{
0170       eOptions,
0171       m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
0172                           eOptions.maxStepSize),
0173       m_navigator.makeState(&start.referenceSurface(), nullptr)};
0174 
0175   static_assert(
0176       Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
0177                            StateType&, const N&>,
0178       "Step method of the Stepper is not compatible with the propagator "
0179       "state");
0180 
0181   // Apply the loop protection - it resets the internal path limit
0182   detail::setupLoopProtection(
0183       state, m_stepper, state.options.abortList.template get<path_aborter_t>(),
0184       false, logger());
0185 
0186   return state;
0187 }
0188 
0189 template <typename S, typename N>
0190 template <typename parameters_t, typename propagator_options_t,
0191           typename target_aborter_t, typename path_aborter_t>
0192 auto Acts::Propagator<S, N>::makeState(
0193     const parameters_t& start, const Surface& target,
0194     const propagator_options_t& options) const {
0195   static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0196                 "Parameters do not fulfill bound parameters concept.");
0197 
0198   // Type of provided options
0199   target_aborter_t targetAborter;
0200   targetAborter.surface = &target;
0201   path_aborter_t pathAborter;
0202   pathAborter.internalLimit = options.pathLimit;
0203   auto abortList = options.abortList.append(targetAborter, pathAborter);
0204 
0205   // Create the extended options and declare their type
0206   auto eOptions = options.extend(abortList);
0207   using OptionsType = decltype(eOptions);
0208 
0209   // Initialize the internal propagator state
0210   using StateType =
0211       action_list_t_state_t<OptionsType,
0212                             typename propagator_options_t::action_list_type>;
0213   StateType state{
0214       eOptions,
0215       m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
0216                           eOptions.maxStepSize),
0217       m_navigator.makeState(&start.referenceSurface(), &target)};
0218 
0219   static_assert(
0220       Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
0221                            StateType&, const N&>,
0222       "Step method of the Stepper is not compatible with the propagator "
0223       "state");
0224 
0225   // Apply the loop protection, it resets the internal path limit
0226   detail::setupLoopProtection(
0227       state, m_stepper, state.options.abortList.template get<path_aborter_t>(),
0228       false, logger());
0229 
0230   return state;
0231 }
0232 
0233 template <typename S, typename N>
0234 template <typename propagator_state_t, typename propagator_options_t>
0235 auto Acts::Propagator<S, N>::makeResult(propagator_state_t state,
0236                                         Result<void> propagationResult,
0237                                         const propagator_options_t& /*options*/,
0238                                         bool makeCurvilinear) const
0239     -> Result<action_list_t_result_t<
0240         StepperCurvilinearTrackParameters,
0241         typename propagator_options_t::action_list_type>> {
0242   // Type of track parameters produced by the propagation
0243   using ReturnParameterType = StepperCurvilinearTrackParameters;
0244 
0245   static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0246                 "return track parameter type must be copy-constructible");
0247 
0248   // Type of the full propagation result, including output from actions
0249   using ResultType =
0250       action_list_t_result_t<ReturnParameterType,
0251                              typename propagator_options_t::action_list_type>;
0252 
0253   if (!propagationResult.ok()) {
0254     return propagationResult.error();
0255   }
0256 
0257   ResultType result{};
0258   moveStateToResult(state, result);
0259 
0260   if (makeCurvilinear) {
0261     if (!m_stepper.prepareCurvilinearState(state, m_navigator)) {
0262       // information to compute curvilinearState is incomplete.
0263       return propagationResult.error();
0264     }
0265     /// Convert into return type and fill the result object
0266     auto curvState = m_stepper.curvilinearState(state.stepping);
0267     // Fill the end parameters
0268     result.endParameters =
0269         std::get<StepperCurvilinearTrackParameters>(curvState);
0270     // Only fill the transport jacobian when covariance transport was done
0271     if (state.stepping.covTransport) {
0272       result.transportJacobian = std::get<Jacobian>(curvState);
0273     }
0274   }
0275 
0276   return Result<ResultType>::success(std::move(result));
0277 }
0278 
0279 template <typename S, typename N>
0280 template <typename propagator_state_t, typename propagator_options_t>
0281 auto Acts::Propagator<S, N>::makeResult(
0282     propagator_state_t state, Result<void> propagationResult,
0283     const Surface& target, const propagator_options_t& /*options*/) const
0284     -> Result<action_list_t_result_t<
0285         StepperBoundTrackParameters,
0286         typename propagator_options_t::action_list_type>> {
0287   // Type of track parameters produced at the end of the propagation
0288   using ReturnParameterType = StepperBoundTrackParameters;
0289 
0290   static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0291                 "return track parameter type must be copy-constructible");
0292 
0293   // Type of the full propagation result, including output from actions
0294   using ResultType =
0295       action_list_t_result_t<ReturnParameterType,
0296                              typename propagator_options_t::action_list_type>;
0297 
0298   if (!propagationResult.ok()) {
0299     return propagationResult.error();
0300   }
0301 
0302   ResultType result{};
0303   moveStateToResult(state, result);
0304 
0305   // Compute the final results and mark the propagation as successful
0306   auto bsRes = m_stepper.boundState(state.stepping, target);
0307   if (!bsRes.ok()) {
0308     return bsRes.error();
0309   }
0310   const auto& bs = *bsRes;
0311 
0312   // Fill the end parameters
0313   result.endParameters = std::get<StepperBoundTrackParameters>(bs);
0314   // Only fill the transport jacobian when covariance transport was done
0315   if (state.stepping.covTransport) {
0316     result.transportJacobian = std::get<Jacobian>(bs);
0317   }
0318   return Result<ResultType>::success(std::move(result));
0319 }
0320 
0321 template <typename S, typename N>
0322 template <typename propagator_state_t, typename result_t>
0323 void Acts::Propagator<S, N>::moveStateToResult(propagator_state_t& state,
0324                                                result_t& result) const {
0325   result.tuple() = std::move(state.tuple());
0326 
0327   result.steps = state.steps;
0328   result.pathLength = state.pathLength;
0329 }
0330 
0331 template <typename derived_t>
0332 Acts::Result<Acts::BoundTrackParameters>
0333 Acts::detail::BasePropagatorHelper<derived_t>::propagateToSurface(
0334     const BoundTrackParameters& start, const Surface& target,
0335     const Options& options) const {
0336   using ResultType = Result<typename derived_t::template action_list_t_result_t<
0337       BoundTrackParameters, ActionList<>>>;
0338 
0339   // dummy initialization
0340   ResultType res = ResultType::failure(PropagatorError::Failure);
0341 
0342   // Due to the geometry of the perigee surface the overstepping tolerance
0343   // is sometimes not met.
0344   if (target.type() == Surface::SurfaceType::Perigee) {
0345     res = static_cast<const derived_t*>(this)
0346               ->template propagate<BoundTrackParameters, PropagatorOptions<>,
0347                                    ForcedSurfaceReached, PathLimitReached>(
0348                   start, target, options);
0349   } else {
0350     res = static_cast<const derived_t*>(this)
0351               ->template propagate<BoundTrackParameters, PropagatorOptions<>,
0352                                    SurfaceReached, PathLimitReached>(
0353                   start, target, options);
0354   }
0355 
0356   if (res.ok()) {
0357     // Without errors we can expect a valid endParameters when propagating to a
0358     // target surface
0359     assert((*res).endParameters);
0360     return std::move((*res).endParameters.value());
0361   } else {
0362     return res.error();
0363   }
0364 }