Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-06 07:45:20

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/BoundTrackParameters.hpp"
0015 #include "Acts/EventData/MultiComponentTrackParameters.hpp"
0016 #include "Acts/EventData/MultiTrajectory.hpp"
0017 #include "Acts/EventData/TrackContainer.hpp"
0018 #include "Acts/EventData/TrackProxy.hpp"
0019 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0020 #include "Acts/EventData/VectorTrackContainer.hpp"
0021 #include "Acts/EventData/detail/TestSourceLink.hpp"
0022 #include "Acts/Geometry/GeometryIdentifier.hpp"
0023 #include "Acts/Propagator/MultiEigenStepperLoop.hpp"
0024 #include "Acts/Propagator/Navigator.hpp"
0025 #include "Acts/Propagator/Propagator.hpp"
0026 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0027 #include "Acts/Surfaces/Surface.hpp"
0028 #include "Acts/TrackFitting/BetheHeitlerApprox.hpp"
0029 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0030 #include "Acts/TrackFitting/GaussianSumFitter.hpp"
0031 #include "Acts/TrackFitting/GsfMixtureReduction.hpp"
0032 #include "Acts/TrackFitting/GsfOptions.hpp"
0033 #include "Acts/Utilities/Holders.hpp"
0034 #include "ActsTests/CommonHelpers/MeasurementsCreator.hpp"
0035 
0036 #include <memory>
0037 #include <optional>
0038 #include <random>
0039 #include <string>
0040 #include <tuple>
0041 #include <vector>
0042 
0043 #include "FitterTestsCommon.hpp"
0044 
0045 using namespace Acts;
0046 using namespace detail::Test;
0047 using namespace UnitLiterals;
0048 
0049 namespace ActsTests {
0050 
0051 static const auto electron = ParticleHypothesis::electron();
0052 
0053 GainMatrixUpdater kfUpdater;
0054 
0055 FitterTester tester;
0056 
0057 GsfExtensions<VectorMultiTrajectory> getExtensions() {
0058   GsfExtensions<VectorMultiTrajectory> extensions;
0059   extensions.calibrator
0060       .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0061   extensions.updater
0062       .connect<&GainMatrixUpdater::operator()<VectorMultiTrajectory>>(
0063           &kfUpdater);
0064   extensions.surfaceAccessor
0065       .connect<&TestSourceLink::SurfaceAccessor::operator()>(
0066           &tester.surfaceAccessor);
0067   extensions.mixtureReducer.connect<&reduceMixtureWithKLDistance>();
0068   return extensions;
0069 }
0070 
0071 using Stepper = MultiEigenStepperLoop<>;
0072 using Propagator = Propagator<Stepper, Navigator>;
0073 using GSF = GaussianSumFitter<Propagator, VectorMultiTrajectory>;
0074 
0075 const GSF gsfZero(
0076     makeConstantFieldPropagator<Stepper>(tester.geometry, 0_T),
0077     std::make_shared<AtlasBetheHeitlerApprox>(makeDefaultBetheHeitlerApprox()));
0078 
0079 std::default_random_engine rng(42);
0080 
0081 auto makeDefaultGsfOptions() {
0082   GsfOptions<VectorMultiTrajectory> opts{tester.geoCtx, tester.magCtx,
0083                                          tester.calCtx};
0084   opts.extensions = getExtensions();
0085   opts.propagatorPlainOptions =
0086       PropagatorPlainOptions(tester.geoCtx, tester.magCtx);
0087   return opts;
0088 }
0089 
0090 // A Helper type to allow us to put the MultiComponentBoundTrackParameters into
0091 // the function so that it can also be used as GenericBoundTrackParameters for
0092 // the MeasurementsCreator
0093 struct MultiCmpsParsInterface : public BoundTrackParameters {
0094   MultiComponentBoundTrackParameters multi_pars;
0095 
0096   explicit MultiCmpsParsInterface(const MultiComponentBoundTrackParameters &p)
0097       : BoundTrackParameters(p.merge(ComponentMergeMethod::eMean)),
0098         multi_pars(p) {}
0099 
0100   explicit operator MultiComponentBoundTrackParameters() const {
0101     return multi_pars;
0102   }
0103 };
0104 
0105 auto makeParameters() {
0106   // create covariance matrix from reasonable standard deviations
0107   BoundVector stddev;
0108   stddev[eBoundLoc0] = 100_um;
0109   stddev[eBoundLoc1] = 100_um;
0110   stddev[eBoundTime] = 25_ns;
0111   stddev[eBoundPhi] = 2_degree;
0112   stddev[eBoundTheta] = 2_degree;
0113   stddev[eBoundQOverP] = 1 / 100_GeV;
0114   BoundMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0115 
0116   // define a track in the transverse plane along x
0117   Vector4 mPos4(-3_m, 0., 0., 42_ns);
0118   BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0119       mPos4, 0_degree, 90_degree, 1_e / 1_GeV, cov, electron);
0120 
0121   // Construct bound multi component parameters from curvilinear ones
0122   BoundVector deltaLOC0 = BoundVector::Zero();
0123   deltaLOC0[eBoundLoc0] = 0.5_mm;
0124 
0125   BoundVector deltaLOC1 = BoundVector::Zero();
0126   deltaLOC1[eBoundLoc1] = 0.5_mm;
0127 
0128   BoundVector deltaQOP = BoundVector::Zero();
0129   deltaQOP[eBoundQOverP] = 0.01_GeV;
0130 
0131   std::vector<std::tuple<double, BoundVector, BoundMatrix>> cmps = {
0132       {0.2, cp.parameters(), cov},
0133       {0.2, cp.parameters() + deltaLOC0 + deltaLOC1 + deltaQOP, cov},
0134       {0.2, cp.parameters() + deltaLOC0 - deltaLOC1 - deltaQOP, cov},
0135       {0.2, cp.parameters() - deltaLOC0 + deltaLOC1 + deltaQOP, cov},
0136       {0.2, cp.parameters() - deltaLOC0 - deltaLOC1 - deltaQOP, cov}};
0137 
0138   return MultiCmpsParsInterface(MultiComponentBoundTrackParameters(
0139       cp.referenceSurface().getSharedPtr(), cmps,
0140       [](const auto &cmp) {
0141         return std::tie(std::get<0>(cmp), std::get<1>(cmp), std::get<2>(cmp));
0142       },
0143       electron));
0144 }
0145 
0146 BOOST_AUTO_TEST_SUITE(TrackFittingSuite)
0147 
0148 BOOST_AUTO_TEST_CASE(ZeroFieldNoSurfaceForward) {
0149   auto multi_pars = makeParameters();
0150   auto options = makeDefaultGsfOptions();
0151 
0152   tester.test_ZeroFieldNoSurfaceForward(gsfZero, options, multi_pars, rng, true,
0153                                         false, false);
0154 }
0155 
0156 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceForward) {
0157   auto multi_pars = makeParameters();
0158   auto options = makeDefaultGsfOptions();
0159 
0160   tester.test_ZeroFieldWithSurfaceForward(gsfZero, options, multi_pars, rng,
0161                                           true, false, false);
0162 }
0163 
0164 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceBackward) {
0165   auto multi_pars = makeParameters();
0166   auto options = makeDefaultGsfOptions();
0167 
0168   tester.test_ZeroFieldWithSurfaceBackward(gsfZero, options, multi_pars, rng,
0169                                            true, false, false);
0170 }
0171 
0172 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceAtExit) {
0173   auto multi_pars = makeParameters();
0174   auto options = makeDefaultGsfOptions();
0175 
0176   tester.test_ZeroFieldWithSurfaceBackward(gsfZero, options, multi_pars, rng,
0177                                            true, false, false);
0178 }
0179 
0180 BOOST_AUTO_TEST_CASE(ZeroFieldShuffled) {
0181   auto multi_pars = makeParameters();
0182   auto options = makeDefaultGsfOptions();
0183 
0184   tester.test_ZeroFieldShuffled(gsfZero, options, multi_pars, rng, true, false,
0185                                 false);
0186 }
0187 
0188 BOOST_AUTO_TEST_CASE(ZeroFieldWithHole) {
0189   auto options = makeDefaultGsfOptions();
0190   auto multi_pars = makeParameters();
0191 
0192   tester.test_ZeroFieldWithHole(gsfZero, options, multi_pars, rng, true, false,
0193                                 false);
0194 }
0195 
0196 BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
0197   // fitter options w/o target surface. outlier distance is set to be below the
0198   // default outlier distance in the `MeasurementsCreator`
0199   TestOutlierFinder tof{5_mm};
0200   auto options = makeDefaultGsfOptions();
0201   options.extensions.outlierFinder
0202       .connect<&TestOutlierFinder::operator()<VectorMultiTrajectory>>(&tof);
0203 
0204   auto multi_pars = makeParameters();
0205 
0206   tester.test_ZeroFieldWithOutliers(gsfZero, options, multi_pars, rng, true,
0207                                     false, false);
0208 }
0209 
0210 BOOST_AUTO_TEST_CASE(WithFinalMultiComponentState) {
0211   TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0212   using namespace GsfConstants;
0213   std::string key(kFinalMultiComponentStateColumn);
0214   tracks.template addColumn<FinalMultiComponentState>(key);
0215 
0216   auto multi_pars = makeParameters();
0217   auto measurements =
0218       createMeasurements(tester.simPropagator, tester.geoCtx, tester.magCtx,
0219                          multi_pars, tester.resolutions, rng);
0220   auto sourceLinks = tester.prepareSourceLinks(measurements.sourceLinks);
0221   auto options = makeDefaultGsfOptions();
0222 
0223   // create a boundless target surface near the tracker exit
0224   Vector3 center(-3._m, 0., 0.);
0225   Vector3 normal(1., 0., 0.);
0226   std::shared_ptr<PlaneSurface> targetSurface =
0227       CurvilinearSurface(center, normal).planeSurface();
0228 
0229   options.referenceSurface = targetSurface.get();
0230 
0231   auto res = gsfZero.fit(sourceLinks.begin(), sourceLinks.end(), multi_pars,
0232                          options, tracks);
0233 
0234   BOOST_REQUIRE(res.ok());
0235   BOOST_CHECK(res->template component<FinalMultiComponentState>(
0236                      kFinalMultiComponentStateColumn)
0237                   .has_value());
0238 }
0239 
0240 BOOST_AUTO_TEST_SUITE_END()
0241 
0242 }  // namespace ActsTests