Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanFitterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KalmanFitterTests.cpp
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 #include <boost/test/unit_test.hpp>
10 
31 
32 #include <algorithm>
33 #include <functional>
34 #include <map>
35 #include <memory>
36 #include <optional>
37 #include <random>
38 #include <utility>
39 
40 #include "FitterTestsCommon.hpp"
41 
42 namespace {
43 
44 using namespace Acts;
45 using namespace Acts::Test;
46 using namespace Acts::UnitLiterals;
47 
48 using StraightPropagator =
53 
54 using KalmanUpdater = Acts::GainMatrixUpdater;
55 using KalmanSmoother = Acts::GainMatrixSmoother;
56 using KalmanFitter =
58 
59 static const auto pion = Acts::ParticleHypothesis::pion();
60 
61 KalmanUpdater kfUpdater;
62 KalmanSmoother kfSmoother;
63 
64 // Construct initial track parameters.
66  // create covariance matrix from reasonable standard deviations
67  Acts::BoundVector stddev;
68  stddev[Acts::eBoundLoc0] = 100_um;
69  stddev[Acts::eBoundLoc1] = 100_um;
70  stddev[Acts::eBoundTime] = 25_ns;
71  stddev[Acts::eBoundPhi] = 2_degree;
72  stddev[Acts::eBoundTheta] = 2_degree;
73  stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
74  Acts::BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
75  // define a track in the transverse plane along x
76  Acts::Vector4 mPos4(-3_m, 0., 0., 42_ns);
77  return Acts::CurvilinearTrackParameters(mPos4, 0_degree, 90_degree,
78  1_e / 1_GeV, cov, pion);
79 }
80 
81 // Instantiate the tester
82 const FitterTester tester;
83 
84 // reconstruction propagator and fitter
85 auto kfLogger = getDefaultLogger("KalmanFilter", Logging::INFO);
86 const auto kfZeroPropagator =
87  makeConstantFieldPropagator<ConstantFieldStepper>(tester.geometry, 0_T);
88 const auto kfZero = KalmanFitter(kfZeroPropagator, std::move(kfLogger));
89 
90 std::default_random_engine rng(42);
91 
92 auto makeDefaultKalmanFitterOptions() {
94  extensions.calibrator
95  .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
96  extensions.updater.connect<&KalmanUpdater::operator()<VectorMultiTrajectory>>(
97  &kfUpdater);
98  extensions.smoother
99  .connect<&KalmanSmoother::operator()<VectorMultiTrajectory>>(&kfSmoother);
100  extensions.surfaceAccessor
101  .connect<&Acts::Test::TestSourceLink::SurfaceAccessor::operator()>(
102  &tester.surfaceAccessor);
103 
104  return KalmanFitterOptions(tester.geoCtx, tester.magCtx, tester.calCtx,
105  extensions, PropagatorPlainOptions());
106 }
107 
108 } // namespace
109 
110 BOOST_AUTO_TEST_SUITE(TrackFittingKalmanFitter)
111 
112 BOOST_AUTO_TEST_CASE(ZeroFieldNoSurfaceForward) {
113  auto start = makeParameters();
114  auto kfOptions = makeDefaultKalmanFitterOptions();
115 
116  bool expected_reversed = false;
117  bool expected_smoothed = true;
118  tester.test_ZeroFieldNoSurfaceForward(kfZero, kfOptions, start, rng,
119  expected_reversed, expected_smoothed,
120  true);
121 }
122 
123 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceForward) {
124  auto start = makeParameters();
125  auto kfOptions = makeDefaultKalmanFitterOptions();
126 
127  // regular smoothing
128  kfOptions.reversedFiltering = false;
129  bool expected_reversed = false;
130  bool expected_smoothed = true;
131  tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
132  expected_reversed, expected_smoothed,
133  true);
134 
135  // reverse filtering instead of smoothing
136  kfOptions.reversedFiltering = true;
137  kfOptions.reversedFilteringCovarianceScaling = 100.0;
138  expected_reversed = true;
139  expected_smoothed = false;
140  tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
141  expected_reversed, expected_smoothed,
142  true);
143 }
144 
145 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceBackward) {
146  auto start = makeParameters();
147  auto kfOptions = makeDefaultKalmanFitterOptions();
148 
149  // regular smoothing
150  kfOptions.reversedFiltering = false;
151  bool expected_reversed = false;
152  bool expected_smoothed = true;
153  tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
154  expected_reversed, expected_smoothed,
155  true);
156 
157  // reverse filtering instead of smoothing
158  kfOptions.reversedFiltering = true;
159  kfOptions.reversedFilteringCovarianceScaling = 100.0;
160  expected_reversed = true;
161  expected_smoothed = false;
162  tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
163  expected_reversed, expected_smoothed,
164  true);
165 }
166 
167 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceAtExit) {
168  auto start = makeParameters();
169  auto kfOptions = makeDefaultKalmanFitterOptions();
170 
171  bool expected_reversed = false;
172  bool expected_smoothed = true;
173  tester.test_ZeroFieldWithSurfaceAtExit(kfZero, kfOptions, start, rng,
174  expected_reversed, expected_smoothed,
175  true);
176 }
177 
178 BOOST_AUTO_TEST_CASE(ZeroFieldShuffled) {
179  auto start = makeParameters();
180  auto kfOptions = makeDefaultKalmanFitterOptions();
181 
182  bool expected_reversed = false;
183  bool expected_smoothed = true;
184  tester.test_ZeroFieldShuffled(kfZero, kfOptions, start, rng,
185  expected_reversed, expected_smoothed, true);
186 }
187 
188 BOOST_AUTO_TEST_CASE(ZeroFieldWithHole) {
189  auto start = makeParameters();
190  auto kfOptions = makeDefaultKalmanFitterOptions();
191 
192  bool expected_reversed = false;
193  bool expected_smoothed = true;
194  tester.test_ZeroFieldWithHole(kfZero, kfOptions, start, rng,
195  expected_reversed, expected_smoothed, true);
196 }
197 
198 BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
199  auto start = makeParameters();
200 
201  // fitter options w/o target surface. outlier distance is set to be below the
202  // default outlier distance in the `MeasurementsCreator`
203  auto kfOptions = makeDefaultKalmanFitterOptions();
204 
205  TestOutlierFinder tof{5_mm};
206  kfOptions.extensions.outlierFinder
207  .connect<&TestOutlierFinder::operator()<VectorMultiTrajectory>>(&tof);
208 
209  bool expected_reversed = false;
210  bool expected_smoothed = true;
211  tester.test_ZeroFieldWithOutliers(kfZero, kfOptions, start, rng,
212  expected_reversed, expected_smoothed, true);
213 }
214 
215 BOOST_AUTO_TEST_CASE(ZeroFieldWithReverseFiltering) {
216  auto start = makeParameters();
217 
218  auto test = [&](double threshold, bool reverse, bool expected_reversed,
219  bool expected_smoothed) {
220  auto kfOptions = makeDefaultKalmanFitterOptions();
221 
222  TestReverseFilteringLogic trfl{threshold};
223  kfOptions.extensions.reverseFilteringLogic
224  .connect<&TestReverseFilteringLogic::operator()<VectorMultiTrajectory>>(
225  &trfl);
226 
227  kfOptions.reversedFiltering = reverse;
228  kfOptions.reversedFilteringCovarianceScaling = 100.0;
229 
230  tester.test_ZeroFieldWithReverseFiltering(kfZero, kfOptions, start, rng,
231  expected_reversed,
232  expected_smoothed, true);
233  };
234 
235  // Track of 1 GeV with a threshold set at 0.1 GeV, reversed filtering should
236  // not be used
237  test(0.1_GeV, false, false, true);
238 
239  // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
240  // be used
241  test(10._GeV, false, true, false);
242 
243  // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
244  // be used
245  test(0.1_GeV, true, true, false);
246 }
247 
248 // TODO this is not really Kalman fitter specific. is probably better tested
249 // with a synthetic trajectory.
250 BOOST_AUTO_TEST_CASE(GlobalCovariance) {
251  auto start = makeParameters();
252  auto kfOptions = makeDefaultKalmanFitterOptions();
253 
254  tester.test_GlobalCovariance(kfZero, kfOptions, start, rng);
255 }
256 
257 BOOST_AUTO_TEST_SUITE_END()