cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
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" << "* (" << mom.px() << ", "
140 << 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() << ")\n\t"
148 << "= " << energy() * mom.energy() - threeProduct(mom);
149 return energy() * mom.energy() - threeProduct(mom);
150 }
151
152 double Momentum::crossProduct(const Momentum& mom) const { return px() * mom.py() - py() * mom.px(); }
153
154 //--- various setters
155
157 (*this)[X] = px;
158 return computeP();
159 }
160
162 (*this)[Y] = py;
163 return computeP();
164 }
165
167 (*this)[Z] = pz;
168 return computeP();
169 }
170
172 (*this)[E] = e;
173 return *this;
174 }
175
176 Momentum& Momentum::setMass(double m) { return setEnergy(utils::fastHypot(p_, m)).computeP(); }
177
178 Momentum& Momentum::setMass2(double m2) { return setEnergy(std::sqrt(p_ * p_ + m2)).computeP(); }
179
180 Momentum& Momentum::setP(double px, double py, double pz, double e) { return setEnergy(e).setP(px, py, pz); }
181
182 Momentum& Momentum::setP(double px, double py, double pz) { return setPx(px).setPy(py).setPz(pz); }
183
184 //--- kinematics constrainers
185
186 Momentum& Momentum::computeEnergyFromMass(double on_shell_mass) { return setMass(on_shell_mass); }
187
188 Momentum& Momentum::computePzFromMass(double on_shell_mass) {
189 return setPz(normaliseSqrt(pz() * pz() + mass2() - on_shell_mass * on_shell_mass));
190 }
191
192 Momentum& Momentum::computeP() {
193 p_ = utils::fastHypot(px(), py(), pz());
194 return *this;
195 }
196
197 Momentum& Momentum::truncate(double tolerance) {
198 std::replace_if(begin(), end(), [&tolerance](const auto& p) { return p <= tolerance; }, 0.);
199 return computeP();
200 }
201
202 //--- various getters
203
204 std::array<double, 5> Momentum::pVector() const {
205 std::array<double, 5> out;
206 std::copy(begin(), end(), out.begin());
207 out[4] = mass();
208 return out;
209 }
210
211 Momentum::operator Vector() const { return Vector{px(), py(), pz(), energy()}; }
212
213 double Momentum::energyT2() const {
214 const auto ptsq = pt2();
215 return ptsq > 0. ? energy2() * ptsq / (ptsq + pz() * pz()) : 0.;
216 }
217
218 double Momentum::energyT() const { return normaliseSqrt(energyT2()); }
219
220 double Momentum::mass2() const { return energy2() - p2(); }
221
222 double Momentum::mass() const { return normaliseSqrt(mass2()); }
223
224 double Momentum::massT2() const { return energy2() - pz() * pz(); }
225
226 double Momentum::massT() const { return normaliseSqrt(massT2()); }
227
228 double Momentum::theta() const { return atan2(pt(), pz()); }
229
230 double Momentum::phi() const { return normalisePhi(atan2(py(), px()), {0., 2. * M_PI}); }
231
232 double Momentum::pt() const { return utils::fastHypot(px(), py()); }
233
234 double Momentum::pt2() const { return px() * px() + py() * py(); }
235
238 }
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 const auto apz = pz(), ae = energy();
301 return setEnergy(gamma * ae + betagamma * apz).setPz(gamma * apz + betagamma * ae);
302 }
303
305 if (mom.p() == 0.)
306 return *this; // do not boost on a system at rest
307 const auto mass = mom.mass();
308 if (mass == 0.)
309 return *this;
310 const auto pf4 = (threeProduct(mom) + energy() * mom.energy()) / mass;
311 const auto fn = (pf4 + energy()) / (mass + mom.energy());
312 (*this) += fn * mom;
313 return setEnergy(pf4);
314 /*const auto norm_mom = mom * (1. / mom.energy());
315 const auto b2 = norm_mom.p2();
316 const auto gamma = std::sqrt(1. / (1. - b2)), gamma2 = b2 > 0 ? (gamma - 1.0) / b2 : 0.;
317 const auto bp = threeProduct(norm_mom);
318 return setPx(px() + gamma2 * bp * norm_mom.px() + gamma * norm_mom.px() * energy())
319 .setPy(py() + gamma2 * bp * norm_mom.py() + gamma * norm_mom.py() * energy())
320 .setPz(pz() + gamma2 * bp * norm_mom.pz() + gamma * norm_mom.pz() * energy())
321 .setEnergy(gamma * (energy() + bp));*/
322 }
323
324 Momentum& Momentum::rotatePhi(double phi, double sign) {
325 const auto sphi = std::sin(phi), cphi = std::cos(phi);
326 const auto pxp = px() * cphi + sign * py() * sphi, pyp = -px() * sphi + sign * py() * cphi;
327 return setPx(pxp).setPy(pyp);
328 }
329
330 Momentum& Momentum::rotateThetaPhi(double theta, double phi) {
331 const double ctheta = cos(theta), stheta = sin(theta);
332 const double cphi = cos(phi), sphi = sin(phi);
333 double rotmtx[3][3]; //FIXME check this! cos(phi)->-sin(phi) & sin(phi)->cos(phi) --> phi->phi+pi/2 ?
334 std::vector<double> mom(3, 0.);
335 rotmtx[X][X] = -sphi;
336 rotmtx[X][Y] = -ctheta * cphi;
337 rotmtx[X][Z] = stheta * cphi;
338 rotmtx[Y][X] = cphi;
339 rotmtx[Y][Y] = -ctheta * sphi;
340 rotmtx[Y][Z] = stheta * sphi;
341 rotmtx[Z][X] = 0.;
342 rotmtx[Z][Y] = stheta;
343 rotmtx[Z][Z] = ctheta;
344
345 for (size_t i = X; i <= Z; ++i)
346 for (size_t j = X; j <= Z; ++j)
347 mom[i] += rotmtx[i][j] * (*this)[j];
348 return setP(mom.at(X), mom.at(Y), mom.at(Z));
349 }
350
351 //--- printout
352
353 std::ostream& operator<<(std::ostream& os, const Momentum& mom) {
354 return os << utils::format(
355 "(%8.3f,%8.3f,%8.3f;%8.3f|%8.3f)", mom.px(), mom.py(), mom.pz(), mom.energy(), mom.mass());
356 }
357} // 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:234
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:178
double deltaR(const Momentum &) const
Angular distance between two momenta.
Definition Momentum.cpp:259
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:213
double rapidity() const
Rapidity.
Definition Momentum.cpp:246
Momentum & setPy(double py)
Set the momentum along the -axis (in GeV)
Definition Momentum.cpp:161
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
Momentum & rotateThetaPhi(double theta, double phi)
Rotate the particle's momentum by a polar/azimuthal angle.
Definition Momentum.cpp:330
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:304
Momentum & computeEnergyFromMass(double on_shell_mass)
Compute the mass from 4-momentum.
Definition Momentum.cpp:186
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:180
Momentum & setEnergy(double)
Set the energy (in GeV)
Definition Momentum.cpp:171
double crossProduct(const Momentum &) const
Vector product of the 3-momentum with another 3-momentum.
Definition Momentum.cpp:152
double massT2() const
Squared transverse mass (in GeV )
Definition Momentum.cpp:224
double energy2() const
Squared energy (in GeV )
Definition Momentum.h:138
double massT() const
Transverse mass (in GeV)
Definition Momentum.cpp:226
double pt() const
Transverse momentum (in GeV)
Definition Momentum.cpp:232
Momentum & setPz(double pz)
Set the longitudinal momentum (in GeV)
Definition Momentum.cpp:166
Momentum & setMass(double)
Compute the energy from the mass.
Definition Momentum.cpp:176
Momentum transverse() const
Transverse coordinates of a momentum.
Definition Momentum.cpp:236
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:156
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:230
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:222
Momentum & truncate(double tolerance=1.e-10)
Apply a threshold to all values with a given tolerance.
Definition Momentum.cpp:197
double energyT() const
Tranverse energy component (in GeV)
Definition Momentum.cpp:218
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:204
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:188
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:324
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:228
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:220
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:61
double fastSqrtSqDiff(double x, double y)
Compute the square root of the squared difference (sqrt(a^2-b^2))
Definition Math.cpp:43
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