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/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.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/TrackStatePropMask.hpp"
0019 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0020 #include "Acts/EventData/VectorTrackContainer.hpp"
0021 #include "Acts/EventData/detail/GenerateParameters.hpp"
0022 #include "Acts/EventData/detail/TestTrackState.hpp"
0023 #include "Acts/Geometry/GeometryContext.hpp"
0024 #include "Acts/Utilities/HashedString.hpp"
0025 #include "Acts/Utilities/Holders.hpp"
0026
0027 #include <algorithm>
0028 #include <cstddef>
0029 #include <iterator>
0030 #include <memory>
0031 #include <numeric>
0032 #include <random>
0033 #include <stdexcept>
0034 #include <tuple>
0035 #include <type_traits>
0036 #include <utility>
0037 #include <vector>
0038
0039 namespace {
0040
0041 using namespace Acts::UnitLiterals;
0042
0043 using namespace Acts;
0044 using namespace Acts::HashedStringLiteral;
0045 using namespace Acts::detail::Test;
0046
0047 using MultiTrajectoryTraits::IndexType;
0048
0049 const GeometryContext gctx;
0050
0051 std::default_random_engine rng(31415);
0052
0053
0054
0055
0056
0057 template <typename track_container_t, typename traj_t,
0058 template <typename> class holder_t>
0059 struct Factory {};
0060
0061 template <typename track_container_t, typename traj_t>
0062 struct Factory<track_container_t, traj_t, detail::RefHolder> {
0063 using track_container_type =
0064 TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0065
0066 track_container_t vtc;
0067 traj_t mtj;
0068 track_container_type tc{vtc, mtj};
0069
0070 auto& trackContainer() { return tc; }
0071 auto& trackStateContainer() { return mtj; }
0072 auto& backend() { return vtc; }
0073 };
0074
0075 template <typename track_container_t, typename traj_t>
0076 struct Factory<track_container_t, traj_t, detail::ValueHolder> {
0077 using track_container_type =
0078 TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0079
0080 track_container_type tc{track_container_t{}, traj_t{}};
0081
0082 auto& trackContainer() { return tc; }
0083 auto& trackStateContainer() { return tc.trackStateContainer(); }
0084 auto& backend() { return tc.container(); }
0085 };
0086
0087 template <typename track_container_t, typename traj_t>
0088 struct Factory<track_container_t, traj_t, std::shared_ptr> {
0089 using track_container_type =
0090 TrackContainer<track_container_t, traj_t, std::shared_ptr>;
0091
0092 std::shared_ptr<track_container_t> vtc{std::make_shared<track_container_t>()};
0093 std::shared_ptr<traj_t> mtj{std::make_shared<traj_t>()};
0094 track_container_type tc{vtc, mtj};
0095
0096 auto& trackContainer() { return tc; }
0097 auto& trackStateContainer() { return *mtj; }
0098 auto& backend() { return *vtc; }
0099 };
0100
0101 template <typename track_container_t, typename traj_t,
0102 template <typename> class... holders>
0103 using holder_types_t =
0104 std::tuple<Factory<track_container_t, traj_t, holders>...>;
0105
0106 using holder_types = holder_types_t<VectorTrackContainer, VectorMultiTrajectory,
0107
0108
0109 std::shared_ptr>;
0110
0111 using const_holder_types =
0112 holder_types_t<ConstVectorTrackContainer, ConstVectorMultiTrajectory,
0113 detail::ValueHolder, detail::RefHolder, std::shared_ptr>;
0114
0115 }
0116
0117 BOOST_AUTO_TEST_SUITE(EventDataTrack)
0118
0119 BOOST_AUTO_TEST_CASE_TEMPLATE(TrackStateAccess, factory_t, holder_types) {
0120 factory_t factory;
0121 auto& tc = factory.trackContainer();
0122
0123 VectorMultiTrajectory& traj = factory.trackStateContainer();
0124
0125 auto mkts = [&](auto prev) {
0126 if constexpr (std::is_same_v<decltype(prev), IndexType>) {
0127 auto ts = traj.makeTrackState(TrackStatePropMask::All, prev);
0128 TestTrackState pc(rng, 2u);
0129 fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0130 return ts;
0131 } else {
0132 auto ts = traj.makeTrackState(TrackStatePropMask::All, prev.index());
0133 TestTrackState pc(rng, 2u);
0134 fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0135 return ts;
0136 }
0137 };
0138
0139 auto ts1 = mkts(MultiTrajectoryTraits::kInvalid);
0140 auto ts2 = mkts(ts1);
0141 auto ts3 = mkts(ts2);
0142 auto ts4 = mkts(ts3);
0143 auto ts5 = mkts(ts4);
0144
0145 auto t = tc.makeTrack();
0146 t.tipIndex() = ts5.index();
0147
0148 std::vector<IndexType> act;
0149 for (const auto& ts : t.trackStatesReversed()) {
0150 act.push_back(ts.index());
0151 }
0152
0153 std::vector<IndexType> exp;
0154 exp.resize(5);
0155 std::iota(exp.rbegin(), exp.rend(), 0);
0156 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(), exp.end());
0157
0158 const auto& ct = t;
0159
0160 for (const auto& ts : ct.trackStatesReversed()) {
0161 (void)ts;
0162 }
0163
0164 BOOST_CHECK_EQUAL(t.nTrackStates(), 5);
0165
0166 auto tNone = tc.makeTrack();
0167 BOOST_CHECK_EQUAL(tNone.nTrackStates(), 0);
0168
0169 auto tsRange = tNone.trackStatesReversed();
0170 BOOST_CHECK(tsRange.begin() == tsRange.end());
0171
0172 std::size_t i = 0;
0173 for (const auto& state : tNone.trackStatesReversed()) {
0174 (void)state;
0175 i++;
0176 }
0177 BOOST_CHECK_EQUAL(i, 0);
0178 }
0179
0180 BOOST_AUTO_TEST_CASE_TEMPLATE(TrackIterator, factory_t, holder_types) {
0181 factory_t factory;
0182 auto& tc = factory.trackContainer();
0183
0184 for (unsigned int i = 0; i < 10; i++) {
0185 auto t = tc.makeTrack();
0186 t.tipIndex() = i;
0187 }
0188 BOOST_CHECK_EQUAL(tc.size(), 10);
0189
0190 unsigned int i = 0;
0191 for (auto track : tc) {
0192 BOOST_CHECK_EQUAL(i, track.tipIndex());
0193 track.parameters().setRandom();
0194 i++;
0195 }
0196
0197 BOOST_CHECK_EQUAL(std::distance(tc.begin(), tc.end()), tc.size());
0198 }
0199
0200 BOOST_AUTO_TEST_CASE(IteratorConcept) {
0201 VectorTrackContainer vtc;
0202 VectorMultiTrajectory mtj;
0203 TrackContainer tc{vtc, mtj};
0204
0205 for (unsigned int i = 0; i < 10; i++) {
0206 auto t = tc.makeTrack();
0207 t.tipIndex() = i;
0208 }
0209 BOOST_CHECK_EQUAL(tc.size(), 10);
0210 BOOST_CHECK_EQUAL(std::distance(tc.begin(), tc.end()), tc.size());
0211
0212 {
0213 auto it = tc.begin();
0214 BOOST_CHECK(*it == tc.getTrack(0));
0215 ++it;
0216 BOOST_CHECK(*it == tc.getTrack(1));
0217 it += 1;
0218 BOOST_CHECK(*it == tc.getTrack(2));
0219 it -= 1;
0220 BOOST_CHECK(*it == tc.getTrack(1));
0221 ++it;
0222 ++it;
0223 --it;
0224 BOOST_CHECK(*it == tc.getTrack(2));
0225 }
0226 {
0227 auto it = tc.begin();
0228 BOOST_CHECK(*it == tc.getTrack(0));
0229 std::advance(it, 4);
0230 BOOST_CHECK(*it == tc.getTrack(4));
0231 BOOST_CHECK(*(it + (-1)) == tc.getTrack(3));
0232 BOOST_CHECK(*(it + 0) == tc.getTrack(4));
0233 BOOST_CHECK(*(it + 1) == tc.getTrack(5));
0234 BOOST_CHECK(*(it - 2) == tc.getTrack(2));
0235 }
0236
0237 {
0238 auto it = tc.begin();
0239 auto it4 = it + 4;
0240 auto it5 = it + 5;
0241 auto it6 = it + 6;
0242
0243 BOOST_CHECK(it4 < it5);
0244 BOOST_CHECK(it5 < it6);
0245 BOOST_CHECK(it4 < it6);
0246
0247 BOOST_CHECK(it6 > it5);
0248 BOOST_CHECK(it5 > it4);
0249 BOOST_CHECK(it6 > it4);
0250
0251 BOOST_CHECK(it4 <= it4);
0252 BOOST_CHECK(it4 <= it5);
0253 BOOST_CHECK(it5 <= it5);
0254 BOOST_CHECK(it5 <= it6);
0255
0256 BOOST_CHECK(it6 >= it6);
0257 BOOST_CHECK(it6 >= it5);
0258 }
0259 }
0260
0261 BOOST_AUTO_TEST_CASE(ConstCorrectness) {
0262 VectorTrackContainer vtc;
0263 VectorMultiTrajectory mtj;
0264 {
0265 TrackContainer tc{vtc, mtj};
0266
0267 for (unsigned int i = 0; i < 10; i++) {
0268 auto t = tc.makeTrack();
0269 t.tipIndex() = i;
0270 }
0271
0272 unsigned int i = 0;
0273 for (auto track : tc) {
0274 BOOST_CHECK_EQUAL(i, track.tipIndex());
0275 track.parameters().setRandom();
0276 i++;
0277 }
0278
0279 for (const auto track : tc) {
0280 (void)track;
0281
0282
0283 }
0284 }
0285
0286 ConstVectorTrackContainer cvtc{std::move(vtc)};
0287 ConstVectorMultiTrajectory cmtj{std::move(mtj)};
0288 {
0289 TrackContainer tc{cvtc, cmtj};
0290
0291 unsigned int i = 0;
0292 for (auto track : tc) {
0293 BOOST_CHECK_EQUAL(i, track.tipIndex());
0294 i++;
0295
0296
0297 }
0298 }
0299 }
0300
0301 BOOST_AUTO_TEST_CASE(BuildFromConstRef) {
0302 VectorTrackContainer mutVtc;
0303 VectorMultiTrajectory mutMtj;
0304
0305 TrackContainer mutTc{mutVtc, mutMtj};
0306 static_assert(!mutTc.ReadOnly, "Unexpectedly read only");
0307
0308 auto t = mutTc.makeTrack();
0309 t.appendTrackState();
0310 t.appendTrackState();
0311 t.appendTrackState();
0312 t = mutTc.makeTrack();
0313 t.appendTrackState();
0314
0315 BOOST_CHECK_EQUAL(mutTc.size(), 2);
0316 BOOST_CHECK_EQUAL(mutMtj.size(), 4);
0317
0318 ConstVectorTrackContainer vtc{std::move(mutVtc)};
0319 ConstVectorMultiTrajectory mtj{std::move(mutMtj)};
0320
0321
0322 BOOST_CHECK_EQUAL(mutTc.size(), 0);
0323 BOOST_CHECK_EQUAL(mutMtj.size(), 0);
0324
0325 TrackContainer ctc{vtc, mtj};
0326 static_assert(ctc.ReadOnly, "Unexpectedly not read only");
0327
0328
0329
0330
0331 BOOST_CHECK_EQUAL(ctc.size(), 2);
0332 BOOST_CHECK_EQUAL(mtj.size(), 4);
0333
0334 const auto& cvtc = vtc;
0335 const auto& cmtj = mtj;
0336
0337 TrackContainer crtc{cvtc, cmtj};
0338
0339 BOOST_CHECK_EQUAL(crtc.size(), 2);
0340 BOOST_CHECK_EQUAL(cmtj.size(), 4);
0341
0342
0343
0344
0345
0346
0347
0348 }
0349
0350 BOOST_AUTO_TEST_CASE_TEMPLATE(BuildReadOnly, factory_t, const_holder_types) {
0351 factory_t factory;
0352 auto& tc = factory.trackContainer();
0353
0354 static_assert(std::is_same_v<std::decay_t<decltype(tc)>,
0355 typename factory_t::track_container_type>,
0356 "Incorrect deduction");
0357
0358 static_assert(std::decay_t<decltype(tc)>::ReadOnly, "Should be read only");
0359 BOOST_CHECK(tc.ReadOnly);
0360 }
0361
0362 BOOST_AUTO_TEST_CASE_TEMPLATE(DynamicColumns, factory_t, holder_types) {
0363 factory_t factory;
0364 auto& tc = factory.trackContainer();
0365
0366 BOOST_CHECK(!tc.hasColumn("col_a"_hash));
0367 tc.template addColumn<float>("col_a");
0368 BOOST_CHECK(tc.hasColumn("col_a"_hash));
0369
0370 auto t = tc.makeTrack();
0371 t.template component<float>("col_a") = 5.6f;
0372 BOOST_CHECK_EQUAL((t.template component<float, "col_a"_hash>()), 5.6f);
0373 }
0374
0375 BOOST_AUTO_TEST_CASE(EnsureDynamicColumns) {
0376 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0377 tc.addColumn<std::size_t>("counter");
0378 tc.addColumn<bool>("odd");
0379
0380 BOOST_CHECK(tc.hasColumn("counter"));
0381 BOOST_CHECK(tc.hasColumn("odd"));
0382
0383 TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0384
0385 BOOST_CHECK(!tc2.hasColumn("counter"));
0386 BOOST_CHECK(!tc2.hasColumn("odd"));
0387
0388 tc2.ensureDynamicColumns(tc);
0389
0390 BOOST_CHECK(tc2.hasColumn("counter"));
0391 BOOST_CHECK(tc2.hasColumn("odd"));
0392 }
0393
0394 BOOST_AUTO_TEST_CASE(AppendTrackState) {
0395 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0396 auto t = tc.makeTrack();
0397
0398 std::vector<VectorMultiTrajectory::TrackStateProxy> trackStates;
0399 trackStates.push_back(t.appendTrackState());
0400 trackStates.push_back(t.appendTrackState());
0401 trackStates.push_back(t.appendTrackState());
0402 trackStates.push_back(t.appendTrackState());
0403 trackStates.push_back(t.appendTrackState());
0404 trackStates.push_back(t.appendTrackState());
0405
0406 BOOST_CHECK_EQUAL(trackStates.size(), t.nTrackStates());
0407
0408 for (std::size_t i = trackStates.size() - 1; i > 0; i--) {
0409 BOOST_CHECK_EQUAL(trackStates.at(i).index(), i);
0410 }
0411 }
0412
0413 BOOST_AUTO_TEST_CASE(ForwardIteration) {
0414 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0415 {
0416
0417 auto t = tc.makeTrack();
0418 for (std::size_t i = 0; i < 10; i++) {
0419 t.appendTrackState();
0420 }
0421 }
0422
0423 auto t = tc.makeTrack();
0424
0425 auto stem = t.appendTrackState();
0426 t.appendTrackState();
0427 t.appendTrackState();
0428 t.appendTrackState();
0429 t.appendTrackState();
0430
0431 BOOST_CHECK_THROW(t.trackStates(), std::invalid_argument);
0432 BOOST_CHECK(!t.innermostTrackState().has_value());
0433
0434 t.linkForward();
0435
0436 BOOST_CHECK_EQUAL(t.stemIndex(), stem.index());
0437 BOOST_CHECK_EQUAL(t.innermostTrackState().value().index(), stem.index());
0438 t.innermostTrackState()->predicted().setRandom();
0439
0440 std::vector<IndexType> indices;
0441 for (const auto& ts : t.trackStatesReversed()) {
0442 indices.push_back(ts.index());
0443 }
0444
0445 std::ranges::reverse(indices);
0446
0447 std::vector<IndexType> act;
0448 for (auto ts : t.trackStates()) {
0449 act.push_back(ts.index());
0450 ts.predicted().setRandom();
0451 }
0452
0453 BOOST_CHECK_EQUAL_COLLECTIONS(indices.begin(), indices.end(), act.begin(),
0454 act.end());
0455
0456 t.reverseTrackStates();
0457 BOOST_CHECK_EQUAL(t.innermostTrackState().value().index(), indices.back());
0458 t.innermostTrackState()->predicted().setRandom();
0459
0460 act.clear();
0461 for (const auto& ts : t.trackStates()) {
0462 act.push_back(ts.index());
0463 }
0464
0465 BOOST_CHECK_EQUAL_COLLECTIONS(indices.rbegin(), indices.rend(), act.begin(),
0466 act.end());
0467 }
0468
0469 BOOST_AUTO_TEST_CASE(ShallowCopy) {
0470 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0471 auto t = tc.makeTrack();
0472
0473 auto ts1 = t.appendTrackState();
0474 ts1.predicted().setRandom();
0475 auto ts2 = t.appendTrackState();
0476 ts2.predicted().setRandom();
0477 auto ts3 = t.appendTrackState();
0478 ts3.predicted().setRandom();
0479
0480 auto t2 = t.shallowCopy();
0481
0482 BOOST_CHECK_NE(t.index(), t2.index());
0483 BOOST_CHECK_EQUAL(t.nTrackStates(), t2.nTrackStates());
0484
0485 std::vector<decltype(tc)::TrackStateProxy> trackStates;
0486 for (const auto& ts : t.trackStatesReversed()) {
0487 trackStates.insert(trackStates.begin(), ts);
0488 }
0489
0490 auto t2_ts1 = trackStates.at(0);
0491 auto t2_ts2 = trackStates.at(1);
0492 auto t2_ts3 = trackStates.at(2);
0493
0494 BOOST_CHECK_EQUAL(t2_ts1.predicted(), ts1.predicted());
0495 BOOST_CHECK_EQUAL(t2_ts1.index(), ts1.index());
0496 BOOST_CHECK_EQUAL(t2_ts2.predicted(), ts2.predicted());
0497 BOOST_CHECK_EQUAL(t2_ts2.index(), ts2.index());
0498 BOOST_CHECK_EQUAL(t2_ts3.predicted(), ts3.predicted());
0499 BOOST_CHECK_EQUAL(t2_ts3.index(), ts3.index());
0500 }
0501
0502 BOOST_AUTO_TEST_SUITE_END()