Analysis Software
Documentation for sPHENIX simulation 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 
32 
33 #include <algorithm>
34 #include <array>
35 #include <cmath>
36 #include <limits>
37 #include <memory>
38 #include <optional>
39 #include <random>
40 #include <string>
41 #include <tuple>
42 #include <utility>
43 
44 namespace bdata = boost::unit_test::data;
45 namespace tt = boost::test_tools;
46 using namespace Acts::UnitLiterals;
47 
48 namespace Acts {
49 
50 using namespace detail;
51 
52 namespace Test {
53 
54 // Create a test context
57 
59 struct SteppingState {
61  Vector3 pos = Vector3(0., 0., 0.);
62  Vector3 dir = Vector3(0., 0., 1);
63  double p = 100_MeV;
64 };
65 
67 struct Stepper {
68  Vector3 field = Vector3(0., 0., 2_T);
69 
77  Result<Vector3> getField(SteppingState& /*state*/,
78  const Vector3& /*pos*/) const {
79  // get the field from the cell
81  }
82 
84  Vector3 position(const SteppingState& state) const { return state.pos; }
85 
87  Vector3 direction(const SteppingState& state) const { return state.dir; }
88 
90  double absoluteMomentum(const SteppingState& state) const { return state.p; }
91 };
92 
95  bool navigationBreak = false;
96 };
97 
99 struct Options {
101  double pathLimit = std::numeric_limits<double>::max();
102  bool loopProtection = true;
103  double loopFraction = 0.5;
105 
106  bool debug = false;
108  int debugMsgWidth = 60;
109  int debugPfxWidth = 30;
110 
112  AbortList<PathLimitReached> abortList;
113 
115 };
116 
125 };
126 
127 // This test case checks that no segmentation fault appears
128 // - this tests the collection of surfaces
130  loop_aborter_test,
131  bdata::random(
132  (bdata::seed = 21,
133  bdata::distribution = std::uniform_real_distribution<>(-M_PI, M_PI))) ^
134  bdata::random((bdata::seed = 22,
135  bdata::distribution =
136  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
137  bdata::xrange(1),
138  phi, deltaPhi, index) {
139  (void)index;
140  (void)deltaPhi;
141 
142  PropagatorState pState;
143  pState.stepping.dir = Vector3(cos(phi), sin(phi), 0.);
144  pState.stepping.p = 100_MeV;
145 
146  Stepper pStepper;
147 
148  auto& pathLimit = pState.options.abortList.get<PathLimitReached>();
149  auto initialLimit = pathLimit.internalLimit;
150 
152  pState, pStepper, pathLimit, false,
153  *Acts::getDefaultLogger("LoopProt", Logging::INFO));
154 
155  auto updatedLimit =
156  pState.options.abortList.get<PathLimitReached>().internalLimit;
157  BOOST_CHECK_LT(updatedLimit, initialLimit);
158 }
159 
160 using BField = ConstantBField;
163 
164 const int ntests = 100;
165 const int skip = 0;
166 
167 // This test case checks that the propagator with loop LoopProtection
168 // stops where expected
170  propagator_loop_protection_test,
171  bdata::random((bdata::seed = 20,
172  bdata::distribution =
173  std::uniform_real_distribution<>(0.5_GeV, 10_GeV))) ^
174  bdata::random((bdata::seed = 21,
175  bdata::distribution =
176  std::uniform_real_distribution<>(-M_PI, M_PI))) ^
177  bdata::random((bdata::seed = 22,
178  bdata::distribution =
179  std::uniform_real_distribution<>(1.0, M_PI - 1.0))) ^
180  bdata::random(
181  (bdata::seed = 23,
182  bdata::distribution = std::uniform_int_distribution<>(0, 1))) ^
183  bdata::xrange(ntests),
184  pT, phi, theta, charge, index) {
185  if (index < skip) {
186  return;
187  }
188 
189  double px = pT * cos(phi);
190  double py = pT * sin(phi);
191  double pz = pT / tan(theta);
192  double p = pT / sin(theta);
193  double q = -1 + 2 * charge;
194 
195  const double Bz = 2_T;
196  auto bField = std::make_shared<BField>(Vector3{0, 0, Bz});
199 
200  // define start parameters
201  CurvilinearTrackParameters start(Vector4(0, 0, 0, 42), phi, theta, q / p,
202  std::nullopt, ParticleHypothesis::pion());
203 
206  options.maxSteps = 1e6;
207  const auto& result = epropagator.propagate(start, options).value();
208 
209  // this test assumes state.options.loopFraction = 0.5
210  CHECK_CLOSE_REL(px, -result.endParameters->momentum().x(), 1e-2);
211  CHECK_CLOSE_REL(py, -result.endParameters->momentum().y(), 1e-2);
212  CHECK_CLOSE_REL(pz, result.endParameters->momentum().z(), 1e-2);
213 }
214 
215 } // namespace Test
216 } // namespace Acts