Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EigenStepper.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EigenStepper.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2022 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 
28 
29 #include <cmath>
30 #include <functional>
31 #include <limits>
32 
33 namespace Acts {
34 
47 template <typename extensionlist_t = StepperExtensionList<DefaultExtension>,
48  typename auctioneer_t = detail::VoidAuctioneer>
49 class EigenStepper {
50  public:
54  using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
55  using CurvilinearState =
56  std::tuple<CurvilinearTrackParameters, Jacobian, double>;
57 
62  struct State {
63  State() = delete;
64 
73  explicit State(const GeometryContext& gctx,
74  MagneticFieldProvider::Cache fieldCacheIn,
75  const BoundTrackParameters& par,
76  double ssize = std::numeric_limits<double>::max())
78  stepSize(ssize),
79  fieldCache(std::move(fieldCacheIn)),
80  geoContext(gctx) {
81  pars.template segment<3>(eFreePos0) = par.position(gctx);
82  pars.template segment<3>(eFreeDir0) = par.direction();
83  pars[eFreeTime] = par.time();
85 
86  // Init the jacobian matrix if needed
87  if (par.covariance()) {
88  // Get the reference surface for navigation
89  const auto& surface = par.referenceSurface();
90  // set the covariance transport flag to true and copy
91  covTransport = true;
93  jacToGlobal = surface.boundToFreeJacobian(gctx, par.parameters());
94  }
95  }
96 
98  FreeVector pars = FreeVector::Zero();
99 
102 
105  bool covTransport = false;
106  Covariance cov = Covariance::Zero();
107 
109  Jacobian jacobian = Jacobian::Identity();
110 
112  BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
113 
115  FreeMatrix jacTransport = FreeMatrix::Identity();
116 
118  FreeVector derivative = FreeVector::Zero();
119 
121  double pathAccumulated = 0.;
122 
125 
127  double previousStepSize = 0.;
128 
133 
135  std::reference_wrapper<const GeometryContext> geoContext;
136 
138  extensionlist_t extension;
139 
141  auctioneer_t auctioneer;
142 
144  struct {
150  std::array<double, 4> kQoP{};
151  } stepData;
152  };
153 
155  EigenStepper(std::shared_ptr<const MagneticFieldProvider> bField,
156  double overstepLimit = 100 * UnitConstants::um);
157 
158  State makeState(std::reference_wrapper<const GeometryContext> gctx,
159  std::reference_wrapper<const MagneticFieldContext> mctx,
160  const BoundTrackParameters& par,
161  double ssize = std::numeric_limits<double>::max()) const;
162 
170  void resetState(
171  State& state, const BoundVector& boundParams,
172  const BoundSquareMatrix& cov, const Surface& surface,
173  const double stepSize = std::numeric_limits<double>::max()) const;
174 
181  Result<Vector3> getField(State& state, const Vector3& pos) const {
182  // get the field from the cell
183  return m_bField->getField(pos, state.fieldCache);
184  }
185 
189  Vector3 position(const State& state) const {
190  return state.pars.template segment<3>(eFreePos0);
191  }
192 
196  Vector3 direction(const State& state) const {
197  return state.pars.template segment<3>(eFreeDir0);
198  }
199 
203  double qOverP(const State& state) const { return state.pars[eFreeQOverP]; }
204 
208  double absoluteMomentum(const State& state) const {
209  return particleHypothesis(state).extractMomentum(qOverP(state));
210  }
211 
215  Vector3 momentum(const State& state) const {
216  return absoluteMomentum(state) * direction(state);
217  }
218 
222  double charge(const State& state) const {
223  return particleHypothesis(state).extractCharge(qOverP(state));
224  }
225 
229  const ParticleHypothesis& particleHypothesis(const State& state) const {
230  return state.particleHypothesis;
231  }
232 
236  double time(const State& state) const { return state.pars[eFreeTime]; }
237 
250  State& state, const Surface& surface, Direction navDir,
251  const BoundaryCheck& bcheck,
252  ActsScalar surfaceTolerance = s_onSurfaceTolerance,
253  const Logger& logger = getDummyLogger()) const {
254  return detail::updateSingleSurfaceStatus<EigenStepper>(
255  *this, state, surface, navDir, bcheck, surfaceTolerance, logger);
256  }
257 
268  template <typename object_intersection_t>
269  void updateStepSize(State& state, const object_intersection_t& oIntersection,
270  Direction /*direction*/, bool release = true) const {
271  detail::updateSingleStepSize<EigenStepper>(state, oIntersection, release);
272  }
273 
280  void setStepSize(State& state, double stepSize,
282  bool release = true) const {
283  state.previousStepSize = state.stepSize.value();
284  state.stepSize.update(stepSize, stype, release);
285  }
286 
291  double getStepSize(const State& state, ConstrainedStep::Type stype) const {
292  return state.stepSize.value(stype);
293  }
294 
298  void releaseStepSize(State& state) const {
300  }
301 
305  std::string outputStepSize(const State& state) const {
306  return state.stepSize.toString();
307  }
308 
312  double overstepLimit(const State& state) const {
313  (void)state;
314  // A dynamic overstep limit could sit here
315  return -m_overstepLimit;
316  }
317 
335  State& state, const Surface& surface, bool transportCov = true,
336  const FreeToBoundCorrection& freeToBoundCorrection =
337  FreeToBoundCorrection(false)) const;
338 
351  CurvilinearState curvilinearState(State& state,
352  bool transportCov = true) const;
353 
361  void update(State& state, const FreeVector& freeParams,
362  const BoundVector& boundParams, const Covariance& covariance,
363  const Surface& surface) const;
364 
372  void update(State& state, const Vector3& uposition, const Vector3& udirection,
373  double qOverP, double time) const;
374 
380  void transportCovarianceToCurvilinear(State& state) const;
381 
393  State& state, const Surface& surface,
394  const FreeToBoundCorrection& freeToBoundCorrection =
395  FreeToBoundCorrection(false)) const;
396 
405  template <typename propagator_state_t, typename navigator_t>
406  Result<double> step(propagator_state_t& state,
407  const navigator_t& navigator) const;
408 
413  void setIdentityJacobian(State& state) const;
414 
415  protected:
417  std::shared_ptr<const MagneticFieldProvider> m_bField;
418 
421 };
422 } // namespace Acts
423