ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExtrapolatorTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ExtrapolatorTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2019 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/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
12 
29 #include "Acts/Utilities/Units.hpp"
30 
31 namespace bdata = boost::unit_test::data;
32 namespace tt = boost::test_tools;
33 using namespace Acts::UnitLiterals;
34 
35 namespace Acts {
36 namespace Test {
37 
38 // Create a test context
41 
42 // Global definitions
43 // The path limit abort
45 
46 std::vector<std::unique_ptr<const Surface>> stepState;
47 
49 auto tGeometry = cGeometry();
50 
51 // Get the navigator and provide the TrackingGeometry
53 
58 
59 BFieldType bField(0, 0, 2_T);
61 EigenPropagatorType epropagator(std::move(estepper), std::move(navigator));
62 
63 const int ntests = 100;
64 bool debugMode = false;
65 
66 // A plane selector for the SurfaceCollector
67 struct PlaneSelector {
70  bool operator()(const Surface& sf) const {
71  return (sf.type() == Surface::Plane);
72  }
73 };
74 
75 // This test case checks that no segmentation fault appears
76 // - simple extrapolation test
78  test_extrapolation_,
79  bdata::random((bdata::seed = 0,
80  bdata::distribution =
81  std::uniform_real_distribution<>(0.4_GeV, 10_GeV))) ^
82  bdata::random((bdata::seed = 1,
83  bdata::distribution =
84  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
85  bdata::random((bdata::seed = 2,
86  bdata::distribution =
87  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
88  bdata::random(
89  (bdata::seed = 3,
90  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
91  bdata::random(
92  (bdata::seed = 4,
93  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
94  bdata::xrange(ntests),
95  pT, phi, theta, charge, time, index) {
96  double dcharge = -1 + 2 * charge;
97  (void)index;
98 
99  // define start parameters
100  double x = 0;
101  double y = 0;
102  double z = 0;
103  double px = pT * cos(phi);
104  double py = pT * sin(phi);
105  double pz = pT / tan(theta);
106  double q = dcharge;
107  Vector3D pos(x, y, z);
108  Vector3D mom(px, py, pz);
110  Covariance cov;
111  // take some major correlations (off-diagonals)
112  cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
113  0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
114  0, 0;
115  CurvilinearParameters start(cov, pos, mom, q, time);
116 
118  options.maxStepSize = 10_cm;
119  options.pathLimit = 25_cm;
120 
121  BOOST_CHECK(epropagator.propagate(start, options).value().endParameters !=
122  nullptr);
123 }
124 
125 // This test case checks that no segmentation fault appears
126 // - this tests the collection of surfaces
128  test_surface_collection_,
129  bdata::random((bdata::seed = 10,
130  bdata::distribution =
131  std::uniform_real_distribution<>(0.4_GeV, 10_GeV))) ^
132  bdata::random((bdata::seed = 11,
133  bdata::distribution =
134  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
135  bdata::random((bdata::seed = 12,
136  bdata::distribution =
137  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
138  bdata::random(
139  (bdata::seed = 13,
140  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
141  bdata::random(
142  (bdata::seed = 14,
143  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
144  bdata::xrange(ntests),
145  pT, phi, theta, charge, time, index) {
146  double dcharge = -1 + 2 * charge;
147  (void)index;
148 
149  // define start parameters
150  double x = 0;
151  double y = 0;
152  double z = 0;
153  double px = pT * cos(phi);
154  double py = pT * sin(phi);
155  double pz = pT / tan(theta);
156  double q = dcharge;
157  Vector3D pos(x, y, z);
158  Vector3D mom(px, py, pz);
160  Covariance cov;
161  // take some major correlations (off-diagonals)
162  cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
163  0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
164  0, 0;
165  CurvilinearParameters start(cov, pos, mom, q, time);
166 
167  // A PlaneSelector for the SurfaceCollector
168  using PlaneCollector = SurfaceCollector<PlaneSelector>;
169 
171 
172  options.maxStepSize = 10_cm;
173  options.pathLimit = 25_cm;
174  options.debug = debugMode;
175 
176  const auto& result = epropagator.propagate(start, options).value();
177  auto collector_result = result.get<PlaneCollector::result_type>();
178 
179  // step through the surfaces and go step by step
180  PropagatorOptions<> optionsEmpty(tgContext, mfContext);
181 
182  optionsEmpty.maxStepSize = 25_cm;
183  optionsEmpty.debug = true;
184  // Try propagation from start to each surface
185  for (const auto& colsf : collector_result.collected) {
186  const auto& csurface = colsf.surface;
187  // Avoid going to the same surface
188  // @todo: decide on strategy and write unit test for this
189  if (csurface == &start.referenceSurface()) {
190  continue;
191  }
192  // Extrapolate & check
193  const auto& cresult = epropagator.propagate(start, *csurface, optionsEmpty)
194  .value()
195  .endParameters;
196  BOOST_CHECK(cresult != nullptr);
197  }
198 }
199 
200 // This test case checks that no segmentation fault appears
201 // - this tests the collection of surfaces
203  test_material_interactor_,
204  bdata::random((bdata::seed = 20,
205  bdata::distribution =
206  std::uniform_real_distribution<>(0.4_GeV, 10_GeV))) ^
207  bdata::random((bdata::seed = 21,
208  bdata::distribution =
209  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
210  bdata::random((bdata::seed = 22,
211  bdata::distribution =
212  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
213  bdata::random(
214  (bdata::seed = 23,
215  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
216  bdata::random(
217  (bdata::seed = 24,
218  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
219  bdata::xrange(ntests),
220  pT, phi, theta, charge, time, index) {
221  double dcharge = -1 + 2 * charge;
222  (void)index;
223 
224  // define start parameters
225  double x = 0;
226  double y = 0;
227  double z = 0;
228  double px = pT * cos(phi);
229  double py = pT * sin(phi);
230  double pz = pT / tan(theta);
231  double q = dcharge;
232  Vector3D pos(x, y, z);
233  Vector3D mom(px, py, pz);
235  Covariance cov;
236  // take some major correlations (off-diagonals)
237  cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
238  0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
239  0, 0;
240  CurvilinearParameters start(cov, pos, mom, q, time);
241 
243 
246  options.debug = debugMode;
247  options.maxStepSize = 25_cm;
248  options.pathLimit = 25_cm;
249 
250  const auto& result = epropagator.propagate(start, options).value();
251  if (result.endParameters) {
252  // test that you actually lost some energy
253  BOOST_CHECK_LT(result.endParameters->momentum().norm(),
254  start.momentum().norm());
255  }
256 
257  if (debugMode) {
258  const auto& output = result.get<DebugOutput::result_type>();
259  std::cout << ">>> Extrapolation output " << std::endl;
260  std::cout << output.debugString << std::endl;
261  }
262 }
263 
264 // This test case checks that no segmentation fault appears
265 // - this tests the loop protection
267  loop_protection_test,
268  bdata::random((bdata::seed = 20,
269  bdata::distribution =
270  std::uniform_real_distribution<>(0.1_GeV, 0.5_GeV))) ^
271  bdata::random((bdata::seed = 21,
272  bdata::distribution =
273  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
274  bdata::random((bdata::seed = 22,
275  bdata::distribution =
276  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
277  bdata::random(
278  (bdata::seed = 23,
279  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
280  bdata::random(
281  (bdata::seed = 24,
282  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
283  bdata::xrange(ntests),
284  pT, phi, theta, charge, time, index) {
285  double dcharge = -1 + 2 * charge;
286  (void)index;
287 
288  // define start parameters
289  double x = 0;
290  double y = 0;
291  double z = 0;
292  double px = pT * cos(phi);
293  double py = pT * sin(phi);
294  double pz = pT / tan(theta);
295  double q = dcharge;
296  Vector3D pos(x, y, z);
297  Vector3D mom(px, py, pz);
299  Covariance cov;
300  // take some major correlations (off-diagonals)
301  cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
302  0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
303  0, 0;
304  CurvilinearParameters start(cov, pos, mom, q, time);
305 
306  // Action list and abort list
308 
311  options.maxStepSize = 25_cm;
312  options.pathLimit = 1500_mm;
313 
314  const auto& status = epropagator.propagate(start, options).value();
315  // this test assumes state.options.loopFraction = 0.5
316  // maximum momentum allowed
317  double pmax = options.pathLimit * bField.getField(pos).norm() / M_PI;
318  if (mom.norm() < pmax) {
319  BOOST_CHECK_LT(status.pathLength, options.pathLimit);
320  } else {
321  CHECK_CLOSE_REL(status.pathLength, options.pathLimit, 1e-3);
322  }
323 }
324 
325 } // namespace Test
326 } // namespace Acts