Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FourMomentum.cc
Go to the documentation of this file.
1 ///
2 /// @file FourMomentum.cc
3 /// @brief Hammer four momentum class
4 ///
5 
6 //**** This file is a part of the HAMMER library
7 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
8 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
9 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
10 
11 // -*- C++ -*-
12 #include <cmath>
13 #include <string>
14 
15 #include "Hammer/Exceptions.hh"
16 #include "Hammer/Math/Utils.hh"
19 
20 using namespace std;
21 
22 namespace Hammer {
23 
24  FourMomentum::FourMomentum() : _vec{{0., 0., 0., 0.}} {
25  }
26 
27  // set the four momentum in format FourMomentum({E,px,py,pz})
28  FourMomentum::FourMomentum(const array<double, 4>& other) : _vec(other) {
29  }
30 
31  // set the four momentum coordinates
32  FourMomentum::FourMomentum(const double E, const double px,
33  const double py, const double pz) : _vec{{E, px, py, pz}} {
34  }
35 
36  FourMomentum& FourMomentum::setE(double E) {
37  _vec[0] = E;
38  return *this;
39  }
40  FourMomentum& FourMomentum::setPx(double px) {
41  _vec[1] = px;
42  return *this;
43  }
44 
45  FourMomentum& FourMomentum::setPy(double py) {
46  _vec[2] = py;
47  return *this;
48  }
49 
50  FourMomentum& FourMomentum::setPz(double pz) {
51  _vec[3] = pz;
52  return *this;
53  }
54 
55  FourMomentum FourMomentum::fromPM(double px, double py, double pz, double mass) {
56  return FourMomentum{sqrt(px * px + py * py + pz * pz + mass * mass), px, py, pz};
57  }
58 
59  FourMomentum FourMomentum::fromPtEtaPhiM(double pt, double eta, double phi, double mass) {
60  return FourMomentum{sqrt(mass * mass + pow(pt * cosh(eta), 2.)), pt * cos(phi), pt * sin(phi), pt * sinh(eta)};
61  }
62 
63  FourMomentum FourMomentum::fromEtaPhiME(double eta, double phi, double mass, double E) {
64  if (E <= mass) {
65  throw RangeError("Invalid mass and energy relation");
66  }
67  double pt = sqrt((E * E - mass * mass) / (1 + pow(sinh(eta), 2.)));
68  return FourMomentum{E, pt * cos(phi), pt * sin(phi), pt * sinh(eta)};
69  }
70 
71 #ifdef HAVE_ROOT
72 
73  FourMomentum FourMomentum::fromRoot(const TLorentzVector& v) {
74  return FourMomentum{v.E(), v.Px(), v.Py(), v.Pz()};
75  }
76 
77 #endif
78 
79  // Values of energy and momentum components.
80  double FourMomentum::E() const {
81  return _vec[0];
82  }
83 
84  double FourMomentum::px() const {
85  return _vec[1];
86  }
87 
88  double FourMomentum::py() const {
89  return _vec[2];
90  }
91 
92  double FourMomentum::pz() const {
93  return _vec[3];
94  }
95 
96 
97  // extract mass
98  double FourMomentum::mass2() const {
99  return (E() * E() - p2());
100  }
101 
102  double FourMomentum::mass() const {
103  if (fuzzyLess(mass2() , 0.0)) { // less than 'a little bit negative'
104  throw Error("Rosebud! Negative mass^2: " + to_string(mass2()));
105  }
106  return sqrt(fabs(mass2()));
107  }
108 
109  // absolute value of spatial momentum, p_T, rapidity, pseudorapidity, azimuthal and polar angles
110  double FourMomentum::p2() const {
111  return px() * px() + py() * py() + pz() * pz();
112  }
113 
114  double FourMomentum::p() const {
115  return sqrt(p2());
116  }
117 
118  double FourMomentum::pt() const {
119  return sqrt(px() * px() + py() * py());
120  }
121 
122  double FourMomentum::rapidity() const {
123  return acosh(E() / mass());
124  }
125 
126  double FourMomentum::theta() const {
127  return atan2(pt(), pz());
128  }
129 
130  double FourMomentum::eta() const {
131  return -log(tan(theta() / 2.));
132  }
133 
134  double FourMomentum::phi() const {
135  return atan2(py(), px());
136  }
137 
138  array<double, 3> FourMomentum::pVec() const {
139  return array<double, 3>{{px(), py(), pz()}};
140  }
141 
142  // dot operator, trace -2 metric
143  double FourMomentum::dot(const FourMomentum& v) const {
144  return E() * v.E() - px() * v.px() - py() * v.py() - pz() * v.pz();
145  }
146 
147  double operator*(const FourMomentum& v, const FourMomentum& w) {
148  return dot(v, w);
149  }
150 
151  double dot(const FourMomentum& v, const FourMomentum& w) {
152  return v.dot(w);
153  }
154 
155  FourMomentum& FourMomentum::operator+=(const FourMomentum& v) {
156  for (size_t i = 0; i <= 3; ++i) {
157  _vec[i] += v._vec[i];
158  }
159  return *this;
160  }
161 
162  FourMomentum& FourMomentum::operator-=(const FourMomentum& v) {
163  for (size_t i = 0; i <= 3; ++i) {
164  _vec[i] -= v._vec[i];
165  }
166  return *this;
167  }
168 
169  FourMomentum FourMomentum::operator-() const {
170  FourMomentum res{-_vec[0], -_vec[1], -_vec[2], -_vec[3]};
171  return res;
172  }
173 
174  FourMomentum& FourMomentum::operator*=(double a) {
175  for (size_t i = 0; i <= 3; ++i) {
176  _vec[i] *= a;
177  }
178  return *this;
179  }
180 
181  FourMomentum& FourMomentum::operator/=(double a) {
182  for (size_t i = 0; i <= 3; ++i) {
183  _vec[i] /= a;
184  }
185  return *this;
186  }
187 
188  FourMomentum FourMomentum::PFlip() const {
189  FourMomentum res{_vec[0], -_vec[1], -_vec[2], -_vec[3]};
190  return res;
191  }
192 
193  // boost variables
194  double FourMomentum::gamma() const {
195  double m = mass();
196  if(isZero(m)) {
197  throw Error("Rosebud! Zero mass: " + to_string(m));
198  }
199  return E() / m;
200  }
201 
202  double FourMomentum::beta() const {
203  double energy = E();
204  if(isZero(energy)) {
205  throw Error("Rosebud! Zero energy: " + to_string(energy));
206  }
207  return p() / energy;
208  }
209 
210  array<double, 3> FourMomentum::boostVector() const {
211  double energy = E();
212  if(isZero(energy)) {
213  throw Error("Rosebud! Zero energy: " + to_string(energy));
214  }
215  return {{_vec[1] / energy, _vec[2] / energy, _vec[3] / energy}};
216  }
217 
218  void FourMomentum::boostBy(const std::array<double, 3>& v) {
219  const double vSq=::Hammer::dot(v, v);;
220  const double gamma = 1.0 / sqrt(1.0 - vSq);
221  const double vp = ::Hammer::dot(v, pVec());
222  const double gamma2 = vSq > 0 ? (gamma - 1.0)/vSq : 0.0;
223 
224  _vec[1] =(px() + (gamma2*vp - gamma*E())*v[0]);
225  _vec[2] =(py() + (gamma2*vp - gamma*E())*v[1]);
226  _vec[3] =(pz() + (gamma2*vp - gamma*E())*v[2]);
227  _vec[0] =gamma*(E()-vp);
228  }
229 
230  FourMomentum& FourMomentum::boostToRestFrameOf(const FourMomentum& v) {
231  boostBy(v.boostVector());
232  return *this;
233  }
234 
235  FourMomentum& FourMomentum::boostToRestFrameOf(const std::array<double, 3>& v) {
236  boostBy(v);
237  return *this;
238  }
239 
240  FourMomentum& FourMomentum::boostFromRestFrameOf(const FourMomentum& v) {
241  boostBy(v.PFlip().boostVector());
242  return *this;
243  }
244 
245  // Delta collider coordinates
246  double angle(const FourMomentum& v, const FourMomentum& w) {
247  return acos(costheta(v.pVec(), w.pVec()));
248  }
249 
250  double deltaPhi(const FourMomentum& v, const FourMomentum& w) {
251  return abs(v.phi() - w.phi());
252  }
253 
254  double deltaEta(const FourMomentum& v, const FourMomentum& w) {
255  return abs(v.eta() - w.eta());
256  }
257 
258  double deltaR(const FourMomentum& v, const FourMomentum& w) {
259  return sqrt(pow(deltaPhi(v, w), 2) + pow(deltaEta(v, w), 2));
260  }
261 
262  // epsilon contraction.
263  double epsilon(const FourMomentum& a, const FourMomentum& b, const FourMomentum& c, const FourMomentum& d) {
264  array<double, 4> p = {{a.E(), a.px(), a.py(), a.pz()}};
265  array<double, 4> q = {{b.E(), b.px(), b.py(), b.pz()}};
266  array<double, 4> r = {{c.E(), c.px(), c.py(), c.pz()}};
267  array<double, 4> s = {{d.E(), d.px(), d.py(), d.pz()}};
268  double temp = +(-p[3] * q[2] * r[1] * s[0] + p[2] * q[3] * r[1] * s[0] + p[3] * q[1] * r[2] * s[0] -
269  p[1] * q[3] * r[2] * s[0] - p[2] * q[1] * r[3] * s[0] + p[1] * q[2] * r[3] * s[0] +
270  p[3] * q[2] * r[0] * s[1] - p[2] * q[3] * r[0] * s[1] - p[3] * q[0] * r[2] * s[1] +
271  p[0] * q[3] * r[2] * s[1] + p[2] * q[0] * r[3] * s[1] - p[0] * q[2] * r[3] * s[1] -
272  p[3] * q[1] * r[0] * s[2] + p[1] * q[3] * r[0] * s[2] + p[3] * q[0] * r[1] * s[2] -
273  p[0] * q[3] * r[1] * s[2] - p[1] * q[0] * r[3] * s[2] + p[0] * q[1] * r[3] * s[2] +
274  p[2] * q[1] * r[0] * s[3] - p[1] * q[2] * r[0] * s[3] - p[2] * q[0] * r[1] * s[3] +
275  p[0] * q[2] * r[1] * s[3] + p[1] * q[0] * r[2] * s[3] - p[0] * q[1] * r[2] * s[3]);
276  return temp;
277  }
278 
279  FourMomentum boostToRestFrameOf(const FourMomentum& mom, double vx, double vy, double vz) {
280  FourMomentum result = mom;
281  result.boostToRestFrameOf(array<double, 3>{{vx, vy, vz}});
282  return result;
283  }
284 
285  FourMomentum boostToRestFrameOf(const FourMomentum& mom, const array<double, 3>& v) {
286  FourMomentum result = mom;
287  result.boostToRestFrameOf(v);
288  return result;
289  }
290 
291  FourMomentum boostToRestFrameOf(const FourMomentum& mom, const FourMomentum& v) {
292  FourMomentum result = mom;
293  result.boostToRestFrameOf(v);
294  return result;
295  }
296 
297  double dot(const array<double, 3>& a, const array<double, 3>& b) {
298  return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
299  }
300 
301  double costheta(const array<double, 3>& a, const array<double, 3>& b) {
302  double res = dot(a,b)/sqrt(dot(a,a)*dot(b,b));
303  if(::isnan(res)) {
304  throw Error("Nan in Cosine. Cock. In Hungarian.");
305  }
306  return res;
307  }
308 
309 } // namespace Hammer
FourMomentum boostToRestFrameOf(const FourMomentum &mom, double vx, double vy, double vz)
FourMomentum & boostToRestFrameOf(const FourMomentum &v)
returns a boosted 4-vector
FourMomentum()
default constructor
Definition: FourMomentum.cc:24
static FourMomentum fromPM(double px, double py, double pz, double mass)
builder method based on 3-momentum and invariant mass
double eta() const
returns the pseudorapidity (along the z-axis)
double phi() const
returns the azimuthal angle
FourMomentum & operator-=(const FourMomentum &v)
subtract the 4-momentum by another
double p2() const
returns the squared 3-momentum
double p() const
returns the absolute value of the 3-momentum
double gamma() const
returns the for the Lorentz transformation to the rest frame
double E() const
returns the energy
FourMomentum & operator+=(const FourMomentum &v)
adds the another 4-momentum to itself
Hammer four momentum class.
double costheta(const std::array< double, 3 > &a, const std::array< double, 3 > &b)
double dot(const FourMomentum &v) const
contracts the 4-momentum with another
FourMomentum & setPy(double py)
set the 4-momentum momentum y component
double angle(const FourMomentum &v, const FourMomentum &w)
computes the angle between the spatial components of two 4-momenta
double pt() const
returns the transverse momentum
static FourMomentum fromPtEtaPhiM(double pt, double eta, double phi, double mass)
builder method based on collider-friendly variables
double mass2() const
returns the squared invariant mass
double mass() const
returns the invariant mass if the invariant mass squared is negative returns
FourMomentum & setE(double E)
set the 4-momentum energy
FourMomentum PFlip() const
construct a copy of itself with all the signs of the spatial components flipped
double beta() const
returns the value of the boost to the rest frame
Hammer exception definitions.
void boostBy(const std::array< double, 3 > &v)
FourMomentum operator-() const
construct a copy of itself with all the signs of the components flipped
double epsilon(const FourMomentum &a, const FourMomentum &b, const FourMomentum &c, const FourMomentum &d)
contracts four 4-momenta with an 4D epsilon tensor.
std::array< double, 4 > _vec
the contents of the 4-momentum in the notation .
double deltaR(const FourMomentum &v, const FourMomentum &w)
computes between two 4-momenta
FourMomentum & boostFromRestFrameOf(const FourMomentum &v)
FourMomentum & operator*=(double a)
multiplies the components by a constant
std::array< double, 3 > pVec() const
returns the spatial 3-vector as an array
bool fuzzyLess(const double val1, const double val2)
Definition: Math/Utils.hh:42
bool isZero(const std::complex< double > val)
Definition: Math/Utils.hh:25
Tensor operator*(const Tensor &first, double val)
left multiplies a tensor by a real constant
Definition: Tensor.cc:286
FourMomentum & operator/=(double a)
divides the components by a constant
ROOT includes.
double deltaPhi(const FourMomentum &v, const FourMomentum &w)
computes the difference between the azimuthal angles of two 4-momenta
FourMomentum & setPz(double pz)
set the 4-momentum momentum z component
std::array< double, 3 > boostVector() const
returns the boost 3-vector
double pz() const
returns the momentum z component
double deltaEta(const FourMomentum &v, const FourMomentum &w)
computes the difference between the pseudorapidities of two 4-momenta
Tensor & dot(const Tensor &other, const UniqueLabelsList &indices={})
contract this tensor with another and stores the result in this tensor
Definition: Tensor.cc:114
double py() const
returns the momentum y component
FourMomentum & setPx(double px)
set the 4-momentum momentum x component
static FourMomentum fromEtaPhiME(double eta, double phi, double mass, double E)
builder method based on collider-friendly variables
double theta() const
returns the polar angle (along the z-axis)
double rapidity() const
returns the rapidity (along the z-axis)
double px() const
returns the momentum x component
Tensor dot(const Tensor &first, const Tensor &second, const set< IndexLabel > &indices)
Definition: Tensor.cc:268