cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.3
A generic central exclusive processes event generator
Loading...
Searching...
No Matches
Momentum.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2013-2021 Laurent Forthomme
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <cmath>
20#include <iomanip>
21
25#include "CepGen/Utils/Limits.h"
26#include "CepGen/Utils/Math.h"
27#include "CepGen/Utils/String.h"
28
29namespace cepgen {
31 static double normalisePhi(double phi, const Limits& range) {
32 static const double M_2PI = 2. * M_PI;
33 if (range.range() != M_2PI)
34 throw CG_FATAL("Momentum:normalisePhi") << "Invalid boundaries for the angle normalisation: " << range
35 << ". Must be of range 2*pi, has range " << range.range() << ".";
36 while (phi < range.min())
37 phi += M_2PI;
38 while (phi > range.max())
39 phi -= M_2PI;
40 return phi; // contained in range
41 }
42
43 static double normaliseSqrt(double x2) { return std::sqrt(x2 < 0. ? -x2 : x2); }
44
45 Momentum::Momentum(double x, double y, double z, double t) : std::array<double, 4>{{x, y, z, t == -1. ? 0. : t}} {
46 computeP();
47 }
48
49 Momentum::Momentum(double* p) {
50 std::copy(p, p + 4, begin());
51 computeP();
52 }
53
55 if (vec.size() < 3)
56 throw CG_FATAL("Momentum") << "Failed to initialise a momentum from a vector with coordinates " << vec
57 << ". Should have at least 3 coordinates.";
58 setPx(vec(0)).setPy(vec(1)).setPz(vec(2));
59 if (vec.size() > 3)
60 setEnergy(vec(3));
61 }
62
63 bool Momentum::operator==(const Momentum& oth) const {
64 return px() == oth.px() && py() == oth.py() && pz() == oth.pz() && energy() == oth.energy();
65 }
66
67 //--- static constructors
68
69 Momentum Momentum::fromPtEtaPhiE(double pt, double eta, double phi, double e) {
70 return Momentum(pt * cos(phi), pt * sin(phi), pt * sinh(eta), e);
71 }
72
73 Momentum Momentum::fromPtEtaPhiM(double pt, double eta, double phi, double m) {
75 }
76
77 Momentum Momentum::fromPThetaPhiE(double p, double theta, double phi, double e) {
78 const double pt = p * sin(theta), px = pt * cos(phi), py = pt * sin(phi);
79 return Momentum(px, py, p * cos(theta), e);
80 }
81
82 Momentum Momentum::fromPxPyPzE(double px, double py, double pz, double e) { return Momentum(px, py, pz, e); }
83
84 Momentum Momentum::fromPxPyPzM(double px, double py, double pz, double m) {
85 return Momentum(px, py, pz).setMass(m).computeP();
86 }
87
88 Momentum Momentum::fromPxPyYM(double px, double py, double rap, double m) {
89 const double et = utils::fastHypot(px, py, m);
90 return Momentum(px, py, et * sinh(rap), et * cosh(rap));
91 }
92
93 Momentum Momentum::fromPtYPhiM(double pt, double rap, double phi, double m) {
94 const double et = utils::fastHypot(pt, m);
95 return Momentum(pt * cos(phi), pt * sin(phi), et * sinh(rap), et * cosh(rap));
96 }
97
98 //--- arithmetic operators
99
101 return Momentum(px() + mom.px(), py() + mom.py(), pz() + mom.pz(), energy() + mom.energy());
102 }
103
105 *this = *this + mom;
106 return computeP();
107 }
108
109 Momentum Momentum::operator-() const { return Momentum(-px(), -py(), -pz(), energy()); }
110
112 return Momentum(px() - mom.px(), py() - mom.py(), pz() - mom.pz(), energy() - mom.energy());
113 }
114
116 *this = *this - mom;
117 return computeP();
118 }
119
120 double Momentum::operator*(const Momentum& mom) const { return threeProduct(mom); }
121
123 return Momentum(
124 py() * mom.pz() - pz() * mom.py(), pz() * mom.px() - px() * mom.pz(), px() * mom.py() - py() * mom.px());
125 }
126
127 Momentum Momentum::operator*(double c) const { return Momentum(c * px(), c * py(), c * pz(), c * energy()); }
128
130 *this = *this * c;
131 return computeP();
132 }
133
134 Momentum operator*(double c, const Momentum& mom) {
135 return Momentum(c * mom.px(), c * mom.py(), c * mom.pz(), c * mom.energy());
136 }
137
138 double Momentum::threeProduct(const Momentum& mom) const {
139 CG_DEBUG_LOOP("Momentum") << " (" << px() << ", " << py() << ", " << pz() << ")\n\t"
140 << "* (" << mom.px() << ", " << mom.py() << ", " << mom.pz() << ")\n\t"
141 << "= " << px() * mom.px() + py() * mom.py() + pz() * mom.pz();
142 return px() * mom.px() + py() * mom.py() + pz() * mom.pz();
143 }
144
145 double Momentum::fourProduct(const Momentum& mom) const {
146 CG_DEBUG_LOOP("Momentum") << " (" << px() << ", " << py() << ", " << pz() << ", " << energy() << ")\n\t"
147 << "* (" << mom.px() << ", " << mom.py() << ", " << mom.pz() << ", " << mom.energy()
148 << ")\n\t"
149 << "= " << energy() * mom.energy() - threeProduct(mom);
150 return energy() * mom.energy() - threeProduct(mom);
151 }
152
153 double Momentum::crossProduct(const Momentum& mom) const { return px() * mom.py() - py() * mom.px(); }
154
155 //--- various setters
156
158 (*this)[X] = px;
159 return computeP();
160 }
161
163 (*this)[Y] = py;
164 return computeP();
165 }
166
168 (*this)[Z] = pz;
169 return computeP();
170 }
171
173 (*this)[E] = e;
174 return *this;
175 }
176
177 Momentum& Momentum::setMass(double m) { return setEnergy(utils::fastHypot(p_, m)).computeP(); }
178
179 Momentum& Momentum::setMass2(double m2) { return setEnergy(std::sqrt(p_ * p_ + m2)).computeP(); }
180
181 Momentum& Momentum::setP(double px, double py, double pz, double e) { return setEnergy(e).setP(px, py, pz); }
182
183 Momentum& Momentum::setP(double px, double py, double pz) { return setPx(px).setPy(py).setPz(pz); }
184
185 //--- kinematics constrainers
186
187 Momentum& Momentum::computeEnergyFromMass(double on_shell_mass) { return setMass(on_shell_mass); }
188
189 Momentum& Momentum::computePzFromMass(double on_shell_mass) {
190 return setPz(normaliseSqrt(pz() * pz() + mass2() - on_shell_mass * on_shell_mass));
191 }
192
193 Momentum& Momentum::computeP() {
194 p_ = utils::fastHypot(px(), py(), pz());
195 return *this;
196 }
197
198 Momentum& Momentum::truncate(double tolerance) {
199 std::replace_if(
200 begin(), end(), [&tolerance](const auto& p) { return p <= tolerance; }, 0.);
201 return computeP();
202 }
203
204 //--- various getters
205
206 std::array<double, 5> Momentum::pVector() const {
207 std::array<double, 5> out;
208 std::copy(begin(), end(), out.begin());
209 out[4] = mass();
210 return out;
211 }
212
213 Momentum::operator Vector() const { return Vector{px(), py(), pz(), energy()}; }
214
215 double Momentum::energyT2() const {
216 const auto ptsq = pt2();
217 return ptsq > 0. ? energy2() * ptsq / (ptsq + pz() * pz()) : 0.;
218 }
219
220 double Momentum::energyT() const { return normaliseSqrt(energyT2()); }
221
222 double Momentum::mass2() const { return energy2() - p2(); }
223
224 double Momentum::mass() const { return normaliseSqrt(mass2()); }
225
226 double Momentum::massT2() const { return energy2() - pz() * pz(); }
227
228 double Momentum::massT() const { return normaliseSqrt(massT2()); }
229
230 double Momentum::theta() const { return atan2(pt(), pz()); }
231
232 double Momentum::phi() const { return normalisePhi(atan2(py(), px()), {0., 2. * M_PI}); }
233
234 double Momentum::pt() const { return utils::fastHypot(px(), py()); }
235
236 double Momentum::pt2() const { return px() * px() + py() * py(); }
237
239
240 double Momentum::eta() const {
241 const int sign = pz() / fabs(pz());
242 const auto ptval = pt();
243 return (ptval != 0. ? std::log((p() + fabs(pz())) / ptval) : 9999.) * sign;
244 }
245
246 double Momentum::rapidity() const {
247 const int sign = pz() / fabs(pz());
248 return energy() >= 0. ? std::log((energy() + pz()) / (energy() - pz())) * 0.5 : 999. * sign;
249 }
250
251 double Momentum::deltaEta(const Momentum& oth) const { return fabs(eta() - oth.eta()); }
252
253 double Momentum::deltaPhi(const Momentum& oth) const {
254 return normalisePhi(phi() - oth.phi(), {-M_PI, M_PI}); // has to be contained in [-M_PI, M_PI]
255 }
256
257 double Momentum::deltaPt(const Momentum& oth) const { return fabs(pt() - oth.pt()); }
258
259 double Momentum::deltaR(const Momentum& oth) const {
260 return utils::fastHypot(rapidity() - oth.rapidity(), deltaPhi(oth));
261 }
262
263 //--- boosts/rotations
264
265 double Momentum::beta() const {
266 const auto mom = p(), ene = energy();
267 if (ene == 0.) {
268 if (mom == 0.)
269 return 0.;
270 else {
271 CG_WARNING("Momentum:beta") << "beta computed for t=0 momentum.";
272 return 1. / ene;
273 }
274 }
275 if (mass2() <= 0.)
276 CG_WARNING("Momentum:beta") << "beta computed for an invalid, non-timelike momentum.";
277 return mom / ene;
278 }
279
280 double Momentum::gamma2() const {
281 const auto mom2 = p2(), ene2 = energy2();
282 if (ene2 == 0.) {
283 if (mom2 == 0.)
284 return 1.;
285 CG_WARNING("Momentum:gamma") << "gamma computed for t=0 momentum.";
286 }
287 if (ene2 < mom2) {
288 CG_WARNING("Momentum:gamma") << "gamma computed for an invalid spacelike momentum.";
289 return 0.;
290 } else if (ene2 == mom2)
291 CG_WARNING("Momentum:gamma") << "gamma computed for a lightlike momentum.";
292 return ene2 / (ene2 - mom2);
293 }
294
295 double Momentum::gamma() const { return std::sqrt(gamma2()); }
296
297 Momentum& Momentum::betaGammaBoost(double gamma, double betagamma) {
298 if (gamma == 1. && betagamma == 0.)
299 return *this; // trivial case
300
301 const double apz = pz(), ae = energy();
302
303 return setEnergy(gamma * ae + betagamma * apz).setPz(gamma * apz + betagamma * ae);
304 }
305
307 //--- do not boost on a system at rest
308 if (mom.p() == 0.)
309 return *this;
310
311 const double mass = mom.mass();
312 const double pf4 = ((*this)[X] * mom[X] + (*this)[Y] * mom[Y] + (*this)[Z] * mom[Z] + (*this)[E] * mom[E]) / mass;
313 const double fn = (pf4 + (*this)[E]) / (mom[E] + mass);
314 (*this) += fn * mom;
315 return setEnergy(pf4);
316 }
317
318 Momentum& Momentum::rotatePhi(double phi, double sign) {
319 const double sphi = sin(phi), cphi = cos(phi);
320 const double px = (*this)[X] * cphi + sign * (*this)[Y] * sphi, py = -(*this)[X] * sphi + sign * (*this)[Y] * cphi;
321 return setPx(px).setPy(py);
322 }
323
324 Momentum& Momentum::rotateThetaPhi(double theta, double phi) {
325 const double ctheta = cos(theta), stheta = sin(theta);
326 const double cphi = cos(phi), sphi = sin(phi);
327 double rotmtx[3][3], mom[3]; //FIXME check this! cos(phi)->-sin(phi) & sin(phi)->cos(phi) --> phi->phi+pi/2 ?
328 rotmtx[X][X] = -sphi;
329 rotmtx[X][Y] = -ctheta * cphi;
330 rotmtx[X][Z] = stheta * cphi;
331 rotmtx[Y][X] = cphi;
332 rotmtx[Y][Y] = -ctheta * sphi;
333 rotmtx[Y][Z] = stheta * sphi;
334 rotmtx[Z][X] = 0.;
335 rotmtx[Z][Y] = stheta;
336 rotmtx[Z][Z] = ctheta;
337
338 for (size_t i = X; i <= Z; ++i) {
339 mom[i] = 0.;
340 for (size_t j = X; j <= Z; ++j)
341 mom[i] += rotmtx[i][j] * (*this)[j];
342 }
343 return setP(mom[X], mom[Y], mom[Z]);
344 }
345
346 //--- printout
347
348 std::ostream& operator<<(std::ostream& os, const Momentum& mom) {
349 return os << utils::format(
350 "(%8.3f,%8.3f,%8.3f;%8.3f|%8.3f)", mom.px(), mom.py(), mom.pz(), mom.energy(), mom.mass());
351 }
352} // namespace cepgen
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_WARNING(mod)
Definition Message.h:228
#define CG_DEBUG_LOOP(mod)
Definition Message.h:224
Validity interval for a variable.
Definition Limits.h:28
double range() const
Full variable range allowed.
Definition Limits.cpp:65
double min() const
Lower limit to apply on the variable.
Definition Limits.h:52
double max() const
Upper limit to apply on the variable.
Definition Limits.h:54
Container for a particle's 4-momentum, along with useful methods to ease the development of any matri...
Definition Momentum.h:33
double pt2() const
Squared transverse momentum (in GeV )
Definition Momentum.cpp:236
double pz() const
Longitudinal momentum (in GeV)
Definition Momentum.h:120
double operator*=(const Momentum &)
Scalar product of the 3-momentum with another 3-momentum.
double threeProduct(const Momentum &) const
Scalar product of the 3-momentum with another 3-momentum.
Definition Momentum.cpp:138
Momentum & setMass2(double)
Compute the energy from the mass.
Definition Momentum.cpp:179
double deltaR(const Momentum &) const
Angular distance between two momenta.
Definition Momentum.cpp:259
Momentum & rotateThetaPhi(double theta_, double phi_)
Rotate the particle's momentum by a polar/azimuthal angle.
Definition Momentum.cpp:324
Momentum(double x=0., double y=0., double z=0., double t=-1.)
Build a 4-momentum using its 3-momentum coordinates and its energy.
Definition Momentum.cpp:45
double deltaEta(const Momentum &) const
Pseudorapidity distance between two momenta.
Definition Momentum.cpp:251
double energyT2() const
Squared tranverse energy component (in GeV )
Definition Momentum.cpp:215
double rapidity() const
Rapidity.
Definition Momentum.cpp:246
Momentum & setPy(double py)
Set the momentum along the -axis (in GeV)
Definition Momentum.cpp:162
Momentum & betaGammaBoost(double gamma, double betagamma)
Forward boost.
Definition Momentum.cpp:297
double deltaPt(const Momentum &) const
Transverse momentum distance between two momenta.
Definition Momentum.cpp:257
Momentum & operator+=(const Momentum &)
Add a 4-momentum through a 4-vector sum.
Definition Momentum.cpp:104
double gamma2() const
Squared gamma scalar value.
Definition Momentum.cpp:280
double deltaPhi(const Momentum &) const
Azimutal angle opening between two momenta.
Definition Momentum.cpp:253
double eta() const
Pseudo-rapidity.
Definition Momentum.cpp:240
Momentum & lorentzBoost(const Momentum &p)
Forward Lorentz boost.
Definition Momentum.cpp:306
Momentum & computeEnergyFromMass(double on_shell_mass)
Compute the mass from 4-momentum.
Definition Momentum.cpp:187
friend Momentum operator*(double, const Momentum &)
Left-multiply all 4-momentum coordinates by a scalar.
Definition Momentum.cpp:134
double px() const
Momentum along the -axis (in GeV)
Definition Momentum.h:112
static Momentum fromPxPyYM(double px, double py, double rap, double m)
Build a 4-momentum from its transverse momentum, rapidity and mass.
Definition Momentum.cpp:88
double gamma() const
Gamma scalar value.
Definition Momentum.cpp:295
double p2() const
Squared 3-momentum norm (in GeV )
Definition Momentum.h:132
double py() const
Momentum along the -axis (in GeV)
Definition Momentum.h:116
static Momentum fromPxPyPzM(double px, double py, double pz, double m)
Build a 4-momentum from its three momentum coordinates and mass.
Definition Momentum.cpp:84
double beta() const
Beta scalar value.
Definition Momentum.cpp:265
static Momentum fromPxPyPzE(double px, double py, double pz, double e)
Build a 4-momentum from its four momentum and energy coordinates.
Definition Momentum.cpp:82
Momentum & setP(double px, double py, double pz, double e)
Set all the components of the 4-momentum (in GeV)
Definition Momentum.cpp:181
Momentum & setEnergy(double)
Set the energy (in GeV)
Definition Momentum.cpp:172
double crossProduct(const Momentum &) const
Vector product of the 3-momentum with another 3-momentum.
Definition Momentum.cpp:153
double massT2() const
Squared transverse mass (in GeV )
Definition Momentum.cpp:226
double energy2() const
Squared energy (in GeV )
Definition Momentum.h:138
double massT() const
Transverse mass (in GeV)
Definition Momentum.cpp:228
double pt() const
Transverse momentum (in GeV)
Definition Momentum.cpp:234
Momentum & setPz(double pz)
Set the longitudinal momentum (in GeV)
Definition Momentum.cpp:167
Momentum & setMass(double)
Compute the energy from the mass.
Definition Momentum.cpp:177
Momentum transverse() const
Transverse coordinates of a momentum.
Definition Momentum.cpp:238
double fourProduct(const Momentum &) const
Scalar product of the 4-momentum with another 4-momentum.
Definition Momentum.cpp:145
Momentum & setPx(double px)
Set the momentum along the -axis (in GeV)
Definition Momentum.cpp:157
static Momentum fromPtEtaPhiM(double pt, double eta, double phi, double m)
Build a 3-momentum from its three pseudo-cylindrical coordinates.
Definition Momentum.cpp:73
double phi() const
Azimuthal angle (angle in the transverse plane)
Definition Momentum.cpp:232
double p() const
3-momentum norm (in GeV)
Definition Momentum.h:130
Momentum operator+(const Momentum &) const
Compute the 4-vector sum of two 4-momenta.
Definition Momentum.cpp:100
Momentum operator%(const Momentum &) const
Vector product of two 3-momenta.
Definition Momentum.cpp:122
double mass() const
Mass (in GeV) as computed from its energy and momentum.
Definition Momentum.cpp:224
Momentum & truncate(double tolerance=1.e-10)
Apply a threshold to all values with a given tolerance.
Definition Momentum.cpp:198
double energyT() const
Tranverse energy component (in GeV)
Definition Momentum.cpp:220
Momentum & operator-=(const Momentum &)
Subtract a 4-momentum through a 4-vector sum.
Definition Momentum.cpp:115
std::array< double, 5 > pVector() const
5-vector of double precision floats (in GeV)
Definition Momentum.cpp:206
static Momentum fromPtYPhiM(double pt, double rap, double phi, double m)
Build a 4-momentum from its transverse momentum, azimuthal angle, rapidity and mass.
Definition Momentum.cpp:93
Momentum & computePzFromMass(double on_shell_mass)
Compute the longitudinal coordinate from energy-mass-transverse momentum constraints.
Definition Momentum.cpp:189
static Momentum fromPtEtaPhiE(double pt, double eta, double phi, double e=-1.)
Build a 3-momentum from its three pseudo-cylindrical coordinates.
Definition Momentum.cpp:69
Momentum & rotatePhi(double phi, double sign)
Rotate the transverse components by an angle phi (and reflect the y coordinate)
Definition Momentum.cpp:318
double energy() const
Energy (in GeV)
Definition Momentum.h:136
double theta() const
Polar angle (angle with respect to the longitudinal direction)
Definition Momentum.cpp:230
bool operator==(const Momentum &) const
Equality operator.
Definition Momentum.cpp:63
static Momentum fromPThetaPhiE(double p, double theta, double phi, double e=-1.)
Build a 4-momentum from its scalar momentum, and its polar and azimuthal angles.
Definition Momentum.cpp:77
Momentum operator-() const
Unary inverse operator.
Definition Momentum.cpp:109
double mass2() const
Squared mass (in GeV ) as computed from its energy and momentum.
Definition Momentum.cpp:222
Specialisation of a matrix.
Definition Algebra.h:139
size_t size() const
Vector multiplicity (number of lines)
Definition Algebra.cpp:325
std::string format(const std::string &fmt, Args... args)
Format a string using a printf style format descriptor.
Definition String.h:59
double fastHypot(double x, double y)
Definition Math.cpp:33
Common namespace for this Monte Carlo generator.
Momentum operator*(double c, const Momentum &mom)
Definition Momentum.cpp:134
static double normaliseSqrt(double x2)
Definition Momentum.cpp:43
static double normalisePhi(double phi, const Limits &range)
Express an angle in between two extrema.
Definition Momentum.cpp:31
std::ostream & operator<<(std::ostream &os, const Exception::Type &type)
Definition Exception.cpp:59