Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:25:19

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/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 /// The random number generator used in the framework.
0025 using RandomEngine = std::mt19937;  ///< Mersenne Twister
0026 
0027 ParamVector makeTrack(RandomEngine& rndEngine) {
0028   ParamVector pars{};
0029   pars[toUnderlying(ParIndices::x0)] =
0030       std::uniform_real_distribution{-500., 500.}(rndEngine);
0031   pars[toUnderlying(ParIndices::y0)] =
0032       std::uniform_real_distribution{-500., 500.}(rndEngine);
0033   pars[toUnderlying(ParIndices::theta)] =
0034       std::uniform_real_distribution{0.1_degree, 179.9_degree}(rndEngine);
0035   pars[toUnderlying(ParIndices::phi)] =
0036       std::uniform_real_distribution{-180_degree, 180_degree}(rndEngine);
0037   return pars;
0038 }
0039 
0040 namespace ActsTests {
0041 
0042 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0043 
0044 BOOST_AUTO_TEST_CASE(lineParameterTest) {
0045   constexpr std::size_t trials = 1000;
0046   constexpr double tolerance = 1.e-12;
0047   RandomEngine rndEngine{3585};
0048   for (std::size_t i = 0; i < trials; ++i) {
0049     auto pars = makeTrack(rndEngine);
0050     Line_t newLine{pars};
0051     BOOST_CHECK_CLOSE(newLine.position()[Acts::eX],
0052                       pars[toUnderlying(ParIndices::x0)], tolerance);
0053     BOOST_CHECK_CLOSE(newLine.position()[Acts::eY],
0054                       pars[toUnderlying(ParIndices::y0)], tolerance);
0055     BOOST_CHECK_LE(newLine.position()[Acts::eZ], tolerance);
0056     const Acts::Vector3 dir =
0057         Acts::makeDirectionFromPhiTheta(pars[toUnderlying(ParIndices::phi)],
0058                                         pars[toUnderlying(ParIndices::theta)]);
0059     BOOST_CHECK_CLOSE(newLine.direction().dot(dir), 1., tolerance);
0060   }
0061 }
0062 BOOST_AUTO_TEST_CASE(lineGradientTest) {
0063   constexpr std::size_t trials = 1000;
0064   RandomEngine rndEngine{26934};
0065   constexpr double h = 1.e-8;
0066   constexpr double tolerance = 1.e-7;
0067   for (std::size_t trial = 0; trial < trials; ++trial) {
0068     const ParamVector pars{makeTrack(rndEngine)};
0069     std::cout << "lineGradientTest -- Generated parameters  x: "
0070               << pars[toUnderlying(ParIndices::x0)]
0071               << ", y: " << pars[toUnderlying(ParIndices::y0)] << ", theta: "
0072               << (pars[toUnderlying(ParIndices::theta)] / 1_degree)
0073               << ", phi: " << (pars[toUnderlying(ParIndices::phi)] / 1_degree)
0074               << std::endl;
0075     Line_t segLine{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     /// check that the returned parameters correspond to the parsed one
0082     const ParamVector parsFromL = segLine.parameters();
0083     BOOST_CHECK_CLOSE(parsFromL[toUnderlying(ParIndices::x0)],
0084                       pars[toUnderlying(ParIndices::x0)], tolerance);
0085     BOOST_CHECK_CLOSE(parsFromL[toUnderlying(ParIndices::y0)],
0086                       pars[toUnderlying(ParIndices::y0)], tolerance);
0087     BOOST_CHECK_CLOSE(parsFromL[toUnderlying(ParIndices::theta)],
0088                       pars[toUnderlying(ParIndices::theta)], tolerance);
0089     BOOST_CHECK_CLOSE(parsFromL[toUnderlying(ParIndices::phi)],
0090                       pars[toUnderlying(ParIndices::phi)], tolerance);
0091 
0092     for (const auto param : {ParIndices::theta, ParIndices::phi}) {
0093       ParamVector parsUp{pars}, parsDn{pars};
0094       parsUp[toUnderlying(param)] += h;
0095       parsDn[toUnderlying(param)] -= h;
0096       Line_t segLineUp{parsUp}, segLineDn{parsDn};
0097 
0098       const Vector3 numDeriv{(segLineUp.direction() - segLineDn.direction()) /
0099                              (2. * h)};
0100       BOOST_CHECK_LE((numDeriv - segLine.gradient(param)).norm(), tolerance);
0101       /** Calculate the second order derivatives of the line partials */
0102       for (const auto param1 : {ParIndices::theta, ParIndices::phi,
0103                                 ParIndices::x0, ParIndices::y0}) {
0104         ParamVector parsUp1{pars}, parsDn1{pars};
0105         parsUp1[toUnderlying(param1)] += h;
0106         parsDn1[toUnderlying(param1)] -= h;
0107 
0108         segLineUp.updateParameters(parsUp1);
0109         segLineDn.updateParameters(parsDn1);
0110 
0111         const Vector3 numDeriv1{
0112             (segLineUp.gradient(param) - segLineDn.gradient(param)) / (2. * h)};
0113         const Vector3& analyticDeriv = segLine.hessian(param, param1);
0114         BOOST_CHECK_LE((numDeriv1 - analyticDeriv).norm(), tolerance);
0115       }
0116     }
0117   }
0118 }
0119 BOOST_AUTO_TEST_SUITE_END()
0120 
0121 }  // namespace ActsTests