[95a917c] | 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
|
---|