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