File indexing completed on 2026-03-28 07:46:25
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/EventData/AnyTrackProxy.hpp"
0014 #include "Acts/EventData/MultiTrajectory.hpp"
0015 #include "Acts/EventData/ProxyAccessor.hpp"
0016 #include "Acts/EventData/TrackContainer.hpp"
0017 #include "Acts/EventData/TrackProxy.hpp"
0018 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0019 #include "Acts/EventData/VectorTrackContainer.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Surfaces/PerigeeSurface.hpp"
0022 #include "Acts/Utilities/HashedString.hpp"
0023 #include "Acts/Utilities/Holders.hpp"
0024
0025 #include <memory>
0026 #include <vector>
0027
0028 namespace {
0029
0030 using namespace Acts::UnitLiterals;
0031 using namespace Acts;
0032 using namespace Acts::HashedStringLiteral;
0033
0034 const auto gctx = GeometryContext::dangerouslyDefaultConstruct();
0035
0036
0037 template <typename track_container_t>
0038 void fillTestTrack(typename track_container_t::TrackProxy track) {
0039 auto surface = Acts::Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0040
0041
0042 track.setReferenceSurface(surface);
0043
0044
0045 auto params = track.parameters();
0046 params[eBoundLoc0] = 1.0;
0047 params[eBoundLoc1] = 2.0;
0048 params[eBoundTime] = 3.0;
0049 params[eBoundPhi] = 0.5;
0050 params[eBoundTheta] = std::numbers::pi / 4.0;
0051 params[eBoundQOverP] = 0.1;
0052
0053
0054 auto cov = track.covariance();
0055 cov.setIdentity();
0056 cov(eBoundLoc0, eBoundLoc0) = 0.01;
0057 cov(eBoundQOverP, eBoundQOverP) = 0.0001;
0058
0059
0060 track.chi2() = 12.5f;
0061 track.nDoF() = 10u;
0062 track.nMeasurements() = 8u;
0063 track.nHoles() = 1u;
0064 track.nOutliers() = 0u;
0065 track.nSharedHits() = 2u;
0066
0067
0068 track.setParticleHypothesis(ParticleHypothesis::pion());
0069 }
0070
0071 }
0072
0073 BOOST_AUTO_TEST_SUITE(EventDataAnyTrack)
0074
0075 BOOST_AUTO_TEST_CASE(ConstructFromTrackProxy_ValueHolder) {
0076 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0077
0078 auto track = tc.makeTrack();
0079 fillTestTrack<decltype(tc)>(track);
0080
0081
0082 AnyMutableTrackProxy anyTrack(track);
0083
0084
0085 BOOST_CHECK_EQUAL(anyTrack.index(), track.index());
0086 }
0087
0088 BOOST_AUTO_TEST_CASE(ConstructFromTrackProxy_SharedPtr) {
0089 auto vtc = std::make_shared<VectorTrackContainer>();
0090 auto mtj = std::make_shared<VectorMultiTrajectory>();
0091 TrackContainer tc{vtc, mtj};
0092
0093 auto track = tc.makeTrack();
0094 fillTestTrack<decltype(tc)>(track);
0095
0096
0097 AnyMutableTrackProxy anyTrack(track);
0098
0099
0100 BOOST_CHECK_EQUAL(anyTrack.index(), track.index());
0101 }
0102
0103 BOOST_AUTO_TEST_CASE(ConstructFromConstTrackProxy) {
0104 VectorTrackContainer vtc;
0105 VectorMultiTrajectory mtj;
0106 TrackContainer tc{vtc, mtj};
0107
0108 auto track = tc.makeTrack();
0109 fillTestTrack<decltype(tc)>(track);
0110
0111
0112 auto constTrack = tc.getTrack(track.index());
0113
0114
0115 AnyConstTrackProxy anyTrack(constTrack);
0116
0117 BOOST_CHECK_EQUAL(anyTrack.index(), track.index());
0118 }
0119
0120 BOOST_AUTO_TEST_CASE(ConstructFromReadOnlyTrackContainer) {
0121 VectorTrackContainer vtc;
0122 VectorMultiTrajectory mtj;
0123 TrackContainer tc{vtc, mtj};
0124
0125 auto track = tc.makeTrack();
0126 fillTestTrack<decltype(tc)>(track);
0127
0128 TrackContainer constTc{ConstVectorTrackContainer{vtc},
0129 ConstVectorMultiTrajectory{mtj}};
0130 auto constTrack = constTc.getTrack(track.index());
0131
0132 AnyConstTrackProxy anyTrack(constTrack);
0133
0134 BOOST_CHECK_EQUAL(anyTrack.index(), track.index());
0135 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundLoc0), 1.0, 1e-6);
0136 }
0137
0138 BOOST_AUTO_TEST_CASE(AccessIndices) {
0139 VectorTrackContainer vtc;
0140 VectorMultiTrajectory mtj;
0141 TrackContainer tc{vtc, mtj};
0142
0143 auto track = tc.makeTrack();
0144 fillTestTrack<decltype(tc)>(track);
0145
0146 track.tipIndex() = 42;
0147 track.stemIndex() = 7;
0148
0149 AnyMutableTrackProxy anyTrack(track);
0150
0151 BOOST_CHECK_EQUAL(anyTrack.tipIndex(), 42u);
0152 BOOST_CHECK_EQUAL(anyTrack.stemIndex(), 7u);
0153 BOOST_CHECK_EQUAL(anyTrack.index(), track.index());
0154 }
0155
0156 BOOST_AUTO_TEST_CASE(AccessReferenceSurface) {
0157 VectorTrackContainer vtc;
0158 VectorMultiTrajectory mtj;
0159 TrackContainer tc{vtc, mtj};
0160
0161 auto track = tc.makeTrack();
0162 auto surface = Acts::Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0163 track.setReferenceSurface(surface);
0164
0165 AnyMutableTrackProxy anyTrack(track);
0166
0167 BOOST_CHECK(anyTrack.hasReferenceSurface());
0168 BOOST_CHECK_EQUAL(&anyTrack.referenceSurface(), surface.get());
0169 }
0170
0171 BOOST_AUTO_TEST_CASE(AccessParameters) {
0172 VectorTrackContainer vtc;
0173 VectorMultiTrajectory mtj;
0174 TrackContainer tc{vtc, mtj};
0175
0176 auto track = tc.makeTrack();
0177 fillTestTrack<decltype(tc)>(track);
0178
0179 AnyMutableTrackProxy anyTrack(track);
0180
0181
0182 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundLoc0), 1.0, 1e-6);
0183 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundLoc1), 2.0, 1e-6);
0184 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundTime), 3.0, 1e-6);
0185 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundPhi), 0.5, 1e-6);
0186 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundTheta), std::numbers::pi / 4.0,
0187 1e-6);
0188 BOOST_CHECK_CLOSE(anyTrack.parameter(eBoundQOverP), 0.1, 1e-6);
0189
0190
0191 BOOST_CHECK_CLOSE(anyTrack.phi(), 0.5, 1e-6);
0192 BOOST_CHECK_CLOSE(anyTrack.theta(), std::numbers::pi / 4.0, 1e-6);
0193 BOOST_CHECK_CLOSE(anyTrack.qOverP(), 0.1, 1e-6);
0194
0195
0196 auto paramsView = anyTrack.parameters();
0197 paramsView[eBoundLoc0] = 9.0;
0198 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], 9.0, 1e-6);
0199
0200 AnyConstTrackProxy constTrack(track);
0201 auto constParamsView = constTrack.parameters();
0202 BOOST_CHECK_CLOSE(constParamsView[eBoundLoc0], 9.0, 1e-6);
0203 }
0204
0205 BOOST_AUTO_TEST_CASE(AccessCovariance) {
0206 VectorTrackContainer vtc;
0207 VectorMultiTrajectory mtj;
0208 TrackContainer tc{vtc, mtj};
0209
0210 auto track = tc.makeTrack();
0211 fillTestTrack<decltype(tc)>(track);
0212
0213 AnyMutableTrackProxy anyTrack(track);
0214
0215
0216 BOOST_CHECK_CLOSE(anyTrack.covariance(eBoundLoc0, eBoundLoc0), 0.01, 1e-6);
0217 BOOST_CHECK_CLOSE(anyTrack.covariance(eBoundQOverP, eBoundQOverP), 0.0001,
0218 1e-6);
0219 BOOST_CHECK_CLOSE(anyTrack.covariance(eBoundLoc0, eBoundLoc1), 0.0, 1e-6);
0220
0221
0222 auto covView = anyTrack.covariance();
0223 covView(eBoundLoc0, eBoundLoc1) = 0.5;
0224 BOOST_CHECK_CLOSE(track.covariance()(eBoundLoc0, eBoundLoc1), 0.5, 1e-6);
0225
0226 AnyConstTrackProxy constTrack(track);
0227 auto constCovView = constTrack.covariance();
0228 BOOST_CHECK_CLOSE(constCovView(eBoundLoc0, eBoundLoc1), 0.5, 1e-6);
0229 }
0230
0231 BOOST_AUTO_TEST_CASE(AccessParticleHypothesis) {
0232 VectorTrackContainer vtc;
0233 VectorMultiTrajectory mtj;
0234 TrackContainer tc{vtc, mtj};
0235
0236 auto track = tc.makeTrack();
0237 fillTestTrack<decltype(tc)>(track);
0238
0239 AnyMutableTrackProxy anyTrack(track);
0240
0241 auto ph = anyTrack.particleHypothesis();
0242 BOOST_CHECK_EQUAL(ph, ParticleHypothesis::pion());
0243 }
0244
0245 BOOST_AUTO_TEST_CASE(AccessDerivedQuantities) {
0246 VectorTrackContainer vtc;
0247 VectorMultiTrajectory mtj;
0248 TrackContainer tc{vtc, mtj};
0249
0250 auto track = tc.makeTrack();
0251 fillTestTrack<decltype(tc)>(track);
0252
0253 AnyMutableTrackProxy anyTrack(track);
0254
0255
0256 double expectedCharge =
0257 ParticleHypothesis::pion().extractCharge(track.qOverP());
0258 BOOST_CHECK_CLOSE(anyTrack.charge(), expectedCharge, 1e-6);
0259
0260
0261 double expectedMomentum =
0262 ParticleHypothesis::pion().extractMomentum(track.qOverP());
0263 BOOST_CHECK_CLOSE(anyTrack.absoluteMomentum(), expectedMomentum, 1e-6);
0264
0265
0266 double expectedPt = std::sin(track.theta()) * expectedMomentum;
0267 BOOST_CHECK_CLOSE(anyTrack.transverseMomentum(), expectedPt, 1e-6);
0268 }
0269
0270 BOOST_AUTO_TEST_CASE(AccessStatistics) {
0271 VectorTrackContainer vtc;
0272 VectorMultiTrajectory mtj;
0273 TrackContainer tc{vtc, mtj};
0274
0275 auto track = tc.makeTrack();
0276 fillTestTrack<decltype(tc)>(track);
0277
0278 AnyMutableTrackProxy anyTrack(track);
0279
0280 BOOST_CHECK_EQUAL(anyTrack.chi2(), 12.5f);
0281 BOOST_CHECK_EQUAL(anyTrack.nDoF(), 10u);
0282 BOOST_CHECK_EQUAL(anyTrack.nMeasurements(), 8u);
0283 BOOST_CHECK_EQUAL(anyTrack.nHoles(), 1u);
0284 BOOST_CHECK_EQUAL(anyTrack.nOutliers(), 0u);
0285 BOOST_CHECK_EQUAL(anyTrack.nSharedHits(), 2u);
0286 }
0287
0288 BOOST_AUTO_TEST_CASE(AccessTrackStates) {
0289 VectorTrackContainer vtc;
0290 VectorMultiTrajectory mtj;
0291 TrackContainer tc{vtc, mtj};
0292
0293 auto track = tc.makeTrack();
0294 fillTestTrack<decltype(tc)>(track);
0295
0296
0297 auto ts1 = tc.trackStateContainer().makeTrackState();
0298 auto ts2 = tc.trackStateContainer().makeTrackState();
0299 ts2.previous() = ts1.index();
0300 auto ts3 = tc.trackStateContainer().makeTrackState();
0301 ts3.previous() = ts2.index();
0302
0303 track.tipIndex() = ts3.index();
0304
0305 AnyMutableTrackProxy anyTrack(track);
0306
0307 BOOST_CHECK_EQUAL(anyTrack.nTrackStates(), 3u);
0308 }
0309
0310 BOOST_AUTO_TEST_CASE(AccessDynamicColumns) {
0311 VectorTrackContainer vtc;
0312 VectorMultiTrajectory mtj;
0313 TrackContainer tc{vtc, mtj};
0314
0315
0316 tc.addColumn<int>("customInt");
0317 tc.addColumn<float>("customFloat");
0318
0319 auto track = tc.makeTrack();
0320 fillTestTrack<decltype(tc)>(track);
0321
0322 track.template component<int>("customInt") = 42;
0323 track.template component<float>("customFloat") = 3.14f;
0324
0325 AnyMutableTrackProxy anyTrack(track);
0326
0327
0328 BOOST_CHECK(anyTrack.hasColumn("customInt"_hash));
0329 BOOST_CHECK(anyTrack.hasColumn("customFloat"_hash));
0330 BOOST_CHECK(!anyTrack.hasColumn("nonExistent"_hash));
0331
0332
0333 BOOST_CHECK_EQUAL(anyTrack.component<int>("customInt"_hash), 42);
0334 BOOST_CHECK_CLOSE(anyTrack.component<float>("customFloat"_hash), 3.14f, 1e-6);
0335
0336
0337 BOOST_CHECK_EQUAL((anyTrack.component<int, "customInt"_hash>()), 42);
0338 BOOST_CHECK_CLOSE((anyTrack.component<float, "customFloat"_hash>()), 3.14f,
0339 1e-6);
0340
0341
0342 anyTrack.component<int>("customInt"_hash) = 7;
0343 BOOST_CHECK_EQUAL(anyTrack.component<int>("customInt"_hash), 7);
0344 AnyConstTrackProxy constTrack(track);
0345 BOOST_CHECK_EQUAL(constTrack.component<int>("customInt"_hash), 7);
0346 }
0347
0348 BOOST_AUTO_TEST_CASE(ProxyAccessorWithAnyTrack) {
0349 VectorTrackContainer vtc;
0350 VectorMultiTrajectory mtj;
0351 TrackContainer tc{vtc, mtj};
0352
0353 tc.addColumn<float>("customFloat");
0354 auto track = tc.makeTrack();
0355 fillTestTrack<decltype(tc)>(track);
0356 track.template component<float>("customFloat"_hash) = 1.5f;
0357
0358 ProxyAccessor<float> mutableAccessor("customFloat");
0359 ConstProxyAccessor<float> constAccessor("customFloat");
0360
0361 AnyMutableTrackProxy anyTrack(track);
0362 BOOST_CHECK_CLOSE(mutableAccessor(anyTrack), 1.5f, 1e-6);
0363 mutableAccessor(anyTrack) = 2.25f;
0364 BOOST_CHECK_CLOSE(track.template component<float>("customFloat"_hash), 2.25f,
0365 1e-6);
0366
0367 AnyConstTrackProxy constTrack(track);
0368 BOOST_CHECK_CLOSE(constAccessor(constTrack), 2.25f, 1e-6);
0369 BOOST_CHECK(constAccessor.hasColumn(constTrack));
0370 }
0371
0372 BOOST_AUTO_TEST_CASE(TypeErasureHeterogeneousStorage) {
0373
0374 VectorTrackContainer vtc1;
0375 VectorMultiTrajectory mtj1;
0376 TrackContainer tc1{vtc1, mtj1};
0377
0378 TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0379
0380 auto vtc3 = std::make_shared<VectorTrackContainer>();
0381 auto mtj3 = std::make_shared<VectorMultiTrajectory>();
0382 TrackContainer tc3{vtc3, mtj3};
0383
0384 auto track1 = tc1.makeTrack();
0385 auto track2 = tc2.makeTrack();
0386 auto track3 = tc3.makeTrack();
0387
0388 fillTestTrack<decltype(tc1)>(track1);
0389 fillTestTrack<decltype(tc2)>(track2);
0390 fillTestTrack<decltype(tc3)>(track3);
0391
0392 track1.chi2() = 10.0f;
0393 track2.chi2() = 20.0f;
0394 track3.chi2() = 30.0f;
0395
0396
0397 std::vector<AnyMutableTrackProxy> anyTracks;
0398 anyTracks.emplace_back(track1);
0399 anyTracks.emplace_back(track2);
0400 anyTracks.emplace_back(track3);
0401
0402 BOOST_CHECK_EQUAL(anyTracks.size(), 3u);
0403 BOOST_CHECK_EQUAL(anyTracks[0].chi2(), 10.0f);
0404 BOOST_CHECK_EQUAL(anyTracks[1].chi2(), 20.0f);
0405 BOOST_CHECK_EQUAL(anyTracks[2].chi2(), 30.0f);
0406 }
0407
0408 BOOST_AUTO_TEST_CASE(MemoryFootprint) {
0409
0410
0411
0412 BOOST_CHECK_EQUAL(sizeof(AnyMutableTrackProxy), 3 * sizeof(void*));
0413 BOOST_CHECK_EQUAL(sizeof(AnyConstTrackProxy), 3 * sizeof(void*));
0414 }
0415
0416 BOOST_AUTO_TEST_CASE(CrossTalkWithTrackProxy) {
0417
0418
0419 VectorTrackContainer vtc;
0420 VectorMultiTrajectory mtj;
0421 TrackContainer tc{vtc, mtj};
0422
0423 auto track = tc.makeTrack();
0424 fillTestTrack<decltype(tc)>(track);
0425
0426
0427 AnyMutableTrackProxy anyTrack(track);
0428
0429
0430 BOOST_CHECK_EQUAL(track.chi2(), 12.5f);
0431 BOOST_CHECK_EQUAL(anyTrack.chi2(), 12.5f);
0432
0433
0434 track.chi2() = 42.0f;
0435 track.nMeasurements() = 15u;
0436 track.tipIndex() = 99;
0437
0438
0439 BOOST_CHECK_EQUAL(anyTrack.chi2(), 42.0f);
0440 BOOST_CHECK_EQUAL(anyTrack.nMeasurements(), 15u);
0441 BOOST_CHECK_EQUAL(anyTrack.tipIndex(), 99u);
0442
0443
0444 auto track2 = tc.getTrack(track.index());
0445
0446
0447 BOOST_CHECK_EQUAL(track2.chi2(), 42.0f);
0448 BOOST_CHECK_EQUAL(track2.nMeasurements(), 15u);
0449 BOOST_CHECK_EQUAL(track2.tipIndex(), 99u);
0450
0451
0452 anyTrack.chi2() = 7.5f;
0453 anyTrack.nMeasurements() = 5u;
0454 anyTrack.tipIndex() = 123u;
0455 anyTrack.parameter(eBoundLoc0) = 5.5;
0456 anyTrack.covariance(eBoundLoc0, eBoundLoc0) = 0.2;
0457
0458 BOOST_CHECK_EQUAL(track.chi2(), 7.5f);
0459 BOOST_CHECK_EQUAL(track.nMeasurements(), 5u);
0460 BOOST_CHECK_EQUAL(track.tipIndex(), 123u);
0461 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], 5.5, 1e-6);
0462 BOOST_CHECK_CLOSE(track.covariance()(eBoundLoc0, eBoundLoc0), 0.2, 1e-6);
0463
0464 BOOST_CHECK_EQUAL(track2.chi2(), 7.5f);
0465 BOOST_CHECK_EQUAL(track2.nMeasurements(), 5u);
0466 BOOST_CHECK_EQUAL(track2.tipIndex(), 123u);
0467 BOOST_CHECK_CLOSE(track2.parameters()[eBoundLoc0], 5.5, 1e-6);
0468 BOOST_CHECK_CLOSE(track2.covariance()(eBoundLoc0, eBoundLoc0), 0.2, 1e-6);
0469
0470
0471 track2.chi2() = 100.0f;
0472
0473
0474 BOOST_CHECK_EQUAL(track.chi2(), 100.0f);
0475 BOOST_CHECK_EQUAL(anyTrack.chi2(), 100.0f);
0476 }
0477
0478 BOOST_AUTO_TEST_CASE(ConstCorrectnessCrossTalk) {
0479
0480
0481 VectorTrackContainer vtc;
0482 VectorMultiTrajectory mtj;
0483 TrackContainer tc{vtc, mtj};
0484
0485 auto track = tc.makeTrack();
0486 fillTestTrack<decltype(tc)>(track);
0487 track.chi2() = 25.0f;
0488
0489
0490 AnyConstTrackProxy constAnyTrack(track);
0491
0492
0493 BOOST_CHECK_EQUAL(track.chi2(), 25.0f);
0494 BOOST_CHECK_EQUAL(constAnyTrack.chi2(), 25.0f);
0495
0496
0497 track.chi2() = 50.0f;
0498
0499
0500 BOOST_CHECK_EQUAL(constAnyTrack.chi2(), 50.0f);
0501 }
0502
0503 BOOST_AUTO_TEST_CASE(ConstCorrectnessRestrictions) {
0504
0505 VectorTrackContainer vtc;
0506 VectorMultiTrajectory mtj;
0507 TrackContainer tc{vtc, mtj};
0508
0509 auto mutableTrack = tc.makeTrack();
0510 fillTestTrack<decltype(tc)>(mutableTrack);
0511
0512 auto constTrack = tc.getTrack(mutableTrack.index());
0513
0514
0515
0516 AnyMutableTrackProxy anyMutable1(mutableTrack);
0517
0518
0519 AnyConstTrackProxy anyConst1(mutableTrack);
0520
0521
0522 AnyConstTrackProxy anyConst2(constTrack);
0523
0524
0525
0526
0527
0528
0529 mutableTrack.chi2() = 77.0f;
0530 BOOST_CHECK_EQUAL(anyMutable1.chi2(), 77.0f);
0531 BOOST_CHECK_EQUAL(anyConst1.chi2(), 77.0f);
0532 BOOST_CHECK_EQUAL(anyConst2.chi2(), 77.0f);
0533 }
0534
0535 BOOST_AUTO_TEST_SUITE_END()