Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:55

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