Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2020 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/monomorphic.hpp>
0010 #include <boost/test/data/test_case.hpp>
0011 #include <boost/test/unit_test.hpp>
0012 
0013 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0014 #include "Acts/Utilities/detail/periodic.hpp"
0015 
0016 #include <cmath>
0017 #include <limits>
0018 #include <tuple>
0019 #include <utility>
0020 
0021 using Acts::detail::difference_periodic;
0022 using Acts::detail::normalizePhiTheta;
0023 using Acts::detail::radian_pos;
0024 using Acts::detail::radian_sym;
0025 namespace bd = boost::unit_test::data;
0026 
0027 namespace {
0028 constexpr auto tol = std::numeric_limits<double>::epsilon();
0029 }
0030 
0031 namespace {
0032 // Test dataset for periodic difference calculation, each entry is
0033 //
0034 //     lhs, rhs, periodic range, expected difference
0035 //
0036 constexpr std::tuple<double, double, double, double>
0037     kDifferencePeriodicDataset[] = {
0038         // lhs,rhs are exactly n periods apart
0039         {0.0, 1.0, 1.0, 0.0},
0040         {0.5, 1.5, 1.0, 0.0},
0041         {-1.5, 1.5, 1.0, 0.0},
0042         {0.0, 4.0, 1.0, 0.0},
0043         {0.5, 3.5, 1.0, 0.0},
0044         {-1.5, -125.5, 1.0, 0.0},
0045         // lhs,rhs are within one period and close together
0046         {0.75, 1.25, 2.0, -0.5},
0047         {4.25, 4.75, 2.0, -0.5},
0048         // lhs,rhs are within one period but far apart
0049         {0.25, 1.75, 2.0, 0.5},
0050         {-0.75, 0.75, 2.0, 0.5},
0051         // lhs,rhs are not within one period and close together
0052         {0.75, 5.25, 2.0, -0.5},
0053         {1.25, -2.5, 2.0, -0.25},
0054         // one of lhs,rhs is over the edge and close together
0055         {-0.25, +0.25, 2 * M_PI, -0.5},
0056         {+0.25, -0.25, 2 * M_PI, +0.5},
0057         {2 * M_PI - 0.25, 2 * M_PI + 0.25, 2 * M_PI, -0.5},
0058 };
0059 }  // namespace
0060 BOOST_DATA_TEST_CASE(DifferencePeriodic, bd::make(kDifferencePeriodicDataset),
0061                      lhs, rhs, range, diff) {
0062   CHECK_CLOSE_ABS(difference_periodic(lhs, rhs, range), diff, tol);
0063   CHECK_CLOSE_ABS(difference_periodic(rhs, lhs, range), -diff, tol);
0064 }
0065 
0066 BOOST_DATA_TEST_CASE(RadianPos, bd::xrange(0.25, M_PI, 0.5), delta) {
0067   // above upper limit folds back just above lower limit
0068   CHECK_CLOSE_ABS(radian_pos(0 - delta), 2 * M_PI - delta, tol);
0069   // below lower limit folds back just below upper limit
0070   CHECK_CLOSE_ABS(radian_pos(2 * M_PI + delta), delta, tol);
0071   // same as above but with additional 2pi shifts
0072   CHECK_CLOSE_ABS(radian_pos(-2 * M_PI - delta), 2 * M_PI - delta, tol);
0073   CHECK_CLOSE_ABS(radian_pos(4 * M_PI + delta), delta, tol);
0074 }
0075 
0076 BOOST_DATA_TEST_CASE(RadianSym, bd::xrange(0.25, M_PI, 0.5), delta) {
0077   // above upper limit folds back just above lower limit
0078   CHECK_CLOSE_ABS(radian_sym(-M_PI - delta), M_PI - delta, tol);
0079   // below lower limit folds back just below upper limit
0080   CHECK_CLOSE_ABS(radian_sym(M_PI + delta), -M_PI + delta, tol);
0081   // same as above but with additional 2pi shifts
0082   CHECK_CLOSE_ABS(radian_sym(-M_PI - delta - 2 * M_PI), M_PI - delta, tol);
0083   CHECK_CLOSE_ABS(radian_sym(M_PI + delta + 2 * M_PI), -M_PI + delta, tol);
0084 }
0085 
0086 BOOST_DATA_TEST_CASE(NormalizePhiThetaInBounds,
0087                      bd::xrange(-M_PI, M_PI, M_PI_2) *
0088                          bd::xrange(0.0, M_PI, M_PI_4),
0089                      phix, thetax) {
0090   // both phi and theta are in bounds and should remain unchanged
0091   auto [phi, theta] = normalizePhiTheta(phix, thetax);
0092   CHECK_CLOSE_ABS(phi, phix, tol);
0093   CHECK_CLOSE_ABS(theta, thetax, tol);
0094 }
0095 
0096 BOOST_DATA_TEST_CASE(NormalizePhiThetaCyclicPhi,
0097                      bd::xrange(0.25, M_PI, 0.5) *
0098                          bd::xrange(0.0, M_PI, M_PI_4),
0099                      deltaPhi, thetax) {
0100   // phi is outside bounds, but theta is within and should remain unchanged
0101   {
0102     // phi is too large
0103     auto [phi, theta] = normalizePhiTheta(M_PI + deltaPhi, thetax);
0104     CHECK_CLOSE_ABS(phi, -M_PI + deltaPhi, tol);
0105     CHECK_CLOSE_ABS(theta, thetax, tol);
0106   }
0107   {
0108     // phi is too small
0109     auto [phi, theta] = normalizePhiTheta(-M_PI - deltaPhi, thetax);
0110     CHECK_CLOSE_ABS(phi, M_PI - deltaPhi, tol);
0111     CHECK_CLOSE_ABS(theta, thetax, tol);
0112   }
0113 }
0114 
0115 BOOST_DATA_TEST_CASE(NormalizePhiThetaOutOfBoundsTheta,
0116                      bd::xrange(0.0, M_PI, 1.0) * bd::xrange(0.25, M_PI, 1.0),
0117                      positivePhi, deltaTheta) {
0118   // theta is outside bounds, both phi and theta are updated
0119   {
0120     // theta is too large
0121     auto [phi, theta] = normalizePhiTheta(positivePhi, M_PI + deltaTheta);
0122     CHECK_CLOSE_ABS(phi, -M_PI + positivePhi, tol);
0123     CHECK_CLOSE_ABS(theta, M_PI - deltaTheta, tol);
0124   }
0125   {
0126     // theta is too small
0127     auto [phi, theta] = normalizePhiTheta(positivePhi, 0.0 - deltaTheta);
0128     CHECK_CLOSE_ABS(phi, -M_PI + positivePhi, tol);
0129     CHECK_CLOSE_ABS(theta, deltaTheta, tol);
0130   }
0131 }