File indexing completed on 2025-01-18 09:12: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/Zip.hpp"
0018
0019 #include <algorithm>
0020 #include <numeric>
0021
0022 using namespace Acts;
0023 using namespace Acts::HashedStringLiteral;
0024 using MultiTrajectoryTraits::IndexType;
0025 using namespace Acts::UnitLiterals;
0026
0027 template <typename track_container_t, typename traj_t,
0028 template <typename> class holder_t>
0029 struct Factory {};
0030
0031 template <typename track_container_t, typename traj_t>
0032 struct Factory<track_container_t, traj_t, detail::RefHolder> {
0033 using track_container_type =
0034 TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0035
0036 track_container_t vtc;
0037 traj_t mtj;
0038 track_container_type tc{vtc, mtj};
0039
0040 auto& trackContainer() { return tc; }
0041 auto& trackStateContainer() { return mtj; }
0042 auto& backend() { return vtc; }
0043 };
0044
0045 template <typename track_container_t, typename traj_t>
0046 struct Factory<track_container_t, traj_t, detail::ValueHolder> {
0047 using track_container_type =
0048 TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0049
0050 track_container_type tc{track_container_t{}, traj_t{}};
0051
0052 auto& trackContainer() { return tc; }
0053 auto& trackStateContainer() { return tc.trackStateContainer(); }
0054 auto& backend() { return tc.container(); }
0055 };
0056
0057 template <typename track_container_t, typename traj_t>
0058 struct Factory<track_container_t, traj_t, std::shared_ptr> {
0059 using track_container_type =
0060 TrackContainer<track_container_t, traj_t, std::shared_ptr>;
0061
0062 std::shared_ptr<track_container_t> vtc{std::make_shared<track_container_t>()};
0063 std::shared_ptr<traj_t> mtj{std::make_shared<traj_t>()};
0064 track_container_type tc{vtc, mtj};
0065
0066 auto& trackContainer() { return tc; }
0067 auto& trackStateContainer() { return *mtj; }
0068 auto& backend() { return *vtc; }
0069 };
0070
0071 template <typename track_container_t, typename traj_t,
0072 template <typename> class... holders>
0073 using holder_types_t =
0074 std::tuple<Factory<track_container_t, traj_t, holders>...>;
0075
0076 using holder_types = holder_types_t<VectorTrackContainer, VectorMultiTrajectory,
0077
0078
0079 std::shared_ptr>;
0080
0081 using const_holder_types =
0082 holder_types_t<ConstVectorTrackContainer, ConstVectorMultiTrajectory,
0083 detail::ValueHolder, detail::RefHolder, std::shared_ptr>;
0084
0085 BOOST_AUTO_TEST_SUITE(EventDataTrack)
0086
0087 BOOST_AUTO_TEST_CASE(BuildDefaultHolder) {
0088 VectorMultiTrajectory mtj{};
0089 VectorTrackContainer vtc{};
0090 TrackContainer tc{vtc, mtj};
0091
0092 static_assert(
0093 std::is_same_v<decltype(tc),
0094 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0095 detail::RefHolder>>,
0096 "Incorrect deduced type");
0097 BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0098 BOOST_CHECK_EQUAL(&vtc, &tc.container());
0099 tc.addTrack();
0100
0101 std::decay_t<decltype(tc)> copy = tc;
0102 BOOST_CHECK_EQUAL(&mtj, ©.trackStateContainer());
0103 BOOST_CHECK_EQUAL(&vtc, ©.container());
0104 }
0105
0106 BOOST_AUTO_TEST_CASE(BuildValueHolder) {
0107 {
0108 VectorMultiTrajectory mtj{};
0109 VectorTrackContainer vtc{};
0110 TrackContainer tc{std::move(vtc), std::move(mtj)};
0111 static_assert(
0112 std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0113 VectorMultiTrajectory,
0114 detail::ValueHolder>>,
0115 "Incorrect deduced type");
0116 std::decay_t<decltype(tc)> copy = tc;
0117 BOOST_CHECK_NE(&tc.trackStateContainer(), ©.trackStateContainer());
0118 BOOST_CHECK_NE(&tc.container(), ©.container());
0119 }
0120 {
0121 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0122
0123 static_assert(
0124 std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0125 VectorMultiTrajectory,
0126 detail::ValueHolder>>,
0127 "Incorrect deduced type");
0128 tc.addTrack();
0129 std::decay_t<decltype(tc)> copy = tc;
0130 BOOST_CHECK_NE(&tc.trackStateContainer(), ©.trackStateContainer());
0131 BOOST_CHECK_NE(&tc.container(), ©.container());
0132 }
0133 }
0134
0135 BOOST_AUTO_TEST_CASE(BuildRefHolder) {
0136 VectorMultiTrajectory mtj{};
0137 VectorTrackContainer vtc{};
0138 TrackContainer<VectorTrackContainer, VectorMultiTrajectory, detail::RefHolder>
0139 tc{vtc, mtj};
0140
0141 static_assert(
0142 std::is_same_v<decltype(tc),
0143 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0144 detail::RefHolder>>,
0145 "Incorrect deduced type");
0146 BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0147 BOOST_CHECK_EQUAL(&vtc, &tc.container());
0148 tc.addTrack();
0149 std::decay_t<decltype(tc)> copy = tc;
0150 BOOST_CHECK_EQUAL(&mtj, ©.trackStateContainer());
0151 BOOST_CHECK_EQUAL(&vtc, ©.container());
0152 }
0153
0154 BOOST_AUTO_TEST_CASE(BuildSharedPtr) {
0155 auto mtj = std::make_shared<VectorMultiTrajectory>();
0156 auto vtc = std::make_shared<VectorTrackContainer>();
0157 TrackContainer<VectorTrackContainer, VectorMultiTrajectory, std::shared_ptr>
0158 tc{vtc, mtj};
0159
0160 static_assert(
0161 std::is_same_v<decltype(tc),
0162 TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0163 std::shared_ptr>>,
0164 "Incorrect deduced type");
0165 BOOST_CHECK_EQUAL(mtj.get(), &tc.trackStateContainer());
0166 BOOST_CHECK_EQUAL(vtc.get(), &tc.container());
0167 tc.addTrack();
0168 std::decay_t<decltype(tc)> copy = tc;
0169 BOOST_CHECK_EQUAL(mtj.get(), ©.trackStateContainer());
0170 BOOST_CHECK_EQUAL(vtc.get(), ©.container());
0171 }
0172
0173 BOOST_AUTO_TEST_CASE(BuildConvenience) {
0174 VectorMultiTrajectory mtj{};
0175 VectorTrackContainer vtc{};
0176 TrackContainer tc{vtc, mtj};
0177
0178 BOOST_CHECK_EQUAL(tc.size(), 0);
0179 auto track1 = tc.makeTrack();
0180 BOOST_CHECK_EQUAL(tc.size(), 1);
0181 auto track2 = tc.makeTrack();
0182 BOOST_CHECK_EQUAL(tc.size(), 2);
0183
0184 BOOST_CHECK_EQUAL(track1.index(), 0);
0185 BOOST_CHECK_EQUAL(track2.index(), 1);
0186 }
0187
0188 BOOST_AUTO_TEST_CASE_TEMPLATE(Build, factory_t, holder_types) {
0189 factory_t factory;
0190
0191 auto& tc = factory.trackContainer();
0192
0193 static_assert(std::is_same_v<std::decay_t<decltype(tc)>,
0194 typename factory_t::track_container_type>,
0195 "Incorrect deduction");
0196
0197 static_assert(!std::decay_t<decltype(tc)>::ReadOnly,
0198 "Should not be read only");
0199 BOOST_CHECK(!tc.ReadOnly);
0200
0201 auto idx = tc.addTrack();
0202 auto t = tc.getTrack(idx);
0203 auto t2 = tc.getTrack(idx);
0204 t.template component<IndexType, "tipIndex"_hash>() = 5;
0205
0206 BOOST_CHECK_EQUAL((t.template component<IndexType, "tipIndex"_hash>()), 5);
0207 BOOST_CHECK_EQUAL(t.tipIndex(), 5);
0208 t.tipIndex() = 6;
0209 BOOST_CHECK_EQUAL(t.tipIndex(), 6);
0210
0211 BoundVector pars;
0212 pars.setRandom();
0213 t.parameters() = pars;
0214 BOOST_CHECK_EQUAL(t.parameters(), pars);
0215
0216 BoundMatrix cov;
0217 cov.setRandom();
0218 t.covariance() = cov;
0219 BOOST_CHECK_EQUAL(t.covariance(), cov);
0220
0221 auto surface =
0222 CurvilinearSurface(Acts::Vector3{-3_m, 0., 0.}, Acts::Vector3{1., 0., 0})
0223 .planeSurface();
0224
0225 t.setReferenceSurface(surface);
0226 BOOST_CHECK_EQUAL(surface.get(), &t.referenceSurface());
0227
0228 ProxyAccessor<unsigned int> accNMeasuements("nMeasurements");
0229 ConstProxyAccessor<unsigned int> caccNMeasuements("nMeasurements");
0230
0231 t.nMeasurements() = 42;
0232 BOOST_CHECK_EQUAL(t2.nMeasurements(), 42);
0233 BOOST_CHECK_EQUAL(accNMeasuements(t), 42);
0234 accNMeasuements(t) = 89;
0235 BOOST_CHECK_EQUAL(t2.nMeasurements(), 89);
0236 BOOST_CHECK_EQUAL(caccNMeasuements(t), 89);
0237
0238
0239
0240
0241 t2.nHoles() = 67;
0242 BOOST_CHECK_EQUAL(t.nHoles(), 67);
0243
0244 t2.nOutliers() = 68;
0245 BOOST_CHECK_EQUAL(t.nOutliers(), 68);
0246
0247 t2.nSharedHits() = 69;
0248 BOOST_CHECK_EQUAL(t.nSharedHits(), 69);
0249
0250 t2.chi2() = 555.0;
0251 BOOST_CHECK_EQUAL(t2.chi2(), 555.0);
0252
0253 t2.nDoF() = 123;
0254 BOOST_CHECK_EQUAL(t2.nDoF(), 123);
0255
0256
0257
0258
0259
0260
0261 }
0262
0263 BOOST_AUTO_TEST_CASE(CopyTracksIncludingDynamicColumns) {
0264
0265 VectorTrackContainer vtc{};
0266 VectorMultiTrajectory mtj{};
0267 TrackContainer tc{vtc, mtj};
0268 tc.addColumn<std::size_t>("counter");
0269 tc.addColumn<bool>("odd");
0270 mtj.addColumn<std::size_t>("ts_counter");
0271 mtj.addColumn<bool>("ts_odd");
0272
0273 TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0274
0275
0276 VectorTrackContainer vtc3{};
0277 VectorMultiTrajectory mtj3{};
0278 mtj3.addColumn<std::size_t>("ts_counter");
0279 mtj3.addColumn<bool>("ts_odd");
0280
0281 TrackContainer tc3{vtc3, mtj3};
0282
0283 tc3.addColumn<std::size_t>("counter");
0284 tc3.addColumn<bool>("odd");
0285
0286 for (std::size_t i = 0; i < 10; i++) {
0287 auto t = tc.makeTrack();
0288 auto ts = t.appendTrackState();
0289 ts.predicted() = BoundVector::Ones();
0290 ts.component<std::size_t, "ts_counter"_hash>() = i;
0291
0292 ts = t.appendTrackState();
0293 ts.predicted().setOnes();
0294 ts.predicted() *= 2;
0295 ts.component<std::size_t, "ts_counter"_hash>() = i + 1;
0296
0297 ts = t.appendTrackState();
0298 ts.predicted().setOnes();
0299 ts.predicted() *= 3;
0300 ts.component<std::size_t, "ts_counter"_hash>() = i + 2;
0301
0302 t.template component<std::size_t>("counter") = i;
0303 t.template component<bool>("odd") = i % 2 == 0;
0304
0305 auto t2 = tc2.makeTrack();
0306 BOOST_CHECK_THROW(t2.copyFrom(t),
0307 std::invalid_argument);
0308
0309 auto t3 = tc3.makeTrack();
0310 t3.copyFrom(t);
0311
0312 BOOST_CHECK_NE(t3.tipIndex(), MultiTrajectoryTraits::kInvalid);
0313 BOOST_CHECK_GT(t3.nTrackStates(), 0);
0314 BOOST_REQUIRE_EQUAL(t.nTrackStates(), t3.nTrackStates());
0315
0316 for (auto [tsa, tsb] :
0317 zip(t.trackStatesReversed(), t3.trackStatesReversed())) {
0318 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0319
0320 BOOST_CHECK_EQUAL(
0321 (tsa.template component<std::size_t, "ts_counter"_hash>()),
0322 (tsb.template component<std::size_t, "ts_counter"_hash>()));
0323
0324 BOOST_CHECK_EQUAL((tsa.template component<bool, "ts_odd"_hash>()),
0325 (tsb.template component<bool, "ts_odd"_hash>()));
0326 }
0327
0328 BOOST_CHECK_EQUAL(t.template component<std::size_t>("counter"),
0329 t3.template component<std::size_t>("counter"));
0330 BOOST_CHECK_EQUAL(t.template component<bool>("odd"),
0331 t3.template component<bool>("odd"));
0332 }
0333
0334 std::size_t before = mtj.size();
0335 TrackContainer tc4{ConstVectorTrackContainer{vtc},
0336 ConstVectorMultiTrajectory{mtj}};
0337
0338 BOOST_REQUIRE_EQUAL(tc4.trackStateContainer().size(), before);
0339
0340 VectorTrackContainer vtc5{};
0341 VectorMultiTrajectory mtj5{};
0342 mtj5.addColumn<std::size_t>("ts_counter");
0343 mtj5.addColumn<bool>("ts_odd");
0344
0345 TrackContainer tc5{vtc5, mtj5};
0346 tc5.addColumn<std::size_t>("counter");
0347 tc5.addColumn<bool>("odd");
0348
0349 for (std::size_t i = 0; i < 10; i++) {
0350 auto t4 = tc4.getTrack(i);
0351 BOOST_CHECK_NE(t4.nTrackStates(), 0);
0352
0353 auto t5 = tc5.makeTrack();
0354 t5.copyFrom(t4);
0355
0356 BOOST_CHECK_NE(t5.tipIndex(), MultiTrajectoryTraits::kInvalid);
0357 BOOST_CHECK_GT(t5.nTrackStates(), 0);
0358 BOOST_REQUIRE_EQUAL(t4.nTrackStates(), t5.nTrackStates());
0359
0360 for (auto [tsa, tsb] :
0361 zip(t4.trackStatesReversed(), t5.trackStatesReversed())) {
0362 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0363 }
0364
0365 BOOST_CHECK_EQUAL(t4.template component<std::size_t>("counter"),
0366 t5.template component<std::size_t>("counter"));
0367 BOOST_CHECK_EQUAL(t4.template component<bool>("odd"),
0368 t5.template component<bool>("odd"));
0369 }
0370 }
0371
0372 BOOST_AUTO_TEST_CASE(ReverseTrackStates) {
0373 VectorTrackContainer vtc{};
0374 VectorMultiTrajectory mtj{};
0375 TrackContainer tc{vtc, mtj};
0376
0377 auto t = tc.makeTrack();
0378
0379 for (std::size_t i = 0; i < 4; i++) {
0380 auto ts = t.appendTrackState();
0381 ts.jacobian() = Acts::BoundMatrix::Identity() * i;
0382 }
0383
0384 std::vector<IndexType> exp;
0385 exp.resize(t.nTrackStates());
0386 std::iota(exp.rbegin(), exp.rend(), 0);
0387 std::vector<IndexType> act;
0388 std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0389 std::back_inserter(act),
0390 [](const auto& ts) { return ts.index(); });
0391
0392
0393 for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0394 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0395 }
0396
0397 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0398
0399
0400 t.reverseTrackStates();
0401
0402 std::iota(exp.begin(), exp.end(), 0);
0403 act.clear();
0404 std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0405 std::back_inserter(act),
0406 [](const auto& ts) { return ts.index(); });
0407 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0408
0409
0410 for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0411 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0412 }
0413
0414
0415 t.reverseTrackStates();
0416
0417
0418 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0419 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0420 }
0421
0422
0423 t.reverseTrackStates(true);
0424
0425 std::ranges::reverse(exp);
0426 std::rotate(exp.rbegin(), std::next(exp.rbegin()), exp.rend());
0427
0428 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0429 Acts::BoundMatrix expJac;
0430 if (e == 0) {
0431 expJac = Acts::BoundMatrix::Zero();
0432 } else {
0433 expJac = (Acts::BoundMatrix::Identity() * e).inverse();
0434 }
0435
0436 BOOST_CHECK_EQUAL(ts.jacobian(), expJac);
0437 }
0438
0439
0440 t.reverseTrackStates(true);
0441
0442
0443 std::iota(exp.begin(), exp.end(), 0);
0444
0445 for (const auto [e, ts] : zip(exp, t.trackStates())) {
0446 BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0447 }
0448 }
0449
0450 BOOST_AUTO_TEST_CASE(CopyTrackProxyCalibrated) {
0451 VectorTrackContainer vtc{};
0452 VectorMultiTrajectory mtj{};
0453 TrackContainer tc{vtc, mtj};
0454
0455 constexpr static std::size_t kMeasurementSize = 3;
0456
0457 auto track1 = tc.makeTrack();
0458 auto ts = track1.appendTrackState(TrackStatePropMask::Calibrated);
0459 ts.allocateCalibrated(kMeasurementSize);
0460 ts.setProjectorSubspaceIndices(BoundSubspaceIndices{});
0461
0462 auto tsCopy = track1.appendTrackState(TrackStatePropMask::Calibrated);
0463 tsCopy.copyFrom(ts, TrackStatePropMask::Calibrated, false);
0464
0465 BOOST_CHECK_EQUAL(ts.calibratedSize(), tsCopy.calibratedSize());
0466 }
0467
0468 BOOST_AUTO_TEST_SUITE_END()