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 #include <boost/test/unit_test.hpp>
0009 
0010 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0011 #include "Acts/EventData/VectorTrackContainer.hpp"
0012 #include "Acts/Utilities/Zip.hpp"
0013 
0014 #include <numeric>
0015 
0016 using namespace Acts;
0017 using namespace Acts::HashedStringLiteral;
0018 using MultiTrajectoryTraits::IndexType;
0019 
0020 BOOST_AUTO_TEST_SUITE(EventDataTrack)
0021 
0022 BOOST_AUTO_TEST_CASE(CopyTracksIncludingDynamicColumns) {
0023   // mutable source
0024   VectorTrackContainer vtc{};
0025   VectorMultiTrajectory mtj{};
0026   TrackContainer tc{vtc, mtj};
0027   tc.addColumn<std::size_t>("counter");
0028   tc.addColumn<bool>("odd");
0029   mtj.addColumn<std::size_t>("ts_counter");
0030   mtj.addColumn<bool>("ts_odd");
0031 
0032   TrackContainer tc2{VectorTrackContainer{}, VectorMultiTrajectory{}};
0033   // doesn't have the dynamic column
0034 
0035   VectorTrackContainer vtc3{};
0036   VectorMultiTrajectory mtj3{};
0037   mtj3.addColumn<std::size_t>("ts_counter");
0038   mtj3.addColumn<bool>("ts_odd");
0039 
0040   TrackContainer tc3{vtc3, mtj3};
0041 
0042   tc3.addColumn<std::size_t>("counter");
0043   tc3.addColumn<bool>("odd");
0044 
0045   for (std::size_t i = 0; i < 10; i++) {
0046     auto t = tc.makeTrack();
0047     auto ts = t.appendTrackState();
0048     ts.predicted() = BoundVector::Ones();
0049     ts.component<std::size_t, "ts_counter"_hash>() = i;
0050 
0051     ts = t.appendTrackState();
0052     ts.predicted().setOnes();
0053     ts.predicted() *= 2;
0054     ts.component<std::size_t, "ts_counter"_hash>() = i + 1;
0055 
0056     ts = t.appendTrackState();
0057     ts.predicted().setOnes();
0058     ts.predicted() *= 3;
0059     ts.component<std::size_t, "ts_counter"_hash>() = i + 2;
0060 
0061     t.template component<std::size_t>("counter") = i;
0062     t.template component<bool>("odd") = i % 2 == 0;
0063 
0064     auto t2 = tc2.makeTrack();
0065     BOOST_CHECK_THROW(t2.copyFrom(t),
0066                       std::invalid_argument);  // this should fail
0067 
0068     auto t3 = tc3.makeTrack();
0069     t3.copyFrom(t);  // this should work
0070 
0071     BOOST_CHECK_NE(t3.tipIndex(), MultiTrajectoryTraits::kInvalid);
0072     BOOST_CHECK_GT(t3.nTrackStates(), 0);
0073     BOOST_REQUIRE_EQUAL(t.nTrackStates(), t3.nTrackStates());
0074 
0075     for (auto [tsa, tsb] :
0076          zip(t.trackStatesReversed(), t3.trackStatesReversed())) {
0077       BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0078 
0079       BOOST_CHECK_EQUAL(
0080           (tsa.template component<std::size_t, "ts_counter"_hash>()),
0081           (tsb.template component<std::size_t, "ts_counter"_hash>()));
0082 
0083       BOOST_CHECK_EQUAL((tsa.template component<bool, "ts_odd"_hash>()),
0084                         (tsb.template component<bool, "ts_odd"_hash>()));
0085     }
0086 
0087     BOOST_CHECK_EQUAL(t.template component<std::size_t>("counter"),
0088                       t3.template component<std::size_t>("counter"));
0089     BOOST_CHECK_EQUAL(t.template component<bool>("odd"),
0090                       t3.template component<bool>("odd"));
0091   }
0092 
0093   std::size_t before = mtj.size();
0094   TrackContainer tc4{ConstVectorTrackContainer{vtc},
0095                      ConstVectorMultiTrajectory{mtj}};
0096 
0097   BOOST_REQUIRE_EQUAL(tc4.trackStateContainer().size(), before);
0098 
0099   VectorTrackContainer vtc5{};
0100   VectorMultiTrajectory mtj5{};
0101   mtj5.addColumn<std::size_t>("ts_counter");
0102   mtj5.addColumn<bool>("ts_odd");
0103 
0104   TrackContainer tc5{vtc5, mtj5};
0105   tc5.addColumn<std::size_t>("counter");
0106   tc5.addColumn<bool>("odd");
0107 
0108   for (std::size_t i = 0; i < 10; i++) {
0109     auto t4 = tc4.getTrack(i);  // const source!
0110     BOOST_CHECK_NE(t4.nTrackStates(), 0);
0111 
0112     auto t5 = tc5.makeTrack();
0113     t5.copyFrom(t4);  // this should work
0114 
0115     BOOST_CHECK_NE(t5.tipIndex(), MultiTrajectoryTraits::kInvalid);
0116     BOOST_CHECK_GT(t5.nTrackStates(), 0);
0117     BOOST_REQUIRE_EQUAL(t4.nTrackStates(), t5.nTrackStates());
0118 
0119     for (auto [tsa, tsb] :
0120          zip(t4.trackStatesReversed(), t5.trackStatesReversed())) {
0121       BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
0122     }
0123 
0124     BOOST_CHECK_EQUAL(t4.template component<std::size_t>("counter"),
0125                       t5.template component<std::size_t>("counter"));
0126     BOOST_CHECK_EQUAL(t4.template component<bool>("odd"),
0127                       t5.template component<bool>("odd"));
0128   }
0129 }
0130 
0131 BOOST_AUTO_TEST_CASE(ReverseTrackStates) {
0132   VectorTrackContainer vtc{};
0133   VectorMultiTrajectory mtj{};
0134   TrackContainer tc{vtc, mtj};
0135 
0136   auto t = tc.makeTrack();
0137 
0138   for (std::size_t i = 0; i < 4; i++) {
0139     auto ts = t.appendTrackState();
0140     ts.jacobian() = Acts::BoundMatrix::Identity() * i;
0141   }
0142 
0143   std::vector<IndexType> exp;
0144   exp.resize(t.nTrackStates());
0145   std::iota(exp.rbegin(), exp.rend(), 0);
0146   std::vector<IndexType> act;
0147   std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0148                  std::back_inserter(act),
0149                  [](const auto& ts) { return ts.index(); });
0150 
0151   // jacobians count up
0152   for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0153     BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0154   }
0155 
0156   BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0157 
0158   // reverse!
0159   t.reverseTrackStates();
0160 
0161   std::iota(exp.begin(), exp.end(), 0);
0162   act.clear();
0163   std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
0164                  std::back_inserter(act),
0165                  [](const auto& ts) { return ts.index(); });
0166   BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0167 
0168   // jacobians stay with their track states
0169   for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
0170     BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0171   }
0172 
0173   // back to original!
0174   t.reverseTrackStates();
0175 
0176   // jacobians stay with their track states
0177   for (const auto [e, ts] : zip(exp, t.trackStates())) {
0178     BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0179   }
0180 
0181   // reverse with jacobians
0182   t.reverseTrackStates(true);
0183 
0184   std::reverse(exp.begin(), exp.end());
0185   std::rotate(exp.rbegin(), std::next(exp.rbegin()), exp.rend());
0186 
0187   for (const auto [e, ts] : zip(exp, t.trackStates())) {
0188     Acts::BoundMatrix expJac;
0189     if (e == 0) {
0190       expJac = Acts::BoundMatrix::Zero();
0191     } else {
0192       expJac = (Acts::BoundMatrix::Identity() * e).inverse();
0193     }
0194 
0195     BOOST_CHECK_EQUAL(ts.jacobian(), expJac);
0196   }
0197 
0198   // now back to original order, revert jacobians again
0199   t.reverseTrackStates(true);
0200 
0201   // reset exp to range(0, N)
0202   std::iota(exp.begin(), exp.end(), 0);
0203 
0204   for (const auto [e, ts] : zip(exp, t.trackStates())) {
0205     BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
0206   }
0207 }
0208 
0209 BOOST_AUTO_TEST_SUITE_END()