Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StraightLineStepper.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file StraightLineStepper.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 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 
9 #pragma once
10 
11 // Workaround for building on clang+libstdc++
13 
30 
31 #include <algorithm>
32 #include <cmath>
33 #include <functional>
34 #include <limits>
35 #include <string>
36 #include <tuple>
37 
38 namespace Acts {
39 
46  public:
49  using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
50  using CurvilinearState =
51  std::tuple<CurvilinearTrackParameters, Jacobian, double>;
52  using BField = NullBField;
53 
56  struct State {
57  State() = delete;
58 
68  explicit State(const GeometryContext& gctx,
69  const MagneticFieldContext& mctx,
70  const BoundTrackParameters& par,
71  double ssize = std::numeric_limits<double>::max(),
72  double stolerance = s_onSurfaceTolerance)
74  stepSize(ssize),
75  tolerance(stolerance),
76  geoContext(gctx) {
77  (void)mctx;
78  pars.template segment<3>(eFreePos0) = par.position(gctx);
79  pars.template segment<3>(eFreeDir0) = par.direction();
80  pars[eFreeTime] = par.time();
82  if (par.covariance()) {
83  // Get the reference surface for navigation
84  const auto& surface = par.referenceSurface();
85  // set the covariance transport flag to true and copy
86  covTransport = true;
88  jacToGlobal = surface.boundToFreeJacobian(gctx, par.parameters());
89  }
90  }
91 
93  BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
94 
96  FreeMatrix jacTransport = FreeMatrix::Identity();
97 
99  Jacobian jacobian = Jacobian::Identity();
100 
102  FreeVector derivative = FreeVector::Zero();
103 
105  FreeVector pars = FreeVector::Zero();
106 
109 
111  bool covTransport = false;
112  Covariance cov = Covariance::Zero();
113 
115  double pathAccumulated = 0.;
116 
119 
120  // Previous step size for overstep estimation (ignored for SL stepper)
121  double previousStepSize = 0.;
122 
125 
126  // Cache the geometry context of this propagation
127  std::reference_wrapper<const GeometryContext> geoContext;
128  };
129 
132  using state_type = State;
133 
134  StraightLineStepper() = default;
135 
136  State makeState(std::reference_wrapper<const GeometryContext> gctx,
137  std::reference_wrapper<const MagneticFieldContext> mctx,
138  const BoundTrackParameters& par,
139  double ssize = std::numeric_limits<double>::max(),
140  double stolerance = s_onSurfaceTolerance) const {
141  return State{gctx, mctx, par, ssize, stolerance};
142  }
143 
151  void resetState(
152  State& state, const BoundVector& boundParams,
153  const BoundSquareMatrix& cov, const Surface& surface,
154  const double stepSize = std::numeric_limits<double>::max()) const;
155 
161  Result<Vector3> getField(State& state, const Vector3& pos) const {
162  (void)state;
163  (void)pos;
164  // get the field from the cell
165  return Result<Vector3>::success({0., 0., 0.});
166  }
167 
171  Vector3 position(const State& state) const {
172  return state.pars.template segment<3>(eFreePos0);
173  }
174 
178  Vector3 direction(const State& state) const {
179  return state.pars.template segment<3>(eFreeDir0);
180  }
181 
185  double qOverP(const State& state) const { return state.pars[eFreeQOverP]; }
186 
190  double absoluteMomentum(const State& state) const {
191  return particleHypothesis(state).extractMomentum(qOverP(state));
192  }
193 
197  Vector3 momentum(const State& state) const {
198  return absoluteMomentum(state) * direction(state);
199  }
200 
204  double charge(const State& state) const {
205  return particleHypothesis(state).extractCharge(qOverP(state));
206  }
207 
211  const ParticleHypothesis& particleHypothesis(const State& state) const {
212  return state.particleHypothesis;
213  }
214 
218  double time(const State& state) const { return state.pars[eFreeTime]; }
219 
223  double overstepLimit(const State& state) const {
224  (void)state;
225  return -m_overstepLimit;
226  }
227 
242  State& state, const Surface& surface, Direction navDir,
243  const BoundaryCheck& bcheck,
244  ActsScalar surfaceTolerance = s_onSurfaceTolerance,
245  const Logger& logger = getDummyLogger()) const {
246  return detail::updateSingleSurfaceStatus<StraightLineStepper>(
247  *this, state, surface, navDir, bcheck, surfaceTolerance, logger);
248  }
249 
258  template <typename object_intersection_t>
259  void updateStepSize(State& state, const object_intersection_t& oIntersection,
260  Direction /*direction*/, bool release = true) const {
261  detail::updateSingleStepSize<StraightLineStepper>(state, oIntersection,
262  release);
263  }
264 
271  void setStepSize(State& state, double stepSize,
273  bool release = true) const {
274  state.previousStepSize = state.stepSize.value();
275  state.stepSize.update(stepSize, stype, release);
276  }
277 
282  double getStepSize(const State& state, ConstrainedStep::Type stype) const {
283  return state.stepSize.value(stype);
284  }
285 
289  void releaseStepSize(State& state) const {
291  }
292 
296  std::string outputStepSize(const State& state) const {
297  return state.stepSize.toString();
298  }
299 
315  State& state, const Surface& surface, bool transportCov = true,
316  const FreeToBoundCorrection& freeToBoundCorrection =
317  FreeToBoundCorrection(false)) const;
318 
330  CurvilinearState curvilinearState(State& state,
331  bool transportCov = true) const;
332 
340  void update(State& state, const FreeVector& freeParams,
341  const BoundVector& boundParams, const Covariance& covariance,
342  const Surface& surface) const;
343 
351  void update(State& state, const Vector3& uposition, const Vector3& udirection,
352  double qop, double time) const;
353 
359  void transportCovarianceToCurvilinear(State& state) const;
360 
374  State& state, const Surface& surface,
375  const FreeToBoundCorrection& freeToBoundCorrection =
376  FreeToBoundCorrection(false)) const;
377 
388  template <typename propagator_state_t, typename navigator_t>
389  Result<double> step(propagator_state_t& state,
390  const navigator_t& /*navigator*/) const {
391  // use the adjusted step size
392  const auto h = state.stepping.stepSize.value() * state.options.direction;
393  const auto m = state.stepping.particleHypothesis.mass();
394  const auto p = absoluteMomentum(state.stepping);
395  // time propagates along distance as 1/b = sqrt(1 + m²/p²)
396  const auto dtds = std::hypot(1., m / p);
397  // Update the track parameters according to the equations of motion
398  Vector3 dir = direction(state.stepping);
399  state.stepping.pars.template segment<3>(eFreePos0) += h * dir;
400  state.stepping.pars[eFreeTime] += h * dtds;
401  // Propagate the jacobian
402  if (state.stepping.covTransport) {
403  // The step transport matrix in global coordinates
404  FreeMatrix D = FreeMatrix::Identity();
405  D.block<3, 3>(0, 4) = ActsSquareMatrix<3>::Identity() * h;
406  // Extend the calculation by the time propagation
407  // Evaluate dt/dlambda
408  D(3, 7) = h * m * m * state.stepping.pars[eFreeQOverP] / dtds;
409  // Set the derivative factor the time
410  state.stepping.derivative(3) = dtds;
411  // Update jacobian and derivative
412  state.stepping.jacTransport = D * state.stepping.jacTransport;
413  state.stepping.derivative.template head<3>() = dir;
414  }
415  // state the path length
416  state.stepping.pathAccumulated += h;
417 
418  // return h
419  return h;
420  }
421 
422  private:
424 };
425 
426 } // namespace Acts