File indexing completed on 2025-09-16 08:14:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/EventData/ProxyAccessor.hpp"
0013 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0014 #include "Acts/EventData/VectorTrackContainer.hpp"
0015 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Utilities/Diagnostics.hpp"
0018 #include "Acts/Utilities/Zip.hpp"
0019
0020 #include <algorithm>
0021 #include <numeric>
0022
0023 using namespace Acts;
0024 using namespace Acts::HashedStringLiteral;
0025 using MultiTrajectoryTraits::IndexType;
0026 using namespace Acts::UnitLiterals;
0027
0028 template <typename track_container_t, typename traj_t,
0029 template <typename> class holder_t>
0030 struct Factory {};
0031
0032 template <typename track_container_t, typename traj_t>
0033 struct Factory<track_container_t, traj_t, detail::RefHolder> {
0034 using track_container_type =
0035 TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0036
0037 track_container_t vtc;
0038 traj_t mtj;
0039 track_container_type tc{vtc, mtj};
0040
0041 auto& trackContainer() { return tc; }
0042 auto& trackStateContainer() { return mtj; }
0043 auto& backend() { return vtc; }
0044 };
0045
0046 template <typename track_container_t, typename traj_t>
0047 struct Factory<track_container_t, traj_t, detail::ValueHolder> {
0048 using track_container_type =
0049 TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0050
0051 track_container_type tc{track_container_t{}, traj_t{}};
0052
0053 auto& trackContainer() { return tc; }
0054 auto& trackStateContainer() { return tc.trackStateContainer(); }
0055 auto& backend() { return tc.container(); }
0056 };
0057
0058 template <typename track_container_t, typename traj_t>
0059 struct Factory<track_container_t, traj_t, std::shared_ptr> {
0060 using track_container_type =
0061 TrackContainer<track_container_t, traj_t, std::shared_ptr>;
0062
0063 std::shared_ptr<track_container_t> vtc{std::make_shared<track_container_t>()};
0064 std::shared_ptr<traj_t> mtj{std::make_shared<traj_t>()};
0065 track_container_type tc{vtc, mtj};
0066
0067 auto& trackContainer() { return tc; }
0068 auto& trackStateContainer() { return *mtj; }
0069 auto& backend() { return *vtc; }
0070 };
0071
0072 template <typename track_container_t, typename traj_t,
0073 template <typename> class... holders>
0074 using holder_types_t =
0075 std::tuple<Factory<track_container_t, traj_t, holders>...>;
0076
0077 using holder_types = holder_types_t<VectorTrackContainer, VectorMultiTrajectory,
0078
0079
0080 std::shared_ptr>;
0081
0082 using const_holder_types =
0083 holder_types_t<ConstVectorTrackContainer, ConstVectorMultiTrajectory,
0084 detail::ValueHolder, detail::RefHolder, std::shared_ptr>;
0085
0086 BOOST_AUTO_TEST_SUITE(EventDataTrack)
0087
0088 BOOST_AUTO_TEST_CASE(BuildDefaultHolder) {
0089 VectorMultiTrajectory mtj{};
0090 VectorTrackContainer vtc{};
0091 TrackContainer tc{vtc, mtj};
0092
0093 static_assert(
0094 std::is_same_v<decltype(tc),
0095 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0096 detail::RefHolder>>,
0097 "Incorrect deduced type");
0098 BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0099 BOOST_CHECK_EQUAL(&vtc, &tc.container());
0100 tc.addTrack();
0101
0102 std::decay_t<decltype(tc)> copy = tc;
0103 BOOST_CHECK_EQUAL(&mtj, ©.trackStateContainer());
0104 BOOST_CHECK_EQUAL(&vtc, ©.container());
0105 }
0106
0107 BOOST_AUTO_TEST_CASE(BuildValueHolder) {
0108 {
0109 VectorMultiTrajectory mtj{};
0110 VectorTrackContainer vtc{};
0111 TrackContainer tc{std::move(vtc), std::move(mtj)};
0112 static_assert(
0113 std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0114 VectorMultiTrajectory,
0115 detail::ValueHolder>>,
0116 "Incorrect deduced type");
0117 std::decay_t<decltype(tc)> copy = tc;
0118 BOOST_CHECK_NE(&tc.trackStateContainer(), ©.trackStateContainer());
0119 BOOST_CHECK_NE(&tc.container(), ©.container());
0120 }
0121 {
0122 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0123
0124 static_assert(
0125 std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0126 VectorMultiTrajectory,
0127 detail::ValueHolder>>,
0128 "Incorrect deduced type");
0129 tc.addTrack();
0130 std::decay_t<decltype(tc)> copy = tc;
0131 BOOST_CHECK_NE(&tc.trackStateContainer(), ©.trackStateContainer());
0132 BOOST_CHECK_NE(&tc.container(), ©.container());
0133 }
0134 }
0135
0136 BOOST_AUTO_TEST_CASE(BuildRefHolder) {
0137 VectorMultiTrajectory mtj{};
0138 VectorTrackContainer vtc{};
0139 TrackContainer<VectorTrackContainer, VectorMultiTrajectory, detail::RefHolder>
0140 tc{vtc, mtj};
0141
0142 static_assert(
0143 std::is_same_v<decltype(tc),
0144 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0145 detail::RefHolder>>,
0146 "Incorrect deduced type");
0147 BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0148 BOOST_CHECK_EQUAL(&vtc, &tc.container());
0149 tc.addTrack();
0150 std::decay_t<decltype(tc)> copy = tc;
0151 BOOST_CHECK_EQUAL(&mtj, ©.trackStateContainer());
0152 BOOST_CHECK_EQUAL(&vtc, ©.container());
0153 }
0154
0155 BOOST_AUTO_TEST_CASE(BuildSharedPtr) {
0156 auto mtj = std::make_shared<VectorMultiTrajectory>();
0157 auto vtc = std::make_shared<VectorTrackContainer>();
0158 TrackContainer<VectorTrackContainer, VectorMultiTrajectory, std::shared_ptr>
0159 tc{vtc, mtj};
0160
0161 static_assert(
0162 std::is_same_v<decltype(tc),
0163 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0164 std::shared_ptr>>,
0165 "Incorrect deduced type");
0166 BOOST_CHECK_EQUAL(mtj.get(), &tc.trackStateContainer());
0167 BOOST_CHECK_EQUAL(vtc.get(), &tc.container());
0168 tc.addTrack();
0169 std::decay_t<decltype(tc)> copy = tc;
0170 BOOST_CHECK_EQUAL(mtj.get(), ©.trackStateContainer());
0171 BOOST_CHECK_EQUAL(vtc.get(), ©.container());
0172 }
0173
0174 BOOST_AUTO_TEST_CASE(BuildConvenience) {
0175 VectorMultiTrajectory mtj{};
0176 VectorTrackContainer vtc{};
0177 TrackContainer tc{vtc, mtj};
0178
0179 BOOST_CHECK_EQUAL(tc.size(), 0);
0180 auto track1 = tc.makeTrack();
0181 BOOST_CHECK_EQUAL(tc.size(), 1);
0182 auto track2 = tc.makeTrack();
0183 BOOST_CHECK_EQUAL(tc.size(), 2);
0184
0185 BOOST_CHECK_EQUAL(track1.index(), 0);
0186 BOOST_CHECK_EQUAL(track2.index(), 1);
0187 }
0188
0189 BOOST_AUTO_TEST_CASE_TEMPLATE(Build, factory_t, holder_types) {
0190 factory_t factory;
0191
0192 auto& tc = factory.trackContainer();
0193
0194 static_assert(std::is_same_v<std::decay_t<decltype(tc)>,
0195 typename factory_t::track_container_type>,
0196 "Incorrect deduction");
0197
0198 static_assert(!std::decay_t<decltype(tc)>::ReadOnly,
0199 "Should not be read only");
0200 BOOST_CHECK(!tc.ReadOnly);
0201
0202 auto idx = tc.addTrack();
0203 auto t = tc.getTrack(idx);
0204 auto t2 = tc.getTrack(idx);
0205 t.template component<IndexType, "tipIndex"_hash>() = 5;
0206
0207 BOOST_CHECK_EQUAL((t.template component<IndexType, "tipIndex"_hash>()), 5);
0208 BOOST_CHECK_EQUAL(t.tipIndex(), 5);
0209 t.tipIndex() = 6;
0210 BOOST_CHECK_EQUAL(t.tipIndex(), 6);
0211
0212 BoundVector pars;
0213 pars.setRandom();
0214 t.parameters() = pars;
0215 BOOST_CHECK_EQUAL(t.parameters(), pars);
0216
0217 BoundMatrix cov;
0218 cov.setRandom();
0219 t.covariance() = cov;
0220 BOOST_CHECK_EQUAL(t.covariance(), cov);
0221
0222 std::shared_ptr<PlaneSurface> surface =
0223 CurvilinearSurface(Acts::Vector3{-3_m, 0., 0.}, Acts::Vector3{1., 0., 0})
0224 .planeSurface();
0225
0226 t.setReferenceSurface(surface);
0227 BOOST_CHECK_EQUAL(surface.get(), &t.referenceSurface());
0228
0229 ProxyAccessor<unsigned int> accNMeasuements("nMeasurements");
0230 ConstProxyAccessor<unsigned int> caccNMeasuements("nMeasurements");
0231
0232 t.nMeasurements() = 42;
0233 BOOST_CHECK_EQUAL(t2.nMeasurements(), 42);
0234 BOOST_CHECK_EQUAL(accNMeasuements(t), 42);
0235 accNMeasuements(t) = 89;
0236 BOOST_CHECK_EQUAL(t2.nMeasurements(), 89);
0237 BOOST_CHECK_EQUAL(caccNMeasuements(t), 89);
0238
0239
0240 BOOST_CHECK(accNMeasuements.hasColumn(t));
0241 BOOST_CHECK(caccNMeasuements.hasColumn(t));
0242
0243 ProxyAccessor<std::string> accNonExistent("nonExistentColumn");
0244 ConstProxyAccessor<std::string> caccNonExistent("nonExistentColumn");
0245 BOOST_CHECK(!accNonExistent.hasColumn(t));
0246 BOOST_CHECK(!caccNonExistent.hasColumn(t));
0247
0248
0249
0250
0251 t2.nHoles() = 67;
0252 BOOST_CHECK_EQUAL(t.nHoles(), 67);
0253
0254 t2.nOutliers() = 68;
0255 BOOST_CHECK_EQUAL(t.nOutliers(), 68);
0256
0257 t2.nSharedHits() = 69;
0258 BOOST_CHECK_EQUAL(t.nSharedHits(), 69);
0259
0260 t2.chi2() = 555.0;
0261 BOOST_CHECK_EQUAL(t2.chi2(), 555.0);
0262
0263 t2.nDoF() = 123;
0264 BOOST_CHECK_EQUAL(t2.nDoF(), 123);
0265
0266
0267
0268
0269
0270
0271 }
0272
0273 BOOST_AUTO_TEST_CASE(CopyTracksIncludingDynamicColumns) {
0274
0275 VectorTrackContainer vtc{};
0276 VectorMultiTrajectory mtj{};
0277 TrackContainer tc{vtc, mtj};
0278 tc.addColumn<std::size_t>("counter");
0279 tc.addColumn<bool>("odd");
0280 mtj.addColumn<std::size_t>("ts_counter");
0281 mtj.addColumn<bool>("ts_odd");
0282
0283 TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0284
0285
0286 VectorTrackContainer vtc3{};
0287 VectorMultiTrajectory mtj3{};
0288 mtj3.addColumn<std::size_t>("ts_counter");
0289 mtj3.addColumn<bool>("ts_odd");
0290
0291 TrackContainer tc3{vtc3, mtj3};
0292
0293 tc3.addColumn<std::size_t>("counter");
0294 tc3.addColumn<bool>("odd");
0295
0296 for (std::size_t i = 0; i < 10; i++) {
0297 auto t = tc.makeTrack();
0298 auto ts = t.appendTrackState();
0299 ts.predicted() = BoundVector::Ones();
0300 ts.component<std::size_t, "ts_counter"_hash>() = i;
0301
0302 ts = t.appendTrackState();
0303 ts.predicted().setOnes();
0304 ts.predicted() *= 2;
0305 ts.component<std::size_t, "ts_counter"_hash>() = i + 1;
0306
0307 ts = t.appendTrackState();
0308 ts.predicted().setOnes();
0309 ts.predicted() *= 3;
0310 ts.component<std::size_t, "ts_counter"_hash>() = i + 2;
0311
0312 t.template component<std::size_t>("counter") = i;
0313 t.template component<bool>("odd") = i % 2 == 0;
0314
0315 auto t2 = tc2.makeTrack();
0316 BOOST_CHECK_THROW(t2.copyFrom(t),
0317 std::invalid_argument);
0318
0319 auto t3 = tc3.makeTrack();
0320 t3.copyFrom(t);
0321
0322 BOOST_CHECK_NE(t3.tipIndex(), MultiTrajectoryTraits::kInvalid);
0323 BOOST_CHECK_GT(t3.nTrackStates(), 0);
0324 BOOST_REQUIRE_EQUAL(t.nTrackStates(), t3.nTrackStates());
0325
0326 for (auto [tsa, tsb] :
0327 zip(t.trackStatesReversed(), t3.trackStatesReversed())) {
0328 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0329
0330 BOOST_CHECK_EQUAL(
0331 (tsa.template component<std::size_t, "ts_counter"_hash>()),
0332 (tsb.template component<std::size_t, "ts_counter"_hash>()));
0333
0334 BOOST_CHECK_EQUAL((tsa.template component<bool, "ts_odd"_hash>()),
0335 (tsb.template component<bool, "ts_odd"_hash>()));
0336 }
0337
0338 BOOST_CHECK_EQUAL(t.template component<std::size_t>("counter"),
0339 t3.template component<std::size_t>("counter"));
0340 BOOST_CHECK_EQUAL(t.template component<bool>("odd"),
0341 t3.template component<bool>("odd"));
0342 }
0343
0344 std::size_t before = mtj.size();
0345 TrackContainer tc4{ConstVectorTrackContainer{vtc},
0346 ConstVectorMultiTrajectory{mtj}};
0347
0348 BOOST_REQUIRE_EQUAL(tc4.trackStateContainer().size(), before);
0349
0350 VectorTrackContainer vtc5{};
0351 VectorMultiTrajectory mtj5{};
0352 mtj5.addColumn<std::size_t>("ts_counter");
0353 mtj5.addColumn<bool>("ts_odd");
0354
0355 TrackContainer tc5{vtc5, mtj5};
0356 tc5.addColumn<std::size_t>("counter");
0357 tc5.addColumn<bool>("odd");
0358
0359 for (std::size_t i = 0; i < 10; i++) {
0360 auto t4 = tc4.getTrack(i);
0361 BOOST_CHECK_NE(t4.nTrackStates(), 0);
0362
0363 auto t5 = tc5.makeTrack();
0364 t5.copyFrom(t4);
0365
0366 BOOST_CHECK_NE(t5.tipIndex(), MultiTrajectoryTraits::kInvalid);
0367 BOOST_CHECK_GT(t5.nTrackStates(), 0);
0368 BOOST_REQUIRE_EQUAL(t4.nTrackStates(), t5.nTrackStates());
0369
0370 for (auto [tsa, tsb] :
0371 zip(t4.trackStatesReversed(), t5.trackStatesReversed())) {
0372 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0373 }
0374
0375 BOOST_CHECK_EQUAL(t4.template component<std::size_t>("counter"),
0376 t5.template component<std::size_t>("counter"));
0377 BOOST_CHECK_EQUAL(t4.template component<bool>("odd"),
0378 t5.template component<bool>("odd"));
0379 }
0380 }
0381
0382 BOOST_AUTO_TEST_CASE(ReverseTrackStates) {
0383 VectorTrackContainer vtc{};
0384 VectorMultiTrajectory mtj{};
0385 TrackContainer tc{vtc, mtj};
0386
0387 auto t = tc.makeTrack();
0388
0389 for (std::size_t i = 0; i < 4; i++) {
0390 auto ts = t.appendTrackState();
0391 ts.jacobian() = Acts::BoundMatrix::Identity() * i;
0392 }
0393
0394 std::vector<IndexType> exp;
0395 exp.resize(t.nTrackStates());
0396 std::iota(exp.rbegin(), exp.rend(), 0);
0397 std::vector<IndexType> act;
0398 std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0399 std::back_inserter(act),
0400 [](const auto& ts) { return ts.index(); });
0401
0402
0403 for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0404 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0405 }
0406
0407 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0408
0409
0410 t.reverseTrackStates();
0411
0412 std::iota(exp.begin(), exp.end(), 0);
0413 act.clear();
0414 std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0415 std::back_inserter(act),
0416 [](const auto& ts) { return ts.index(); });
0417 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0418
0419
0420 for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0421 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0422 }
0423
0424
0425 t.reverseTrackStates();
0426
0427
0428 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0429 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0430 }
0431
0432
0433 t.reverseTrackStates(true);
0434
0435 std::ranges::reverse(exp);
0436 std::rotate(exp.rbegin(), std::next(exp.rbegin()), exp.rend());
0437
0438 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0439 Acts::BoundMatrix expJac;
0440 if (e == 0) {
0441 expJac = Acts::BoundMatrix::Zero();
0442 } else {
0443 expJac = (Acts::BoundMatrix::Identity() * e).inverse();
0444 }
0445
0446 BOOST_CHECK_EQUAL(ts.jacobian(), expJac);
0447 }
0448
0449
0450 t.reverseTrackStates(true);
0451
0452
0453 std::iota(exp.begin(), exp.end(), 0);
0454
0455 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0456 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0457 }
0458 }
0459
0460 BOOST_AUTO_TEST_CASE(CopyTrackProxyCalibrated) {
0461 VectorTrackContainer vtc{};
0462 VectorMultiTrajectory mtj{};
0463 TrackContainer tc{vtc, mtj};
0464
0465 constexpr static std::size_t kMeasurementSize = 3;
0466
0467 auto track1 = tc.makeTrack();
0468 auto ts = track1.appendTrackState(TrackStatePropMask::Calibrated);
0469 ts.allocateCalibrated(kMeasurementSize);
0470 ts.setProjectorSubspaceIndices(BoundSubspaceIndices{});
0471
0472 auto tsCopy = track1.appendTrackState(TrackStatePropMask::Calibrated);
0473 tsCopy.copyFrom(ts, TrackStatePropMask::Calibrated, false);
0474
0475 BOOST_CHECK_EQUAL(ts.calibratedSize(), tsCopy.calibratedSize());
0476 }
0477
0478 BOOST_AUTO_TEST_CASE(ProxyAccessorHasColumn) {
0479 VectorTrackContainer vtc{};
0480 VectorMultiTrajectory mtj{};
0481 TrackContainer tc{vtc, mtj};
0482
0483
0484 mtj.addColumn<float>("customFloat");
0485
0486 tc.addColumn<std::string>("customString");
0487
0488 auto track = tc.makeTrack();
0489 auto ts = track.appendTrackState(TrackStatePropMask::Predicted);
0490 ts.predicted() = BoundVector::Zero();
0491
0492
0493 ts.component<float>("customFloat") = 42.5f;
0494 track.component<std::string>("customString") = "test";
0495
0496
0497
0498 BOOST_CHECK(ConstProxyAccessor<IndexType>("tipIndex").hasColumn(track));
0499 BOOST_CHECK(ConstProxyAccessor<IndexType>("stemIndex").hasColumn(track));
0500 BOOST_CHECK(ConstProxyAccessor<BoundVector>("params").hasColumn(track));
0501 BOOST_CHECK(ConstProxyAccessor<BoundMatrix>("cov").hasColumn(track));
0502 BOOST_CHECK(
0503 ConstProxyAccessor<unsigned int>("nMeasurements").hasColumn(track));
0504 BOOST_CHECK(ConstProxyAccessor<unsigned int>("nHoles").hasColumn(track));
0505 BOOST_CHECK(ConstProxyAccessor<float>("chi2").hasColumn(track));
0506 BOOST_CHECK(ConstProxyAccessor<unsigned int>("ndf").hasColumn(track));
0507 BOOST_CHECK(ConstProxyAccessor<unsigned int>("nOutliers").hasColumn(track));
0508 BOOST_CHECK(ConstProxyAccessor<unsigned int>("nSharedHits").hasColumn(track));
0509
0510
0511 BOOST_CHECK(ConstProxyAccessor<std::string>("customString").hasColumn(track));
0512
0513
0514
0515 BOOST_CHECK(ConstProxyAccessor<IndexType>("previous").hasColumn(ts));
0516 BOOST_CHECK(ConstProxyAccessor<IndexType>("next").hasColumn(ts));
0517 BOOST_CHECK(ConstProxyAccessor<IndexType>("predicted").hasColumn(ts));
0518 BOOST_CHECK(ConstProxyAccessor<IndexType>("filtered").hasColumn(ts));
0519 BOOST_CHECK(ConstProxyAccessor<IndexType>("smoothed").hasColumn(ts));
0520 BOOST_CHECK(ConstProxyAccessor<IndexType>("calibrated").hasColumn(ts));
0521 BOOST_CHECK(ConstProxyAccessor<IndexType>("calibratedCov").hasColumn(ts));
0522 BOOST_CHECK(ConstProxyAccessor<IndexType>("jacobian").hasColumn(ts));
0523 BOOST_CHECK(ConstProxyAccessor<IndexType>("projector").hasColumn(ts));
0524 BOOST_CHECK(
0525 ConstProxyAccessor<std::optional<SourceLink>>("uncalibratedSourceLink")
0526 .hasColumn(ts));
0527 BOOST_CHECK(
0528 ConstProxyAccessor<std::shared_ptr<const Surface>>("referenceSurface")
0529 .hasColumn(ts));
0530 BOOST_CHECK(ConstProxyAccessor<std::uint8_t>("measdim").hasColumn(ts));
0531 BOOST_CHECK(ConstProxyAccessor<float>("chi2").hasColumn(ts));
0532 BOOST_CHECK(ConstProxyAccessor<double>("pathLength").hasColumn(ts));
0533 BOOST_CHECK(
0534 ConstProxyAccessor<TrackStateType::raw_type>("typeFlags").hasColumn(ts));
0535
0536
0537 BOOST_CHECK(ConstProxyAccessor<float>("customFloat").hasColumn(ts));
0538
0539
0540 BOOST_CHECK(!ConstProxyAccessor<int>("nonExistentColumn").hasColumn(ts));
0541 BOOST_CHECK(!ConstProxyAccessor<std::string>("nonExistentTrackColumn")
0542 .hasColumn(track));
0543
0544
0545 ProxyAccessor<float> accCustomFloat("customFloat");
0546 ConstProxyAccessor<float> caccCustomFloat("customFloat");
0547 BOOST_CHECK_EQUAL(accCustomFloat(ts), 42.5f);
0548 BOOST_CHECK_EQUAL(caccCustomFloat(ts), 42.5f);
0549
0550 ProxyAccessor<std::string> accCustomString("customString");
0551 ConstProxyAccessor<std::string> caccCustomString("customString");
0552 BOOST_CHECK_EQUAL(accCustomString(track), "test");
0553 BOOST_CHECK_EQUAL(caccCustomString(track), "test");
0554 }
0555
0556 consteval ProxyAccessor<int> makeProxyAccessor() {
0557 return ProxyAccessor<int>("test_consteval");
0558 }
0559
0560 BOOST_AUTO_TEST_CASE(ProxyAccessorConstexprConstruction) {
0561 static_assert(ProxyAccessor<int>("test").key == "test"_hash,
0562 "ProxyAccessor should be constructible with a string key");
0563
0564 constexpr auto acc = makeProxyAccessor();
0565
0566 static_assert(acc.key == "test_consteval"_hash,
0567 "ProxyAccessor should be constructible at compile time");
0568 }
0569
0570 BOOST_AUTO_TEST_CASE(CopyFromWithoutStatesInvalidatesIndices) {
0571 VectorTrackContainer vtc{};
0572 VectorMultiTrajectory mtj{};
0573 TrackContainer tc{vtc, mtj};
0574
0575
0576 auto sourceTrack = tc.makeTrack();
0577 sourceTrack.appendTrackState();
0578 sourceTrack.appendTrackState();
0579 sourceTrack.appendTrackState();
0580 sourceTrack.linkForward();
0581
0582
0583 BOOST_CHECK_NE(sourceTrack.tipIndex(), MultiTrajectoryTraits::kInvalid);
0584 BOOST_CHECK_NE(sourceTrack.stemIndex(), MultiTrajectoryTraits::kInvalid);
0585 BOOST_CHECK_EQUAL(sourceTrack.nTrackStates(), 3);
0586
0587
0588 sourceTrack.nMeasurements() = 42;
0589 sourceTrack.nHoles() = 5;
0590 sourceTrack.chi2() = 123.45f;
0591
0592
0593 auto destTrack = tc.makeTrack();
0594 destTrack.appendTrackState();
0595 destTrack.appendTrackState();
0596 destTrack.linkForward();
0597
0598
0599 BOOST_CHECK_NE(destTrack.tipIndex(), MultiTrajectoryTraits::kInvalid);
0600 BOOST_CHECK_NE(destTrack.stemIndex(), MultiTrajectoryTraits::kInvalid);
0601 BOOST_CHECK_EQUAL(destTrack.nTrackStates(), 2);
0602
0603
0604 destTrack.copyFromWithoutStates(sourceTrack);
0605
0606
0607 BOOST_CHECK_EQUAL(destTrack.tipIndex(), MultiTrajectoryTraits::kInvalid);
0608 BOOST_CHECK_EQUAL(destTrack.stemIndex(), MultiTrajectoryTraits::kInvalid);
0609
0610
0611 BOOST_CHECK_EQUAL(destTrack.nMeasurements(), 42);
0612 BOOST_CHECK_EQUAL(destTrack.nHoles(), 5);
0613 BOOST_CHECK_EQUAL(destTrack.chi2(), 123.45f);
0614
0615
0616 BOOST_CHECK_EQUAL(destTrack.nTrackStates(), 0);
0617
0618
0619
0620 BOOST_CHECK_EQUAL(sourceTrack.nTrackStates(), 3);
0621 BOOST_CHECK_NE(sourceTrack.tipIndex(), MultiTrajectoryTraits::kInvalid);
0622 }
0623
0624 BOOST_AUTO_TEST_CASE(CopyFromDeepCopyFunctionality) {
0625 VectorTrackContainer vtc{};
0626 VectorMultiTrajectory mtj{};
0627 TrackContainer tc{vtc, mtj};
0628
0629
0630 auto sourceTrack = tc.makeTrack();
0631
0632
0633 sourceTrack.nMeasurements() = 15;
0634 sourceTrack.nHoles() = 3;
0635 sourceTrack.nOutliers() = 2;
0636 sourceTrack.chi2() = 42.5f;
0637 sourceTrack.nDoF() = 10;
0638
0639
0640 auto ts1 = sourceTrack.appendTrackState();
0641 ts1.predicted() = BoundVector::Ones() * 1.0;
0642
0643 auto ts2 = sourceTrack.appendTrackState();
0644 ts2.predicted() = BoundVector::Ones() * 2.0;
0645
0646 auto ts3 = sourceTrack.appendTrackState();
0647 ts3.predicted() = BoundVector::Ones() * 3.0;
0648
0649
0650 BOOST_CHECK_EQUAL(sourceTrack.nTrackStates(), 3);
0651
0652
0653 auto destTrack = tc.makeTrack();
0654 destTrack.copyFrom(sourceTrack);
0655
0656
0657 BOOST_CHECK_EQUAL(destTrack.nMeasurements(), 15);
0658 BOOST_CHECK_EQUAL(destTrack.nHoles(), 3);
0659 BOOST_CHECK_EQUAL(destTrack.nOutliers(), 2);
0660 BOOST_CHECK_EQUAL(destTrack.chi2(), 42.5f);
0661 BOOST_CHECK_EQUAL(destTrack.nDoF(), 10);
0662
0663
0664 BOOST_CHECK_EQUAL(destTrack.nTrackStates(), 3);
0665 BOOST_CHECK_NE(destTrack.tipIndex(), MultiTrajectoryTraits::kInvalid);
0666 BOOST_CHECK_NE(destTrack.stemIndex(), MultiTrajectoryTraits::kInvalid);
0667
0668
0669 BOOST_CHECK(destTrack.innermostTrackState().has_value());
0670
0671
0672 std::vector<BoundVector> sourceParams;
0673 for (const auto& ts : sourceTrack.trackStatesReversed()) {
0674 sourceParams.insert(sourceParams.begin(), ts.predicted());
0675 }
0676
0677 std::vector<BoundVector> destParams;
0678 for (const auto& ts : destTrack.trackStatesReversed()) {
0679 destParams.insert(destParams.begin(), ts.predicted());
0680 }
0681
0682 BOOST_REQUIRE_EQUAL(sourceParams.size(), destParams.size());
0683 for (std::size_t i = 0; i < sourceParams.size(); ++i) {
0684 BOOST_CHECK_EQUAL(sourceParams[i], destParams[i]);
0685 }
0686
0687
0688 std::vector<IndexType> sourceIndices;
0689 for (const auto& ts : sourceTrack.trackStatesReversed()) {
0690 sourceIndices.push_back(ts.index());
0691 }
0692
0693 std::vector<IndexType> destIndices;
0694 for (const auto& ts : destTrack.trackStatesReversed()) {
0695 destIndices.push_back(ts.index());
0696 }
0697
0698 BOOST_REQUIRE_EQUAL(sourceIndices.size(), destIndices.size());
0699 for (std::size_t i = 0; i < sourceIndices.size(); ++i) {
0700 BOOST_CHECK_NE(sourceIndices[i], destIndices[i]);
0701 }
0702
0703
0704 std::vector<BoundVector> forwardParams;
0705 for (const auto& ts : destTrack.trackStates()) {
0706 forwardParams.push_back(ts.predicted());
0707 }
0708
0709
0710 BOOST_REQUIRE_EQUAL(destParams.size(), forwardParams.size());
0711 for (std::size_t i = 0; i < destParams.size(); ++i) {
0712 BOOST_CHECK_EQUAL(destParams[i], forwardParams[i]);
0713 }
0714
0715
0716 destTrack.nMeasurements() = 99;
0717 BOOST_CHECK_EQUAL(sourceTrack.nMeasurements(), 15);
0718 BOOST_CHECK_EQUAL(destTrack.nMeasurements(), 99);
0719 }
0720
0721 BOOST_AUTO_TEST_CASE(DeprecatedCopyFromWithBooleanStillWorks) {
0722 VectorTrackContainer vtc{};
0723 VectorMultiTrajectory mtj{};
0724 TrackContainer tc{vtc, mtj};
0725
0726
0727 auto sourceTrack = tc.makeTrack();
0728 sourceTrack.nMeasurements() = 25;
0729 sourceTrack.chi2() = 78.9f;
0730
0731 auto ts1 = sourceTrack.appendTrackState();
0732 ts1.predicted() = BoundVector::Ones() * 5.0;
0733 auto ts2 = sourceTrack.appendTrackState();
0734 ts2.predicted() = BoundVector::Ones() * 10.0;
0735
0736 BOOST_CHECK_EQUAL(sourceTrack.nTrackStates(), 2);
0737
0738
0739 auto destTrack1 = tc.makeTrack();
0740
0741 ACTS_DIAGNOSTIC_PUSH()
0742 ACTS_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations")
0743
0744 destTrack1.copyFrom(sourceTrack, true);
0745
0746 ACTS_DIAGNOSTIC_POP()
0747
0748
0749 BOOST_CHECK_EQUAL(destTrack1.nMeasurements(), 25);
0750 BOOST_CHECK_EQUAL(destTrack1.chi2(), 78.9f);
0751 BOOST_CHECK_EQUAL(destTrack1.nTrackStates(), 2);
0752 BOOST_CHECK_NE(destTrack1.tipIndex(), MultiTrajectoryTraits::kInvalid);
0753 BOOST_CHECK_NE(destTrack1.stemIndex(), MultiTrajectoryTraits::kInvalid);
0754
0755
0756 std::vector<BoundVector> sourceParams, destParams;
0757 for (const auto& ts : sourceTrack.trackStatesReversed()) {
0758 sourceParams.insert(sourceParams.begin(), ts.predicted());
0759 }
0760 for (const auto& ts : destTrack1.trackStatesReversed()) {
0761 destParams.insert(destParams.begin(), ts.predicted());
0762 }
0763
0764 BOOST_REQUIRE_EQUAL(sourceParams.size(), destParams.size());
0765 for (std::size_t i = 0; i < sourceParams.size(); ++i) {
0766 BOOST_CHECK_EQUAL(sourceParams[i], destParams[i]);
0767 }
0768
0769
0770 auto destTrack2 = tc.makeTrack();
0771 destTrack2.appendTrackState();
0772 destTrack2.appendTrackState();
0773 destTrack2.linkForward();
0774
0775 ACTS_DIAGNOSTIC_PUSH()
0776 ACTS_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations")
0777
0778 destTrack2.copyFrom(sourceTrack,
0779 false);
0780
0781 ACTS_DIAGNOSTIC_POP()
0782
0783
0784
0785
0786
0787
0788
0789 BOOST_CHECK_EQUAL(destTrack2.nMeasurements(), 25);
0790 BOOST_CHECK_EQUAL(destTrack2.chi2(), 78.9f);
0791
0792
0793 BOOST_CHECK_EQUAL(destTrack2.tipIndex(), 5);
0794 BOOST_CHECK_EQUAL(destTrack2.stemIndex(), 4);
0795
0796
0797 BOOST_CHECK_EQUAL(destTrack2.nTrackStates(), 2);
0798 }
0799
0800 BOOST_AUTO_TEST_SUITE_END()