Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:13:40

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/TrackParameters.hpp"
0017 #include "Acts/EventData/TransformationHelpers.hpp"
0018 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0021 #include "Acts/Propagator/ConstrainedStep.hpp"
0022 #include "Acts/Propagator/StraightLineStepper.hpp"
0023 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0024 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0025 #include "Acts/Surfaces/PlaneSurface.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 #include "Acts/Utilities/Result.hpp"
0028 
0029 #include <limits>
0030 #include <memory>
0031 #include <optional>
0032 #include <string>
0033 
0034 using namespace Acts::UnitLiterals;
0035 using Acts::VectorHelpers::makeVector4;
0036 
0037 namespace Acts::Test {
0038 
0039 using Covariance = BoundSquareMatrix;
0040 
0041 static constexpr auto eps = 2 * std::numeric_limits<double>::epsilon();
0042 
0043 /// These tests are aiming to test whether the state setup is working properly
0044 BOOST_AUTO_TEST_CASE(straight_line_stepper_state_test) {
0045   // Set up some variables
0046   GeometryContext tgContext = GeometryContext();
0047   MagneticFieldContext mfContext = MagneticFieldContext();
0048   double stepSize = 123.;
0049 
0050   Vector3 pos(1., 2., 3.);
0051   Vector3 dir(4., 5., 6.);
0052   double time = 7.;
0053   double absMom = 8.;
0054   double charge = -1.;
0055 
0056   StraightLineStepper::Options slsOptions(tgContext, mfContext);
0057   slsOptions.maxStepSize = stepSize;
0058 
0059   // Test charged parameters without covariance matrix
0060   BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0061       makeVector4(pos, time), dir, charge / absMom, std::nullopt,
0062       ParticleHypothesis::pion());
0063 
0064   StraightLineStepper sls;
0065   StraightLineStepper::State slsState = sls.makeState(slsOptions);
0066   sls.initialize(slsState, cp);
0067 
0068   // Test the result & compare with the input/test for reasonable members
0069   BOOST_CHECK_EQUAL(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0070   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0071   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0072   BOOST_CHECK(!slsState.covTransport);
0073   BOOST_CHECK_EQUAL(slsState.cov, Covariance::Zero());
0074   CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0075   CHECK_CLOSE_OR_SMALL(sls.direction(slsState), dir.normalized(), eps, eps);
0076   CHECK_CLOSE_REL(sls.absoluteMomentum(slsState), absMom, eps);
0077   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0078   CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0079   BOOST_CHECK_EQUAL(slsState.pathAccumulated, 0.);
0080   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0081   BOOST_CHECK_EQUAL(slsState.previousStepSize, 0.);
0082 
0083   // Test without charge and covariance matrix
0084   BoundTrackParameters ncp = BoundTrackParameters::createCurvilinear(
0085       makeVector4(pos, time), dir, 1 / absMom, std::nullopt,
0086       ParticleHypothesis::pion0());
0087   sls.initialize(slsState, ncp);
0088 
0089   // Test with covariance matrix
0090   Covariance cov = 8. * Covariance::Identity();
0091   ncp = BoundTrackParameters::createCurvilinear(makeVector4(pos, time), dir,
0092                                                 1 / absMom, cov,
0093                                                 ParticleHypothesis::pion0());
0094   sls.initialize(slsState, ncp);
0095   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0096   BOOST_CHECK(slsState.covTransport);
0097   BOOST_CHECK_EQUAL(slsState.cov, cov);
0098 }
0099 
0100 /// These tests are aiming to test the functions of the StraightLineStepper
0101 /// The numerical correctness of the stepper is tested in the integration tests
0102 BOOST_AUTO_TEST_CASE(straight_line_stepper_test) {
0103   // Set up some variables for the state
0104   GeometryContext tgContext = GeometryContext();
0105   MagneticFieldContext mfContext = MagneticFieldContext();
0106   Direction navDir = Direction::Backward();
0107   double stepSize = 123.;
0108 
0109   // Construct the parameters
0110   Vector3 pos(1., 2., 3.);
0111   Vector3 dir = Vector3(4., 5., 6.).normalized();
0112   double time = 7.;
0113   double absMom = 8.;
0114   double charge = -1.;
0115   Covariance cov = 8. * Covariance::Identity();
0116   BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0117       makeVector4(pos, time), dir, charge / absMom, cov,
0118       ParticleHypothesis::pion());
0119 
0120   StraightLineStepper::Options options(tgContext, mfContext);
0121   options.maxStepSize = stepSize;
0122   options.initialStepSize = 10_m;
0123 
0124   // Build the stepper and the state
0125   StraightLineStepper sls;
0126   StraightLineStepper::State slsState = sls.makeState(options);
0127   sls.initialize(slsState, cp);
0128 
0129   // Test the getters
0130   CHECK_CLOSE_ABS(sls.position(slsState), pos, 1e-6);
0131   CHECK_CLOSE_ABS(sls.direction(slsState), dir, 1e-6);
0132   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), absMom, 1e-6);
0133   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0134   BOOST_CHECK_EQUAL(sls.time(slsState), time);
0135 
0136   // Step size modifies
0137   const std::string originalStepSize = slsState.stepSize.toString();
0138 
0139   sls.updateStepSize(slsState, -1337., ConstrainedStep::Type::Navigator);
0140   BOOST_CHECK_EQUAL(slsState.previousStepSize, stepSize);
0141   BOOST_CHECK_EQUAL(slsState.stepSize.value(), -1337.);
0142 
0143   sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0144   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0145   BOOST_CHECK_EQUAL(sls.outputStepSize(slsState), originalStepSize);
0146 
0147   // Test the curvilinear state construction
0148   auto curvState = sls.curvilinearState(slsState);
0149   auto curvPars = std::get<0>(curvState);
0150   CHECK_CLOSE_ABS(curvPars.position(tgContext), cp.position(tgContext), 1e-6);
0151   CHECK_CLOSE_ABS(curvPars.absoluteMomentum(), cp.absoluteMomentum(), 1e-6);
0152   CHECK_CLOSE_ABS(curvPars.charge(), cp.charge(), 1e-6);
0153   CHECK_CLOSE_ABS(curvPars.time(), cp.time(), 1e-6);
0154   BOOST_CHECK(curvPars.covariance().has_value());
0155   BOOST_CHECK_NE(*curvPars.covariance(), cov);
0156   CHECK_CLOSE_COVARIANCE(std::get<1>(curvState),
0157                          BoundMatrix(BoundMatrix::Identity()), 1e-6);
0158   CHECK_CLOSE_ABS(std::get<2>(curvState), 0., 1e-6);
0159 
0160   // Test the update method
0161   Vector3 newPos(2., 4., 8.);
0162   Vector3 newMom(3., 9., 27.);
0163   double newTime(321.);
0164   sls.update(slsState, newPos, newMom.normalized(), charge / newMom.norm(),
0165              newTime);
0166   CHECK_CLOSE_ABS(sls.position(slsState), newPos, 1e-6);
0167   CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0168   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0169   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0170   BOOST_CHECK_EQUAL(sls.time(slsState), newTime);
0171 
0172   // The covariance transport
0173   slsState.cov = cov;
0174   sls.transportCovarianceToCurvilinear(slsState);
0175   BOOST_CHECK_NE(slsState.cov, cov);
0176   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0177   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0178   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0179 
0180   // Perform a step without and with covariance transport
0181   slsState.cov = cov;
0182 
0183   slsState.covTransport = false;
0184   double h = sls.step(slsState, navDir, nullptr).value();
0185   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0186   BOOST_CHECK_EQUAL(slsState.stepSize.value(), h * navDir);
0187   CHECK_CLOSE_COVARIANCE(slsState.cov, cov, 1e-6);
0188   BOOST_CHECK_GT(sls.position(slsState).norm(), newPos.norm());
0189   CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0190   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0191   CHECK_CLOSE_ABS(sls.charge(slsState), charge, 1e-6);
0192   BOOST_CHECK_LT(sls.time(slsState), newTime);
0193   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0194   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0195 
0196   slsState.covTransport = true;
0197   double h2 = sls.step(slsState, navDir, nullptr).value();
0198   BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0199   BOOST_CHECK_EQUAL(h2, h);
0200   CHECK_CLOSE_COVARIANCE(slsState.cov, cov, 1e-6);
0201   BOOST_CHECK_GT(sls.position(slsState).norm(), newPos.norm());
0202   CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0203   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0204   CHECK_CLOSE_ABS(sls.charge(slsState), charge, 1e-6);
0205   BOOST_CHECK_LT(sls.time(slsState), newTime);
0206   BOOST_CHECK_NE(slsState.derivative, FreeVector::Zero());
0207   BOOST_CHECK_NE(slsState.jacTransport, FreeMatrix::Identity());
0208 
0209   /// Test the state reset
0210   // Construct the parameters
0211   Vector3 pos2(1.5, -2.5, 3.5);
0212   Vector3 dir2 = Vector3(4.5, -5.5, 6.5).normalized();
0213   double time2 = 7.5;
0214   double absMom2 = 8.5;
0215   double charge2 = 1.;
0216   BoundSquareMatrix cov2 = 8.5 * Covariance::Identity();
0217   BoundTrackParameters cp2 = BoundTrackParameters::createCurvilinear(
0218       makeVector4(pos2, time2), dir2, charge2 / absMom2, cov2,
0219       ParticleHypothesis::pion());
0220   BOOST_CHECK(cp2.covariance().has_value());
0221   FreeVector freeParams = transformBoundToFreeParameters(
0222       cp2.referenceSurface(), tgContext, cp2.parameters());
0223   navDir = Direction::Forward();
0224 
0225   // Reset all possible parameters
0226   StraightLineStepper::State slsStateCopy = slsState;
0227   sls.initialize(slsStateCopy, cp2.parameters(), cp2.covariance(),
0228                  cp2.particleHypothesis(), cp2.referenceSurface());
0229   // Test all components
0230   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, BoundToFreeMatrix::Zero());
0231   BOOST_CHECK_NE(slsStateCopy.jacToGlobal, slsState.jacToGlobal);
0232   BOOST_CHECK_EQUAL(slsStateCopy.jacTransport, FreeMatrix::Identity());
0233   BOOST_CHECK_EQUAL(slsStateCopy.derivative, FreeVector::Zero());
0234   BOOST_CHECK(slsStateCopy.covTransport);
0235   BOOST_CHECK_EQUAL(slsStateCopy.cov, cov2);
0236   CHECK_CLOSE_ABS(sls.position(slsStateCopy),
0237                   freeParams.template segment<3>(eFreePos0), 1e-6);
0238   CHECK_CLOSE_ABS(sls.direction(slsStateCopy),
0239                   freeParams.template segment<3>(eFreeDir0).normalized(), 1e-6);
0240   CHECK_CLOSE_ABS(sls.absoluteMomentum(slsStateCopy),
0241                   std::abs(1. / freeParams[eFreeQOverP]), 1e-6);
0242   CHECK_CLOSE_ABS(sls.charge(slsStateCopy), -sls.charge(slsState), 1e-6);
0243   CHECK_CLOSE_ABS(sls.time(slsStateCopy), freeParams[eFreeTime], 1e-6);
0244   BOOST_CHECK_EQUAL(slsStateCopy.pathAccumulated, 0.);
0245   BOOST_CHECK_EQUAL(slsStateCopy.stepSize.value(), stepSize);
0246   BOOST_CHECK_EQUAL(slsStateCopy.previousStepSize, 0.);
0247 
0248   /// Repeat with surface related methods
0249   std::shared_ptr<PlaneSurface> plane =
0250       CurvilinearSurface(pos, dir).planeSurface();
0251   auto bp = BoundTrackParameters::create(
0252                 tgContext, plane, makeVector4(pos, time), dir, charge / absMom,
0253                 cov, ParticleHypothesis::pion())
0254                 .value();
0255   slsState = sls.makeState(options);
0256   sls.initialize(slsState, bp);
0257 
0258   // Test the intersection in the context of a surface
0259   std::shared_ptr<PlaneSurface> targetSurface =
0260       CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface();
0261   sls.updateSurfaceStatus(slsState, *targetSurface, 0, navDir,
0262                           BoundaryTolerance::Infinite(), s_onSurfaceTolerance,
0263                           ConstrainedStep::Type::Navigator);
0264   CHECK_CLOSE_ABS(slsState.stepSize.value(ConstrainedStep::Type::Navigator),
0265                   navDir * 2., 1e-6);
0266 
0267   // Test the step size modification in the context of a surface
0268   sls.updateStepSize(slsState,
0269                      targetSurface
0270                          ->intersect(tgContext, sls.position(slsState),
0271                                      navDir * sls.direction(slsState),
0272                                      BoundaryTolerance::Infinite())
0273                          .closest(),
0274                      navDir, ConstrainedStep::Type::Navigator);
0275   CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0276   slsState.stepSize.setUser(navDir * stepSize);
0277   sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0278   sls.updateStepSize(slsState,
0279                      targetSurface
0280                          ->intersect(tgContext, sls.position(slsState),
0281                                      navDir * sls.direction(slsState),
0282                                      BoundaryTolerance::Infinite())
0283                          .closest(),
0284                      navDir, ConstrainedStep::Type::Navigator);
0285   CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0286 
0287   // Test the bound state construction
0288   FreeToBoundCorrection freeToBoundCorrection(false);
0289   auto boundState =
0290       sls.boundState(slsState, *plane, true, freeToBoundCorrection).value();
0291   auto boundPars = std::get<0>(boundState);
0292   CHECK_CLOSE_ABS(boundPars.position(tgContext), bp.position(tgContext), 1e-6);
0293   CHECK_CLOSE_ABS(boundPars.momentum(), bp.momentum(), 1e-6);
0294   CHECK_CLOSE_ABS(boundPars.charge(), bp.charge(), 1e-6);
0295   CHECK_CLOSE_ABS(boundPars.time(), bp.time(), 1e-6);
0296   BOOST_CHECK(boundPars.covariance().has_value());
0297   BOOST_CHECK_NE(*boundPars.covariance(), cov);
0298   CHECK_CLOSE_COVARIANCE(std::get<1>(boundState),
0299                          BoundMatrix(BoundMatrix::Identity()), 1e-6);
0300   CHECK_CLOSE_ABS(std::get<2>(boundState), 0., 1e-6);
0301 
0302   // Transport the covariance in the context of a surface
0303   sls.transportCovarianceToBound(slsState, *plane, freeToBoundCorrection);
0304   BOOST_CHECK_NE(slsState.cov, cov);
0305   BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0306   BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0307   BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0308 
0309   // Update in context of a surface
0310   freeParams = transformBoundToFreeParameters(bp.referenceSurface(), tgContext,
0311                                               bp.parameters());
0312 
0313   BOOST_CHECK(bp.covariance().has_value());
0314   sls.update(slsState, freeParams, bp.parameters(), 2 * (*bp.covariance()),
0315              *plane);
0316   CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0317   BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0318   CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0319   CHECK_CLOSE_COVARIANCE(slsState.cov, Covariance(2. * cov), 1e-6);
0320 }
0321 
0322 }  // namespace Acts::Test