Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-05 08:55:17

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