Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:35

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 // fixed seed for reproducible tests
0051 std::default_random_engine rng(31415);
0052 
0053 // template <template <typename> class holder_t>
0054 // using track_container_t =
0055 // TrackContainer<VectorTrackContainer, VectorMultiTrajectory, holder_t>;
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                                     // detail_tc::ValueHolder,
0108                                     // detail_tc::RefHolder,
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 }  // namespace
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       // does not compile
0282       // track.parameters().setRandom();
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       // does not compile
0296       // track.parameters().setRandom();
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   // moved from
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   // Does not compile:
0329   // ctc.addTrack();
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   // Does not compile: holder deduced to ConstRefHolder, but is not RO
0343   // const auto& mrvtc = mutVtc;
0344   // const auto& mrmtj = mutMtj;
0345   // TrackContainer mrtc{mrvtc, mrmtj};
0346   // static_assert(ctc.ReadOnly, "Unexpectedly not read only");
0347   // mrtc.addTrack();
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     // let's create an unrelated track first
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()