File indexing completed on 2026-04-06 07:45:20
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/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
0091
0092
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
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
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
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
0198
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
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 }