ATLAS Offline Software
Loading...
Searching...
No Matches
phihelper.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
10#ifndef CXXUTILS_PHIHELPER_H
11#define CXXUTILS_PHIHELPER_H
12
13#include <climits>
14#include <numbers>
15#include <concepts>
16#include <cmath>
17
18namespace CxxUtils {
19
30 template <std::floating_point T>
31 inline constexpr T wrapToPi(T phi)
32 {
33 constexpr T TWOPI = 2*std::numbers::pi_v<T>;
34 constexpr T INV2PI = std::numbers::inv_pi_v<T>/2;
35 T x = phi * INV2PI;
36
37 // Round x to the nearest integer.
38 // https://stackoverflow.com/questions/17035464/a-fast-method-to-round-a-double-to-a-32-bit-int-explained
39 static_assert (std::numeric_limits<T>::digits/2 <= sizeof (long int) * CHAR_BIT);
40 // Break up the exponent into two pieces to avoid overflowing a long int
41 // for an ARM long double with 113 mantissa bits.
42 constexpr T TOINT = 0x1.8p0 *
43 (1ull<<(std::numeric_limits<T>::digits/2)) *
44 (1ull<<(std::numeric_limits<T>::digits-1-std::numeric_limits<T>::digits/2));
45 T ix = (x + TOINT) - TOINT;
46
47 // Above gives banker's rounding; that is, halves round to even integers.
48 // However, to get the cases of phi=Npi right, we want halves to round
49 // towards zero. Fix up the rounding in that case. Is there a
50 // better way of doing this?
51 T diff = ix - x;
52 if (std::abs(diff) == 0.5) {
53 if (ix > 0) --ix;
54 else if (ix < 0) ++ix;
55 }
56
57 return phi - TWOPI*ix;
58 }
59
63 template <std::floating_point T>
64 inline constexpr T deltaPhi(T phiA, T phiB)
65 {
66 return wrapToPi(phiA - phiB);
67 }
68
80 template <std::floating_point T>
81 inline constexpr T phiMean(T phiA, T phiB)
82 {
83 const T diff = wrapToPi(phiA - phiB);
84 return wrapToPi(phiB + 0.5 * diff);
85 }
86
96 template <std::floating_point T>
97 inline constexpr T phiBisect(T phiA, T phiB)
98 {
99 T phi = 0.5 * (phiA + phiB);
100 if (phiA > phiB) phi += std::numbers::pi;
101 return wrapToPi(phi);
102 }
103
104} // namespace CxxUtils
105
106#endif
Scalar phi() const
phi method
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
#define x
constexpr T deltaPhi(T phiA, T phiB)
Return difference phiA - phiB in range [-pi, pi].
Definition phihelper.h:64
constexpr T phiBisect(T phiA, T phiB)
Bisect (average) the angle spanned by phiA and phiB.
Definition phihelper.h:97
constexpr T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition phihelper.h:31
constexpr T phiMean(T phiA, T phiB)
Calculate average of two angles.
Definition phihelper.h:81