File indexing completed on 2025-08-05 08:09:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Utilities/StringHelpers.hpp"
0013 #include "Acts/Utilities/UnitVectors.hpp"
0014 #include "Acts/Utilities/detail/Line3DWithPartialDerivatives.hpp"
0015
0016 #include <random>
0017
0018 using namespace Acts;
0019 using namespace Acts::detail;
0020 using Line_t = Line3DWithPartialDerivatives<double>;
0021 using ParamVector = Line_t::ParamVector;
0022 using ParIndices = Line_t::ParIndex;
0023 using namespace Acts::UnitLiterals;
0024
0025 using RandomEngine = std::mt19937;
0026
0027 constexpr auto p_x0 = static_cast<std::size_t>(ParIndices::x0);
0028 constexpr auto p_y0 = static_cast<std::size_t>(ParIndices::y0);
0029 constexpr auto p_theta = static_cast<std::size_t>(ParIndices::theta);
0030 constexpr auto p_phi = static_cast<std::size_t>(ParIndices::phi);
0031
0032 ParamVector makeTrack(RandomEngine& rndEngine) {
0033 ParamVector pars{};
0034 pars[p_x0] =
0035 static_cast<double>(rndEngine() % 1000) - 500;
0036 pars[p_y0] =
0037 static_cast<double>(rndEngine() % 1000) - 500;
0038 pars[p_theta] = static_cast<double>(rndEngine() % 180) *
0039 1_degree;
0040 pars[p_phi] = static_cast<double>(rndEngine() % 360) *
0041 1_degree;
0042 return pars;
0043 }
0044
0045 BOOST_AUTO_TEST_SUITE(LineWithPartialTests)
0046
0047 BOOST_AUTO_TEST_CASE(lineParameterTest) {
0048 Line_t newLine{};
0049 constexpr std::size_t trials = 1000;
0050 constexpr double tolerance = 1.e-12;
0051 RandomEngine rndEngine{3585};
0052 for (std::size_t i = 0; i < trials; ++i) {
0053 auto pars = makeTrack(rndEngine);
0054 newLine.updateParameters(pars);
0055 BOOST_CHECK_CLOSE(newLine.position()[Acts::eX], pars[p_x0], tolerance);
0056 BOOST_CHECK_CLOSE(newLine.position()[Acts::eY], pars[p_y0], tolerance);
0057 BOOST_CHECK_LE(newLine.position()[Acts::eZ], tolerance);
0058 const Acts::Vector3 dir =
0059 Acts::makeDirectionFromPhiTheta(pars[p_phi], pars[p_theta]);
0060 BOOST_CHECK_CLOSE(newLine.direction().dot(dir), 1., tolerance);
0061 }
0062 }
0063 BOOST_AUTO_TEST_CASE(lineGradientTest) {
0064 constexpr std::size_t trials = 1000;
0065 RandomEngine rndEngine{26934};
0066 constexpr double h = 1.e-8;
0067 constexpr double tolerance = 1.e-7;
0068 for (std::size_t trial = 0; trial < trials; ++trial) {
0069 const ParamVector pars{makeTrack(rndEngine)};
0070 std::cout << "lineGradientTest -- Generated parameters x: " << pars[p_x0]
0071 << ", y: " << pars[p_y0]
0072 << ", theta: " << (pars[p_theta] / 1_degree)
0073 << ", phi: " << (pars[p_phi] / 1_degree) << std::endl;
0074 Line_t segLine{};
0075 segLine.updateParameters(pars);
0076
0077 BOOST_CHECK_LE((segLine.gradient(ParIndices::x0) - Vector3::UnitX()).norm(),
0078 tolerance);
0079 BOOST_CHECK_LE((segLine.gradient(ParIndices::y0) - Vector3::UnitY()).norm(),
0080 tolerance);
0081
0082 for (const auto param : {ParIndices::theta, ParIndices::phi}) {
0083 ParamVector parsUp{pars}, parsDn{pars};
0084 parsUp[static_cast<std::size_t>(param)] += h;
0085 parsDn[static_cast<std::size_t>(param)] -= h;
0086 Line_t segLineUp{}, segLineDn{};
0087 segLineUp.updateParameters(parsUp);
0088 segLineDn.updateParameters(parsDn);
0089
0090 const Vector3 numDeriv{(segLineUp.direction() - segLineDn.direction()) /
0091 (2. * h)};
0092 BOOST_CHECK_LE((numDeriv - segLine.gradient(param)).norm(), tolerance);
0093
0094 for (const auto param1 : {ParIndices::theta, ParIndices::phi,
0095 ParIndices::x0, ParIndices::y0}) {
0096 ParamVector parsUp1{pars}, parsDn1{pars};
0097 parsUp1[static_cast<std::size_t>(param1)] += h;
0098 parsDn1[static_cast<std::size_t>(param1)] -= h;
0099
0100 segLineUp.updateParameters(parsUp1);
0101 segLineDn.updateParameters(parsDn1);
0102
0103 const Vector3 numDeriv1{
0104 (segLineUp.gradient(param) - segLineDn.gradient(param)) / (2. * h)};
0105 const Vector3& analyticDeriv = segLine.hessian(param, param1);
0106 BOOST_CHECK_LE((numDeriv1 - analyticDeriv).norm(), tolerance);
0107 }
0108 }
0109 }
0110 }
0111 BOOST_AUTO_TEST_SUITE_END()