Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Propagator.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Propagator.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
12 
13 #include <type_traits>
14 
15 template <typename S, typename N>
16 template <typename result_t, typename propagator_state_t>
18  result_t& result) const
19  -> Result<void> {
20  // Pre-stepping call to the navigator and action list
21  ACTS_VERBOSE("Entering propagation.");
22 
23  // Navigator initialize state call
24  m_navigator.initialize(state, m_stepper);
25  // Pre-Stepping call to the action list
26  state.options.actionList(state, m_stepper, m_navigator, result, logger());
27  // assume negative outcome, only set to true later if we actually have
28  // a positive outcome.
29 
30  // start at true, if we don't begin the stepping loop we're fine.
31  bool terminatedNormally = true;
32 
33  // Pre-Stepping: abort condition check
34  if (!state.options.abortList(state, m_stepper, m_navigator, result,
35  logger())) {
36  // Stepping loop
37  ACTS_VERBOSE("Starting stepping loop.");
38 
39  terminatedNormally = false; // priming error condition
40 
41  // Propagation loop : stepping
42  for (; result.steps < state.options.maxSteps; ++result.steps) {
43  // Pre-Stepping: target setting
44  m_navigator.preStep(state, m_stepper);
45  // Perform a propagation step - it takes the propagation state
46  Result<double> res = m_stepper.step(state, m_navigator);
47  if (res.ok()) {
48  // Accumulate the path length
49  double s = *res;
50  result.pathLength += s;
51  ACTS_VERBOSE("Step with size = " << s << " performed");
52  } else {
53  ACTS_ERROR("Step failed with " << res.error() << ": "
54  << res.error().message());
55  // pass error to caller
56  return res.error();
57  }
58  // Post-stepping:
59  // navigator post step call - action list - aborter list
60  m_navigator.postStep(state, m_stepper);
61  state.options.actionList(state, m_stepper, m_navigator, result, logger());
62  if (state.options.abortList(state, m_stepper, m_navigator, result,
63  logger())) {
64  terminatedNormally = true;
65  break;
66  }
67  }
68  } else {
69  ACTS_VERBOSE("Propagation terminated without going into stepping loop.");
70  }
71 
72  // if we didn't terminate normally (via aborters) set navigation break.
73  // this will trigger error output in the lines below
74  if (!terminatedNormally) {
75  m_navigator.navigationBreak(state.navigation, true);
76  ACTS_ERROR("Propagation reached the step count limit of "
77  << state.options.maxSteps << " (did " << result.steps
78  << " steps)");
79  return PropagatorError::StepCountLimitReached;
80  }
81 
82  // Post-stepping call to the action list
83  ACTS_VERBOSE("Stepping loop done.");
84  state.options.actionList(state, m_stepper, m_navigator, result, logger());
85 
86  // return progress flag here, decide on SUCCESS later
87  return Result<void>::success();
88 }
89 
90 template <typename S, typename N>
91 template <typename parameters_t, typename propagator_options_t,
92  typename path_aborter_t>
93 auto Acts::Propagator<S, N>::propagate(const parameters_t& start,
94  const propagator_options_t& options,
95  bool makeCurvilinear) const
98  typename propagator_options_t::action_list_type>> {
99  // Type of track parameters produced by the propagation
100  using ReturnParameterType = StepperCurvilinearTrackParameters;
101 
103  "return track parameter type must be copy-constructible");
104 
105  // Type of the full propagation result, including output from actions
106  using ResultType =
107  action_list_t_result_t<ReturnParameterType,
108  typename propagator_options_t::action_list_type>;
109 
110  return propagate<parameters_t, propagator_options_t, path_aborter_t>(
111  start, options, makeCurvilinear, ResultType{});
112 }
113 
114 template <typename S, typename N>
115 template <typename parameters_t, typename propagator_options_t,
116  typename path_aborter_t>
118  const parameters_t& start, const propagator_options_t& options,
119  bool makeCurvilinear,
121  typename propagator_options_t::action_list_type>&&
122  inputResult) const
125  typename propagator_options_t::action_list_type>> {
126  static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
127  "Parameters do not fulfill bound parameters concept.");
128 
129  using ResultType = std::decay_t<decltype(inputResult)>;
130 
131  // Type of track parameters produced by the propagation
132  using ReturnParameterType = StepperCurvilinearTrackParameters;
133 
135  "return track parameter type must be copy-constructible");
136 
137  // Expand the abort list with a path aborter
138  path_aborter_t pathAborter;
139  pathAborter.internalLimit = options.pathLimit;
140 
141  auto abortList = options.abortList.append(pathAborter);
142 
143  // The expanded options (including path limit)
144  auto eOptions = options.extend(abortList);
145  using OptionsType = decltype(eOptions);
146  // Initialize the internal propagator state
147  using StateType = State<OptionsType>;
148  StateType state{
149  eOptions,
150  m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
151  eOptions.maxStepSize),
152  m_navigator.makeState(&start.referenceSurface(), nullptr)};
153 
154  static_assert(
155  Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
156  StateType&, const N&>,
157  "Step method of the Stepper is not compatible with the propagator "
158  "state");
159 
160  // Apply the loop protection - it resets the internal path limit
162  state, m_stepper, state.options.abortList.template get<path_aborter_t>(),
163  false, logger());
164  // Perform the actual propagation & check its outcome
165  auto result = propagate_impl<ResultType>(state, inputResult);
166  if (result.ok()) {
167  if (makeCurvilinear) {
169  auto curvState = m_stepper.curvilinearState(state.stepping);
170  // Fill the end parameters
171  inputResult.endParameters =
172  std::get<StepperCurvilinearTrackParameters>(curvState);
173  // Only fill the transport jacobian when covariance transport was done
174  if (state.stepping.covTransport) {
175  inputResult.transportJacobian = std::get<Jacobian>(curvState);
176  }
177  }
178  return Result<ResultType>::success(std::forward<ResultType>(inputResult));
179  } else {
180  return result.error();
181  }
182 }
183 
184 template <typename S, typename N>
185 template <typename parameters_t, typename propagator_options_t,
186  typename target_aborter_t, typename path_aborter_t>
188  const parameters_t& start, const Surface& target,
189  const propagator_options_t& options) const
192  typename propagator_options_t::action_list_type>> {
193  static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
194  "Parameters do not fulfill bound parameters concept.");
195 
196  // Type of track parameters produced at the end of the propagation
197  using return_parameter_type = StepperBoundTrackParameters;
198 
199  // Type of the full propagation result, including output from actions
200  using ResultType =
201  action_list_t_result_t<return_parameter_type,
202  typename propagator_options_t::action_list_type>;
203 
204  return propagate<parameters_t, propagator_options_t, target_aborter_t,
205  path_aborter_t>(start, target, options, ResultType{});
206 }
207 
208 template <typename S, typename N>
209 template <typename parameters_t, typename propagator_options_t,
210  typename target_aborter_t, typename path_aborter_t>
212  const parameters_t& start, const Surface& target,
213  const propagator_options_t& options,
214  action_list_t_result_t<StepperBoundTrackParameters,
215  typename propagator_options_t::action_list_type>
216  inputResult) const
218  StepperBoundTrackParameters,
219  typename propagator_options_t::action_list_type>> {
220  static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
221  "Parameters do not fulfill bound parameters concept.");
222 
223  using ResultType = std::decay_t<decltype(inputResult)>;
224 
225  // Type of provided options
226  target_aborter_t targetAborter;
227  path_aborter_t pathAborter;
228  pathAborter.internalLimit = options.pathLimit;
229  auto abortList = options.abortList.append(targetAborter, pathAborter);
230 
231  // Create the extended options and declare their type
232  auto eOptions = options.extend(abortList);
233  using OptionsType = decltype(eOptions);
234 
235  // Initialize the internal propagator state
236  using StateType = State<OptionsType>;
237  StateType state{
238  eOptions,
239  m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
240  eOptions.maxStepSize),
241  m_navigator.makeState(&start.referenceSurface(), &target)};
242 
243  static_assert(
244  Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
245  StateType&, const N&>,
246  "Step method of the Stepper is not compatible with the propagator "
247  "state");
248 
249  // Apply the loop protection, it resets the internal path limit
251  state, m_stepper, state.options.abortList.template get<path_aborter_t>(),
252  false, logger());
253 
254  // Perform the actual propagation
255  auto result = propagate_impl<ResultType>(state, inputResult);
256 
257  if (result.ok()) {
258  // Compute the final results and mark the propagation as successful
259  auto bsRes = m_stepper.boundState(state.stepping, target);
260  if (!bsRes.ok()) {
261  return bsRes.error();
262  }
263 
264  const auto& bs = *bsRes;
265 
266  // Fill the end parameters
267  inputResult.endParameters = std::get<StepperBoundTrackParameters>(bs);
268  // Only fill the transport jacobian when covariance transport was done
269  if (state.stepping.covTransport) {
270  inputResult.transportJacobian = std::get<Jacobian>(bs);
271  }
272  return Result<ResultType>::success(std::forward<ResultType>(inputResult));
273  } else {
274  return result.error();
275  }
276 }