File indexing completed on 2025-08-05 08:09:19
0001
0002
0003
0004
0005
0006
0007
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
0023 ACTS_VERBOSE("Entering propagation.");
0024
0025 state.stage = PropagatorStage::prePropagation;
0026
0027
0028 m_navigator.initialize(state, m_stepper);
0029
0030 state.options.actionList(state, m_stepper, m_navigator, logger());
0031
0032
0033
0034
0035 bool terminatedNormally = true;
0036
0037
0038 if (!state.options.abortList(state, m_stepper, m_navigator, logger())) {
0039
0040 ACTS_VERBOSE("Starting stepping loop.");
0041
0042 terminatedNormally = false;
0043
0044
0045 for (; state.steps < state.options.maxSteps; ++state.steps) {
0046
0047 state.stage = PropagatorStage::preStep;
0048 m_navigator.preStep(state, m_stepper);
0049
0050 Result<double> res = m_stepper.step(state, m_navigator);
0051 if (res.ok()) {
0052
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
0060 return res.error();
0061 }
0062
0063 m_stepper.releaseStepSize(state.stepping, ConstrainedStep::actor);
0064 m_stepper.releaseStepSize(state.stepping, ConstrainedStep::aborter);
0065
0066
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
0082
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
0092 ACTS_VERBOSE("Stepping loop done.");
0093 state.options.actionList(state, m_stepper, m_navigator, logger());
0094
0095
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
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
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
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
0157 path_aborter_t pathAborter;
0158 pathAborter.internalLimit = options.pathLimit;
0159
0160 auto abortList = options.abortList.append(pathAborter);
0161
0162
0163 auto eOptions = options.extend(abortList);
0164 using OptionsType = decltype(eOptions);
0165
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
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
0199 target_aborter_t targetAborter;
0200 targetAborter.surface = ⌖
0201 path_aborter_t pathAborter;
0202 pathAborter.internalLimit = options.pathLimit;
0203 auto abortList = options.abortList.append(targetAborter, pathAborter);
0204
0205
0206 auto eOptions = options.extend(abortList);
0207 using OptionsType = decltype(eOptions);
0208
0209
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
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& ,
0238 bool makeCurvilinear) const
0239 -> Result<action_list_t_result_t<
0240 StepperCurvilinearTrackParameters,
0241 typename propagator_options_t::action_list_type>> {
0242
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
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
0263 return propagationResult.error();
0264 }
0265
0266 auto curvState = m_stepper.curvilinearState(state.stepping);
0267
0268 result.endParameters =
0269 std::get<StepperCurvilinearTrackParameters>(curvState);
0270
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& ) const
0284 -> Result<action_list_t_result_t<
0285 StepperBoundTrackParameters,
0286 typename propagator_options_t::action_list_type>> {
0287
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
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
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
0313 result.endParameters = std::get<StepperBoundTrackParameters>(bs);
0314
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
0340 ResultType res = ResultType::failure(PropagatorError::Failure);
0341
0342
0343
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
0358
0359 assert((*res).endParameters);
0360 return std::move((*res).endParameters.value());
0361 } else {
0362 return res.error();
0363 }
0364 }