Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-23 08:24:29

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 using namespace Acts;
0035 using namespace Acts::detail::Test;
0036 using namespace Acts::UnitLiterals;
0037 
0038 namespace ActsTests {
0039 
0040 using StraightPropagator =
0041     Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0042 using ConstantFieldStepper = Acts::EigenStepper<>;
0043 using ConstantFieldPropagator =
0044     Acts::Propagator<ConstantFieldStepper, Acts::Navigator>;
0045 
0046 using KalmanUpdater = Acts::GainMatrixUpdater;
0047 using KalmanSmoother = Acts::GainMatrixSmoother;
0048 using KalmanFitter =
0049     Acts::KalmanFitter<ConstantFieldPropagator, VectorMultiTrajectory>;
0050 
0051 static const auto pion = Acts::ParticleHypothesis::pion();
0052 
0053 KalmanUpdater kfUpdater;
0054 KalmanSmoother kfSmoother;
0055 
0056 // Construct initial track parameters.
0057 Acts::BoundTrackParameters makeParameters() {
0058   // create covariance matrix from reasonable standard deviations
0059   Acts::BoundVector stddev;
0060   stddev[Acts::eBoundLoc0] = 100_um;
0061   stddev[Acts::eBoundLoc1] = 100_um;
0062   stddev[Acts::eBoundTime] = 25_ns;
0063   stddev[Acts::eBoundPhi] = 2_degree;
0064   stddev[Acts::eBoundTheta] = 2_degree;
0065   stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
0066   Acts::BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0067   // define a track in the transverse plane along x
0068   Acts::Vector4 mPos4(-3_m, 0., 0., 42_ns);
0069   return Acts::BoundTrackParameters::createCurvilinear(
0070       mPos4, 0_degree, 90_degree, 1_e / 1_GeV, cov, pion);
0071 }
0072 
0073 // Instantiate the tester
0074 const FitterTester tester;
0075 
0076 // reconstruction propagator and fitter
0077 auto kfLogger = getDefaultLogger("KalmanFilter", Logging::INFO);
0078 const auto kfZeroPropagator =
0079     makeConstantFieldPropagator<ConstantFieldStepper>(tester.geometry, 0_T);
0080 const auto kfZero = KalmanFitter(kfZeroPropagator, std::move(kfLogger));
0081 
0082 std::default_random_engine rng(42);
0083 
0084 auto makeDefaultKalmanFitterOptions() {
0085   KalmanFitterExtensions<VectorMultiTrajectory> extensions;
0086   extensions.calibrator
0087       .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0088   extensions.updater.connect<&KalmanUpdater::operator()<VectorMultiTrajectory>>(
0089       &kfUpdater);
0090   extensions.smoother
0091       .connect<&KalmanSmoother::operator()<VectorMultiTrajectory>>(&kfSmoother);
0092   extensions.surfaceAccessor.connect<
0093       &Acts::detail::Test::TestSourceLink::SurfaceAccessor::operator()>(
0094       &tester.surfaceAccessor);
0095 
0096   return KalmanFitterOptions(
0097       tester.geoCtx, tester.magCtx, tester.calCtx, extensions,
0098       PropagatorPlainOptions(tester.geoCtx, tester.magCtx));
0099 }
0100 
0101 BOOST_AUTO_TEST_SUITE(TrackFittingSuite)
0102 
0103 BOOST_AUTO_TEST_CASE(ZeroFieldNoSurfaceForward) {
0104   auto start = makeParameters();
0105   auto kfOptions = makeDefaultKalmanFitterOptions();
0106 
0107   bool expected_reversed = false;
0108   bool expected_smoothed = true;
0109   tester.test_ZeroFieldNoSurfaceForward(kfZero, kfOptions, start, rng,
0110                                         expected_reversed, expected_smoothed,
0111                                         true);
0112 }
0113 
0114 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceForward) {
0115   auto start = makeParameters();
0116   auto kfOptions = makeDefaultKalmanFitterOptions();
0117 
0118   // regular smoothing
0119   kfOptions.reversedFiltering = false;
0120   bool expected_reversed = false;
0121   bool expected_smoothed = true;
0122   tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
0123                                           expected_reversed, expected_smoothed,
0124                                           true);
0125 
0126   // reverse filtering instead of smoothing
0127   kfOptions.reversedFiltering = true;
0128   kfOptions.reversedFilteringCovarianceScaling = 100.0;
0129   expected_reversed = true;
0130   expected_smoothed = false;
0131   tester.test_ZeroFieldWithSurfaceForward(kfZero, kfOptions, start, rng,
0132                                           expected_reversed, expected_smoothed,
0133                                           true);
0134 }
0135 
0136 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceBackward) {
0137   auto start = makeParameters();
0138   auto kfOptions = makeDefaultKalmanFitterOptions();
0139 
0140   // regular smoothing
0141   kfOptions.reversedFiltering = false;
0142   bool expected_reversed = false;
0143   bool expected_smoothed = true;
0144   tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
0145                                            expected_reversed, expected_smoothed,
0146                                            true);
0147 
0148   // reverse filtering instead of smoothing
0149   kfOptions.reversedFiltering = true;
0150   kfOptions.reversedFilteringCovarianceScaling = 100.0;
0151   expected_reversed = true;
0152   expected_smoothed = false;
0153   tester.test_ZeroFieldWithSurfaceBackward(kfZero, kfOptions, start, rng,
0154                                            expected_reversed, expected_smoothed,
0155                                            true);
0156 }
0157 
0158 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceAtExit) {
0159   auto start = makeParameters();
0160   auto kfOptions = makeDefaultKalmanFitterOptions();
0161 
0162   bool expected_reversed = false;
0163   bool expected_smoothed = true;
0164   tester.test_ZeroFieldWithSurfaceAtExit(kfZero, kfOptions, start, rng,
0165                                          expected_reversed, expected_smoothed,
0166                                          true);
0167 }
0168 
0169 BOOST_AUTO_TEST_CASE(ZeroFieldShuffled) {
0170   auto start = makeParameters();
0171   auto kfOptions = makeDefaultKalmanFitterOptions();
0172 
0173   bool expected_reversed = false;
0174   bool expected_smoothed = true;
0175   tester.test_ZeroFieldShuffled(kfZero, kfOptions, start, rng,
0176                                 expected_reversed, expected_smoothed, true);
0177 }
0178 
0179 BOOST_AUTO_TEST_CASE(ZeroFieldWithHole) {
0180   auto start = makeParameters();
0181   auto kfOptions = makeDefaultKalmanFitterOptions();
0182 
0183   bool expected_reversed = false;
0184   bool expected_smoothed = true;
0185   tester.test_ZeroFieldWithHole(kfZero, kfOptions, start, rng,
0186                                 expected_reversed, expected_smoothed, true);
0187 }
0188 
0189 BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
0190   auto start = makeParameters();
0191 
0192   // fitter options w/o target surface. outlier distance is set to be below the
0193   // default outlier distance in the `MeasurementsCreator`
0194   auto kfOptions = makeDefaultKalmanFitterOptions();
0195 
0196   TestOutlierFinder tof{5_mm};
0197   kfOptions.extensions.outlierFinder
0198       .connect<&TestOutlierFinder::operator()<VectorMultiTrajectory>>(&tof);
0199 
0200   bool expected_reversed = false;
0201   bool expected_smoothed = true;
0202   tester.test_ZeroFieldWithOutliers(kfZero, kfOptions, start, rng,
0203                                     expected_reversed, expected_smoothed, true);
0204 }
0205 
0206 BOOST_AUTO_TEST_CASE(ZeroFieldWithReverseFiltering) {
0207   auto start = makeParameters();
0208 
0209   auto test = [&](double threshold, bool reverse, bool expected_reversed,
0210                   bool expected_smoothed) {
0211     auto kfOptions = makeDefaultKalmanFitterOptions();
0212 
0213     TestReverseFilteringLogic trfl{threshold};
0214     kfOptions.extensions.reverseFilteringLogic
0215         .connect<&TestReverseFilteringLogic::operator()<VectorMultiTrajectory>>(
0216             &trfl);
0217 
0218     kfOptions.reversedFiltering = reverse;
0219     kfOptions.reversedFilteringCovarianceScaling = 100.0;
0220 
0221     tester.test_ZeroFieldWithReverseFiltering(kfZero, kfOptions, start, rng,
0222                                               expected_reversed,
0223                                               expected_smoothed, true);
0224   };
0225 
0226   // Track of 1 GeV with a threshold set at 0.1 GeV, reversed filtering should
0227   // not be used
0228   test(0.1_GeV, false, false, true);
0229 
0230   // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
0231   // be used
0232   test(10._GeV, false, true, false);
0233 
0234   // Track of 1 GeV with a threshold set at 10 GeV, reversed filtering should
0235   // be used
0236   test(0.1_GeV, true, true, false);
0237 }
0238 
0239 // TODO this is not really Kalman fitter specific. is probably better tested
0240 // with a synthetic trajectory.
0241 BOOST_AUTO_TEST_CASE(GlobalCovariance) {
0242   auto start = makeParameters();
0243   auto kfOptions = makeDefaultKalmanFitterOptions();
0244 
0245   tester.test_GlobalCovariance(kfZero, kfOptions, start, rng);
0246 }
0247 
0248 BOOST_AUTO_TEST_SUITE_END()
0249 
0250 }  // namespace ActsTests