EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialCollectionTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialCollectionTests.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 
28 #include "Acts/Utilities/Units.hpp"
29 
30 #include <memory>
31 
32 namespace bdata = boost::unit_test::data;
33 namespace tt = boost::test_tools;
34 using namespace Acts::UnitLiterals;
35 
36 namespace Acts {
37 namespace Test {
38 
39 // Create a test context
42 
43 // Global definitions
44 // The path limit abort
45 using path_limit = PathLimitReached;
46 
47 CylindricalTrackingGeometry cGeometry(tgContext);
48 auto tGeometry = cGeometry();
49 
50 // create a navigator for this tracking geometry
51 Navigator navigatorES(tGeometry);
52 Navigator navigatorSL(tGeometry);
53 
54 using BField = ConstantBField;
55 using EigenStepper = EigenStepper<BField>;
56 using EigenPropagator = Propagator<EigenStepper, Navigator>;
58 
59 const double Bz = 2_T;
60 BField bField(0, 0, Bz);
62 EigenPropagator epropagator(std::move(estepper), std::move(navigatorES));
63 
66  std::move(navigatorSL));
67 const int ntests = 500;
68 const int skip = 0;
69 bool debugModeFwd = false;
70 bool debugModeBwd = false;
71 bool debugModeFwdStep = false;
72 bool debugModeBwdStep = false;
73 
84 template <typename propagator_t>
85 void runTest(const propagator_t& prop, double pT, double phi, double theta,
86  int charge, double time, int index) {
87  double p = pT / sin(theta);
88  double q = -1 + 2 * charge;
89 
90  if (index < skip) {
91  return;
92  }
93 
94  // define start parameters
96  // take some major correlations (off-diagonals)
97  // clang-format off
98  cov <<
99  10_mm, 0, 0.123, 0, 0.5, 0,
100  0, 10_mm, 0, 0.162, 0, 0,
101  0.123, 0, 0.1, 0, 0, 0,
102  0, 0.162, 0, 0.1, 0, 0,
103  0.5, 0, 0, 0, 1_e / 10_GeV, 0,
104  0, 0, 0, 0, 0, 1_us;
105  // clang-format on
106  std::cout << cov.determinant() << std::endl;
107  CurvilinearTrackParameters start(Vector4D(0, 0, 0, time), phi, theta, q / p,
108  cov);
109 
110  // Action list and abort list
111  using ActionListType = ActionList<MaterialInteractor>;
112  using AbortListType = AbortList<>;
113 
115  Options fwdOptions(tgContext, mfContext, getDummyLogger());
116 
117  fwdOptions.maxStepSize = 25_cm;
118  fwdOptions.pathLimit = 25_cm;
119 
120  // get the material collector and configure it
121  auto& fwdMaterialInteractor =
122  fwdOptions.actionList.template get<MaterialInteractor>();
123  fwdMaterialInteractor.recordInteractions = true;
124  fwdMaterialInteractor.energyLoss = false;
125  fwdMaterialInteractor.multipleScattering = false;
126 
127  if (debugModeFwd) {
128  std::cout << ">>> Forward Propagation : start." << std::endl;
129  }
130  // forward material test
131  const auto& fwdResult = prop.propagate(start, fwdOptions).value();
132  auto& fwdMaterial = fwdResult.template get<MaterialInteractor::result_type>();
133 
134  double fwdStepMaterialInX0 = 0.;
135  double fwdStepMaterialInL0 = 0.;
136  // check that the collected material is not zero
137  BOOST_CHECK_NE(fwdMaterial.materialInX0, 0.);
138  BOOST_CHECK_NE(fwdMaterial.materialInL0, 0.);
139  // check that the sum of all steps is the total material
140  for (auto& mInteraction : fwdMaterial.materialInteractions) {
141  fwdStepMaterialInX0 += mInteraction.materialSlab.thicknessInX0();
142  fwdStepMaterialInL0 += mInteraction.materialSlab.thicknessInL0();
143  }
144  CHECK_CLOSE_REL(fwdMaterial.materialInX0, fwdStepMaterialInX0, 1e-3);
145  CHECK_CLOSE_REL(fwdMaterial.materialInL0, fwdStepMaterialInL0, 1e-3);
146 
147  // get the forward output to the screen
148  if (debugModeFwd) {
149  // check if the surfaces are free
150  std::cout << ">>> Material steps found on ..." << std::endl;
151  for (auto& fwdStepsC : fwdMaterial.materialInteractions) {
152  std::cout << "--> Surface with " << fwdStepsC.surface->geometryId()
153  << std::endl;
154  }
155  }
156 
157  // backward material test
158  Options bwdOptions(tgContext, mfContext, getDummyLogger());
159  bwdOptions.maxStepSize = -25_cm;
160  bwdOptions.pathLimit = -25_cm;
161  bwdOptions.direction = backward;
162 
163  // get the material collector and configure it
164  auto& bwdMaterialInteractor =
165  bwdOptions.actionList.template get<MaterialInteractor>();
166  bwdMaterialInteractor.recordInteractions = true;
167  bwdMaterialInteractor.energyLoss = false;
168  bwdMaterialInteractor.multipleScattering = false;
169 
170  const auto& startSurface = start.referenceSurface();
171 
172  if (debugModeBwd) {
173  std::cout << ">>> Backward Propagation : start." << std::endl;
174  }
175  const auto& bwdResult =
176  prop.propagate(*fwdResult.endParameters.get(), startSurface, bwdOptions)
177  .value();
178 
179  if (debugModeBwd) {
180  std::cout << ">>> Backward Propagation : end." << std::endl;
181  }
182 
183  auto& bwdMaterial =
184  bwdResult.template get<typename MaterialInteractor::result_type>();
185 
186  double bwdStepMaterialInX0 = 0.;
187  double bwdStepMaterialInL0 = 0.;
188 
189  // check that the collected material is not zero
190  BOOST_CHECK_NE(bwdMaterial.materialInX0, 0.);
191  BOOST_CHECK_NE(bwdMaterial.materialInL0, 0.);
192  // check that the sum of all steps is the total material
193  for (auto& mInteraction : bwdMaterial.materialInteractions) {
194  bwdStepMaterialInX0 += mInteraction.materialSlab.thicknessInX0();
195  bwdStepMaterialInL0 += mInteraction.materialSlab.thicknessInL0();
196  }
197 
198  CHECK_CLOSE_REL(bwdMaterial.materialInX0, bwdStepMaterialInX0, 1e-3);
199  CHECK_CLOSE_REL(bwdMaterial.materialInL0, bwdStepMaterialInL0, 1e-3);
200 
201  // get the backward output to the screen
202  if (debugModeBwd) {
203  // check if the surfaces are free
204  std::cout << ">>> Material steps found on ..." << std::endl;
205  for (auto& bwdStepsC : bwdMaterial.materialInteractions) {
206  std::cout << "--> Surface with " << bwdStepsC.surface->geometryId()
207  << std::endl;
208  }
209  }
210 
211  // forward-backward compatibility test
212  BOOST_CHECK_EQUAL(bwdMaterial.materialInteractions.size(),
213  fwdMaterial.materialInteractions.size());
214 
215  CHECK_CLOSE_REL(bwdMaterial.materialInX0, fwdMaterial.materialInX0, 1e-3);
216  CHECK_CLOSE_REL(bwdMaterial.materialInL0, bwdMaterial.materialInL0, 1e-3);
217 
218  // stepping from one surface to the next
219  // now go from surface to surface and check
220  Options fwdStepOptions(tgContext, mfContext, getDummyLogger());
221  fwdStepOptions.maxStepSize = 25_cm;
222  fwdStepOptions.pathLimit = 25_cm;
223 
224  // get the material collector and configure it
225  auto& fwdStepMaterialInteractor =
226  fwdStepOptions.actionList.template get<MaterialInteractor>();
227  fwdStepMaterialInteractor.recordInteractions = true;
228  fwdStepMaterialInteractor.energyLoss = false;
229  fwdStepMaterialInteractor.multipleScattering = false;
230 
231  double fwdStepStepMaterialInX0 = 0.;
232  double fwdStepStepMaterialInL0 = 0.;
233 
234  if (debugModeFwdStep) {
235  // check if the surfaces are free
236  std::cout << ">>> Forward steps to be processed sequentially ..."
237  << std::endl;
238  for (auto& fwdStepsC : fwdMaterial.materialInteractions) {
239  std::cout << "--> Surface with " << fwdStepsC.surface->geometryId()
240  << std::endl;
241  }
242  }
243 
244  // move forward step by step through the surfaces
245  const BoundTrackParameters* sParameters = &start;
246  std::vector<std::unique_ptr<const BoundTrackParameters>> stepParameters;
247  for (auto& fwdSteps : fwdMaterial.materialInteractions) {
248  if (debugModeFwdStep) {
249  std::cout << ">>> Forward step : "
250  << sParameters->referenceSurface().geometryId() << " --> "
251  << fwdSteps.surface->geometryId() << std::endl;
252  }
253 
254  // make a forward step
255  const auto& fwdStep =
256  prop.propagate(*sParameters, (*fwdSteps.surface), fwdStepOptions)
257  .value();
258 
259  auto& fwdStepMaterial =
260  fwdStep.template get<typename MaterialInteractor::result_type>();
261  fwdStepStepMaterialInX0 += fwdStepMaterial.materialInX0;
262  fwdStepStepMaterialInL0 += fwdStepMaterial.materialInL0;
263 
264  if (fwdStep.endParameters != nullptr) {
265  // make sure the parameters do not run out of scope
266  stepParameters.push_back(std::make_unique<BoundTrackParameters>(
267  (*fwdStep.endParameters.get())));
268  sParameters = stepParameters.back().get();
269  }
270  }
271  // final destination surface
272  const Surface& dSurface = fwdResult.endParameters->referenceSurface();
273 
274  if (debugModeFwdStep) {
275  std::cout << ">>> Forward step : "
276  << sParameters->referenceSurface().geometryId() << " --> "
277  << dSurface.geometryId() << std::endl;
278  }
279 
280  const auto& fwdStepFinal =
281  prop.propagate(*sParameters, dSurface, fwdStepOptions).value();
282 
283  auto& fwdStepMaterial =
284  fwdStepFinal.template get<typename MaterialInteractor::result_type>();
285  fwdStepStepMaterialInX0 += fwdStepMaterial.materialInX0;
286  fwdStepStepMaterialInL0 += fwdStepMaterial.materialInL0;
287 
288  // forward-forward step compatibility test
289  CHECK_CLOSE_REL(fwdStepStepMaterialInX0, fwdStepMaterialInX0, 1e-3);
290  CHECK_CLOSE_REL(fwdStepStepMaterialInL0, fwdStepMaterialInL0, 1e-3);
291 
292  // stepping from one surface to the next : backwards
293  // now go from surface to surface and check
294  Options bwdStepOptions(tgContext, mfContext, getDummyLogger());
295 
296  bwdStepOptions.maxStepSize = -25_cm;
297  bwdStepOptions.pathLimit = -25_cm;
298  bwdStepOptions.direction = backward;
299 
300  // get the material collector and configure it
301  auto& bwdStepMaterialInteractor =
302  bwdStepOptions.actionList.template get<MaterialInteractor>();
303  bwdStepMaterialInteractor.recordInteractions = true;
304  bwdStepMaterialInteractor.multipleScattering = false;
305  bwdStepMaterialInteractor.energyLoss = false;
306 
307  double bwdStepStepMaterialInX0 = 0.;
308  double bwdStepStepMaterialInL0 = 0.;
309 
310  if (debugModeBwdStep) {
311  // check if the surfaces are free
312  std::cout << ">>> Backward steps to be processed sequentially ..."
313  << std::endl;
314  for (auto& bwdStepsC : bwdMaterial.materialInteractions) {
315  std::cout << "--> Surface with " << bwdStepsC.surface->geometryId()
316  << std::endl;
317  }
318  }
319 
320  // move forward step by step through the surfaces
321  sParameters = fwdResult.endParameters.get();
322  for (auto& bwdSteps : bwdMaterial.materialInteractions) {
323  if (debugModeBwdStep) {
324  std::cout << ">>> Backward step : "
325  << sParameters->referenceSurface().geometryId() << " --> "
326  << bwdSteps.surface->geometryId() << std::endl;
327  }
328  // make a forward step
329  const auto& bwdStep =
330  prop.propagate(*sParameters, (*bwdSteps.surface), bwdStepOptions)
331  .value();
332 
333  auto& bwdStepMaterial =
334  bwdStep.template get<typename MaterialInteractor::result_type>();
335  bwdStepStepMaterialInX0 += bwdStepMaterial.materialInX0;
336  bwdStepStepMaterialInL0 += bwdStepMaterial.materialInL0;
337 
338  if (bwdStep.endParameters != nullptr) {
339  // make sure the parameters do not run out of scope
340  stepParameters.push_back(std::make_unique<BoundTrackParameters>(
341  *(bwdStep.endParameters.get())));
342  sParameters = stepParameters.back().get();
343  }
344  }
345  // final destination surface
346  const Surface& dbSurface = start.referenceSurface();
347 
348  if (debugModeBwdStep) {
349  std::cout << ">>> Backward step : "
350  << sParameters->referenceSurface().geometryId() << " --> "
351  << dSurface.geometryId() << std::endl;
352  }
353 
354  const auto& bwdStepFinal =
355  prop.propagate(*sParameters, dbSurface, bwdStepOptions).value();
356 
357  auto& bwdStepMaterial =
358  bwdStepFinal.template get<typename MaterialInteractor::result_type>();
359  bwdStepStepMaterialInX0 += bwdStepMaterial.materialInX0;
360  bwdStepStepMaterialInL0 += bwdStepMaterial.materialInL0;
361 
362  // forward-forward step compatibility test
363  CHECK_CLOSE_REL(bwdStepStepMaterialInX0, bwdStepMaterialInX0, 1e-3);
364  CHECK_CLOSE_REL(bwdStepStepMaterialInL0, bwdStepMaterialInL0, 1e-3);
365 
366  // Test the material affects the covariance into the right direction
367  // get the material collector and configure it
368  auto& covfwdMaterialInteractor =
369  fwdOptions.actionList.template get<MaterialInteractor>();
370  covfwdMaterialInteractor.recordInteractions = false;
371  covfwdMaterialInteractor.energyLoss = true;
372  covfwdMaterialInteractor.multipleScattering = true;
373 
374  // forward material test
375  const auto& covfwdResult = prop.propagate(start, fwdOptions).value();
376 
377  BOOST_CHECK_LE(
378  cov.determinant(),
379  covfwdResult.endParameters->covariance().value().determinant());
380 }
381 
382 // This test case checks that no segmentation fault appears
383 // - this tests the collection of surfaces
385  test_material_collector,
386  bdata::random((bdata::seed = 20,
387  bdata::distribution =
388  std::uniform_real_distribution<>(0.5_GeV, 10_GeV))) ^
389  bdata::random((bdata::seed = 21,
390  bdata::distribution =
391  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
392  bdata::random((bdata::seed = 22,
393  bdata::distribution =
394  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
395  bdata::random(
396  (bdata::seed = 23,
397  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
398  bdata::random(
399  (bdata::seed = 24,
400  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
402  pT, phi, theta, charge, time, index) {
403  runTest(epropagator, pT, phi, theta, charge, time, index);
404  runTest(slpropagator, pT, phi, theta, charge, time, index);
405 }
406 
407 } // namespace Test
408 } // namespace Acts