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