Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Acts/Propagator/Propagator.ipp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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