Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackTestsExtra.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackTestsExtra.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 #include <boost/test/unit_test.hpp>
9 
12 #include "Acts/Utilities/Zip.hpp"
13 
14 #include <numeric>
15 
16 using namespace Acts;
17 using namespace Acts::HashedStringLiteral;
19 
20 BOOST_AUTO_TEST_SUITE(EventDataTrack)
21 
22 BOOST_AUTO_TEST_CASE(CopyTracksIncludingDynamicColumns) {
23  // mutable source
26  TrackContainer tc{vtc, mtj};
27  tc.addColumn<size_t>("counter");
28  tc.addColumn<bool>("odd");
29 
31  // doesn't have the dynamic column
32 
34  tc3.addColumn<size_t>("counter");
35  tc3.addColumn<bool>("odd");
36 
37  for (size_t i = 0; i < 10; i++) {
38  auto t = tc.getTrack(tc.addTrack());
39  auto ts = t.appendTrackState();
40  ts.predicted() = BoundVector::Ones();
41  ts = t.appendTrackState();
42  ts.predicted().setOnes();
43  ts.predicted() *= 2;
44 
45  ts = t.appendTrackState();
46  ts.predicted().setOnes();
47  ts.predicted() *= 3;
48 
49  t.template component<size_t>("counter") = i;
50  t.template component<bool>("odd") = i % 2 == 0;
51 
52  auto t2 = tc2.getTrack(tc2.addTrack());
53  BOOST_CHECK_THROW(t2.copyFrom(t),
54  std::invalid_argument); // this should fail
55 
56  auto t3 = tc3.getTrack(tc3.addTrack());
57  t3.copyFrom(t); // this should work
58 
59  BOOST_CHECK_NE(t3.tipIndex(), MultiTrajectoryTraits::kInvalid);
60  BOOST_CHECK(t3.nTrackStates() > 0);
61  BOOST_REQUIRE_EQUAL(t.nTrackStates(), t3.nTrackStates());
62 
63  for (auto [tsa, tsb] :
64  zip(t.trackStatesReversed(), t3.trackStatesReversed())) {
65  BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
66  }
67 
68  BOOST_CHECK_EQUAL(t.template component<size_t>("counter"),
69  t3.template component<size_t>("counter"));
70  BOOST_CHECK_EQUAL(t.template component<bool>("odd"),
71  t3.template component<bool>("odd"));
72  }
73 
74  size_t before = mtj.size();
77 
78  BOOST_REQUIRE_EQUAL(tc4.trackStateContainer().size(), before);
79 
81  tc5.addColumn<size_t>("counter");
82  tc5.addColumn<bool>("odd");
83 
84  for (size_t i = 0; i < 10; i++) {
85  auto t4 = tc4.getTrack(i); // const source!
86  BOOST_CHECK_NE(t4.nTrackStates(), 0);
87 
88  auto t5 = tc5.getTrack(tc5.addTrack());
89  t5.copyFrom(t4); // this should work
90 
91  BOOST_CHECK_NE(t5.tipIndex(), MultiTrajectoryTraits::kInvalid);
92  BOOST_CHECK(t5.nTrackStates() > 0);
93  BOOST_REQUIRE_EQUAL(t4.nTrackStates(), t5.nTrackStates());
94 
95  for (auto [tsa, tsb] :
96  zip(t4.trackStatesReversed(), t5.trackStatesReversed())) {
97  BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
98  }
99 
100  BOOST_CHECK_EQUAL(t4.template component<size_t>("counter"),
101  t5.template component<size_t>("counter"));
102  BOOST_CHECK_EQUAL(t4.template component<bool>("odd"),
103  t5.template component<bool>("odd"));
104  }
105 }
106 
107 BOOST_AUTO_TEST_CASE(ReverseTrackStates) {
108  VectorTrackContainer vtc{};
110  TrackContainer tc{vtc, mtj};
111 
112  auto t = tc.getTrack(tc.addTrack());
113 
114  for (size_t i = 0; i < 4; i++) {
115  auto ts = t.appendTrackState();
116  ts.jacobian() = Acts::BoundMatrix::Identity() * i;
117  }
118 
119  std::vector<IndexType> exp;
120  exp.resize(t.nTrackStates());
121  std::iota(exp.rbegin(), exp.rend(), 0);
122  std::vector<IndexType> act;
123  std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
124  std::back_inserter(act),
125  [](const auto& ts) { return ts.index(); });
126 
127  // jacobians count up
128  for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
129  BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
130  }
131 
132  BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
133 
134  // reverse!
135  t.reverseTrackStates();
136 
137  std::iota(exp.begin(), exp.end(), 0);
138  act.clear();
139  std::transform(t.trackStatesReversed().begin(), t.trackStatesReversed().end(),
140  std::back_inserter(act),
141  [](const auto& ts) { return ts.index(); });
142  BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
143 
144  // jacobians stay with their track states
145  for (const auto [e, ts] : zip(exp, t.trackStatesReversed())) {
146  BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
147  }
148 
149  // back to original!
150  t.reverseTrackStates();
151 
152  // jacobians stay with their track states
153  for (const auto [e, ts] : zip(exp, t.trackStates())) {
154  BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
155  }
156 
157  // reverse with jacobians
158  t.reverseTrackStates(true);
159 
160  std::reverse(exp.begin(), exp.end());
161  std::rotate(exp.rbegin(), std::next(exp.rbegin()), exp.rend());
162 
163  for (const auto [e, ts] : zip(exp, t.trackStates())) {
164  Acts::BoundMatrix expJac;
165  if (e == 0) {
166  expJac = Acts::BoundMatrix::Zero();
167  } else {
168  expJac = (Acts::BoundMatrix::Identity() * e).inverse();
169  }
170 
171  BOOST_CHECK_EQUAL(ts.jacobian(), expJac);
172  }
173 
174  // now back to original order, revert jacobians again
175  t.reverseTrackStates(true);
176 
177  // reset exp to range(0, N)
178  std::iota(exp.begin(), exp.end(), 0);
179 
180  for (const auto [e, ts] : zip(exp, t.trackStates())) {
181  BOOST_CHECK_EQUAL(ts.jacobian(), Acts::BoundMatrix::Identity() * e);
182  }
183 }
184 
185 BOOST_AUTO_TEST_SUITE_END()