1 | // -*- C++ -*-
|
---|
2 | //
|
---|
3 | // This file is part of HepMC
|
---|
4 | // Copyright (C) 2014-2020 The HepMC collaboration (see AUTHORS for details)
|
---|
5 | //
|
---|
6 | #ifndef HEPMC3_FOURVECTOR_H
|
---|
7 | #define HEPMC3_FOURVECTOR_H
|
---|
8 | /**
|
---|
9 | * @file FourVector.h
|
---|
10 | * @brief Definition of \b class FourVector
|
---|
11 | */
|
---|
12 | #include <cmath>
|
---|
13 | #ifndef M_PI
|
---|
14 | /** @brief Definition of PI. Needed on some platforms */
|
---|
15 | #define M_PI 3.14159265358979323846264338327950288
|
---|
16 | #endif
|
---|
17 | namespace HepMC3 {
|
---|
18 |
|
---|
19 |
|
---|
20 | /**
|
---|
21 | * @brief Generic 4-vector
|
---|
22 | *
|
---|
23 | * Interpretation of its content depends on accessors used: it's much simpler to do this
|
---|
24 | * than to distinguish between space and momentum vectors via the type system (especially
|
---|
25 | * given the need for backward compatibility with HepMC2). Be sensible and don't call
|
---|
26 | * energy functions on spatial vectors! To avoid duplication, most definitions are only
|
---|
27 | * implemented on the spatial function names, with the energy-momentum functions as aliases.
|
---|
28 | *
|
---|
29 | * This is @a not intended to be a fully featured 4-vector, but does contain the majority
|
---|
30 | * of common non-boosting functionality, as well as a few support operations on
|
---|
31 | * 4-vectors.
|
---|
32 | *
|
---|
33 | * The implementations in this class are fully inlined.
|
---|
34 | */
|
---|
35 | class FourVector {
|
---|
36 | public:
|
---|
37 |
|
---|
38 | /** @brief Default constructor */
|
---|
39 | FourVector()
|
---|
40 | : m_v1(0.0), m_v2(0.0), m_v3(0.0), m_v4(0.0) {}
|
---|
41 | /** @brief Sets all FourVector fields */
|
---|
42 | FourVector(double xx, double yy, double zz, double ee)
|
---|
43 | : m_v1(xx), m_v2(yy), m_v3(zz), m_v4(ee) {}
|
---|
44 | /** @brief Copy constructor */
|
---|
45 | FourVector(const FourVector & v)
|
---|
46 | : m_v1(v.m_v1), m_v2(v.m_v2), m_v3(v.m_v3), m_v4(v.m_v4) {}
|
---|
47 |
|
---|
48 |
|
---|
49 | /// @name Component accessors
|
---|
50 | //@{
|
---|
51 |
|
---|
52 | /** @brief Set all FourVector fields, in order x,y,z,t */
|
---|
53 | void set(double x1, double x2, double x3, double x4) {
|
---|
54 | m_v1 = x1;
|
---|
55 | m_v2 = x2;
|
---|
56 | m_v3 = x3;
|
---|
57 | m_v4 = x4;
|
---|
58 | }
|
---|
59 |
|
---|
60 | /// set component of position/displacement
|
---|
61 | void set_component(const int i, const double x)
|
---|
62 | {
|
---|
63 | if (i==0) {m_v1=x; return; }
|
---|
64 | if (i==1) {m_v2=x; return; }
|
---|
65 | if (i==2) {m_v3=x; return; }
|
---|
66 | if (i==3) {m_v4=x; return; }
|
---|
67 | }
|
---|
68 | /// get component of position/displacement
|
---|
69 | double get_component(const int i) const
|
---|
70 | {
|
---|
71 | if (i==0) return m_v1;
|
---|
72 | if (i==1) return m_v2;
|
---|
73 | if (i==2) return m_v3;
|
---|
74 | if (i==3) return m_v4;
|
---|
75 | return 0.0;
|
---|
76 | }
|
---|
77 |
|
---|
78 |
|
---|
79 | /// x-component of position/displacement
|
---|
80 | double x() const { return m_v1; }
|
---|
81 | /// Set x-component of position/displacement
|
---|
82 | void set_x(double xx) { m_v1 = xx; }
|
---|
83 | /// @deprecated Prefer the HepMC-style set_x() function
|
---|
84 | void setX(double xx) { set_x(xx); }
|
---|
85 |
|
---|
86 | /// y-component of position/displacement
|
---|
87 | double y() const { return m_v2; }
|
---|
88 | /// Set y-component of position/displacement
|
---|
89 | void set_y(double yy) { m_v2 = yy; }
|
---|
90 | /// @deprecated Prefer the HepMC-style set_y() function
|
---|
91 | void setY(double yy) { set_y(yy); }
|
---|
92 |
|
---|
93 | /// z-component of position/displacement
|
---|
94 | double z() const { return m_v3; }
|
---|
95 | /// Set z-component of position/displacement
|
---|
96 | void set_z(double zz) { m_v3 = zz; }
|
---|
97 | /// @deprecated Prefer the HepMC-style set_z() function
|
---|
98 | void setZ(double zz) { set_z(zz); }
|
---|
99 |
|
---|
100 | /// Time component of position/displacement
|
---|
101 | double t() const { return m_v4; }
|
---|
102 | /// Set time component of position/displacement
|
---|
103 | void set_t(double tt) { m_v4 = tt; }
|
---|
104 | /// @deprecated Prefer the HepMC-style set_t() function
|
---|
105 | void setT(double tt) { set_t(tt); }
|
---|
106 |
|
---|
107 |
|
---|
108 | /// x-component of momentum
|
---|
109 | double px() const { return x(); }
|
---|
110 | /// Set x-component of momentum
|
---|
111 | void set_px(double pxx) { set_x(pxx); }
|
---|
112 | /// @deprecated Prefer the HepMC-style set_px() function
|
---|
113 | void setPx(double pxx) { set_px(pxx); }
|
---|
114 |
|
---|
115 | /// y-component of momentum
|
---|
116 | double py() const { return y(); }
|
---|
117 | /// Set y-component of momentum
|
---|
118 | void set_py(double pyy) { set_y(pyy); }
|
---|
119 | /// @deprecated Prefer the HepMC-style set_py() function
|
---|
120 | void setPy(double pyy) { set_py(pyy); }
|
---|
121 |
|
---|
122 | /// z-component of momentum
|
---|
123 | double pz() const { return z(); }
|
---|
124 | /// Set z-component of momentum
|
---|
125 | void set_pz(double pzz) { set_z(pzz); }
|
---|
126 | /// @deprecated Prefer the HepMC-style set_pz() function
|
---|
127 | void setPz(double pzz) { set_pz(pzz); }
|
---|
128 |
|
---|
129 | /// Energy component of momentum
|
---|
130 | double e() const { return t(); }
|
---|
131 | /// Set energy component of momentum
|
---|
132 | void set_e(double ee ) { this->set_t(ee); }
|
---|
133 | /// @deprecated Prefer the HepMC-style set_y() function
|
---|
134 | void setE(double ee) { set_e(ee); }
|
---|
135 |
|
---|
136 | //@}
|
---|
137 |
|
---|
138 |
|
---|
139 | /// @name Computed properties
|
---|
140 | //@{
|
---|
141 |
|
---|
142 | /// Squared magnitude of (x, y, z) 3-vector
|
---|
143 | double length2() const { return x()*x() + y()*y() + z()*z(); }
|
---|
144 | /// Magnitude of spatial (x, y, z) 3-vector
|
---|
145 | double length() const { return sqrt(length2()); }
|
---|
146 | /// Squared magnitude of (x, y) vector
|
---|
147 | double perp2() const { return x()*x() + y()*y(); }
|
---|
148 | /// Magnitude of (x, y) vector
|
---|
149 | double perp() const { return sqrt(perp2()); }
|
---|
150 | /// Spacetime invariant interval s^2 = t^2 - x^2 - y^2 - z^2
|
---|
151 | double interval() const { return t()*t() - length2(); }
|
---|
152 |
|
---|
153 | /// Squared magnitude of p3 = (px, py, pz) vector
|
---|
154 | double p3mod2() const { return length2(); }
|
---|
155 | /// Magnitude of p3 = (px, py, pz) vector
|
---|
156 | double p3mod() const { return length(); }
|
---|
157 | /// Squared transverse momentum px^2 + py^2
|
---|
158 | double pt2() const { return perp2(); }
|
---|
159 | /// Transverse momentum
|
---|
160 | double pt() const { return perp(); }
|
---|
161 | /// Squared invariant mass m^2 = E^2 - px^2 - py^2 - pz^2
|
---|
162 | double m2() const { return interval(); }
|
---|
163 | /// Invariant mass. Returns -sqrt(-m) if e^2 - P^2 is negative
|
---|
164 | double m() const { return (m2() > 0.0) ? std::sqrt(m2()) : -std::sqrt(-m2()); }
|
---|
165 |
|
---|
166 | /// Azimuthal angle
|
---|
167 | double phi() const { return atan2( y(), x() ); }
|
---|
168 | /// Polar angle w.r.t. z direction
|
---|
169 | double theta() const { return atan2( perp(), z() ); }
|
---|
170 | // /// Cosine of polar angle w.r.t. z direction
|
---|
171 | // double costheta() const { return z() / p3mod(); }
|
---|
172 | /// Pseudorapidity
|
---|
173 | double eta() const { return 0.5*std::log( (p3mod() + pz()) / (p3mod() - pz()) ); }
|
---|
174 | /// Rapidity
|
---|
175 | double rap() const { return 0.5*std::log( (e() + pz()) / (e() - pz()) ); }
|
---|
176 | /// Absolute pseudorapidity
|
---|
177 | double abs_eta() const { return std::abs( eta() ); }
|
---|
178 | /// Absolute rapidity
|
---|
179 | double abs_rap() const { return std::abs( rap() ); }
|
---|
180 |
|
---|
181 | /// Same as eta()
|
---|
182 | /// @deprecated Prefer 'only one way to do it', and we don't have equivalent long names for e.g. pid, phi or eta
|
---|
183 | double pseudoRapidity() const { return eta(); }
|
---|
184 |
|
---|
185 | //@}
|
---|
186 |
|
---|
187 |
|
---|
188 | /// @name Comparisons to another FourVector
|
---|
189 | //@{
|
---|
190 |
|
---|
191 | /// Check if the length of this vertex is zero
|
---|
192 | bool is_zero() const { return x() == 0 && y() == 0 && z() == 0 && t() == 0; }
|
---|
193 |
|
---|
194 | /// Signed azimuthal angle separation in [-pi, pi]
|
---|
195 | double delta_phi(const FourVector &v) const {
|
---|
196 | double dphi = phi() - v.phi();
|
---|
197 | if (dphi != dphi) return dphi;
|
---|
198 | while (dphi >= M_PI) dphi -= 2.*M_PI;
|
---|
199 | while (dphi < -M_PI) dphi += 2.*M_PI;
|
---|
200 | return dphi;
|
---|
201 | }
|
---|
202 |
|
---|
203 | /// Pseudorapidity separation
|
---|
204 | double delta_eta(const FourVector &v) const { return eta() - v.eta(); }
|
---|
205 |
|
---|
206 | /// Rapidity separation
|
---|
207 | double delta_rap(const FourVector &v) const { return rap() - v.rap(); }
|
---|
208 |
|
---|
209 | /// R_eta^2-distance separation dR^2 = dphi^2 + deta^2
|
---|
210 | double delta_r2_eta(const FourVector &v) const {
|
---|
211 | return delta_phi(v)*delta_phi(v) + delta_eta(v)*delta_eta(v);
|
---|
212 | }
|
---|
213 |
|
---|
214 | /// R_eta-distance separation dR = sqrt(dphi^2 + deta^2)
|
---|
215 | double delta_r_eta(const FourVector &v) const {
|
---|
216 | return sqrt( delta_r2_eta(v) );
|
---|
217 | }
|
---|
218 |
|
---|
219 | /// R_rap^2-distance separation dR^2 = dphi^2 + drap^2
|
---|
220 | double delta_r2_rap(const FourVector &v) const {
|
---|
221 | return delta_phi(v)*delta_phi(v) + delta_rap(v)*delta_rap(v);
|
---|
222 | }
|
---|
223 |
|
---|
224 | /// R-rap-distance separation dR = sqrt(dphi^2 + drap^2)
|
---|
225 | double delta_r_rap(const FourVector &v) const {
|
---|
226 | return sqrt( delta_r2_rap(v) );
|
---|
227 | }
|
---|
228 |
|
---|
229 | //@}
|
---|
230 |
|
---|
231 |
|
---|
232 | /// @name Operators
|
---|
233 | //@{
|
---|
234 |
|
---|
235 | /// Equality
|
---|
236 | bool operator==(const FourVector& rhs) const {
|
---|
237 | return x() == rhs.x() && y() == rhs.y() && z() == rhs.z() && t() == rhs.t();
|
---|
238 | }
|
---|
239 | /// Inequality
|
---|
240 | bool operator!=(const FourVector& rhs) const { return !(*this == rhs); }
|
---|
241 |
|
---|
242 | /// Arithmetic operator +
|
---|
243 | FourVector operator+ (const FourVector& rhs) const {
|
---|
244 | return FourVector( x() + rhs.x(), y() + rhs.y(), z() + rhs.z(), t() + rhs.t() );
|
---|
245 | }
|
---|
246 | /// Arithmetic operator -
|
---|
247 | FourVector operator- (const FourVector& rhs) const {
|
---|
248 | return FourVector( x() - rhs.x(), y() - rhs.y(), z() - rhs.z(), t() - rhs.t() );
|
---|
249 | }
|
---|
250 | /// Arithmetic operator * by scalar
|
---|
251 | FourVector operator* (const double rhs) const {
|
---|
252 | return FourVector( x()*rhs, y()*rhs, z()*rhs, t()*rhs );
|
---|
253 | }
|
---|
254 | /// Arithmetic operator / by scalar
|
---|
255 | FourVector operator/ (const double rhs) const {
|
---|
256 | return FourVector( x()/rhs, y()/rhs, z()/rhs, t()/rhs );
|
---|
257 | }
|
---|
258 |
|
---|
259 | /// Arithmetic operator +=
|
---|
260 | void operator += (const FourVector& rhs) {
|
---|
261 | setX(x() + rhs.x());
|
---|
262 | setY(y() + rhs.y());
|
---|
263 | setZ(z() + rhs.z());
|
---|
264 | setT(t() + rhs.t());
|
---|
265 | }
|
---|
266 | /// Arithmetic operator -=
|
---|
267 | void operator -= (const FourVector& rhs) {
|
---|
268 | setX(x() - rhs.x());
|
---|
269 | setY(y() - rhs.y());
|
---|
270 | setZ(z() - rhs.z());
|
---|
271 | setT(t() - rhs.t());
|
---|
272 | }
|
---|
273 | /// Arithmetic operator *= by scalar
|
---|
274 | void operator *= (const double rhs) {
|
---|
275 | setX(x()*rhs);
|
---|
276 | setY(y()*rhs);
|
---|
277 | setZ(z()*rhs);
|
---|
278 | setT(t()*rhs);
|
---|
279 | }
|
---|
280 | /// Arithmetic operator /= by scalar
|
---|
281 | void operator /= (const double rhs) {
|
---|
282 | setX(x()/rhs);
|
---|
283 | setY(y()/rhs);
|
---|
284 | setZ(z()/rhs);
|
---|
285 | setT(t()/rhs);
|
---|
286 | }
|
---|
287 |
|
---|
288 | //@}
|
---|
289 |
|
---|
290 |
|
---|
291 | /// Static null FourVector = (0,0,0,0)
|
---|
292 | static const FourVector& ZERO_VECTOR() {
|
---|
293 | static const FourVector v;
|
---|
294 | return v;
|
---|
295 | }
|
---|
296 |
|
---|
297 |
|
---|
298 | private:
|
---|
299 |
|
---|
300 | double m_v1; ///< px or x. Interpretation depends on accessors used
|
---|
301 | double m_v2; ///< py or y. Interpretation depends on accessors used
|
---|
302 | double m_v3; ///< pz or z. Interpretation depends on accessors used
|
---|
303 | double m_v4; ///< e or t. Interpretation depends on accessors used
|
---|
304 |
|
---|
305 | };
|
---|
306 |
|
---|
307 |
|
---|
308 | /// @name Unbound vector comparison functions
|
---|
309 | //@{
|
---|
310 |
|
---|
311 | /// Signed azimuthal angle separation in [-pi, pi] between vecs @c a and @c b
|
---|
312 | inline double delta_phi(const FourVector &a, const FourVector &b) { return b.delta_phi(a); }
|
---|
313 |
|
---|
314 | /// Pseudorapidity separation between vecs @c a and @c b
|
---|
315 | inline double delta_eta(const FourVector &a, const FourVector &b) { return b.delta_eta(a); }
|
---|
316 |
|
---|
317 | /// Rapidity separation between vecs @c a and @c b
|
---|
318 | inline double delta_rap(const FourVector &a, const FourVector &b) { return b.delta_rap(a); }
|
---|
319 |
|
---|
320 | /// R_eta^2-distance separation dR^2 = dphi^2 + deta^2 between vecs @c a and @c b
|
---|
321 | inline double delta_r2_eta(const FourVector &a, const FourVector &b) { return b.delta_r2_eta(a); }
|
---|
322 |
|
---|
323 | /// R_eta-distance separation dR = sqrt(dphi^2 + deta^2) between vecs @c a and @c b
|
---|
324 | inline double delta_r_eta(const FourVector &a, const FourVector &b) { return b.delta_r_eta(a); }
|
---|
325 |
|
---|
326 | /// R_rap^2-distance separation dR^2 = dphi^2 + drap^2 between vecs @c a and @c b
|
---|
327 | inline double delta_r2_rap(const FourVector &a, const FourVector &b) { return b.delta_r2_rap(a); }
|
---|
328 |
|
---|
329 | /// R_rap-distance separation dR = sqrt(dphi^2 + drap^2) between vecs @c a and @c b
|
---|
330 | inline double delta_r_rap(const FourVector &a, const FourVector &b) { return b.delta_r_rap(a); }
|
---|
331 |
|
---|
332 | //@}
|
---|
333 |
|
---|
334 |
|
---|
335 | } // namespace HepMC3
|
---|
336 |
|
---|
337 |
|
---|
338 | #endif
|
---|