Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-12 07:53:23

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 // Construct initial track parameters.
0058 Acts::BoundTrackParameters makeParameters() {
0059   // create covariance matrix from reasonable standard deviations
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   // define a track in the transverse plane along x
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 // Instantiate the tester
0075 const FitterTester tester;
0076 
0077 // reconstruction propagator and fitter
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 }  // namespace
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   // regular smoothing
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   // reverse filtering instead of smoothing
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   // regular smoothing
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   // reverse filtering instead of smoothing
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   // fitter options w/o target surface. outlier distance is set to be below the
0196   // default outlier distance in the `MeasurementsCreator`
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   // Track of 1 GeV with a threshold set at 0.1 GeV, reversed filtering should
0230   // not be used
0231   test(0.1_GeV, false, false, true);
0232 
0233   // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
0234   // be used
0235   test(10._GeV, false, true, false);
0236 
0237   // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
0238   // be used
0239   test(0.1_GeV, true, true, false);
0240 }
0241 
0242 // TODO this is not really Kalman fitter specific. is probably better tested
0243 // with a synthetic trajectory.
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()