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