Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:02

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2025 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 #pragma once
0009 
0010 // Project include(s).
0011 #include "traccc/definitions/common.hpp"
0012 #include "traccc/definitions/math.hpp"
0013 #include "traccc/definitions/primitives.hpp"
0014 #include "traccc/definitions/qualifiers.hpp"
0015 
0016 /// @see
0017 /// https://github.com/acts-project/acts/blob/8098e6953ac35771c34a4e3b13dbfee50869a0c1/Core/include/Acts/Utilities/detail/periodic.hpp
0018 namespace traccc::detail {
0019 
0020 /// Wrap a periodic value back into the nominal range.
0021 TRACCC_HOST_DEVICE
0022 constexpr traccc::scalar wrap_periodic(traccc::scalar value,
0023                                        traccc::scalar start,
0024                                        traccc::scalar range) {
0025   // only wrap if really necessary
0026   const traccc::scalar diff{value - start};
0027   return ((0 <= diff) && (diff < range))
0028              ? value
0029              : (value - range * math::floor(diff / range));
0030 }
0031 
0032 /// Calculate the equivalent angle in the [-pi, pi) range.
0033 TRACCC_HOST_DEVICE
0034 constexpr traccc::scalar wrap_phi(traccc::scalar phi) {
0035   constexpr traccc::scalar PI{traccc::constant<traccc::scalar>::pi};
0036   constexpr traccc::scalar TWOPI{2.f * traccc::constant<traccc::scalar>::pi};
0037   return wrap_periodic(phi, -PI, TWOPI);
0038 }
0039 
0040 /// Calculate the equivalent angle in the [0, 2*pi) range.
0041 TRACCC_HOST_DEVICE
0042 constexpr traccc::scalar wrap_theta(traccc::scalar theta) {
0043   constexpr traccc::scalar TWOPI{2.f * traccc::constant<traccc::scalar>::pi};
0044   return wrap_periodic(theta, 0.f, TWOPI);
0045 }
0046 
0047 /// Ensure both phi and theta direction angles are within the allowed range.
0048 ///
0049 /// @param[in] phi Transverse direction angle
0050 /// @param[in] theta Longitudinal direction angle
0051 /// @return pair<phi,theta> containing the updated angles
0052 ///
0053 /// The phi angle is truly cyclic, i.e. all values outside the nominal range
0054 /// [-pi,pi) have a corresponding value inside nominal range, independent from
0055 /// the theta angle. The theta angle is more complicated. Imagine that the two
0056 /// angles describe a position on the unit sphere. If theta moves outside its
0057 /// nominal range [0,pi], we are moving over one of the two poles of the unit
0058 /// sphere along the great circle defined by phi. The angles still describe a
0059 /// valid position on the unit sphere, but to describe it with angles within
0060 /// their nominal range, both phi and theta need to be updated; when moving over
0061 /// the poles, phi needs to be flipped by 180degree to allow theta to remain
0062 /// within its nominal range.
0063 constexpr std::pair<traccc::scalar, traccc::scalar> wrap_phi_theta(
0064     traccc::scalar phi, traccc::scalar theta) {
0065   constexpr traccc::scalar PI{traccc::constant<traccc::scalar>::pi};
0066   constexpr traccc::scalar TWOPI{2.f * traccc::constant<traccc::scalar>::pi};
0067 
0068   // wrap to [0,2pi). while the nominal range of theta is [0,pi], it is
0069   // periodic, i.e. describes identical positions, in the full [0,2pi) range.
0070   // moving it first to the periodic range simplifies further steps as the
0071   // possible range of theta becomes fixed.
0072   theta = wrap_theta(theta);
0073   if (PI < theta) {
0074     // theta is in the second half of the great circle and outside its
0075     // nominal range. need to change both phi and theta to be within range.
0076     phi += PI;
0077     theta = TWOPI - theta;
0078   }
0079 
0080   return {wrap_phi(phi), theta};
0081 }
0082 
0083 }  // namespace traccc::detail