Analysis Software
Documentation for sPHENIX simulation 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 
31 
32 #include <algorithm>
33 #include <array>
34 #include <cmath>
35 #include <iostream>
36 #include <memory>
37 #include <random>
38 #include <tuple>
39 #include <utility>
40 #include <vector>
41 
42 namespace Acts {
43 class Surface;
44 } // namespace Acts
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 CylindricalTrackingGeometry cGeometry(tgContext);
59 
60 // Create a navigator for this tracking geometry
63 
65 using Stepper = EigenStepper<>;
68 
69 const double Bz = 2_T;
70 auto bField = std::make_shared<BField>(Vector3{0, 0, Bz});
73 
76 
77 const int ntests = 1000;
78 const int skip = 0;
79 bool debugMode = false;
80 bool referenceTiming = false;
81 bool oversteppingTest = false;
83 
97 template <typename rpropagator_t, typename dpropagator_t>
98 void runTest(const rpropagator_t& rprop, const dpropagator_t& dprop, double pT,
99  double phi, double theta, int charge, double time, int index) {
100  double dcharge = -1 + 2 * charge;
101 
102  if (index < skip) {
103  return;
104  }
105 
106  // Define start parameters from ranom input
107  double p = pT / sin(theta);
108  CurvilinearTrackParameters start(Vector4(0, 0, 0, time), phi, theta,
109  dcharge / p, std::nullopt,
111 
113 
114  // Action list and abort list
115  using RefereceActionList = ActionList<MaterialInteractor, SurfaceCollector<>>;
116  using ReferenceAbortList = AbortList<EndOfWorld>;
117 
118  // Options definition
120  Options pOptions(tgContext, mfContext);
121  if (oversteppingTest) {
122  pOptions.maxStepSize = oversteppingMaxStepSize;
123  }
124 
125  // Surface collector configuration
126  auto& sCollector = pOptions.actionList.template get<SurfaceCollector<>>();
127  sCollector.selector.selectSensitive = true;
128  sCollector.selector.selectMaterial = true;
129 
130  // Result is immediately used, non-valid result would indicate failure
131  const auto& pResult = rprop.propagate(start, pOptions).value();
132  auto& cSurfaces = pResult.template get<SurfaceCollector<>::result_type>();
133  auto& cMaterial = pResult.template get<MaterialInteractor::result_type>();
134  const Surface& destination = pResult.endParameters->referenceSurface();
135 
136  std::cout << " - the standard navigator yielded "
137  << cSurfaces.collected.size() << " collected surfaces" << std::endl;
138 
139  if (not referenceTiming) {
140  // Create the surface sequence
141  std::vector<const Surface*> surfaceSequence;
142  surfaceSequence.reserve(cSurfaces.collected.size());
143  for (auto& cs : cSurfaces.collected) {
144  surfaceSequence.push_back(cs.surface);
145  }
146 
147  // Action list for direct navigator with its initializer
148  using DirectActionList = ActionList<DirectNavigator::Initializer,
150 
151  // Direct options definition
153  DirectOptions dOptions(tgContext, mfContext);
154  // Set the surface sequence
155  auto& dInitializer =
156  dOptions.actionList.get<DirectNavigator::Initializer>();
157  dInitializer.navSurfaces = surfaceSequence;
158  // Surface collector configuration
159  auto& dCollector = dOptions.actionList.template get<SurfaceCollector<>>();
160  dCollector.selector.selectSensitive = true;
161  dCollector.selector.selectMaterial = true;
162 
163  // Now redo the propagation with the direct propagator
164  const auto& ddResult =
165  dprop.propagate(start, destination, dOptions).value();
166  auto& ddSurfaces = ddResult.template get<SurfaceCollector<>::result_type>();
167  auto& ddMaterial = ddResult.template get<MaterialInteractor::result_type>();
168 
169  // CHECK if you have as many surfaces collected as the default navigator
170  BOOST_CHECK_EQUAL(cSurfaces.collected.size(), ddSurfaces.collected.size());
171  CHECK_CLOSE_REL(cMaterial.materialInX0, ddMaterial.materialInX0, 1e-3);
172 
173  // Now redo the propagation with the direct propagator - without destination
174  const auto& dwResult = dprop.propagate(start, dOptions).value();
175  auto& dwSurfaces = dwResult.template get<SurfaceCollector<>::result_type>();
176 
177  // CHECK if you have as many surfaces collected as the default navigator
178  BOOST_CHECK_EQUAL(cSurfaces.collected.size(), dwSurfaces.collected.size());
179  }
180 }
181 
182 // This test case checks that no segmentation fault appears
183 // - this tests the collection of surfaces
185  test_direct_navigator,
186  bdata::random((bdata::seed = 20,
187  bdata::distribution =
188  std::uniform_real_distribution<>(0.15_GeV, 10_GeV))) ^
189  bdata::random((bdata::seed = 21,
190  bdata::distribution =
191  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
192  bdata::random((bdata::seed = 22,
193  bdata::distribution =
194  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
195  bdata::random(
196  (bdata::seed = 23,
197  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
198  bdata::random(
199  (bdata::seed = 24,
200  bdata::distribution = std::uniform_int_distribution<>(0, 100))) ^
201  bdata::xrange(ntests),
202  pT, phi, theta, charge, time, index) {
203  // Run the test
205 }
206 
207 } // namespace Test
208 } // namespace Acts