ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DirectNavigatorTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DirectNavigatorTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 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 
28 
29 namespace bdata = boost::unit_test::data;
30 namespace tt = boost::test_tools;
31 using namespace Acts::UnitLiterals;
32 
33 namespace Acts {
34 namespace Test {
35 
36 // Create a test context
39 
40 CylindricalTrackingGeometry cGeometry(tgContext);
42 
43 // Create a navigator for this tracking geometry
46 
51 
52 const double Bz = 2_T;
53 BField bField(0, 0, Bz);
56 
57 ReferencePropagator rpropagator(std::move(estepper), std::move(navigator));
58 DirectPropagator dpropagator(std::move(dstepper), std::move(dnavigator));
59 
60 const int ntests = 1000;
61 const int skip = 0;
62 bool debugMode = false;
63 bool referenceTiming = false;
64 bool oversteppingTest = false;
66 
80 template <typename rpropagator_t, typename dpropagator_t>
81 void runTest(const rpropagator_t& rprop, const dpropagator_t& dprop, double pT,
82  double phi, double theta, int charge, double time, int index) {
83  double dcharge = -1 + 2 * charge;
84 
85  if (index < skip) {
86  return;
87  }
88 
89  // Define start parameters from ranom input
90  double x = 0;
91  double y = 0;
92  double z = 0;
93  double px = pT * cos(phi);
94  double py = pT * sin(phi);
95  double pz = pT / tan(theta);
96  double q = dcharge;
97  Vector3D pos(x, y, z);
98  Vector3D mom(px, py, pz);
99  CurvilinearParameters start(std::nullopt, pos, mom, q, time);
100 
103 
104  // Action list and abort list
105  using RefereceActionList =
107  using ReferenceAbortList = AbortList<EndOfWorld>;
108 
109  // Options definition
111  Options pOptions(tgContext, mfContext);
112  pOptions.debug = debugMode;
113  if (oversteppingTest) {
114  pOptions.maxStepSize = oversteppingMaxStepSize;
115  }
116 
117  // Surface collector configuration
118  auto& sCollector = pOptions.actionList.template get<SurfaceCollector<>>();
119  sCollector.selector.selectSensitive = true;
120  sCollector.selector.selectMaterial = true;
121 
122  // Result is immediately used, non-valid result would indicate failure
123  const auto& pResult = rprop.propagate(start, pOptions).value();
124  auto& cSurfaces = pResult.template get<SurfaceCollector<>::result_type>();
125  auto& cOutput = pResult.template get<DebugOutput::result_type>();
126  auto& cMaterial = pResult.template get<MaterialInteractor::result_type>();
127  const Surface& destination = pResult.endParameters->referenceSurface();
128 
129  if (debugMode) {
130  std::cout << ">>> Standard Navigator output to come : " << std::endl;
131  std::cout << cOutput.debugString << std::endl;
132 
133  std::cout << " - the standard navigator yielded "
134  << cSurfaces.collected.size() << " collected surfaces"
135  << std::endl;
136  }
137 
138  if (not referenceTiming) {
139  // Create the surface sequence
140  std::vector<const Surface*> surfaceSequence;
141  surfaceSequence.reserve(cSurfaces.collected.size());
142  for (auto& cs : cSurfaces.collected) {
143  surfaceSequence.push_back(cs.surface);
144  }
145 
146  // Action list for direct navigator with its initalizer
147  using DirectActionList =
149  SurfaceCollector<>, DebugOutput>;
150 
151  // Direct options definition
153  DirectOptions dOptions(tgContext, mfContext);
154  dOptions.debug = debugMode;
155  // Set the surface sequence
156  auto& dInitializer =
157  dOptions.actionList.get<DirectNavigator::Initializer>();
158  dInitializer.surfaceSequence = surfaceSequence;
159  // Surface collector configuration
160  auto& dCollector = dOptions.actionList.template get<SurfaceCollector<>>();
161  dCollector.selector.selectSensitive = true;
162  dCollector.selector.selectMaterial = true;
163 
164  // Now redo the propagation with the direct propagator
165  const auto& ddResult =
166  dprop.propagate(start, destination, dOptions).value();
167  auto& ddSurfaces = ddResult.template get<SurfaceCollector<>::result_type>();
168  auto& ddOutput = ddResult.template get<DebugOutput::result_type>();
169  auto& ddMaterial = ddResult.template get<MaterialInteractor::result_type>();
170 
171  // CHECK if you have as many surfaces collected as the default navigator
172  BOOST_CHECK_EQUAL(cSurfaces.collected.size(), ddSurfaces.collected.size());
173  CHECK_CLOSE_REL(cMaterial.materialInX0, ddMaterial.materialInX0, 1e-3);
174 
175  if (debugMode) {
176  std::cout << ">>> Direct Navigator (with destination) output to come : "
177  << std::endl;
178  std::cout << ddOutput.debugString << std::endl;
179  }
180 
181  // Now redo the propagation with the direct propagator - without destination
182  const auto& dwResult = dprop.propagate(start, dOptions).value();
183  auto& dwSurfaces = dwResult.template get<SurfaceCollector<>::result_type>();
184  auto& dwOutput = dwResult.template get<DebugOutput::result_type>();
185 
186  if (debugMode) {
187  std::cout << ">>> Direct Navigator (w/o destination) output to come : "
188  << std::endl;
189  std::cout << dwOutput.debugString << std::endl;
190  }
191 
192  // CHECK if you have as many surfaces collected as the default navigator
193  BOOST_CHECK_EQUAL(cSurfaces.collected.size(), dwSurfaces.collected.size());
194  }
195 }
196 
197 // This test case checks that no segmentation fault appears
198 // - this tests the collection of surfaces
200  test_direct_navigator,
201  bdata::random((bdata::seed = 20,
202  bdata::distribution =
203  std::uniform_real_distribution<>(0.15_GeV, 10_GeV))) ^
204  bdata::random((bdata::seed = 21,
205  bdata::distribution =
206  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
207  bdata::random((bdata::seed = 22,
208  bdata::distribution =
209  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
210  bdata::random(
211  (bdata::seed = 23,
212  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
213  bdata::random(
214  (bdata::seed = 24,
215  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
216  bdata::xrange(ntests),
217  pT, phi, theta, charge, time, index) {
218  // Run the test
220 }
221 
222 } // namespace Test
223 } // namespace Acts