EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanExtrapolatorTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KalmanExtrapolatorTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-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 
9 #include <boost/test/unit_test.hpp>
10 
24 
25 #include <cmath>
26 #include <random>
27 #include <vector>
28 
29 using namespace Acts::UnitLiterals;
30 
31 namespace Acts {
32 namespace Test {
33 
34 using Jacobian = BoundMatrix;
36 
37 // Create a test context
43 struct StepWiseActor {
45  struct this_result {
46  std::vector<Jacobian> jacobians = {};
47  std::vector<double> paths = {};
48 
49  double fullPath = 0.;
50 
51  bool finalized = false;
52  };
55 
64  template <typename propagator_state_t, typename stepper_t>
65  void operator()(propagator_state_t& state, const stepper_t& stepper,
66  result_type& result) const {
67  // Listen to the surface and create bound state where necessary
68  auto surface = state.navigation.currentSurface;
69  if (surface and surface->associatedDetectorElement()) {
70  // Create a bound state and log the jacobian
71  auto boundState = stepper.boundState(state.stepping, *surface);
72  result.jacobians.push_back(std::move(std::get<Jacobian>(boundState)));
73  result.paths.push_back(std::get<double>(boundState));
74  }
75  // Also store the jacobian and full path
76  if ((state.navigation.navigationBreak or state.navigation.targetReached) and
77  not result.finalized) {
78  // Set the last stepping parameter
79  result.paths.push_back(state.stepping.pathAccumulated);
80  // Set the full parameter
81  result.fullPath = state.stepping.pathAccumulated;
82  // Remember that you finalized this
83  result.finalized = true;
84  }
85  }
86 
94  template <typename propagator_state_t, typename stepper_t>
95  void operator()(propagator_state_t& /*state*/,
96  const stepper_t& /*unused*/) const {}
97 };
98 
102 BOOST_AUTO_TEST_CASE(kalman_extrapolator) {
103  // Build detector, take the cubic detector
105  auto detector = cGeometry();
106 
107  // The Navigator through the detector geometry
109  navigator.resolvePassive = false;
110  navigator.resolveMaterial = true;
111  navigator.resolveSensitive = true;
112 
113  // Configure propagation with deactivated B-field
114  ConstantBField bField(Vector3D(0., 0., 0.));
116  Stepper stepper(bField);
118  Propagator propagator(stepper, navigator);
119 
120  // Set initial parameters for the particle track
121  Covariance cov;
122  cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
123  0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
124  0, 0;
125  // The start parameters
126  CurvilinearTrackParameters start(Vector4D(-3_m, 0, 0, 42_ns), 0_degree,
127  90_degree, 1_GeV, 1_e, cov);
128 
129  // Create the ActionList and AbortList
130  using StepWiseResult = StepWiseActor::result_type;
131  using StepWiseActors = ActionList<StepWiseActor>;
132  using Aborters = AbortList<EndOfWorldReached>;
133 
134  // Create some options
135  using StepWiseOptions = PropagatorOptions<StepWiseActors, Aborters>;
136  StepWiseOptions swOptions(tgContext, mfContext, getDummyLogger());
137 
138  using PlainActors = ActionList<>;
139  using PlainOptions = PropagatorOptions<PlainActors, Aborters>;
140  PlainOptions pOptions(tgContext, mfContext, getDummyLogger());
141 
142  // Run the standard propagation
143  const auto& pResult = propagator.propagate(start, pOptions).value();
144  // Let's get the end parameters and jacobian matrix
145  const auto& pJacobian = *(pResult.transportJacobian);
146 
147  // Run the stepwise propagation
148  const auto& swResult = propagator.propagate(start, swOptions).value();
149  auto swJacobianTest = swResult.template get<StepWiseResult>();
150 
151  // (1) Path length test
152  double accPath = 0.;
153  auto swPaths = swJacobianTest.paths;
154  // Sum up the step-wise paths, they are total though
155  for (auto cpath = swPaths.rbegin(); cpath != swPaths.rend(); ++cpath) {
156  if (cpath != swPaths.rend() - 1) {
157  accPath += (*cpath) - (*(cpath + 1));
158  continue;
159  }
160  accPath += (*cpath) - 0.;
161  }
162  CHECK_CLOSE_REL(swJacobianTest.fullPath, accPath, 1e-6);
163 
164  // (2) Jacobian test
165  Jacobian accJacobian = Jacobian::Identity();
166  // The stepwise jacobians
167  auto swJacobians = swJacobianTest.jacobians;
168  // The last-step jacobian, needed for the full jacobian transport
169  const auto& swlJacobian = *(swResult.transportJacobian);
170 
171  // Build up the step-wise jacobians
172  for (auto& j : swJacobians) {
173  accJacobian = j * accJacobian;
174  }
175  accJacobian = swlJacobian * accJacobian;
176  CHECK_CLOSE_OR_SMALL(pJacobian, accJacobian, 1e-6, 1e-9);
177 }
178 
179 } // namespace Test
180 } // namespace Acts