ECCE @ 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 
11 #include <cmath>
12 #include <random>
13 #include <vector>
14 
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 
126  // The start position and start parameters
127  Vector3D pos(-3_m, 0., 0.), mom(1_GeV, 0., 0);
129 
130  // Create the ActionList and AbortList
131  using StepWiseResult = StepWiseActor::result_type;
132  using StepWiseActors = ActionList<StepWiseActor>;
133  using Aborters = AbortList<EndOfWorldReached>;
134 
135  // Create some options
136  using StepWiseOptions = PropagatorOptions<StepWiseActors, Aborters>;
137  StepWiseOptions swOptions(tgContext, mfContext);
138 
139  using PlainActors = ActionList<>;
140  using PlainOptions = PropagatorOptions<PlainActors, Aborters>;
141  PlainOptions pOptions(tgContext, mfContext);
142 
143  // Run the standard propagation
144  const auto& pResult = propagator.propagate(start, pOptions).value();
145  // Let's get the end parameters and jacobian matrix
146  const auto& pJacobian = *(pResult.transportJacobian);
147 
148  // Run the stepwise propagation
149  const auto& swResult = propagator.propagate(start, swOptions).value();
150  auto swJacobianTest = swResult.template get<StepWiseResult>();
151 
152  // (1) Path length test
153  double accPath = 0.;
154  auto swPaths = swJacobianTest.paths;
155  // Sum up the step-wise paths, they are total though
156  for (auto cpath = swPaths.rbegin(); cpath != swPaths.rend(); ++cpath) {
157  if (cpath != swPaths.rend() - 1) {
158  accPath += (*cpath) - (*(cpath + 1));
159  continue;
160  }
161  accPath += (*cpath) - 0.;
162  }
163  CHECK_CLOSE_REL(swJacobianTest.fullPath, accPath, 1e-6);
164 
165  // (2) Jacobian test
166  Jacobian accJacobian = Jacobian::Identity();
167  // The stepwise jacobians
168  auto swJacobians = swJacobianTest.jacobians;
169  // The last-step jacobian, needed for the full jacobian transport
170  const auto& swlJacobian = *(swResult.transportJacobian);
171 
172  // Build up the step-wise jacobians
173  for (auto& j : swJacobians) {
174  accJacobian = j * accJacobian;
175  }
176  accJacobian = swlJacobian * accJacobian;
177  CHECK_CLOSE_OR_SMALL(pJacobian, accJacobian, 1e-6, 1e-9);
178 }
179 
180 } // namespace Test
181 } // namespace Acts