ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LoopProtectionTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file LoopProtectionTests.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 
24 #include "Acts/Utilities/Units.hpp"
25 
26 namespace bdata = boost::unit_test::data;
27 namespace tt = boost::test_tools;
28 using namespace Acts::UnitLiterals;
29 
30 namespace Acts {
31 
32 using namespace detail;
33 
34 namespace Test {
35 
36 // Create a test context
39 
41 struct SteppingState {
43  Vector3D pos = Vector3D(0., 0., 0.);
44  Vector3D dir = Vector3D(0., 0., 1);
45  double p = 100_MeV;
46 
48 };
49 
51 struct Stepper {
52  Vector3D field = Vector3D(0., 0., 2_T);
53 
61  Vector3D getField(SteppingState& /*unused*/,
62  const Vector3D& /*unused*/) const {
63  // get the field from the cell
64  return field;
65  }
66 
68  Vector3D position(const SteppingState& state) const { return state.pos; }
69 
71  Vector3D direction(const SteppingState& state) const { return state.dir; }
72 
74  double momentum(const SteppingState& state) const { return state.p; }
75 };
76 
79  bool navigationBreak = false;
80 };
81 
83 struct Options {
85  double pathLimit = std::numeric_limits<double>::max();
86  bool loopProtection = true;
87  double loopFraction = 0.5;
88 
89  bool debug = false;
90  std::string debugString;
91  int debugMsgWidth = 60;
92  int debugPfxWidth = 30;
93 
96 };
97 
99 struct PropagatorState {
105  Options options;
106 };
107 
108 // This test case checks that no segmentation fault appears
109 // - this tests the collection of surfaces
111  loop_aborter_test,
112  bdata::random(
113  (bdata::seed = 21,
114  bdata::distribution = std::uniform_real_distribution<>(-M_PI, M_PI))) ^
115  bdata::random((bdata::seed = 22,
116  bdata::distribution =
117  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
118  bdata::xrange(1),
119  phi, deltaPhi, index) {
120  (void)index;
121  (void)deltaPhi;
122 
123  PropagatorState pState;
124  pState.stepping.dir = Vector3D(cos(phi), sin(phi), 0.);
125  pState.stepping.p = 100_MeV;
126 
127  Stepper pStepper;
128 
129  auto initialLimit =
130  pState.options.abortList.get<PathLimitReached>().internalLimit;
131 
133  lProtection(pState, pStepper);
134 
135  auto updatedLimit =
136  pState.options.abortList.get<PathLimitReached>().internalLimit;
137  BOOST_CHECK_LT(updatedLimit, initialLimit);
138 }
139 
140 using BField = ConstantBField;
143 
144 const int ntests = 100;
145 const int skip = 0;
146 
147 // This test case checks that the propagator with loop LoopProtection
148 // stops where expected
150  propagator_loop_protection_test,
151  bdata::random((bdata::seed = 20,
152  bdata::distribution =
153  std::uniform_real_distribution<>(0.5_GeV, 10_GeV))) ^
154  bdata::random((bdata::seed = 21,
155  bdata::distribution =
156  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
157  bdata::random((bdata::seed = 22,
158  bdata::distribution =
159  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
160  bdata::random(
161  (bdata::seed = 23,
162  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
163  bdata::xrange(ntests),
164  pT, phi, theta, charge, index) {
165  if (index < skip) {
166  return;
167  }
168 
169  double dcharge = -1 + 2 * charge;
170 
171  const double Bz = 2_T;
172  BField bField(0, 0, Bz);
173 
174  EigenStepper estepper(bField);
175 
176  EigenPropagator epropagator(std::move(estepper));
177 
178  // define start parameters
179  double x = 0;
180  double y = 0;
181  double z = 0;
182  double px = pT * cos(phi);
183  double py = pT * sin(phi);
184  double pz = pT / tan(theta);
185  double q = dcharge;
186  Vector3D pos(x, y, z);
187  Vector3D mom(px, py, pz);
188  CurvilinearParameters start(std::nullopt, pos, mom, q, 42.);
189 
191  using ProopagatorOptions =
193  ProopagatorOptions options(tgContext, mfContext);
194  options.debug = false;
195  options.maxSteps = 1e6;
196  const auto& result = epropagator.propagate(start, options).value();
197 
198  if (options.debug) {
199  const auto debugString =
200  result.template get<DebugOutput::result_type>().debugString;
201  std::cout << debugString << std::endl;
202  }
203 
204  // this test assumes state.options.loopFraction = 0.5
205  CHECK_CLOSE_REL(px, -result.endParameters->momentum().x(), 1e-2);
206  CHECK_CLOSE_REL(py, -result.endParameters->momentum().y(), 1e-2);
207  CHECK_CLOSE_REL(pz, result.endParameters->momentum().z(), 1e-2);
208 }
209 
210 } // namespace Test
211 } // namespace Acts