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