EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NavigatorTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file NavigatorTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2020 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 
25 #include "Acts/Utilities/Units.hpp"
26 
27 #include <memory>
28 
29 namespace bdata = boost::unit_test::data;
30 namespace tt = boost::test_tools;
31 using namespace Acts::UnitLiterals;
33 
34 namespace Acts {
35 namespace Test {
36 
37 // Create a test context
39 
42 struct PropagatorState {
44  struct Stepper {
45  // comply with concept
48  using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
49  using CurvilinearState =
50  std::tuple<CurvilinearTrackParameters, Jacobian, double>;
51  using BField = int;
52 
53  template <typename, typename>
55 
58  struct State {
60  Vector4D pos4 = Vector4D(0., 0., 0., 0.);
61 
63  Vector3D dir = Vector3D(1., 0., 0.);
64 
66  double p;
67 
69  double q;
70 
73 
74  // accummulated path length cache
75  double pathAccumulated = 0.;
76 
77  // adaptive sep size of the runge-kutta integration
79 
80  // Previous step size for overstep estimation (ignored here)
81  double previousStepSize = 0.;
82 
85 
87  };
88 
90  void resetState(State& /*unused*/, const BoundVector& /*unused*/,
91  const BoundSymMatrix& /*unused*/, const Surface& /*unused*/,
92  const NavigationDirection /*unused*/,
93  const double /*unused*/) const {}
94 
96  Vector3D position(const State& state) const {
97  return state.pos4.segment<3>(Acts::ePos0);
98  }
99 
101  double time(const State& state) const { return state.pos4[Acts::eTime]; }
102 
104  Vector3D direction(const State& state) const { return state.dir; }
105 
107  double momentum(const State& state) const { return state.p; }
108 
110  double charge(const State& state) const { return state.q; }
111 
113  double overstepLimit(const State& /*state*/) const {
114  return s_onSurfaceTolerance;
115  }
116 
117  Intersection3D::Status updateSurfaceStatus(
118  State& state, const Surface& surface,
119  const BoundaryCheck& bcheck) const {
120  return detail::updateSingleSurfaceStatus<Stepper>(*this, state, surface,
121  bcheck);
122  }
123 
124  template <typename object_intersection_t>
125  void updateStepSize(State& state,
126  const object_intersection_t& oIntersection,
127  bool release = true) const {
128  detail::updateSingleStepSize<Stepper>(state, oIntersection, release);
129  }
130 
131  void setStepSize(
132  State& state, double stepSize,
134  state.previousStepSize = state.stepSize;
135  state.stepSize.update(stepSize, stype, true);
136  }
137 
138  void releaseStepSize(State& state) const {
140  }
141 
142  std::string outputStepSize(const State& state) const {
143  return state.stepSize.toString();
144  }
145 
146  BoundState boundState(State& state, const Surface& surface) const {
148  state.pos4, state.dir, state.p, state.q);
149  BoundState bState{std::move(parameters), Jacobian::Identity(),
150  state.pathAccumulated};
151  return bState;
152  }
153 
155  CurvilinearTrackParameters parameters(state.pos4, state.dir, state.p,
156  state.q);
157  // Create the bound state
158  CurvilinearState curvState{std::move(parameters), Jacobian::Identity(),
159  state.pathAccumulated};
160  return curvState;
161  }
162 
163  void update(State& /*state*/, const FreeVector& /*pars*/,
164  const Covariance& /*cov*/) const {}
165 
166  void update(State& /*state*/, const Vector3D& /*uposition*/,
167  const Vector3D& /*udirection*/, double /*up*/,
168  double /*time*/) const {}
169 
170  void covarianceTransport(State& /*state*/) const {}
171 
172  void covarianceTransport(State& /*unused*/,
173  const Surface& /*surface*/) const {}
174 
175  Vector3D getField(State& /*state*/, const Vector3D& /*pos*/) const {
176  // get the field from the cell
177  return Vector3D(0., 0., 0.);
178  }
179  };
180 
181  static_assert(StepperConcept<Stepper>,
182  "Dummy stepper does not fulfill concept");
183 
185  struct Options {
188  bool debug = false;
189  std::string debugString = "";
191  size_t debugPfxWidth = 30;
192  size_t debugMsgWidth = 50;
193 
194  LoggerWrapper logger{getDummyLogger()};
195  };
196 
198  const Surface* startSurface = nullptr;
199 
201  const Surface* currentSurface = nullptr;
202 
204  const Surface* targetSurface = nullptr;
205  bool targetReached = false;
206 
208  Options options;
209 
212 
215 
216  // The context cache for this propagation
218 };
219 
220 template <typename stepper_state_t>
221 void step(stepper_state_t& sstate) {
222  // update the cache position
223  sstate.pos4[Acts::ePos0] += sstate.stepSize * sstate.dir[Acts::eMom0];
224  sstate.pos4[Acts::ePos1] += sstate.stepSize * sstate.dir[Acts::eMom1];
225  sstate.pos4[Acts::ePos2] += sstate.stepSize * sstate.dir[Acts::eMom2];
226  // create navigation parameters
227  return;
228 }
229 
237 bool testNavigatorStateVectors(Navigator::State& state, size_t navSurf,
238  size_t navLay, size_t navBound, size_t extSurf) {
239  return ((state.navSurfaces.size() == navSurf) &&
240  (state.navLayers.size() == navLay) &&
241  (state.navBoundaries.size() == navBound) &&
242  (state.externalSurfaces.size() == extSurf));
243 }
244 
258  Navigator::State& state, const TrackingVolume* worldVol,
259  const TrackingVolume* startVol, const Layer* startLay,
260  const Surface* startSurf, const Surface* currSurf,
261  const TrackingVolume* currVol, const TrackingVolume* targetVol,
262  const Layer* targetLay, const Surface* targetSurf) {
263  return (
264  (state.worldVolume == worldVol) && (state.startVolume == startVol) &&
265  (state.startLayer == startLay) && (state.startSurface == startSurf) &&
266  (state.currentSurface == currSurf) && (state.currentVolume == currVol) &&
267  (state.targetVolume == targetVol) && (state.targetLayer == targetLay) &&
268  (state.targetSurface == targetSurf));
269 }
270 // the surface cache & the creation of the geometry
271 
272 CylindricalTrackingGeometry cGeometry(tgContext);
273 auto tGeometry = cGeometry();
274 
275 // the debug boolean
276 bool debug = true;
277 
278 BOOST_AUTO_TEST_CASE(Navigator_status_methods) {
279  // create a navigator
281  navigator.resolveSensitive = false;
282  navigator.resolveMaterial = false;
283  navigator.resolvePassive = false;
284 
285  // position and direction vector
286  Vector4D position4(0., 0., 0, 0);
287  Vector3D momentum(1., 1., 0);
288 
289  // the propagator cache
290  PropagatorState state;
291  state.options.debug = debug;
292 
293  // the stepper cache
294  state.stepping.pos4 = position4;
295  state.stepping.dir = momentum.normalized();
296 
297  // Stepper
299 
300  //
301  // (1) Test for inactivity
302  //
303  // Run without anything present
304  navigator.status(state, stepper);
305  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
306  BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
307  nullptr, nullptr, nullptr, nullptr,
308  nullptr, nullptr, nullptr));
309 
310  // Run with geometry but without resolving
311  navigator.trackingGeometry = tGeometry;
312  navigator.status(state, stepper);
313  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
314  BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
315  nullptr, nullptr, nullptr, nullptr,
316  nullptr, nullptr, nullptr));
317 
318  // Run with geometry and resolving but broken navigation for various reasons
319  navigator.resolveSensitive = true;
320  navigator.resolveMaterial = true;
321  navigator.resolvePassive = true;
322  state.navigation.navigationBreak = true;
323  // a) Because target is reached
324  state.navigation.targetReached = true;
325  navigator.status(state, stepper);
326  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
327  BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
328  nullptr, nullptr, nullptr, nullptr,
329  nullptr, nullptr, nullptr));
330  // b) Beacause of no target surface
331  state.navigation.targetReached = false;
332  state.navigation.targetSurface = nullptr;
333  navigator.status(state, stepper);
334  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
335  BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
336  nullptr, nullptr, nullptr, nullptr,
337  nullptr, nullptr, nullptr));
338  // c) Because the target surface is reached
339  const Surface* startSurf = tGeometry->getBeamline();
340  state.stepping.pos4.segment<3>(Acts::ePos0) =
341  startSurf->center(state.geoContext);
342  const Surface* targetSurf = startSurf;
343  state.navigation.targetSurface = targetSurf;
344  navigator.status(state, stepper);
345  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
346  BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
347  nullptr, nullptr, targetSurf, nullptr,
348  nullptr, nullptr, targetSurf));
349 
350  //
351  // (2) Test the initialisation
352  //
353  // a) Initialise without additional information
354  state.navigation = Navigator::State();
355  state.stepping.pos4 << 0., 0., 0., 0.;
356  const TrackingVolume* worldVol = tGeometry->highestTrackingVolume();
357  const TrackingVolume* startVol = tGeometry->lowestTrackingVolume(
358  state.geoContext, stepper.position(state.stepping));
359  const Layer* startLay = startVol->associatedLayer(
360  state.geoContext, stepper.position(state.stepping));
361  navigator.status(state, stepper);
362  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
363  BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol,
364  startLay, nullptr, nullptr, startVol,
365  nullptr, nullptr, nullptr));
366 
367  // b) Initialise having a start surface
368  state.navigation = Navigator::State();
369  state.navigation.startSurface = startSurf;
370  navigator.status(state, stepper);
371  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
372  BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol,
373  startLay, startSurf, startSurf,
374  startVol, nullptr, nullptr, nullptr));
375 
376  // c) Initialise having a start volume
377  state.navigation = Navigator::State();
378  state.navigation.startVolume = startVol;
379  navigator.status(state, stepper);
380  BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
381  BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol,
382  startLay, nullptr, nullptr, startVol,
383  nullptr, nullptr, nullptr));
384 }
385 
386 BOOST_AUTO_TEST_CASE(Navigator_target_methods) {
387  // create a navigator
389  navigator.trackingGeometry = tGeometry;
390  navigator.resolveSensitive = true;
391  navigator.resolveMaterial = true;
392  navigator.resolvePassive = false;
393 
394  // position and direction vector
395  Vector4D position4(0., 0., 0, 0);
396  Vector3D momentum(1., 1., 0);
397 
398  // the propagator cache
399  PropagatorState state;
400  state.options.debug = debug;
401 
402  // the stepper cache
403  state.stepping.pos4 = position4;
404  state.stepping.dir = momentum.normalized();
405 
406  // foward navigation ----------------------------------------------
407  if (debug) {
408  std::cout << "<<<<<<<<<<<<<<<<<<<<< FORWARD NAVIGATION >>>>>>>>>>>>>>>>>>"
409  << std::endl;
410  }
411 
412  // Stepper
414 
415  // (1) Initialization navigation from start point
416  // - this will call resolveLayers() as well
417  // - and thus should call a return to the stepper
418  navigator.status(state, stepper);
419  // Check that the currentVolume is set
420  BOOST_CHECK_NE(state.navigation.currentVolume, nullptr);
421  // Check that the currentVolume is the startVolume
422  BOOST_CHECK_EQUAL(state.navigation.currentVolume,
423  state.navigation.startVolume);
424  // Check that the currentSurface is reset to:
425  BOOST_CHECK_EQUAL(state.navigation.currentSurface, nullptr);
426  // No layer has been found
427  BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 0u);
428  // ACTORS-ABORTERS-TARGET
429  navigator.target(state, stepper);
430  // A layer has been found
431  BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u);
432  // The iterator should points to the begin
433  BOOST_CHECK(state.navigation.navLayerIter ==
434  state.navigation.navLayers.begin());
435  // Cache the beam pipe radius
436  double beamPipeR = perp(state.navigation.navLayerIter->intersection.position);
437  // step size has been updated
438  CHECK_CLOSE_ABS(state.stepping.stepSize, beamPipeR, s_onSurfaceTolerance);
439  if (debug) {
440  std::cout << "<<< Test 1a >>> initialize at "
441  << toString(state.stepping.pos4) << std::endl;
442  std::cout << state.options.debugString << std::endl;
443  // Clear the debug string for the next test
444  state.options.debugString = "";
445  }
446 
447  // Do the step towards the beam pipe
448  step(state.stepping);
449 
450  // (2) re-entering navigator:
451  // STATUS
452  navigator.status(state, stepper);
453  // Check that the currentVolume is the still startVolume
454  BOOST_CHECK_EQUAL(state.navigation.currentVolume,
455  state.navigation.startVolume);
456  // The layer number has not changed
457  BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u);
458  // The iterator still points to the begin
459  BOOST_CHECK(
460  (state.navigation.navLayerIter == state.navigation.navLayers.begin()));
461  // ACTORS-ABORTERS-TARGET
462  navigator.target(state, stepper);
463 
464  if (debug) {
465  std::cout << "<<< Test 1b >>> step to the BeamPipe at "
466  << toString(state.stepping.pos4) << std::endl;
467  std::cout << state.options.debugString << std::endl;
468  state.options.debugString = "";
469  }
470 
471  // Do the step towards the boundary
472  step(state.stepping);
473 
474  // (3) re-entering navigator:
475  // STATUS
476  navigator.status(state, stepper);
477  // ACTORS-ABORTERS-TARGET
478  navigator.target(state, stepper);
479 
480  if (debug) {
481  std::cout << "<<< Test 1c >>> step to the Boundary at "
482  << toString(state.stepping.pos4) << std::endl;
483  std::cout << state.options.debugString << std::endl;
484  state.options.debugString = "";
485  }
486 
487  // positive return: do the step
488  step(state.stepping);
489  // (4) re-entering navigator:
490  // STATUS
491  navigator.status(state, stepper);
492  // ACTORS-ABORTERS-TARGET
493  navigator.target(state, stepper);
494 
495  if (debug) {
496  std::cout << "<<< Test 1d >>> step to 1st layer at "
497  << toString(state.stepping.pos4) << std::endl;
498  std::cout << state.options.debugString << std::endl;
499  state.options.debugString = "";
500  }
501 
502  // Step through the surfaces on first layer
503  for (size_t isf = 0; isf < 5; ++isf) {
504  step(state.stepping);
505  // (5-9) re-entering navigator:
506  // STATUS
507  navigator.status(state, stepper);
508  // ACTORS-ABORTERS-TARGET
509  navigator.target(state, stepper);
510 
511  if (debug) {
512  std::cout << "<<< Test 1e-1i >>> step within 1st layer at "
513  << toString(state.stepping.pos4) << std::endl;
514  std::cout << state.options.debugString << std::endl;
515  state.options.debugString = "";
516  }
517  }
518 
519  // positive return: do the step
520  step(state.stepping);
521  // (10) re-entering navigator:
522  // STATUS
523  navigator.status(state, stepper);
524  // ACTORS-ABORTERS-TARGET
525  navigator.target(state, stepper);
526 
527  if (debug) {
528  std::cout << "<<< Test 1j >>> step to 2nd layer at "
529  << toString(state.stepping.pos4) << std::endl;
530  std::cout << state.options.debugString << std::endl;
531  state.options.debugString = "";
532  }
533 
534  // Step through the surfaces on second layer
535  for (size_t isf = 0; isf < 5; ++isf) {
536  step(state.stepping);
537  // (11-15) re-entering navigator:
538  // STATUS
539  navigator.status(state, stepper);
540  // ACTORS-ABORTERS-TARGET
541  navigator.target(state, stepper);
542 
543  if (debug) {
544  std::cout << "<<< Test 1k-1o >>> step within 2nd layer at "
545  << toString(state.stepping.pos4) << std::endl;
546  std::cout << state.options.debugString << std::endl;
547  state.options.debugString = "";
548  }
549  }
550 
551  // positive return: do the step
552  step(state.stepping);
553  // (16) re-entering navigator:
554  // STATUS
555  navigator.status(state, stepper);
556  // ACTORS-ABORTERS-TARGET
557  navigator.target(state, stepper);
558 
559  if (debug) {
560  std::cout << "<<< Test 1p >>> step to 3rd layer at "
561  << toString(state.stepping.pos4) << std::endl;
562  std::cout << state.options.debugString << std::endl;
563  state.options.debugString = "";
564  }
565 
566  // Step through the surfaces on third layer
567  for (size_t isf = 0; isf < 3; ++isf) {
568  step(state.stepping);
569  // (17-19) re-entering navigator:
570  // STATUS
571  navigator.status(state, stepper);
572  // ACTORS-ABORTERS-TARGET
573  navigator.target(state, stepper);
574 
575  if (debug) {
576  std::cout << "<<< Test 1q-1s >>> step within 3rd layer at "
577  << toString(state.stepping.pos4) << std::endl;
578  std::cout << state.options.debugString << std::endl;
579  state.options.debugString = "";
580  }
581  }
582 
583  // positive return: do the step
584  step(state.stepping);
585  // (20) re-entering navigator:
586  // STATUS
587  navigator.status(state, stepper);
588  // ACTORS-ABORTERS-TARGET
589  navigator.target(state, stepper);
590 
591  if (debug) {
592  std::cout << "<<< Test 1t >>> step to 4th layer at "
593  << toString(state.stepping.pos4) << std::endl;
594  std::cout << state.options.debugString << std::endl;
595  state.options.debugString = "";
596  }
597 
598  // Step through the surfaces on second layer
599  for (size_t isf = 0; isf < 3; ++isf) {
600  step(state.stepping);
601  // (21-23) re-entering navigator:
602  // STATUS
603  navigator.status(state, stepper);
604  // ACTORS-ABORTERS-TARGET
605  navigator.target(state, stepper);
606 
607  if (debug) {
608  std::cout << "<<< Test 1t-1v >>> step within 4th layer at "
609  << toString(state.stepping.pos4) << std::endl;
610  std::cout << state.options.debugString << std::endl;
611  state.options.debugString = "";
612  }
613  }
614 
615  // positive return: do the step
616  step(state.stepping);
617  // (24) re-entering navigator:
618  // STATUS
619  navigator.status(state, stepper);
620  // ACTORS-ABORTERS-TARGET
621  navigator.target(state, stepper);
622 
623  if (debug) {
624  std::cout << "<<< Test 1w >>> step to boundary at "
625  << toString(state.stepping.pos4) << std::endl;
626  std::cout << state.options.debugString << std::endl;
627  state.options.debugString = "";
628  }
629 }
630 
631 } // namespace Test
632 } // namespace Acts