Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:20

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/TrackParametrization.hpp"
0014 #include "Acts/Definitions/Units.hpp"
0015 #include "Acts/EventData/MultiTrajectory.hpp"
0016 #include "Acts/EventData/ProxyAccessor.hpp"
0017 #include "Acts/EventData/TrackContainer.hpp"
0018 #include "Acts/EventData/TrackHelpers.hpp"
0019 #include "Acts/EventData/TrackProxy.hpp"
0020 #include "Acts/EventData/TrackStatePropMask.hpp"
0021 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0022 #include "Acts/EventData/VectorTrackContainer.hpp"
0023 #include "Acts/EventData/detail/GenerateParameters.hpp"
0024 #include "Acts/EventData/detail/TestTrackState.hpp"
0025 #include "Acts/Geometry/GeometryContext.hpp"
0026 #include "Acts/Surfaces/PlaneSurface.hpp"
0027 #include "Acts/Surfaces/Surface.hpp"
0028 #include "Acts/Utilities/HashedString.hpp"
0029 #include "Acts/Utilities/Holders.hpp"
0030 #include "Acts/Utilities/Zip.hpp"
0031 
0032 #include <cstddef>
0033 #include <iterator>
0034 #include <memory>
0035 #include <numeric>
0036 #include <random>
0037 #include <stdexcept>
0038 #include <tuple>
0039 #include <type_traits>
0040 #include <utility>
0041 #include <vector>
0042 
0043 namespace {
0044 
0045 using namespace Acts::UnitLiterals;
0046 
0047 using namespace Acts;
0048 using namespace Acts::HashedStringLiteral;
0049 using namespace Acts::detail::Test;
0050 
0051 using MultiTrajectoryTraits::IndexType;
0052 namespace bd = boost::unit_test::data;
0053 
0054 const GeometryContext gctx;
0055 // fixed seed for reproducible tests
0056 std::default_random_engine rng(31415);
0057 
0058 // template <template <typename> class holder_t>
0059 // using track_container_t =
0060 // TrackContainer<VectorTrackContainer, VectorMultiTrajectory, holder_t>;
0061 
0062 template <typename track_container_t, typename traj_t,
0063           template <typename> class holder_t>
0064 struct Factory {};
0065 
0066 template <typename track_container_t, typename traj_t>
0067 struct Factory<track_container_t, traj_t, detail::RefHolder> {
0068   using track_container_type =
0069       TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0070 
0071   track_container_t vtc;
0072   traj_t mtj;
0073   track_container_type tc{vtc, mtj};
0074 
0075   auto& trackContainer() { return tc; }
0076   auto& trackStateContainer() { return mtj; }
0077   auto& backend() { return vtc; }
0078 };
0079 
0080 template <typename track_container_t, typename traj_t>
0081 struct Factory<track_container_t, traj_t, detail::ValueHolder> {
0082   using track_container_type =
0083       TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0084 
0085   track_container_type tc{track_container_t{}, traj_t{}};
0086 
0087   auto& trackContainer() { return tc; }
0088   auto& trackStateContainer() { return tc.trackStateContainer(); }
0089   auto& backend() { return tc.container(); }
0090 };
0091 
0092 template <typename track_container_t, typename traj_t>
0093 struct Factory<track_container_t, traj_t, std::shared_ptr> {
0094   using track_container_type =
0095       TrackContainer<track_container_t, traj_t, std::shared_ptr>;
0096 
0097   std::shared_ptr<track_container_t> vtc{std::make_shared<track_container_t>()};
0098   std::shared_ptr<traj_t> mtj{std::make_shared<traj_t>()};
0099   track_container_type tc{vtc, mtj};
0100 
0101   auto& trackContainer() { return tc; }
0102   auto& trackStateContainer() { return *mtj; }
0103   auto& backend() { return *vtc; }
0104 };
0105 
0106 template <typename track_container_t, typename traj_t,
0107           template <typename> class... holders>
0108 using holder_types_t =
0109     std::tuple<Factory<track_container_t, traj_t, holders>...>;
0110 
0111 using holder_types = holder_types_t<VectorTrackContainer, VectorMultiTrajectory,
0112                                     // detail_tc::ValueHolder,
0113                                     // detail_tc::RefHolder,
0114                                     std::shared_ptr>;
0115 
0116 using const_holder_types =
0117     holder_types_t<ConstVectorTrackContainer, ConstVectorMultiTrajectory,
0118                    detail::ValueHolder, detail::RefHolder, std::shared_ptr>;
0119 
0120 }  // namespace
0121 
0122 BOOST_AUTO_TEST_SUITE(EventDataTrack)
0123 
0124 BOOST_AUTO_TEST_CASE(BuildDefaultHolder) {
0125   VectorMultiTrajectory mtj{};
0126   VectorTrackContainer vtc{};
0127   TrackContainer tc{vtc, mtj};
0128 
0129   static_assert(
0130       std::is_same_v<decltype(tc),
0131                      TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0132                                     detail::RefHolder>>,
0133       "Incorrect deduced type");
0134   BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0135   BOOST_CHECK_EQUAL(&vtc, &tc.container());
0136   tc.addTrack();
0137 
0138   std::decay_t<decltype(tc)> copy = tc;
0139   BOOST_CHECK_EQUAL(&mtj, &copy.trackStateContainer());
0140   BOOST_CHECK_EQUAL(&vtc, &copy.container());
0141 }
0142 
0143 BOOST_AUTO_TEST_CASE(BuildValueHolder) {
0144   {
0145     VectorMultiTrajectory mtj{};
0146     VectorTrackContainer vtc{};
0147     TrackContainer tc{std::move(vtc), std::move(mtj)};
0148     static_assert(
0149         std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0150                                                     VectorMultiTrajectory,
0151                                                     detail::ValueHolder>>,
0152         "Incorrect deduced type");
0153     std::decay_t<decltype(tc)> copy = tc;
0154     BOOST_CHECK_NE(&tc.trackStateContainer(), &copy.trackStateContainer());
0155     BOOST_CHECK_NE(&tc.container(), &copy.container());
0156   }
0157   {
0158     TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0159 
0160     static_assert(
0161         std::is_same_v<decltype(tc), TrackContainer<VectorTrackContainer,
0162                                                     VectorMultiTrajectory,
0163                                                     detail::ValueHolder>>,
0164         "Incorrect deduced type");
0165     tc.addTrack();
0166     std::decay_t<decltype(tc)> copy = tc;
0167     BOOST_CHECK_NE(&tc.trackStateContainer(), &copy.trackStateContainer());
0168     BOOST_CHECK_NE(&tc.container(), &copy.container());
0169   }
0170 }
0171 
0172 BOOST_AUTO_TEST_CASE(BuildRefHolder) {
0173   VectorMultiTrajectory mtj{};
0174   VectorTrackContainer vtc{};
0175   TrackContainer<VectorTrackContainer, VectorMultiTrajectory, detail::RefHolder>
0176       tc{vtc, mtj};
0177 
0178   static_assert(
0179       std::is_same_v<decltype(tc),
0180                      TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0181                                     detail::RefHolder>>,
0182       "Incorrect deduced type");
0183   BOOST_CHECK_EQUAL(&mtj, &tc.trackStateContainer());
0184   BOOST_CHECK_EQUAL(&vtc, &tc.container());
0185   tc.addTrack();
0186   std::decay_t<decltype(tc)> copy = tc;
0187   BOOST_CHECK_EQUAL(&mtj, &copy.trackStateContainer());
0188   BOOST_CHECK_EQUAL(&vtc, &copy.container());
0189 }
0190 
0191 BOOST_AUTO_TEST_CASE(BuildSharedPtr) {
0192   auto mtj = std::make_shared<VectorMultiTrajectory>();
0193   auto vtc = std::make_shared<VectorTrackContainer>();
0194   TrackContainer<VectorTrackContainer, VectorMultiTrajectory, std::shared_ptr>
0195       tc{vtc, mtj};
0196 
0197   static_assert(
0198       std::is_same_v<decltype(tc),
0199                      TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0200                                     std::shared_ptr>>,
0201       "Incorrect deduced type");
0202   BOOST_CHECK_EQUAL(mtj.get(), &tc.trackStateContainer());
0203   BOOST_CHECK_EQUAL(vtc.get(), &tc.container());
0204   tc.addTrack();
0205   std::decay_t<decltype(tc)> copy = tc;
0206   BOOST_CHECK_EQUAL(mtj.get(), &copy.trackStateContainer());
0207   BOOST_CHECK_EQUAL(vtc.get(), &copy.container());
0208 }
0209 
0210 BOOST_AUTO_TEST_CASE(BuildConvenience) {
0211   VectorMultiTrajectory mtj{};
0212   VectorTrackContainer vtc{};
0213   TrackContainer tc{vtc, mtj};
0214 
0215   BOOST_CHECK_EQUAL(tc.size(), 0);
0216   auto track1 = tc.makeTrack();
0217   BOOST_CHECK_EQUAL(tc.size(), 1);
0218   auto track2 = tc.makeTrack();
0219   BOOST_CHECK_EQUAL(tc.size(), 2);
0220 
0221   BOOST_CHECK_EQUAL(track1.index(), 0);
0222   BOOST_CHECK_EQUAL(track2.index(), 1);
0223 }
0224 
0225 BOOST_AUTO_TEST_CASE_TEMPLATE(Build, factory_t, holder_types) {
0226   factory_t factory;
0227 
0228   auto& tc = factory.trackContainer();
0229 
0230   static_assert(std::is_same_v<std::decay_t<decltype(tc)>,
0231                                typename factory_t::track_container_type>,
0232                 "Incorrect deduction");
0233 
0234   static_assert(!std::decay_t<decltype(tc)>::ReadOnly,
0235                 "Should not be read only");
0236   BOOST_CHECK(!tc.ReadOnly);
0237 
0238   auto idx = tc.addTrack();
0239   auto t = tc.getTrack(idx);
0240   auto t2 = tc.getTrack(idx);
0241   t.template component<IndexType, "tipIndex"_hash>() = 5;
0242 
0243   BOOST_CHECK_EQUAL((t.template component<IndexType, "tipIndex"_hash>()), 5);
0244   BOOST_CHECK_EQUAL(t.tipIndex(), 5);
0245   t.tipIndex() = 6;
0246   BOOST_CHECK_EQUAL(t.tipIndex(), 6);
0247 
0248   BoundVector pars;
0249   pars.setRandom();
0250   t.parameters() = pars;
0251   BOOST_CHECK_EQUAL(t.parameters(), pars);
0252 
0253   BoundMatrix cov;
0254   cov.setRandom();
0255   t.covariance() = cov;
0256   BOOST_CHECK_EQUAL(t.covariance(), cov);
0257 
0258   auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0259       Acts::Vector3{-3_m, 0., 0.}, Acts::Vector3{1., 0., 0});
0260 
0261   t.setReferenceSurface(surface);
0262   BOOST_CHECK_EQUAL(surface.get(), &t.referenceSurface());
0263 
0264   ProxyAccessor<unsigned int> accNMeasuements("nMeasurements");
0265   ConstProxyAccessor<unsigned int> caccNMeasuements("nMeasurements");
0266 
0267   t.nMeasurements() = 42;
0268   BOOST_CHECK_EQUAL(t2.nMeasurements(), 42);
0269   BOOST_CHECK_EQUAL(accNMeasuements(t), 42);
0270   accNMeasuements(t) = 89;
0271   BOOST_CHECK_EQUAL(t2.nMeasurements(), 89);
0272   BOOST_CHECK_EQUAL(caccNMeasuements(t), 89);
0273 
0274   // does not compile
0275   // caccNMeasuements(t) = 66;
0276 
0277   t2.nHoles() = 67;
0278   BOOST_CHECK_EQUAL(t.nHoles(), 67);
0279 
0280   t2.nOutliers() = 68;
0281   BOOST_CHECK_EQUAL(t.nOutliers(), 68);
0282 
0283   t2.nSharedHits() = 69;
0284   BOOST_CHECK_EQUAL(t.nSharedHits(), 69);
0285 
0286   t2.chi2() = 555.0;
0287   BOOST_CHECK_EQUAL(t2.chi2(), 555.0);
0288 
0289   t2.nDoF() = 123;
0290   BOOST_CHECK_EQUAL(t2.nDoF(), 123);
0291 
0292   // const checks: should not compile
0293   // const auto& ctc = tc;
0294   // ctc.getTrack(idx).covariance().setRandom();
0295   // const auto& ctp = t;
0296   // ctp.covariance().setRandom();
0297 }
0298 
0299 BOOST_AUTO_TEST_CASE_TEMPLATE(TrackStateAccess, factory_t, holder_types) {
0300   factory_t factory;
0301   auto& tc = factory.trackContainer();
0302 
0303   VectorMultiTrajectory& traj = factory.trackStateContainer();
0304 
0305   auto mkts = [&](auto prev) {
0306     if constexpr (std::is_same_v<decltype(prev), IndexType>) {
0307       auto ts = traj.makeTrackState(TrackStatePropMask::All, prev);
0308       TestTrackState pc(rng, 2u);
0309       fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0310       return ts;
0311     } else {
0312       auto ts = traj.makeTrackState(TrackStatePropMask::All, prev.index());
0313       TestTrackState pc(rng, 2u);
0314       fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0315       return ts;
0316     }
0317   };
0318 
0319   auto ts1 = mkts(MultiTrajectoryTraits::kInvalid);
0320   auto ts2 = mkts(ts1);
0321   auto ts3 = mkts(ts2);
0322   auto ts4 = mkts(ts3);
0323   auto ts5 = mkts(ts4);
0324 
0325   auto t = tc.makeTrack();
0326   t.tipIndex() = ts5.index();
0327 
0328   std::vector<IndexType> act;
0329   for (const auto& ts : t.trackStatesReversed()) {
0330     act.push_back(ts.index());
0331   }
0332 
0333   std::vector<IndexType> exp;
0334   exp.resize(5);
0335   std::iota(exp.rbegin(), exp.rend(), 0);
0336   BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(), exp.end());
0337 
0338   const auto& ct = t;
0339 
0340   for (const auto& ts : ct.trackStatesReversed()) {
0341     (void)ts;
0342   }
0343 
0344   BOOST_CHECK_EQUAL(t.nTrackStates(), 5);
0345 
0346   auto tNone = tc.makeTrack();
0347   BOOST_CHECK_EQUAL(tNone.nTrackStates(), 0);
0348 
0349   auto tsRange = tNone.trackStatesReversed();
0350   BOOST_CHECK(tsRange.begin() == tsRange.end());
0351 
0352   std::size_t i = 0;
0353   for (const auto& state : tNone.trackStatesReversed()) {
0354     (void)state;
0355     i++;
0356   }
0357   BOOST_CHECK_EQUAL(i, 0);
0358 }
0359 
0360 BOOST_AUTO_TEST_CASE_TEMPLATE(TrackIterator, factory_t, holder_types) {
0361   factory_t factory;
0362   auto& tc = factory.trackContainer();
0363 
0364   for (unsigned int i = 0; i < 10; i++) {
0365     auto t = tc.makeTrack();
0366     t.tipIndex() = i;
0367   }
0368   BOOST_CHECK_EQUAL(tc.size(), 10);
0369 
0370   unsigned int i = 0;
0371   for (auto track : tc) {
0372     BOOST_CHECK_EQUAL(i, track.tipIndex());
0373     track.parameters().setRandom();
0374     i++;
0375   }
0376 
0377   BOOST_CHECK_EQUAL(std::distance(tc.begin(), tc.end()), tc.size());
0378 }
0379 
0380 BOOST_AUTO_TEST_CASE(IteratorConcept) {
0381   VectorTrackContainer vtc;
0382   VectorMultiTrajectory mtj;
0383   TrackContainer tc{vtc, mtj};
0384 
0385   for (unsigned int i = 0; i < 10; i++) {
0386     auto t = tc.makeTrack();
0387     t.tipIndex() = i;
0388   }
0389   BOOST_CHECK_EQUAL(tc.size(), 10);
0390   BOOST_CHECK_EQUAL(std::distance(tc.begin(), tc.end()), tc.size());
0391 
0392   {
0393     auto it = tc.begin();
0394     BOOST_CHECK(*it == tc.getTrack(0));
0395     ++it;
0396     BOOST_CHECK(*it == tc.getTrack(1));
0397     it += 1;
0398     BOOST_CHECK(*it == tc.getTrack(2));
0399     it -= 1;
0400     BOOST_CHECK(*it == tc.getTrack(1));
0401     ++it;
0402     ++it;
0403     --it;
0404     BOOST_CHECK(*it == tc.getTrack(2));
0405   }
0406   {
0407     auto it = tc.begin();
0408     BOOST_CHECK(*it == tc.getTrack(0));
0409     std::advance(it, 4);
0410     BOOST_CHECK(*it == tc.getTrack(4));
0411     BOOST_CHECK(*(it[-1]) == tc.getTrack(3));
0412     BOOST_CHECK(*(it[0]) == tc.getTrack(4));
0413     BOOST_CHECK(*(it[1]) == tc.getTrack(5));
0414     BOOST_CHECK(*(it - 2) == tc.getTrack(2));
0415   }
0416 
0417   {
0418     auto it = tc.begin();
0419     auto it4 = it + 4;
0420     auto it5 = it + 5;
0421     auto it6 = it + 6;
0422 
0423     BOOST_CHECK(it4 < it5);
0424     BOOST_CHECK(it5 < it6);
0425     BOOST_CHECK(it4 < it6);
0426 
0427     BOOST_CHECK(it6 > it5);
0428     BOOST_CHECK(it5 > it4);
0429     BOOST_CHECK(it6 > it4);
0430 
0431     BOOST_CHECK(it4 <= it4);
0432     BOOST_CHECK(it4 <= it5);
0433     BOOST_CHECK(it5 <= it5);
0434     BOOST_CHECK(it5 <= it6);
0435 
0436     BOOST_CHECK(it6 >= it6);
0437     BOOST_CHECK(it6 >= it5);
0438   }
0439 }
0440 
0441 BOOST_AUTO_TEST_CASE(ConstCorrectness) {
0442   VectorTrackContainer vtc;
0443   VectorMultiTrajectory mtj;
0444   {
0445     TrackContainer tc{vtc, mtj};
0446 
0447     for (unsigned int i = 0; i < 10; i++) {
0448       auto t = tc.makeTrack();
0449       t.tipIndex() = i;
0450     }
0451 
0452     unsigned int i = 0;
0453     for (auto track : tc) {
0454       BOOST_CHECK_EQUAL(i, track.tipIndex());
0455       track.parameters().setRandom();
0456       i++;
0457     }
0458 
0459     for (const auto track : tc) {
0460       (void)track;
0461       // does not compile
0462       // track.parameters().setRandom();
0463     }
0464   }
0465 
0466   ConstVectorTrackContainer cvtc{std::move(vtc)};
0467   ConstVectorMultiTrajectory cmtj{std::move(mtj)};
0468   {
0469     TrackContainer tc{cvtc, cmtj};
0470 
0471     unsigned int i = 0;
0472     for (auto track : tc) {
0473       BOOST_CHECK_EQUAL(i, track.tipIndex());
0474       i++;
0475       // does not compile
0476       // track.parameters().setRandom();
0477     }
0478   }
0479 }
0480 
0481 BOOST_AUTO_TEST_CASE(BuildFromConstRef) {
0482   VectorTrackContainer mutVtc;
0483   VectorMultiTrajectory mutMtj;
0484 
0485   TrackContainer mutTc{mutVtc, mutMtj};
0486   static_assert(!mutTc.ReadOnly, "Unexpectedly read only");
0487 
0488   auto t = mutTc.makeTrack();
0489   t.appendTrackState();
0490   t.appendTrackState();
0491   t.appendTrackState();
0492   t = mutTc.makeTrack();
0493   t.appendTrackState();
0494 
0495   BOOST_CHECK_EQUAL(mutTc.size(), 2);
0496   BOOST_CHECK_EQUAL(mutMtj.size(), 4);
0497 
0498   ConstVectorTrackContainer vtc{std::move(mutVtc)};
0499   ConstVectorMultiTrajectory mtj{std::move(mutMtj)};
0500 
0501   // moved from
0502   BOOST_CHECK_EQUAL(mutTc.size(), 0);
0503   BOOST_CHECK_EQUAL(mutMtj.size(), 0);
0504 
0505   TrackContainer ctc{vtc, mtj};
0506   static_assert(ctc.ReadOnly, "Unexpectedly not read only");
0507 
0508   // Does not compile:
0509   // ctc.addTrack();
0510 
0511   BOOST_CHECK_EQUAL(ctc.size(), 2);
0512   BOOST_CHECK_EQUAL(mtj.size(), 4);
0513 
0514   const auto& cvtc = vtc;
0515   const auto& cmtj = mtj;
0516 
0517   TrackContainer crtc{cvtc, cmtj};
0518 
0519   BOOST_CHECK_EQUAL(crtc.size(), 2);
0520   BOOST_CHECK_EQUAL(cmtj.size(), 4);
0521 
0522   // Does not compile: holder deduced to ConstRefHolder, but is not RO
0523   // const auto& mrvtc = mutVtc;
0524   // const auto& mrmtj = mutMtj;
0525   // TrackContainer mrtc{mrvtc, mrmtj};
0526   // static_assert(ctc.ReadOnly, "Unexpectedly not read only");
0527   // mrtc.addTrack();
0528 }
0529 
0530 BOOST_AUTO_TEST_CASE_TEMPLATE(BuildReadOnly, factory_t, const_holder_types) {
0531   factory_t factory;
0532   auto& tc = factory.trackContainer();
0533 
0534   static_assert(std::is_same_v<std::decay_t<decltype(tc)>,
0535                                typename factory_t::track_container_type>,
0536                 "Incorrect deduction");
0537 
0538   static_assert(std::decay_t<decltype(tc)>::ReadOnly, "Should be read only");
0539   BOOST_CHECK(tc.ReadOnly);
0540 }
0541 
0542 BOOST_AUTO_TEST_CASE_TEMPLATE(DynamicColumns, factory_t, holder_types) {
0543   factory_t factory;
0544   auto& tc = factory.trackContainer();
0545 
0546   BOOST_CHECK(!tc.hasColumn("col_a"_hash));
0547   tc.template addColumn<float>("col_a");
0548   BOOST_CHECK(tc.hasColumn("col_a"_hash));
0549 
0550   auto t = tc.makeTrack();
0551   t.template component<float>("col_a") = 5.6f;
0552   BOOST_CHECK_EQUAL((t.template component<float, "col_a"_hash>()), 5.6f);
0553 }
0554 
0555 BOOST_AUTO_TEST_CASE(EnsureDynamicColumns) {
0556   TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0557   tc.addColumn<std::size_t>("counter");
0558   tc.addColumn<bool>("odd");
0559 
0560   BOOST_CHECK(tc.hasColumn("counter"));
0561   BOOST_CHECK(tc.hasColumn("odd"));
0562 
0563   TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0564 
0565   BOOST_CHECK(!tc2.hasColumn("counter"));
0566   BOOST_CHECK(!tc2.hasColumn("odd"));
0567 
0568   tc2.ensureDynamicColumns(tc);
0569 
0570   BOOST_CHECK(tc2.hasColumn("counter"));
0571   BOOST_CHECK(tc2.hasColumn("odd"));
0572 }
0573 
0574 BOOST_AUTO_TEST_CASE(AppendTrackState) {
0575   TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0576   auto t = tc.makeTrack();
0577 
0578   std::vector<VectorMultiTrajectory::TrackStateProxy> trackStates;
0579   trackStates.push_back(t.appendTrackState());
0580   trackStates.push_back(t.appendTrackState());
0581   trackStates.push_back(t.appendTrackState());
0582   trackStates.push_back(t.appendTrackState());
0583   trackStates.push_back(t.appendTrackState());
0584   trackStates.push_back(t.appendTrackState());
0585 
0586   BOOST_CHECK_EQUAL(trackStates.size(), t.nTrackStates());
0587 
0588   for (std::size_t i = trackStates.size() - 1; i > 0; i--) {
0589     BOOST_CHECK_EQUAL(trackStates.at(i).index(), i);
0590   }
0591 }
0592 
0593 BOOST_AUTO_TEST_CASE(ForwardIteration) {
0594   TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0595   {
0596     // let's create an unrelated track first
0597     auto t = tc.makeTrack();
0598     for (std::size_t i = 0; i < 10; i++) {
0599       t.appendTrackState();
0600     }
0601   }
0602 
0603   auto t = tc.makeTrack();
0604 
0605   auto stem = t.appendTrackState();
0606   t.appendTrackState();
0607   t.appendTrackState();
0608   t.appendTrackState();
0609   t.appendTrackState();
0610 
0611   BOOST_CHECK_THROW(t.trackStates(), std::invalid_argument);
0612   BOOST_CHECK(!t.innermostTrackState().has_value());
0613 
0614   t.linkForward();
0615 
0616   BOOST_CHECK_EQUAL(t.stemIndex(), stem.index());
0617   BOOST_CHECK_EQUAL(t.innermostTrackState().value().index(), stem.index());
0618   t.innermostTrackState()->predicted().setRandom();
0619 
0620   std::vector<IndexType> indices;
0621   for (const auto& ts : t.trackStatesReversed()) {
0622     indices.push_back(ts.index());
0623   }
0624 
0625   std::reverse(indices.begin(), indices.end());
0626 
0627   std::vector<IndexType> act;
0628   for (auto ts : t.trackStates()) {
0629     act.push_back(ts.index());
0630     ts.predicted().setRandom();
0631   }
0632 
0633   BOOST_CHECK_EQUAL_COLLECTIONS(indices.begin(), indices.end(), act.begin(),
0634                                 act.end());
0635 
0636   t.reverseTrackStates();
0637   BOOST_CHECK_EQUAL(t.innermostTrackState().value().index(), indices.back());
0638   t.innermostTrackState()->predicted().setRandom();
0639 
0640   act.clear();
0641   for (const auto& ts : t.trackStates()) {
0642     act.push_back(ts.index());
0643   }
0644 
0645   BOOST_CHECK_EQUAL_COLLECTIONS(indices.rbegin(), indices.rend(), act.begin(),
0646                                 act.end());
0647 }
0648 
0649 BOOST_AUTO_TEST_CASE(CalculateQuantities) {
0650   TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0651   auto t = tc.makeTrack();
0652 
0653   auto ts = t.appendTrackState();
0654   ts.typeFlags().set(MeasurementFlag);
0655 
0656   ts = t.appendTrackState();
0657   ts.typeFlags().set(OutlierFlag);
0658 
0659   ts = t.appendTrackState();
0660   ts.typeFlags().set(MeasurementFlag);
0661   ts.typeFlags().set(SharedHitFlag);
0662 
0663   ts = t.appendTrackState();
0664   ts.typeFlags().set(HoleFlag);
0665 
0666   ts = t.appendTrackState();
0667   ts.typeFlags().set(OutlierFlag);
0668 
0669   ts = t.appendTrackState();
0670   ts.typeFlags().set(HoleFlag);
0671 
0672   ts = t.appendTrackState();
0673   ts.typeFlags().set(MeasurementFlag);
0674   ts.typeFlags().set(SharedHitFlag);
0675 
0676   ts = t.appendTrackState();
0677   ts.typeFlags().set(OutlierFlag);
0678 
0679   calculateTrackQuantities(t);
0680 
0681   BOOST_CHECK_EQUAL(t.nHoles(), 2);
0682   BOOST_CHECK_EQUAL(t.nMeasurements(), 3);
0683   BOOST_CHECK_EQUAL(t.nOutliers(), 3);
0684   BOOST_CHECK_EQUAL(t.nSharedHits(), 2);
0685 }
0686 
0687 BOOST_AUTO_TEST_SUITE_END()