File indexing completed on 2026-05-23 07:36:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0015 #include "Acts/EventData/detail/TestSourceLink.hpp"
0016 #include "Acts/Propagator/EigenStepper.hpp"
0017 #include "Acts/Propagator/Navigator.hpp"
0018 #include "Acts/Propagator/Propagator.hpp"
0019 #include "Acts/Propagator/StraightLineStepper.hpp"
0020 #include "Acts/TrackFitting/GainMatrixSmoother.hpp"
0021 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0022 #include "Acts/TrackFitting/KalmanFitter.hpp"
0023 #include "Acts/Utilities/Logger.hpp"
0024
0025 #include <functional>
0026 #include <memory>
0027 #include <optional>
0028 #include <random>
0029 #include <utility>
0030
0031 #include "FitterTestsCommon.hpp"
0032
0033 using namespace Acts;
0034 using namespace Acts::detail::Test;
0035 using namespace Acts::UnitLiterals;
0036
0037 namespace ActsTests {
0038
0039 using StraightPropagator =
0040 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0041 using ConstantFieldStepper = Acts::EigenStepper<>;
0042 using ConstantFieldPropagator =
0043 Acts::Propagator<ConstantFieldStepper, Acts::Navigator>;
0044
0045 using KalmanUpdater = Acts::GainMatrixUpdater;
0046 using KalmanSmoother = Acts::GainMatrixSmoother;
0047 using KalmanFitter =
0048 Acts::KalmanFitter<ConstantFieldPropagator, VectorMultiTrajectory>;
0049
0050 static const auto pion = Acts::ParticleHypothesis::pion();
0051
0052 KalmanUpdater kfUpdater;
0053 KalmanSmoother kfSmoother;
0054
0055
0056 Acts::BoundTrackParameters makeParameters() {
0057
0058 Acts::BoundVector stddev;
0059 stddev[Acts::eBoundLoc0] = 100_um;
0060 stddev[Acts::eBoundLoc1] = 100_um;
0061 stddev[Acts::eBoundTime] = 25_ns;
0062 stddev[Acts::eBoundPhi] = 2_degree;
0063 stddev[Acts::eBoundTheta] = 2_degree;
0064 stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
0065 Acts::BoundMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0066
0067 Acts::Vector4 mPos4(-3_m, 0., 0., 42_ns);
0068 return Acts::BoundTrackParameters::createCurvilinear(
0069 mPos4, 0_degree, 90_degree, 1_e / 1_GeV, cov, pion);
0070 }
0071
0072
0073 const FitterTester tester;
0074
0075
0076 auto kfLogger = getDefaultLogger("KalmanFilter", Logging::INFO);
0077 const auto kfZeroPropagator =
0078 makeConstantFieldPropagator<ConstantFieldStepper>(tester.geometry, 0_T);
0079 const auto kfZero = KalmanFitter(kfZeroPropagator, std::move(kfLogger));
0080
0081 std::default_random_engine rng(42);
0082
0083 auto makeDefaultKalmanFitterOptions() {
0084 KalmanFitterExtensions<VectorMultiTrajectory> extensions;
0085 extensions.calibrator
0086 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0087 extensions.updater.connect<&KalmanUpdater::operator()<VectorMultiTrajectory>>(
0088 &kfUpdater);
0089 extensions.smoother
0090 .connect<&KalmanSmoother::operator()<VectorMultiTrajectory>>(&kfSmoother);
0091 extensions.surfaceAccessor.connect<
0092 &Acts::detail::Test::TestSourceLink::SurfaceAccessor::operator()>(
0093 &tester.surfaceAccessor);
0094
0095 return KalmanFitterOptions(
0096 tester.geoCtx, tester.magCtx, tester.calCtx, extensions,
0097 PropagatorPlainOptions(tester.geoCtx, tester.magCtx));
0098 }
0099
0100 BOOST_AUTO_TEST_SUITE(TrackFittingSuite)
0101
0102 BOOST_AUTO_TEST_CASE(ZeroFieldNoSurfaceForward) {
0103 auto start = makeParameters();
0104 auto kfOptions = makeDefaultKalmanFitterOptions();
0105
0106 bool expected_reversed = false;
0107 bool expected_smoothed = true;
0108 tester.test_ZeroFieldNoSurfaceForward(kfZero, kfOptions, start, rng,
0109 expected_reversed, expected_smoothed,
0110 true);
0111 }
0112
0113 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceForward) {
0114 auto start = makeParameters();
0115 auto kfOptions = makeDefaultKalmanFitterOptions();
0116
0117
0118 kfOptions.reverseFiltering = false;
0119 bool expected_reversed = false;
0120 bool expected_smoothed = true;
0121 tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
0122 expected_reversed, expected_smoothed,
0123 true);
0124
0125
0126 kfOptions.reverseFiltering = true;
0127 kfOptions.reverseFilteringCovarianceScaling = 100.0;
0128 expected_reversed = true;
0129 expected_smoothed = false;
0130 tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
0131 expected_reversed, expected_smoothed,
0132 true);
0133 }
0134
0135 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceBackward) {
0136 auto start = makeParameters();
0137 auto kfOptions = makeDefaultKalmanFitterOptions();
0138
0139
0140 kfOptions.reverseFiltering = false;
0141 bool expected_reversed = false;
0142 bool expected_smoothed = true;
0143 tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
0144 expected_reversed, expected_smoothed,
0145 true);
0146
0147
0148 kfOptions.reverseFiltering = true;
0149 kfOptions.reverseFilteringCovarianceScaling = 100.0;
0150 expected_reversed = true;
0151 expected_smoothed = false;
0152 tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
0153 expected_reversed, expected_smoothed,
0154 true);
0155 }
0156
0157 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceAtExit) {
0158 auto start = makeParameters();
0159 auto kfOptions = makeDefaultKalmanFitterOptions();
0160
0161 bool expected_reversed = false;
0162 bool expected_smoothed = true;
0163 tester.test_ZeroFieldWithSurfaceAtExit(kfZero, kfOptions, start, rng,
0164 expected_reversed, expected_smoothed,
0165 true);
0166 }
0167
0168 BOOST_AUTO_TEST_CASE(ZeroFieldShuffled) {
0169 auto start = makeParameters();
0170 auto kfOptions = makeDefaultKalmanFitterOptions();
0171
0172 bool expected_reversed = false;
0173 bool expected_smoothed = true;
0174 tester.test_ZeroFieldShuffled(kfZero, kfOptions, start, rng,
0175 expected_reversed, expected_smoothed, true);
0176 }
0177
0178 BOOST_AUTO_TEST_CASE(ZeroFieldWithHole) {
0179 auto start = makeParameters();
0180 auto kfOptions = makeDefaultKalmanFitterOptions();
0181
0182 bool expected_reversed = false;
0183 bool expected_smoothed = true;
0184 tester.test_ZeroFieldWithHole(kfZero, kfOptions, start, rng,
0185 expected_reversed, expected_smoothed, true);
0186 }
0187
0188 BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
0189 auto start = makeParameters();
0190
0191
0192
0193 auto kfOptions = makeDefaultKalmanFitterOptions();
0194
0195 TestOutlierFinder tof{5_mm};
0196 kfOptions.extensions.outlierFinder
0197 .connect<&TestOutlierFinder::operator()<VectorMultiTrajectory>>(&tof);
0198
0199 bool expected_reversed = false;
0200 bool expected_smoothed = true;
0201 tester.test_ZeroFieldWithOutliers(kfZero, kfOptions, start, rng,
0202 expected_reversed, expected_smoothed, true);
0203 }
0204
0205 BOOST_AUTO_TEST_CASE(ZeroFieldWithReverseFiltering) {
0206 auto start = makeParameters();
0207
0208 auto test = [&](double threshold, bool reverse, bool expected_reversed,
0209 bool expected_smoothed) {
0210 auto kfOptions = makeDefaultKalmanFitterOptions();
0211
0212 TestReverseFilteringLogic trfl{threshold};
0213 kfOptions.extensions.reverseFilteringLogic
0214 .connect<&TestReverseFilteringLogic::operator()<VectorMultiTrajectory>>(
0215 &trfl);
0216
0217 kfOptions.reverseFiltering = reverse;
0218 kfOptions.reverseFilteringCovarianceScaling = 100.0;
0219
0220 tester.test_ZeroFieldWithReverseFiltering(kfZero, kfOptions, start, rng,
0221 expected_reversed,
0222 expected_smoothed, true);
0223 };
0224
0225
0226
0227 test(0.1_GeV, false, false, true);
0228
0229
0230
0231 test(10._GeV, false, true, false);
0232
0233
0234
0235 test(0.1_GeV, true, true, false);
0236 }
0237
0238
0239
0240 BOOST_AUTO_TEST_CASE(GlobalCovariance) {
0241 auto start = makeParameters();
0242 auto kfOptions = makeDefaultKalmanFitterOptions();
0243
0244 tester.test_GlobalCovariance(kfZero, kfOptions, start, rng);
0245 }
0246
0247 BOOST_AUTO_TEST_SUITE_END()
0248
0249 }