Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:25

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 #include <boost/test/unit_test_log_formatter.hpp>
0012 
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/Definitions/Units.hpp"
0016 #include "Acts/EventData/TransformationHelpers.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/MagneticField/ConstantBField.hpp"
0019 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0020 #include "Acts/Propagator/EigenStepper.hpp"
0021 #include "Acts/Propagator/Navigator.hpp"
0022 #include "Acts/Propagator/Propagator.hpp"
0023 #include "Acts/Propagator/StraightLineStepper.hpp"
0024 #include "Acts/Propagator/VoidNavigator.hpp"
0025 #include "Acts/Propagator/detail/JacobianEngine.hpp"
0026 #include "Acts/Surfaces/DiscSurface.hpp"
0027 #include "Acts/Surfaces/PlaneSurface.hpp"
0028 
0029 #include <cmath>
0030 #include <cstdlib>
0031 #include <exception>
0032 #include <iomanip>
0033 #include <iostream>
0034 #include <typeinfo>
0035 
0036 using namespace Acts;
0037 using namespace Acts::UnitLiterals;
0038 
0039 bool isDebugOutputEnabled() {
0040   std::array<boost::unit_test::output_format, 1> formats{
0041       boost::unit_test::OF_CLF};
0042   for (auto a_format : formats) {
0043     auto formatter = ::boost::unit_test::unit_test_log.get_formatter(a_format);
0044     if (formatter != nullptr) {
0045       return formatter->get_log_level() < boost::unit_test::log_test_units;
0046     }
0047   }
0048   return false;
0049 }
0050 
0051 #define MSG_DEBUG(a)               \
0052   if (isDebugOutputEnabled()) {    \
0053     std::stringstream msg;         \
0054     msg << a;                      \
0055     BOOST_TEST_MESSAGE(msg.str()); \
0056   }                                \
0057   do {                             \
0058   } while (0)
0059 
0060 namespace {
0061 /** Helper function to compute dt/ds
0062  * Helper function to compute the derivative of the time as function of the path
0063  * length
0064  */
0065 template <class T_ParticleHypothesis>
0066 double computeDtDs(const T_ParticleHypothesis &hypothesis, double qop) {
0067   return std::hypot(1., hypothesis.mass() / hypothesis.extractMomentum(qop));
0068 }
0069 
0070 /** Compute the path length derivatives for the free/bound to curvilinear
0071  * parameter transform.
0072  * @param direction the direction of trajectory at the location in question
0073  * @param qop q/p of the particle at the location in question in Acts units
0074  * @param bfield the magnetic field at the location in question in Acts units
0075  * @param particle_hypothesis the particle hypothesis e.g. Acts::ParticleHypothesis::pion()
0076  * @return path length derivatives ( dr(...)/ds, dt/ds, dr(...)/ds2, d qop/ds [== 0] )
0077  */
0078 template <class T_ParticleHypothesis>
0079 FreeToPathMatrix computeFreeToPathDerivatives(
0080     const Vector3 &direction, double qop, const Vector3 &bfield,
0081     const T_ParticleHypothesis &particle_hypothis) {
0082   FreeToPathMatrix path_length_deriv;
0083 #if defined(EIGEN_HAS_CONSTEXPR) && EIGEN_VERSION_AT_LEAST(3, 4, 0)
0084   static_assert(path_length_deriv.cols() ==
0085                 8);  // ensure that all elements are initialized
0086 #endif
0087   path_length_deriv.segment<3>(eFreePos0) = direction;
0088   path_length_deriv(0, eFreeTime) = computeDtDs(particle_hypothis, qop);
0089   path_length_deriv.segment<3>(eFreeDir0) =
0090       (qop * direction.cross(bfield)).transpose();
0091   path_length_deriv(0, Acts::eFreeQOverP) = 0.;
0092   return path_length_deriv;
0093 }
0094 template <typename T, std::size_t Rows, std::size_t Cols>
0095 inline constexpr Eigen::Matrix<T, Rows, Cols> makeMatrix(
0096     std::initializer_list<double> elements) {
0097   // static_assert( elements.size() == Rows*Cols )
0098   if (!(elements.size() == Rows * Cols)) {
0099     // throw std::range_error("Initializer list size does not match matrix
0100     // dimensions.");
0101     std::abort();
0102   }
0103   Eigen::Matrix<T, Rows, Cols> matrix;
0104   auto iter = elements.begin();
0105   for (unsigned int row_i = 0; row_i < matrix.rows(); ++row_i) {
0106     for (unsigned int col_i = 0; col_i < matrix.cols(); ++col_i) {
0107       matrix(row_i, col_i) = *iter;
0108       ++iter;
0109     }
0110   }
0111   return matrix;
0112 }
0113 template <typename T, std::size_t Rows>
0114 inline constexpr Eigen::Matrix<T, Rows, 1> makeVector(
0115     std::initializer_list<double> elements) {
0116   return makeMatrix<T, Rows, 1>(elements);
0117 }
0118 
0119 template <typename T_Matrix>
0120 T_Matrix matrixRatio(const T_Matrix &a, const T_Matrix &b) {
0121   if (a.rows() != b.rows() || a.cols() != b.cols()) {
0122     std::abort();
0123   }
0124   T_Matrix ret;
0125   for (unsigned int row_i = 0; row_i < a.rows(); ++row_i) {
0126     for (unsigned int col_i = 0; col_i < a.cols(); ++col_i) {
0127       if (b(row_i, col_i) == 0.) {
0128         ret(row_i, col_i) = a(row_i, col_i) - b(row_i, col_i);
0129       } else {
0130         ret(row_i, col_i) = a(row_i, col_i) / b(row_i, col_i);
0131       }
0132     }
0133   }
0134   return ret;
0135 }
0136 
0137 }  // namespace
0138 
0139 struct TestData {
0140   enum ESurfaceType { kPlane, kPolarDisk, kCylinder };
0141   TestData(Vector3 &&a_surface_center, ActsMatrix<3, 3> &&a_surface_rot,
0142            ESurfaceType a_surface_type, BoundVector &&a_param_vec,
0143            BoundSquareMatrix &&a_param_cov, Vector3 &&a_bfield)
0144       : surface_center(std::move(a_surface_center)),
0145         surface_rot(std::move(a_surface_rot)),
0146         surface_type(a_surface_type),
0147         param_vec(std::move(a_param_vec)),
0148         param_cov(std::move(a_param_cov)),
0149         bfield(std::move(a_bfield)) {}
0150 
0151   Vector3 surface_center;
0152   ActsMatrix<3, 3> surface_rot;
0153   ESurfaceType surface_type;
0154   BoundVector param_vec;
0155   BoundSquareMatrix param_cov;
0156   Vector3 bfield;
0157 };
0158 
0159 template <typename T_StepperCreator>
0160 void test_bound_to_curvilinear(const std::vector<TestData> &test_data_list,
0161                                const T_StepperCreator &stepper_creator) {
0162   GeometryContext geoCtx;
0163   MagneticFieldContext magFieldContext;
0164 
0165   for (const auto &test_data : test_data_list) {
0166     // create a constant magnetic field provider for the test_data
0167     std::shared_ptr<Acts::MagneticFieldProvider> bField =
0168         std::dynamic_pointer_cast<Acts::MagneticFieldProvider>(
0169             std::make_shared<ConstantBField>(test_data.bfield));
0170 
0171     // create bound parameters from test data
0172     const Vector3 &surface_center = test_data.surface_center;
0173     const ActsMatrix<3, 3> &surface_rot = test_data.surface_rot;
0174     const BoundVector &param_vec = test_data.param_vec;
0175     const BoundSquareMatrix &cov = test_data.param_cov;
0176 
0177     AngleAxis3 surface_transform0;
0178     surface_transform0 = surface_rot;
0179 
0180     std::shared_ptr<Surface> surface;
0181     switch (test_data.surface_type) {
0182       case TestData::kPlane: {
0183         surface = std::dynamic_pointer_cast<Surface>(
0184             Surface::makeShared<PlaneSurface>(Translation3(surface_center) *
0185                                               surface_transform0));
0186         break;
0187       }
0188       case TestData::kPolarDisk: {
0189         surface =
0190             std::dynamic_pointer_cast<Surface>(Surface::makeShared<DiscSurface>(
0191                 Translation3(surface_center) * surface_transform0));
0192         break;
0193       }
0194       default: {
0195         throw std::runtime_error("Unhandled surface type.");
0196         std::abort();
0197       }
0198     }
0199 
0200     Vector3 direction{cos(param_vec[2]) * sin(param_vec[3]),
0201                       sin(param_vec[2]) * sin(param_vec[3]), cos(param_vec[3])};
0202     Vector3 position(surface->localToGlobal(
0203         geoCtx, Vector2{param_vec[0], param_vec[1]}, direction));
0204     BoundTrackParameters params(surface, param_vec,
0205                                 std::optional<BoundSquareMatrix>(cov),
0206                                 ParticleHypothesis::pion());
0207 
0208     // compute curvilinear parameters by using the propagator with
0209     // a small step size : ==0, >0 but below path limit,  > path limit, *10 and
0210     // > path limit
0211     for (unsigned int i = 0; i < 4; ++i) {
0212       MagneticFieldProvider::Cache cache = bField->makeCache(magFieldContext);
0213 
0214       Result<Acts::Vector3> local_bfield = bField->getField(position, cache);
0215       assert(local_bfield.ok());
0216 
0217       auto path_length_derivatives = computeFreeToPathDerivatives(
0218           direction, params.parameters()[eBoundQOverP], local_bfield.value(),
0219           ParticleHypothesis::pion());
0220       MSG_DEBUG("derivatives : " << path_length_derivatives);
0221 
0222       // compute Jacobian for bound to curvilinear covariance transformation
0223       Acts::BoundMatrix b2c;
0224       Acts::detail::boundToCurvilinearTransportJacobian(
0225           direction, surface->boundToFreeJacobian(geoCtx, position, direction),
0226           Acts::FreeMatrix::Identity(),
0227           computeFreeToPathDerivatives(
0228               direction, params.parameters()[eBoundQOverP],
0229               local_bfield.value(), ParticleHypothesis::pion()),
0230           b2c);
0231 
0232       auto curvi_cov_alt = b2c * cov * b2c.transpose();
0233 
0234       MSG_DEBUG("curvilinear covariance alt.:" << std::endl << curvi_cov_alt);
0235 
0236       // configure propagator for tiny step size
0237       Acts::PropagatorOptions<> null_propagation_options(geoCtx,
0238                                                          magFieldContext);
0239 
0240       null_propagation_options.pathLimit =
0241           i == 0 ? 0 : 1e-12 * 1_m * std::pow(10, i - 1);
0242       if (null_propagation_options.pathLimit > 0 && i > 1) {
0243         null_propagation_options.stepTolerance =
0244             null_propagation_options.pathLimit * .99;
0245         null_propagation_options.surfaceTolerance =
0246             null_propagation_options.pathLimit * .99;
0247       }
0248       auto stepper = stepper_creator(bField);
0249       MSG_DEBUG("Stepper type " << typeid(stepper).name());
0250 
0251       auto log_level = (isDebugOutputEnabled() ? Acts::Logging::VERBOSE
0252                                                : Acts::Logging::INFO);
0253 
0254       // Use propagator with small step size to compute parameters in
0255       // curvilinear parameterisation
0256       Propagator<decltype(stepper)> propagator(
0257           std::move(stepper), Acts::VoidNavigator(),
0258           Acts::getDefaultLogger("Propagator", log_level));
0259       auto result =
0260           propagator.propagate(params, null_propagation_options, true);
0261       {
0262         const auto &curvilinear_parameters = result.value().endParameters;
0263         if (curvilinear_parameters.has_value() &&
0264             curvilinear_parameters.value().covariance().has_value()) {
0265           MSG_DEBUG(i << " | "
0266                       << "limit: " << null_propagation_options.pathLimit
0267                       << " tolerance: "
0268                       << null_propagation_options.stepTolerance << std::endl);
0269 
0270           Acts::BoundSquareMatrix curvi_cov =
0271               curvilinear_parameters.value().covariance().value();
0272           MSG_DEBUG("curvilinear covariance:" << std::endl
0273                                               << curvi_cov << std::endl);
0274           if (isDebugOutputEnabled()) {
0275             Acts::BoundSquareMatrix b(curvi_cov_alt);
0276             auto ratio = matrixRatio(curvi_cov, b);
0277             MSG_DEBUG("ratio:" << std::endl << ratio << std::endl);
0278           }
0279           // test that result from propagation and explicit computation are
0280           // compatible.
0281           BOOST_CHECK(curvi_cov_alt.isApprox(curvi_cov));
0282         }
0283       }
0284     }
0285   }
0286 }
0287 
0288 std::vector<TestData> make_test_data(double mag_field_scale = 1.) {
0289   std::vector<TestData> test_data_list{
0290       TestData(
0291           makeVector<ActsScalar, 3>(
0292               {-442.883, -624.094, 857.272}),  // surface center
0293           makeMatrix<ActsScalar, 3, 3>(
0294               {0.677197, 0.0176111, -0.735591, -0.735342, -0.0191232, -0.677426,
0295                -0.0259971, 0.999662, -2.22045e-16}),  // surface rot
0296           TestData::kPlane,
0297           makeVector<ActsScalar, eBoundSize>({46.5758, 4.5564, -2.38067,
0298                                               0.72974, 0.73159,
0299                                               1163.57}),  // param_vec
0300           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0301               {0.00025406,   0.00334274,  2.9713e-06,   -6.40317e-06,
0302                2.52229e-05,  0.00291208,  0.00334274,   9.77017,
0303                0.00109081,   -0.0106064,  -0.00340842,  7.25206,
0304                2.9713e-06,   0.00109081,  4.86984e-07,  -1.68459e-06,
0305                2.0707e-06,   0.000848693, -6.40317e-06, -0.0106064,
0306                -1.68459e-06, 1.58516e-05, 4.40043e-06,  -0.00786289,
0307                2.52229e-05,  -0.00340842, 2.0707e-06,   4.40043e-06,
0308                2.786e-05,    -0.00210611, 0.00291208,   7.25206,
0309                0.000848693,  -0.00786289, -0.00210611,  89880.9}),  // param cov
0310           makeVector<ActsScalar, 3>({-2.64634e-05 * 1000_T,
0311                                      -4.38183e-05 * 1000_T,
0312                                      0.00197353 * 1000_T})),  // magnetic field
0313 
0314       TestData(
0315           makeVector<ActsScalar, 3>(
0316               {-215.895, 979.521, 808.928}),  // surface center
0317           makeMatrix<ActsScalar, 3, 3>(
0318               {-0.999319, -0.0259882, -0.0261772, -0.0261683, -0.00068053,
0319                0.999657, -0.0259971, 0.999662, -2.22045e-16}),  // surface rot
0320           TestData::kPlane,
0321           makeVector<ActsScalar, eBoundSize>({-47.2414, -20.7881, 1.46297,
0322                                               0.926114, 0.723167,
0323                                               1318.63}),  // param_vec
0324           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0325               {0.000299382,  -0.00331811,  -9.93116e-06,
0326                4.79934e-06,  9.50183e-06,  -0.00184948,
0327                -0.00331811,  0.212531,     -3.5517e-05,
0328                -0.00030374,  3.77471e-05,  0.129021,
0329                -9.93116e-06, -3.5517e-05,  1.26087e-06,
0330                2.63359e-08,  -1.11054e-06, -4.07474e-05,
0331                4.79934e-06,  -0.00030374,  2.63359e-08,
0332                2.42802e-06,  1.77196e-07,  -0.000180912,
0333                9.50183e-06,  3.77471e-05,  -1.11054e-06,
0334                1.77196e-07,  2.13352e-05,  0.000394159,
0335                -0.00184948,  0.129021,     -4.07474e-05,
0336                -0.000180912, 0.000394159,  89875.6}),  // param cov
0337           makeVector<ActsScalar, 3>({-7.28154e-06 * 1000_T,
0338                                      4.91679e-05 * 1000_T,
0339                                      0.00200021 * 1000_T})),  // magnetic field
0340 
0341       TestData(makeVector<ActsScalar, 3>(
0342                    {-100.1, 9.9476e-14, 2623}),  // surface center
0343                makeMatrix<ActsScalar, 3, 3>({-9.4369e-16, -1, -2.22045e-16, -1,
0344                                              9.4369e-16, 2.09541e-31, 0,
0345                                              2.22045e-16, -1}),  // surface rot
0346                TestData::kPlane,
0347                makeVector<ActsScalar, eBoundSize>({5.1223, 16.6267, -3.08166,
0348                                                    0.0439704, -0.0358564,
0349                                                    2625.58}),  // param_vec
0350                makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0351                    {0.00017846,   6.32301e-09,  1.31319e-05,
0352                     3.28335e-08,  -1.37002e-07, 6.412e-07,
0353                     6.32301e-09,  0.000178573,  -7.46352e-07,
0354                     5.77821e-07,  1.22545e-08,  7.82577e-06,
0355                     1.31319e-05,  -7.46352e-07, 4.27034e-05,
0356                     -2.44549e-13, -2.98712e-09, 5.95667e-09,
0357                     3.28335e-08,  5.77821e-07,  -2.44549e-13,
0358                     8.26179e-08,  8.02087e-11,  2.53174e-08,
0359                     -1.37002e-07, 1.22545e-08,  -2.98712e-09,
0360                     8.02087e-11,  1.36315e-06,  -1.7853e-06,
0361                     6.412e-07,    7.82577e-06,  5.95667e-09,
0362                     2.53174e-08,  -1.7853e-06,  89875.5}),  // param cov
0363                makeVector<ActsScalar, 3>(
0364                    {-5.04066e-05 * 1000_T, -1.84572e-06 * 1000_T,
0365                     0.00107321 * 1000_T})),  // magnetic field
0366 
0367       TestData(
0368           makeVector<ActsScalar, 3>(
0369               {-2.79072, 18.1615, 1962.71}),  // surface center
0370           makeMatrix<ActsScalar, 3, 3>(
0371               {-0.986831, -0.161755, -2.38917e-17, -0.161755, 0.986831,
0372                -2.35312e-18, 2.39577e-17, 1.54245e-18, -1}),  // surface rot
0373           TestData::kPolarDisk,
0374           makeVector<ActsScalar, eBoundSize>({874.522, -0.0199525, -2.87012,
0375                                               0.412785, -0.218474,
0376                                               2144.77}),  // param_vec
0377           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0378               {0.268052,     6.23529e-06,  -2.89316e-05,
0379                0.000334472,  6.69436e-06,  0.107219,
0380                6.23529e-06,  4.51554e-10,  -5.00139e-09,
0381                7.5944e-09,   1.32896e-09,  2.47693e-06,
0382                -2.89316e-05, -5.00139e-09, 1.10493e-06,
0383                -8.28542e-08, -1.11202e-07, -1.05201e-05,
0384                0.000334472,  7.5944e-09,   -8.28542e-08,
0385                7.43596e-07,  3.40043e-08,  0.00013338,
0386                6.69436e-06,  1.32896e-09,  -1.11202e-07,
0387                3.40043e-08,  2.28008e-06,  -1.3933e-05,
0388                0.107219,     2.47693e-06,  -1.05201e-05,
0389                0.00013338,   -1.3933e-05,  89875.6}),  // param cov
0390           makeVector<ActsScalar, 3>({-0.000238594 * 1000_T,
0391                                      -3.95897e-05 * 1000_T,
0392                                      0.00170904 * 1000_T})),  // magnetic field
0393 
0394       TestData(
0395           makeVector<ActsScalar, 3>(
0396               {-1.04461, -18.345, -2232.72}),  // surface center
0397           makeMatrix<ActsScalar, 3, 3>(
0398               {-0.997764, 0.0668313, 1.22465e-16, 0.0668313, 0.997764,
0399                1.22465e-16, -1.14006e-16, 1.30375e-16, -1}),  // surface rot
0400           TestData::kPolarDisk,
0401           makeVector<ActsScalar, eBoundSize>({919.923, -0.0334805, 3.06771,
0402                                               2.75516, 0.106936,
0403                                               2410.21}),  // param_vec
0404           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0405               {0.249495,     -5.22193e-06, -3.13362e-06,
0406                -0.000237539, -8.44559e-08, 0.0938443,
0407                -5.22193e-06, 4.17316e-10,  -3.62456e-09,
0408                4.90101e-09,  2.09791e-10,  -1.95858e-06,
0409                -3.13362e-06, -3.62456e-09, 9.69964e-07,
0410                -1.38253e-08, -2.38732e-08, -1.43246e-06,
0411                -0.000237539, 4.90101e-09,  -1.38253e-08,
0412                4.54156e-07,  3.99992e-09,  -8.93313e-05,
0413                -8.44559e-08, 2.09791e-10,  -2.38732e-08,
0414                3.99992e-09,  5.6852e-07,   4.62431e-06,
0415                0.0938443,    -1.95858e-06, -1.43246e-06,
0416                -8.93313e-05, 4.62431e-06,  89875.6}),  // param cov
0417           makeVector<ActsScalar, 3>({0.00036598 * 1000_T, -5.73626e-06 * 1000_T,
0418                                      0.0015599 * 1000_T})),  // magnetic field
0419 
0420       TestData(
0421           makeVector<ActsScalar, 3>(
0422               {2.25897, 16.0914, 1962.71}),  // surface center
0423           makeMatrix<ActsScalar, 3, 3>(
0424               {-0.99163, 0.129111, 2.38917e-17, 0.129111, 0.99163, -2.35312e-18,
0425                -2.39955e-17, 7.51254e-19, -1}),  // surface rot
0426           TestData::kPolarDisk,
0427           makeVector<ActsScalar, eBoundSize>({855.523, -0.00206235, 2.78002,
0428                                               0.430255, 0.430811,
0429                                               2164.93}),  // param_vec
0430           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0431               {0.46359,      9.75743e-06,  0.000448092,
0432                0.000688107,  -0.000233571, 0.188268,
0433                9.75743e-06,  6.10067e-10,  -4.97007e-10,
0434                1.52396e-08,  3.93299e-09,  4.13675e-06,
0435                0.000448092,  -4.97007e-10, 4.44146e-06,
0436                8.69542e-07,  -2.28873e-06, 0.00014712,
0437                0.000688107,  1.52396e-08,  8.69542e-07,
0438                2.0094e-06,   -8.25987e-07, 0.000271189,
0439                -0.000233571, 3.93299e-09,  -2.28873e-06,
0440                -8.25987e-07, 4.58208e-05,  0.000645024,
0441                0.188268,     4.13675e-06,  0.00014712,
0442                0.000271189,  0.000645024,  89875.6}),  // param cov
0443           makeVector<ActsScalar, 3>({-0.000235096 * 1000_T,
0444                                      3.37809e-05 * 1000_T,
0445                                      0.00170337 * 1000_T})),  // magnetic field
0446 
0447       TestData(
0448           makeVector<ActsScalar, 3>(
0449               {-956.977, -300.445, -563.272}),  // surface center
0450           makeMatrix<ActsScalar, 3, 3>(
0451               {0.113165, 0.00294296, -0.993572, -0.993236, -0.02583, -0.113203,
0452                -0.0259971, 0.999662, -9.95799e-17}),  // surface rot
0453           TestData::kPlane,
0454           makeVector<ActsScalar, eBoundSize>({43.1027, -20.0508, -2.58378,
0455                                               2.04794, -0.61896,
0456                                               1281.4}),  // param_vec
0457           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0458               {0.000415869,  -0.00624916,  4.30188e-06,
0459                1.11988e-05,  -8.34103e-07, 0.00297658,
0460                -0.00624916,  0.287414,     0.000262654,
0461                -0.000530088, -1.45312e-05, -0.131126,
0462                4.30188e-06,  0.000262654,  2.57536e-06,
0463                -4.80124e-07, -2.45959e-07, -0.000110478,
0464                1.11988e-05,  -0.000530088, -4.80124e-07,
0465                3.87906e-06,  6.73799e-08,  0.0002415,
0466                -8.34103e-07, -1.45312e-05, -2.45959e-07,
0467                6.73799e-08,  4.23156e-06,  -4.9642e-05,
0468                0.00297658,   -0.131126,    -0.000110478,
0469                0.0002415,    -4.9642e-05,  89875.6}),  // param cov
0470           makeVector<ActsScalar, 3>({3.50239e-05 * 1000_T, 1.16125e-05 * 1000_T,
0471                                      0.00201393 * 1000_T})),  // magnetic field
0472 
0473       TestData(
0474           makeVector<ActsScalar, 3>(
0475               {-14.6729, -11.0605, 2860.72}),  // surface center
0476           makeMatrix<ActsScalar, 3, 3>(
0477               {0.609896, -0.792481, -1.01826e-16, -0.792481, -0.609896,
0478                -1.90502e-16, 8.88665e-17, 1.96882e-16, -1}),  // surface rot
0479           TestData::kPolarDisk,
0480           makeVector<ActsScalar, eBoundSize>({878.179, 0.0377489, -0.917117,
0481                                               0.298851, -0.155266,
0482                                               2993.62}),  // param_vec
0483           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0484               {0.247492,     5.75149e-06,  -7.25055e-06,
0485                0.000186384,  2.26831e-05,  0.0724092,
0486                5.75149e-06,  4.34292e-10,  -3.3005e-09,
0487                4.28514e-09,  1.10915e-10,  1.68264e-06,
0488                -7.25055e-06, -3.3005e-09,  5.13085e-07,
0489                -2.15014e-08, 1.38502e-07,  -3.13833e-06,
0490                0.000186384,  4.28514e-09,  -2.15014e-08,
0491                2.64484e-07,  4.58027e-08,  5.43642e-05,
0492                2.26831e-05,  1.10915e-10,  1.38502e-07,
0493                4.58027e-08,  5.0017e-06,   -3.05689e-05,
0494                0.0724092,    1.68264e-06,  -3.13833e-06,
0495                5.43642e-05,  -3.05689e-05, 89875.5}),  // param cov
0496           makeVector<ActsScalar, 3>({0.000246188 * 1000_T,
0497                                      -0.000361053 * 1000_T,
0498                                      0.000756348 * 1000_T})),  // magnetic field
0499 
0500       TestData(
0501           makeVector<ActsScalar, 3>(
0502               {-748.018, 127.04, 1249.27}),  // surface center
0503           makeMatrix<ActsScalar, 3, 3>(
0504               {-0.368695, 0.00958824, -0.929501, -0.929187, 0.0241643, 0.36882,
0505                0.0259971, 0.999662, -2.22045e-16}),  // surface rot
0506           TestData::kPlane,
0507           makeVector<ActsScalar, eBoundSize>({-12.7967, -0.0111021, 2.81269,
0508                                               0.548845, 0.365828,
0509                                               1466.51}),  // param_vec
0510           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0511               {0.000407068, 0.00585003,  -5.06759e-06, -1.4351e-06, 3.49367e-07,
0512                0.00501982,  0.00585003,  0.220933,     -5.8514e-05, 7.21617e-06,
0513                3.69039e-05, 0.189194,    -5.06759e-06, -5.8514e-05, 6.93556e-07,
0514                3.87361e-07, 2.09743e-07, -4.8068e-05,  -1.4351e-06, 7.21617e-06,
0515                3.87361e-07, 1.61864e-06, -3.89113e-08, 5.41601e-06, 3.49367e-07,
0516                3.69039e-05, 2.09743e-07, -3.89113e-08, 3.38809e-06, 6.8792e-05,
0517                0.00501982,  0.189194,    -4.8068e-05,  5.41601e-06, 6.8792e-05,
0518                89875.7}),  // param cov
0519           makeVector<ActsScalar, 3>({-8.32767e-05 * 1000_T,
0520                                      1.42907e-05 * 1000_T,
0521                                      0.00191073 * 1000_T})),  // magnetic field
0522 
0523       TestData(
0524           makeVector<ActsScalar, 3>(
0525               {-522.319, -215.962, 1139.19}),  // surface center
0526           makeMatrix<ActsScalar, 3, 3>(
0527               {0.182174, 0.00473759, -0.983255, -0.982923, -0.0255617,
0528                -0.182236, -0.0259971, 0.999662, -2.22045e-16}),  // surface rot
0529           TestData::kPlane,
0530           makeVector<ActsScalar, eBoundSize>({-15.9238, -9.71785, -2.58798,
0531                                               0.458544, -0.490701,
0532                                               1263.01}),  // param_vec
0533           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0534               {0.000388298,  -0.00663415, -4.45582e-06, -2.98583e-06,
0535                -1.79271e-07, -0.00594178, -0.00663415,  0.28281,
0536                0.000192569,  3.50465e-05, 4.73666e-05,  0.253947,
0537                -4.45582e-06, 0.000192569, 4.58913e-07,  -3.91615e-07,
0538                3.05147e-07,  0.000170095, -2.98583e-06, 3.50465e-05,
0539                -3.91615e-07, 9.06356e-07, 1.00807e-08,  3.10251e-05,
0540                -1.79271e-07, 4.73666e-05, 3.05147e-07,  1.00807e-08,
0541                3.51684e-06,  4.83158e-06, -0.00594178,  0.253947,
0542                0.000170095,  3.10251e-05, 4.83158e-06,  89875.7}),  // param cov
0543           makeVector<ActsScalar, 3>({-5.25166e-05 * 1000_T,
0544                                      -2.12894e-05 * 1000_T,
0545                                      0.00191577 * 1000_T})),  // magnetic field
0546 
0547       TestData(
0548           makeVector<ActsScalar, 3>(
0549               {889.91, 463.263, 269.272}),  // surface center
0550           makeMatrix<ActsScalar, 3, 3>(
0551               {-0.28392, -0.00738357, 0.95882, 0.958496, 0.0249265, 0.284016,
0552                -0.0259971, 0.999662, -2.22045e-16}),  // surface rot
0553           TestData::kPlane,
0554           makeVector<ActsScalar, eBoundSize>({-31.3391, 22.7156, 0.668348,
0555                                               1.23223, -0.672912,
0556                                               887.012}),  // param_vec
0557           makeMatrix<ActsScalar, eBoundSize, eBoundSize>(
0558               {0.000401596,  -0.00580898,  3.84845e-06,
0559                1.07378e-05,  -7.00551e-06, -0.00176611,
0560                -0.00580898,  0.260857,     0.000203293,
0561                -0.000491391, 1.75445e-05,  0.0869615,
0562                3.84845e-06,  0.000203293,  2.13361e-06,
0563                -3.99989e-07, -1.30627e-06, 8.83175e-05,
0564                1.07378e-05,  -0.000491391, -3.99989e-07,
0565                3.41664e-06,  1.46081e-07,  -0.000166376,
0566                -7.00551e-06, 1.75445e-05,  -1.30627e-06,
0567                1.46081e-07,  2.06909e-05,  -0.000261632,
0568                -0.00176611,  0.0869615,    8.83175e-05,
0569                -0.000166376, -0.000261632, 89875.6}),  // param cov
0570           makeVector<ActsScalar, 3>({1.43009e-05 * 1000_T, 7.04031e-06 * 1000_T,
0571                                      0.00202663 * 1000_T}))  // magnetic field
0572 
0573   };
0574   if (mag_field_scale != 1.) {
0575     for (TestData &test_data : test_data_list) {
0576       test_data.bfield *= mag_field_scale;
0577     }
0578   }
0579   return test_data_list;
0580 }
0581 
0582 BOOST_AUTO_TEST_CASE(BoundToCurvilinearEigenStepper) {
0583   // Compare covariance in curvilinear parameterisation:
0584   // explicit computation vs. dummy propagation using EigenStepper
0585   std::vector<TestData> test_data_list(make_test_data());
0586   test_bound_to_curvilinear(
0587       test_data_list,
0588       [](const std::shared_ptr<Acts::MagneticFieldProvider> &bField) {
0589         return EigenStepper<>(bField);
0590       });
0591 }
0592 
0593 BOOST_AUTO_TEST_CASE(BoundToCurvilinearStraightLineStepper) {
0594   // Compare covariance in curvilinear parameterisation for vanishing magnetic
0595   // field: explicit computation vs. dummy propagation using StraightLineStepper
0596   std::vector<TestData> test_data_list(
0597       make_test_data(0.));  // scale magnetic field in test data to zero.
0598   test_bound_to_curvilinear(
0599       test_data_list,
0600       []([[maybe_unused]] const std::shared_ptr<Acts::MagneticFieldProvider>
0601              &bField) { return StraightLineStepper(); });
0602 }