Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:48

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Definitions/Tolerance.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0016 #include "Acts/EventData/GenericCurvilinearTrackParameters.hpp"
0017 #include "Acts/EventData/TrackParameters.hpp"
0018 #include "Acts/EventData/TransformationHelpers.hpp"
0019 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0022 #include "Acts/Propagator/ConstrainedStep.hpp"
0023 #include "Acts/Propagator/StraightLineStepper.hpp"
0024 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0025 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0026 #include "Acts/Surfaces/PlaneSurface.hpp"
0027 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0028 #include "Acts/Utilities/Result.hpp"
0029 
0030 #include <limits>
0031 #include <memory>
0032 #include <optional>
0033 #include <string>
0034 #include <utility>
0035 
0036 using Acts::VectorHelpers::makeVector4;
0037 
0038 namespace Acts::Test {
0039 
0040 using Covariance = BoundSquareMatrix;
0041 
0042 /// @brief Simplified propagator state
0043 struct PropState {
0044   /// @brief Constructor
0045   PropState(Direction direction, StraightLineStepper::State sState)
0046       : stepping(std::move(sState)) {
0047     options.direction = direction;
0048   }
0049   /// State of the straight line stepper
0050   StraightLineStepper::State stepping;
0051   /// Propagator options which only carry the particle's mass
0052   struct {
0053     Direction direction = Direction::Forward();
0054   } options;
0055 };
0056 
0057 struct MockNavigator {};
0058 
0059 static constexpr MockNavigator mockNavigator;
0060 
0061 static constexpr auto eps = 2 * std::numeric_limits<double>::epsilon();
0062 
0063 /// These tests are aiming to test whether the state setup is working properly
0064 BOOST_AUTO_TEST_CASE(straight_line_stepper_state_test) {
0065   // Set up some variables
0066   GeometryContext tgContext = GeometryContext();
0067   MagneticFieldContext mfContext = MagneticFieldContext();
0068   double stepSize = 123.;
0069 
0070   Vector3 pos(1., 2., 3.);
0071   Vector3 dir(4., 5., 6.);
0072   double time = 7.;
0073   double absMom = 8.;
0074   double charge = -1.;
0075 
0076   StraightLineStepper::Options slsOptions(tgContext, mfContext);
0077   slsOptions.maxStepSize = stepSize;
0078 
0079   // Test charged parameters without covariance matrix
0080   CurvilinearTrackParameters cp(makeVector4(pos, time), dir, charge / absMom,
0081                                 std::nullopt, ParticleHypothesis::pion());
0082 
0083   StraightLineStepper sls;
0084   StraightLineStepper::State slsState = sls.makeState(slsOptions, cp);
0085 
0086   // Test the result & compare with the input/test for reasonable members
0087   BOOST_CHECK_EQUAL(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0088   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0089   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0090   BOOST_CHECK(!slsState.covTransport);
0091   BOOST_CHECK_EQUAL(slsState.cov, Covariance::Zero());
0092   CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0093   CHECK_CLOSE_OR_SMALL(sls.direction(slsState), dir.normalized(), eps, eps);
0094   CHECK_CLOSE_REL(sls.absoluteMomentum(slsState), absMom, eps);
0095   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0096   CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0097   BOOST_CHECK_EQUAL(slsState.pathAccumulated, 0.);
0098   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0099   BOOST_CHECK_EQUAL(slsState.previousStepSize, 0.);
0100 
0101   // Test without charge and covariance matrix
0102   CurvilinearTrackParameters ncp(makeVector4(pos, time), dir, 1 / absMom,
0103                                  std::nullopt, ParticleHypothesis::pion0());
0104   slsState = sls.makeState(slsOptions, ncp);
0105 
0106   // Test with covariance matrix
0107   Covariance cov = 8. * Covariance::Identity();
0108   ncp = CurvilinearTrackParameters(makeVector4(pos, time), dir, 1 / absMom, cov,
0109                                    ParticleHypothesis::pion0());
0110   slsState = sls.makeState(slsOptions, ncp);
0111   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0112   BOOST_CHECK(slsState.covTransport);
0113   BOOST_CHECK_EQUAL(slsState.cov, cov);
0114 }
0115 
0116 /// These tests are aiming to test the functions of the StraightLineStepper
0117 /// The numerical correctness of the stepper is tested in the integration tests
0118 BOOST_AUTO_TEST_CASE(straight_line_stepper_test) {
0119   // Set up some variables for the state
0120   GeometryContext tgContext = GeometryContext();
0121   MagneticFieldContext mfContext = MagneticFieldContext();
0122   Direction navDir = Direction::Backward();
0123   double stepSize = 123.;
0124 
0125   // Construct the parameters
0126   Vector3 pos(1., 2., 3.);
0127   Vector3 dir = Vector3(4., 5., 6.).normalized();
0128   double time = 7.;
0129   double absMom = 8.;
0130   double charge = -1.;
0131   Covariance cov = 8. * Covariance::Identity();
0132   CurvilinearTrackParameters cp(makeVector4(pos, time), dir, charge / absMom,
0133                                 cov, ParticleHypothesis::pion());
0134 
0135   StraightLineStepper::Options options(tgContext, mfContext);
0136   options.maxStepSize = stepSize;
0137 
0138   // Build the stepper and the state
0139   StraightLineStepper sls;
0140   StraightLineStepper::State slsState = sls.makeState(options, cp);
0141 
0142   // Test the getters
0143   CHECK_CLOSE_ABS(sls.position(slsState), pos, 1e-6);
0144   CHECK_CLOSE_ABS(sls.direction(slsState), dir, 1e-6);
0145   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), absMom, 1e-6);
0146   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0147   BOOST_CHECK_EQUAL(sls.time(slsState), time);
0148 
0149   // Step size modifies
0150   const std::string originalStepSize = slsState.stepSize.toString();
0151 
0152   sls.updateStepSize(slsState, -1337., ConstrainedStep::Type::Navigator);
0153   BOOST_CHECK_EQUAL(slsState.previousStepSize, stepSize);
0154   BOOST_CHECK_EQUAL(slsState.stepSize.value(), -1337.);
0155 
0156   sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0157   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0158   BOOST_CHECK_EQUAL(sls.outputStepSize(slsState), originalStepSize);
0159 
0160   // Test the curvilinear state construction
0161   auto curvState = sls.curvilinearState(slsState);
0162   auto curvPars = std::get<0>(curvState);
0163   CHECK_CLOSE_ABS(curvPars.position(tgContext), cp.position(tgContext), 1e-6);
0164   CHECK_CLOSE_ABS(curvPars.absoluteMomentum(), cp.absoluteMomentum(), 1e-6);
0165   CHECK_CLOSE_ABS(curvPars.charge(), cp.charge(), 1e-6);
0166   CHECK_CLOSE_ABS(curvPars.time(), cp.time(), 1e-6);
0167   BOOST_CHECK(curvPars.covariance().has_value());
0168   BOOST_CHECK_NE(*curvPars.covariance(), cov);
0169   CHECK_CLOSE_COVARIANCE(std::get<1>(curvState),
0170                          BoundMatrix(BoundMatrix::Identity()), 1e-6);
0171   CHECK_CLOSE_ABS(std::get<2>(curvState), 0., 1e-6);
0172 
0173   // Test the update method
0174   Vector3 newPos(2., 4., 8.);
0175   Vector3 newMom(3., 9., 27.);
0176   double newTime(321.);
0177   sls.update(slsState, newPos, newMom.normalized(), charge / newMom.norm(),
0178              newTime);
0179   CHECK_CLOSE_ABS(sls.position(slsState), newPos, 1e-6);
0180   CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0181   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0182   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0183   BOOST_CHECK_EQUAL(sls.time(slsState), newTime);
0184 
0185   // The covariance transport
0186   slsState.cov = cov;
0187   sls.transportCovarianceToCurvilinear(slsState);
0188   BOOST_CHECK_NE(slsState.cov, cov);
0189   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0190   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0191   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0192 
0193   // Perform a step without and with covariance transport
0194   slsState.cov = cov;
0195   PropState ps(navDir, slsState);
0196 
0197   ps.stepping.covTransport = false;
0198   double h = sls.step(ps, mockNavigator).value();
0199   BOOST_CHECK_EQUAL(ps.stepping.stepSize.value(), stepSize);
0200   BOOST_CHECK_EQUAL(ps.stepping.stepSize.value(), h * navDir);
0201   CHECK_CLOSE_COVARIANCE(ps.stepping.cov, cov, 1e-6);
0202   BOOST_CHECK_GT(sls.position(ps.stepping).norm(), newPos.norm());
0203   CHECK_CLOSE_ABS(sls.direction(ps.stepping), newMom.normalized(), 1e-6);
0204   CHECK_CLOSE_ABS(sls.absoluteMomentum(ps.stepping), newMom.norm(), 1e-6);
0205   CHECK_CLOSE_ABS(sls.charge(ps.stepping), charge, 1e-6);
0206   BOOST_CHECK_LT(sls.time(ps.stepping), newTime);
0207   BOOST_CHECK_EQUAL(ps.stepping.derivative, FreeVector::Zero());
0208   BOOST_CHECK_EQUAL(ps.stepping.jacTransport, FreeMatrix::Identity());
0209 
0210   ps.stepping.covTransport = true;
0211   double h2 = sls.step(ps, mockNavigator).value();
0212   BOOST_CHECK_EQUAL(ps.stepping.stepSize.value(), stepSize);
0213   BOOST_CHECK_EQUAL(h2, h);
0214   CHECK_CLOSE_COVARIANCE(ps.stepping.cov, cov, 1e-6);
0215   BOOST_CHECK_GT(sls.position(ps.stepping).norm(), newPos.norm());
0216   CHECK_CLOSE_ABS(sls.direction(ps.stepping), newMom.normalized(), 1e-6);
0217   CHECK_CLOSE_ABS(sls.absoluteMomentum(ps.stepping), newMom.norm(), 1e-6);
0218   CHECK_CLOSE_ABS(sls.charge(ps.stepping), charge, 1e-6);
0219   BOOST_CHECK_LT(sls.time(ps.stepping), newTime);
0220   BOOST_CHECK_NE(ps.stepping.derivative, FreeVector::Zero());
0221   BOOST_CHECK_NE(ps.stepping.jacTransport, FreeMatrix::Identity());
0222 
0223   /// Test the state reset
0224   // Construct the parameters
0225   Vector3 pos2(1.5, -2.5, 3.5);
0226   Vector3 dir2 = Vector3(4.5, -5.5, 6.5).normalized();
0227   double time2 = 7.5;
0228   double absMom2 = 8.5;
0229   double charge2 = 1.;
0230   BoundSquareMatrix cov2 = 8.5 * Covariance::Identity();
0231   CurvilinearTrackParameters cp2(makeVector4(pos2, time2), dir2,
0232                                  charge2 / absMom2, cov2,
0233                                  ParticleHypothesis::pion());
0234   BOOST_CHECK(cp2.covariance().has_value());
0235   FreeVector freeParams = transformBoundToFreeParameters(
0236       cp2.referenceSurface(), tgContext, cp2.parameters());
0237   navDir = Direction::Forward();
0238   double stepSize2 = -2. * stepSize;
0239 
0240   // Reset all possible parameters
0241   StraightLineStepper::State slsStateCopy = ps.stepping;
0242   sls.resetState(slsStateCopy, cp2.parameters(), *cp2.covariance(),
0243                  cp2.referenceSurface(), stepSize2);
0244   // Test all components
0245   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, BoundToFreeMatrix::Zero());
0246   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, ps.stepping.jacToGlobal);
0247   BOOST_CHECK_EQUAL(slsStateCopy.jacTransport, FreeMatrix::Identity());
0248   BOOST_CHECK_EQUAL(slsStateCopy.derivative, FreeVector::Zero());
0249   BOOST_CHECK(slsStateCopy.covTransport);
0250   BOOST_CHECK_EQUAL(slsStateCopy.cov, cov2);
0251   CHECK_CLOSE_ABS(sls.position(slsStateCopy),
0252                   freeParams.template segment<3>(eFreePos0), 1e-6);
0253   CHECK_CLOSE_ABS(sls.direction(slsStateCopy),
0254                   freeParams.template segment<3>(eFreeDir0).normalized(), 1e-6);
0255   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsStateCopy),
0256                   std::abs(1. / freeParams[eFreeQOverP]), 1e-6);
0257   CHECK_CLOSE_ABS(sls.charge(slsStateCopy), -sls.charge(ps.stepping), 1e-6);
0258   CHECK_CLOSE_ABS(sls.time(slsStateCopy), freeParams[eFreeTime], 1e-6);
0259   BOOST_CHECK_EQUAL(slsStateCopy.pathAccumulated, 0.);
0260   BOOST_CHECK_EQUAL(slsStateCopy.stepSize.value(), navDir * stepSize2);
0261   BOOST_CHECK_EQUAL(slsStateCopy.previousStepSize,
0262                     ps.stepping.previousStepSize);
0263 
0264   // Reset all possible parameters except the step size
0265   slsStateCopy = ps.stepping;
0266   sls.resetState(slsStateCopy, cp2.parameters(), *cp2.covariance(),
0267                  cp2.referenceSurface());
0268   // Test all components
0269   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, BoundToFreeMatrix::Zero());
0270   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, ps.stepping.jacToGlobal);
0271   BOOST_CHECK_EQUAL(slsStateCopy.jacTransport, FreeMatrix::Identity());
0272   BOOST_CHECK_EQUAL(slsStateCopy.derivative, FreeVector::Zero());
0273   BOOST_CHECK(slsStateCopy.covTransport);
0274   BOOST_CHECK_EQUAL(slsStateCopy.cov, cov2);
0275   CHECK_CLOSE_ABS(sls.position(slsStateCopy),
0276                   freeParams.template segment<3>(eFreePos0), 1e-6);
0277   CHECK_CLOSE_ABS(sls.direction(slsStateCopy),
0278                   freeParams.template segment<3>(eFreeDir0), 1e-6);
0279   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsStateCopy),
0280                   std::abs(1. / freeParams[eFreeQOverP]), 1e-6);
0281   CHECK_CLOSE_ABS(sls.charge(slsStateCopy), -sls.charge(ps.stepping), 1e-6);
0282   CHECK_CLOSE_ABS(sls.time(slsStateCopy), freeParams[eFreeTime], 1e-6);
0283   BOOST_CHECK_EQUAL(slsStateCopy.pathAccumulated, 0.);
0284   BOOST_CHECK_EQUAL(slsStateCopy.stepSize.value(),
0285                     std::numeric_limits<double>::max());
0286   BOOST_CHECK_EQUAL(slsStateCopy.previousStepSize,
0287                     ps.stepping.previousStepSize);
0288 
0289   // Reset the least amount of parameters
0290   slsStateCopy = ps.stepping;
0291   sls.resetState(slsStateCopy, cp2.parameters(), *cp2.covariance(),
0292                  cp2.referenceSurface());
0293   // Test all components
0294   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, BoundToFreeMatrix::Zero());
0295   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, ps.stepping.jacToGlobal);
0296   BOOST_CHECK_EQUAL(slsStateCopy.jacTransport, FreeMatrix::Identity());
0297   BOOST_CHECK_EQUAL(slsStateCopy.derivative, FreeVector::Zero());
0298   BOOST_CHECK(slsStateCopy.covTransport);
0299   BOOST_CHECK_EQUAL(slsStateCopy.cov, cov2);
0300   CHECK_CLOSE_ABS(sls.position(slsStateCopy),
0301                   freeParams.template segment<3>(eFreePos0), 1e-6);
0302   CHECK_CLOSE_ABS(sls.direction(slsStateCopy),
0303                   freeParams.template segment<3>(eFreeDir0).normalized(), 1e-6);
0304   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsStateCopy),
0305                   std::abs(1. / freeParams[eFreeQOverP]), 1e-6);
0306   CHECK_CLOSE_ABS(sls.charge(slsStateCopy), -sls.charge(ps.stepping), 1e-6);
0307   CHECK_CLOSE_ABS(sls.time(slsStateCopy), freeParams[eFreeTime], 1e-6);
0308   BOOST_CHECK_EQUAL(slsStateCopy.pathAccumulated, 0.);
0309   BOOST_CHECK_EQUAL(slsStateCopy.stepSize.value(),
0310                     std::numeric_limits<double>::max());
0311   BOOST_CHECK_EQUAL(slsStateCopy.previousStepSize,
0312                     ps.stepping.previousStepSize);
0313 
0314   /// Repeat with surface related methods
0315   auto plane = CurvilinearSurface(pos, dir).planeSurface();
0316   auto bp = BoundTrackParameters::create(
0317                 plane, tgContext, makeVector4(pos, time), dir, charge / absMom,
0318                 cov, ParticleHypothesis::pion())
0319                 .value();
0320   slsState = sls.makeState(options, bp);
0321 
0322   // Test the intersection in the context of a surface
0323   auto targetSurface =
0324       CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface();
0325   sls.updateSurfaceStatus(slsState, *targetSurface, 0, navDir,
0326                           BoundaryTolerance::Infinite(), s_onSurfaceTolerance,
0327                           ConstrainedStep::Type::Navigator);
0328   CHECK_CLOSE_ABS(slsState.stepSize.value(ConstrainedStep::Type::Navigator),
0329                   navDir * 2., 1e-6);
0330 
0331   // Test the step size modification in the context of a surface
0332   sls.updateStepSize(slsState,
0333                      targetSurface
0334                          ->intersect(tgContext, sls.position(slsState),
0335                                      navDir * sls.direction(slsState),
0336                                      BoundaryTolerance::Infinite())
0337                          .closest(),
0338                      navDir, ConstrainedStep::Type::Navigator);
0339   CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0340   slsState.stepSize.setUser(navDir * stepSize);
0341   sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0342   sls.updateStepSize(slsState,
0343                      targetSurface
0344                          ->intersect(tgContext, sls.position(slsState),
0345                                      navDir * sls.direction(slsState),
0346                                      BoundaryTolerance::Infinite())
0347                          .closest(),
0348                      navDir, ConstrainedStep::Type::Navigator);
0349   CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0350 
0351   // Test the bound state construction
0352   FreeToBoundCorrection freeToBoundCorrection(false);
0353   auto boundState =
0354       sls.boundState(slsState, *plane, true, freeToBoundCorrection).value();
0355   auto boundPars = std::get<0>(boundState);
0356   CHECK_CLOSE_ABS(boundPars.position(tgContext), bp.position(tgContext), 1e-6);
0357   CHECK_CLOSE_ABS(boundPars.momentum(), bp.momentum(), 1e-6);
0358   CHECK_CLOSE_ABS(boundPars.charge(), bp.charge(), 1e-6);
0359   CHECK_CLOSE_ABS(boundPars.time(), bp.time(), 1e-6);
0360   BOOST_CHECK(boundPars.covariance().has_value());
0361   BOOST_CHECK_NE(*boundPars.covariance(), cov);
0362   CHECK_CLOSE_COVARIANCE(std::get<1>(boundState),
0363                          BoundMatrix(BoundMatrix::Identity()), 1e-6);
0364   CHECK_CLOSE_ABS(std::get<2>(boundState), 0., 1e-6);
0365 
0366   // Transport the covariance in the context of a surface
0367   sls.transportCovarianceToBound(slsState, *plane, freeToBoundCorrection);
0368   BOOST_CHECK_NE(slsState.cov, cov);
0369   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0370   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0371   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0372 
0373   // Update in context of a surface
0374   freeParams = transformBoundToFreeParameters(bp.referenceSurface(), tgContext,
0375                                               bp.parameters());
0376 
0377   BOOST_CHECK(bp.covariance().has_value());
0378   sls.update(slsState, freeParams, bp.parameters(), 2 * (*bp.covariance()),
0379              *plane);
0380   CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0381   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0382   CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0383   CHECK_CLOSE_COVARIANCE(slsState.cov, Covariance(2. * cov), 1e-6);
0384 }
0385 
0386 }  // namespace Acts::Test