Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:56

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 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;  // Random x0 in [-50, 50]
0036   pars[p_y0] =
0037       static_cast<double>(rndEngine() % 1000) - 500;  // Random y0 in [-50, 50]
0038   pars[p_theta] = static_cast<double>(rndEngine() % 180) *
0039                   1_degree;  // Random theta in [0, 180)
0040   pars[p_phi] = static_cast<double>(rndEngine() % 360) *
0041                 1_degree;  // Random phi in [-180, 180)
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       /** Calculate the second order derivatives of the line partials */
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()