Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BoundTrackParametersTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BoundTrackParametersTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2020 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 
9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/unit_test.hpp>
11 
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <limits>
36 #include <memory>
37 #include <optional>
38 #include <utility>
39 #include <vector>
40 
42 
43 namespace {
44 
45 namespace bdata = boost::unit_test::data;
46 using namespace Acts;
47 using namespace Acts::UnitLiterals;
48 
49 constexpr auto eps = 8 * std::numeric_limits<ActsScalar>::epsilon();
51 const BoundSquareMatrix cov = BoundSquareMatrix::Identity();
52 
53 void checkParameters(const BoundTrackParameters& params, double l0, double l1,
54  double time, double phi, double theta, double p, double q,
55  const Vector3& pos, const Vector3& unitDir) {
56  const auto particleHypothesis = ParticleHypothesis::pionLike(std::abs(q));
57 
58  const auto qOverP = particleHypothesis.qOverP(p, q);
59  const auto pos4 = VectorHelpers::makeVector4(pos, time);
60 
61  // native values
62  CHECK_CLOSE_OR_SMALL(params.template get<eBoundLoc0>(), l0, eps, eps);
63  CHECK_CLOSE_OR_SMALL(params.template get<eBoundLoc1>(), l1, eps, eps);
64  CHECK_CLOSE_OR_SMALL(params.template get<eBoundTime>(), time, eps, eps);
65  CHECK_CLOSE_OR_SMALL(detail::radian_sym(params.template get<eBoundPhi>()),
66  detail::radian_sym(phi), eps, eps);
67  CHECK_CLOSE_OR_SMALL(params.template get<eBoundTheta>(), theta, eps, eps);
68  CHECK_CLOSE_OR_SMALL(params.template get<eBoundQOverP>(), qOverP, eps, eps);
69  // convenience accessors
72  CHECK_CLOSE_OR_SMALL(params.time(), time, eps, eps);
75  CHECK_CLOSE_OR_SMALL(params.transverseMomentum(), p * std::sin(theta), eps,
76  eps);
77  CHECK_CLOSE_OR_SMALL(params.momentum(), p * unitDir, eps, eps);
78  BOOST_CHECK_EQUAL(params.charge(), q);
79 }
80 
81 void runTest(const std::shared_ptr<const Surface>& surface, double l0,
82  double l1, double time, double phi, double theta, double p) {
83  // phi is ill-defined in forward/backward tracks
84  phi = ((0 < theta) and (theta < M_PI)) ? phi : 0.0;
85 
86  // global direction for reference
87  const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
88  // convert local-to-global for reference
89  const Vector2 loc(l0, l1);
90  const Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
91  // global four-position as input
92  Vector4 pos4;
93  pos4.segment<3>(ePos0) = pos;
94  pos4[eTime] = time;
95 
96  // neutral parameters from local vector
97  {
98  BoundVector vector = BoundVector::Zero();
99  vector[eBoundLoc0] = l0;
100  vector[eBoundLoc1] = l1;
101  vector[eBoundTime] = time;
102  vector[eBoundPhi] = phi;
103  vector[eBoundTheta] = theta;
104  vector[eBoundQOverP] = 1 / p;
105  BoundTrackParameters params(surface, vector, std::nullopt,
107  checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
108  BOOST_CHECK(not params.covariance());
109 
110  // reassign w/ covariance
111  params =
113  checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
114  BOOST_CHECK(params.covariance());
115  BOOST_CHECK_EQUAL(params.covariance().value(), cov);
116  }
117  // negative charged parameters from local vector
118  {
119  BoundVector vector = BoundVector::Zero();
120  vector[eBoundLoc0] = l0;
121  vector[eBoundLoc1] = l1;
122  vector[eBoundTime] = time;
123  vector[eBoundPhi] = phi;
124  vector[eBoundTheta] = theta;
125  vector[eBoundQOverP] = -1_e / p;
126  BoundTrackParameters params(surface, vector, std::nullopt,
128  checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
129  BOOST_CHECK(not params.covariance());
130 
131  // reassign w/ covariance
132  params =
134  checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
135  BOOST_CHECK(params.covariance());
136  BOOST_CHECK_EQUAL(params.covariance().value(), cov);
137  }
138  // positive charged parameters from local vector
139  {
140  BoundVector vector = BoundVector::Zero();
141  vector[eBoundLoc0] = l0;
142  vector[eBoundLoc1] = l1;
143  vector[eBoundTime] = time;
144  vector[eBoundPhi] = phi;
145  vector[eBoundTheta] = theta;
146  vector[eBoundQOverP] = 1_e / p;
147  BoundTrackParameters params(surface, vector, std::nullopt,
149  checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
150  BOOST_CHECK(not params.covariance());
151 
152  // reassign w/ covariance
153  params =
155  checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
156  BOOST_CHECK(params.covariance());
157  BOOST_CHECK_EQUAL(params.covariance().value(), cov);
158  }
159  // double-negative charged any parameters from local vector
160  {
161  BoundVector vector = BoundVector::Zero();
162  vector[eBoundLoc0] = l0;
163  vector[eBoundLoc1] = l1;
164  vector[eBoundTime] = time;
165  vector[eBoundPhi] = phi;
166  vector[eBoundTheta] = theta;
167  vector[eBoundQOverP] = -2_e / p;
168  BoundTrackParameters params(surface, vector, std::nullopt,
170  checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
171  BOOST_CHECK(not params.covariance());
172 
173  // reassign w/ covariance
174  params = BoundTrackParameters(surface, vector, cov,
176  checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
177  BOOST_CHECK(params.covariance());
178  BOOST_CHECK_EQUAL(params.covariance().value(), cov);
179  }
180  // neutral parameters from global information
181  {
182  auto params =
183  BoundTrackParameters::create(surface, geoCtx, pos4, dir, 1 / p,
184  std::nullopt, ParticleHypothesis::pion0())
185  .value();
186  checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
187  BOOST_CHECK(not params.covariance());
188  }
189  // negative charged parameters from global information
190  {
191  auto params =
192  BoundTrackParameters::create(surface, geoCtx, pos4, dir, -1_e / p,
193  std::nullopt, ParticleHypothesis::pion())
194  .value();
195  checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
196  BOOST_CHECK(not params.covariance());
197  }
198  // positive charged parameters from global information
199  {
200  auto params =
201  BoundTrackParameters::create(surface, geoCtx, pos4, dir, 1_e / p,
202  std::nullopt, ParticleHypothesis::pion())
203  .value();
204  checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
205  BOOST_CHECK(not params.covariance());
206  }
207  // neutral any parameters from global information
208  {
209  auto params =
210  BoundTrackParameters::create(surface, geoCtx, pos4, dir, 1 / p,
211  std::nullopt, ParticleHypothesis::pion0())
212  .value();
213  checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
214  BOOST_CHECK(not params.covariance());
215  }
216  // double-negative any parameters from global information
217  {
218  auto params = BoundTrackParameters::create(
219  surface, geoCtx, pos4, dir, -2_e / p, std::nullopt,
221  .value();
222  checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
223  BOOST_CHECK(not params.covariance());
224  }
225  // triple-positive any parameters from global information
226  {
227  auto params = BoundTrackParameters::create(
228  surface, geoCtx, pos4, dir, 3_e / p, std::nullopt,
230  .value();
231  checkParameters(params, l0, l1, time, phi, theta, p, 3_e, pos, dir);
232  BOOST_CHECK(not params.covariance());
233  }
234 }
235 
236 // different surfaces
237 // parameters must be chosen such that all possible local positions (as defined
238 // in the dataset's header) represent valid points on the surface.
239 const auto cones = bdata::make({
240  Surface::makeShared<ConeSurface>(Transform3::Identity(),
241  0.5 /* opening angle */),
242 });
243 const auto cylinders = bdata::make({
244  Surface::makeShared<CylinderSurface>(Transform3::Identity(),
245  10.0 /* radius */, 100 /* half z */),
246 });
247 const auto discs = bdata::make({
248  Surface::makeShared<DiscSurface>(Transform3::Identity(), 0 /* radius min */,
249  100 /* radius max */),
250 });
251 const auto perigees = bdata::make({
252  Surface::makeShared<PerigeeSurface>(Vector3(0, 0, -1.5)),
253 });
254 const auto planes = bdata::make({
255  Surface::makeShared<PlaneSurface>(Vector3(1, 2, 3), Vector3::UnitX()),
256  Surface::makeShared<PlaneSurface>(Vector3(-2, -3, -4), Vector3::UnitY()),
257  Surface::makeShared<PlaneSurface>(Vector3(3, -4, 5), Vector3::UnitZ()),
258 });
259 const auto straws = bdata::make({
260  Surface::makeShared<StrawSurface>(Transform3::Identity(), 2.0 /* radius */,
261  200.0 /* half z */),
262 });
263 
264 } // namespace
265 
266 BOOST_AUTO_TEST_SUITE(EventDataBoundTrackParameters)
267 
269  cones* posAngle* posPositiveNonzero* ts* phis* thetas* ps,
270  surface, lphi, lz, time, phi, theta, p) {
271  // TODO extend lz to zero after fixing the transform implementation
272  // local parameter r*phi has limits that depend on the z position
273  const auto r = lz * surface->bounds().tanAlpha();
274  // local coordinates are singular at z = 0 -> normalize local r*phi
275  runTest(surface, (0 < lz) ? (r * lphi) : 0.0, lz, time, phi, theta, p);
276 }
277 
280  cylinders* posSymmetric* posSymmetric* ts* phis* thetas* ps, surface, lrphi,
281  lz, time, phi, theta, p) {
282  runTest(surface, lrphi, lz, time, phi, theta, p);
283 }
284 
286  discs* posPositive* posAngle* ts* phis* thetas* ps,
287  surface, lr, lphi, time, phi, theta, p) {
288  // local coordinates are singular at r = 0 -> normalize local phi
289  runTest(surface, lr, (0 < lr) ? lphi : 0.0, time, phi, theta, p);
290 }
291 
294  perigees* posSymmetric* posSymmetric* ts* phis* thetasNoForwardBackward* ps,
295  surface, d0, z0, time, phi, theta, p) {
296  // TODO extend theta to forward/back extreme cases fixing the transform
297  runTest(surface, d0, z0, time, phi, theta, p);
298 }
299 
301  planes* posSymmetric* posSymmetric* ts* phis* thetas* ps,
302  surface, l0, l1, time, phi, theta, p) {
303  runTest(surface, l0, l1, time, phi, theta, p);
304 }
305 
307  StrawSurface,
308  straws* posPositive* posSymmetric* ts* phis* thetasNoForwardBackward* ps,
309  surface, lr, lz, time, phi, theta, p) {
310  // TODO extend theta to forward/back extreme cases fixing the transform
311  runTest(surface, lr, lz, time, phi, theta, p);
312 }
313 
314 BOOST_AUTO_TEST_SUITE_END()