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