18#include "HepMC3/FourVector.h"
19#include "HepMC3/GenParticle.h"
22#include "marley/marley_utils.hh"
23#include "marley/marley_kinematics.hh"
27 double get_beta2(
double beta_x,
double beta_y,
double beta_z)
29 double beta2 = std::pow(beta_x, 2) + std::pow(beta_y, 2)
30 + std::pow(beta_z, 2);
31 if (beta2 == 1)
throw marley::Error(std::string(
"Cannot perform")
32 +
" Lorentz boost because \u03B2^2 = 1 and therefore the Lorentz factor"
33 +
"\u03B3 is infinite.");
34 else if (beta2 > 1)
throw marley::Error(std::string(
"Cannot perform")
35 +
" Lorentz boost because \u03B2^2 = " + std::to_string(beta2) +
" > 1,"
36 +
" which is unphysical.");
43void marley_kinematics::rotate_momentum_vector(
double x,
double y,
double z,
47 double r = std::sqrt( std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2) );
51 double rp = mom4.
p3mod();
54 double ratio = rp / r;
56 double new_px = x * ratio;
57 double new_py = y * ratio;
58 double new_pz = z * ratio;
69void marley_kinematics::lorentz_boost(
double beta_x,
double beta_y,
72 double beta2 = get_beta2(beta_x, beta_y, beta_z);
76 if ( beta2 == 0. )
return;
79 double gamma = 1. / std::sqrt( 1. - beta2 );
84 double px = mom4.
px();
85 double py = mom4.
py();
86 double pz = mom4.
pz();
92 double beta_dot_p = beta_x * px + beta_y * py + beta_z * pz;
93 double factor = ( gamma - 1. ) * beta_dot_p / beta2;
95 double new_E = gamma * ( E - beta_dot_p );
100 if (new_E < m) new_E = m;
102 double new_px = ( -gamma * E + factor ) * beta_x + px;
103 double new_py = ( -gamma * E + factor ) * beta_y + py;
104 double new_pz = ( -gamma * E + factor ) * beta_z + pz;
123void marley_kinematics::two_body_decay(
124 const std::shared_ptr< HepMC3::GenParticle >& initial_particle,
125 std::shared_ptr< HepMC3::GenParticle >& first_product,
126 std::shared_ptr< HepMC3::GenParticle >& second_product,
127 double cos_theta_first,
double phi_first)
135 if ( M < mfirst + msecond )
throw marley::Error(
"A two-body decay was"
136 " requested that is not kinematically allowed." );
138 double M2 = std::pow( M, 2 );
139 double mfirst2 = std::pow( mfirst, 2 );
140 double msecond2 = std::pow( msecond, 2 );
144 double Efirst = ( M2 - msecond2 + mfirst2 ) / ( 2 * M );
146 double Esecond = M - Efirst;
150 if ( Efirst < mfirst ) Efirst = mfirst;
151 if ( Esecond < msecond ) Esecond = msecond;
155 double pfirst = marley_utils::real_sqrt( std::pow(Efirst, 2) - mfirst2 );
156 double sin_theta_first = marley_utils::real_sqrt( 1.
157 - std::pow(cos_theta_first, 2) );
158 double p1x = pfirst * sin_theta_first * std::cos( phi_first );
159 double p1y = pfirst * sin_theta_first * std::sin( phi_first );
160 double p1z = pfirst * cos_theta_first;
179 double E_i = initial_mom4.
e();
180 double px_i = initial_mom4.
px();
181 double py_i = initial_mom4.
py();
182 double pz_i = initial_mom4.
pz();
187 double beta_x = -px_i / E_i;
188 double beta_y = -py_i / E_i;
189 double beta_z = -pz_i / E_i;
193 lorentz_boost( beta_x, beta_y, beta_z, *first_product );
194 lorentz_boost( beta_x, beta_y, beta_z, *second_product );
199double marley_kinematics::get_mandelstam_s(
205 double E1 = p1_mom4.
e();
208 double E2 = p2_mom4.
e();
214 if (E1 == m1)
return std::pow(m1, 2) + std::pow(m2, 2) + 2 * m1 * E2;
215 else if (E2 == m2)
return std::pow(m1, 2) + std::pow(m2, 2) + 2 * m2 * E1;
218 double E_tot = E1 + E2;
219 double px_tot = p1_mom4.
px() + p2_mom4.
px();
220 double py_tot = p1_mom4.
py() + p2_mom4.
py();
221 double pz_tot = p1_mom4.
pz() + p2_mom4.
pz();
222 double m_tot = m1 + m2;
226 double beta_x = px_tot / E_tot;
227 double beta_y = py_tot / E_tot;
228 double beta_z = pz_tot / E_tot;
231 double beta2 = get_beta2( beta_x, beta_y, beta_z );
232 double gamma = 1.0 / std::sqrt( 1.0 - beta2 );
235 double beta_dot_p_tot = beta_x * px_tot + beta_y * py_tot + beta_z * pz_tot;
236 double E_tot_cm = gamma * ( E_tot - beta_dot_p_tot );
241 if ( E_tot_cm < m_tot ) E_tot_cm = m_tot;
243 return std::pow( E_tot_cm, 2 );
257 double E_tot = p1_mom4.
e() + p2_mom4.
e();
258 double px_tot = p1_mom4.
px() + p2_mom4.
px();
259 double py_tot = p1_mom4.
py() + p2_mom4.
py();
260 double pz_tot = p1_mom4.
pz() + p2_mom4.
pz();
262 double beta_x = px_tot / E_tot;
263 double beta_y = py_tot / E_tot;
264 double beta_z = pz_tot / E_tot;
266 lorentz_boost( beta_x, beta_y, beta_z, p1 );
267 lorentz_boost( beta_x, beta_y, beta_z, p2 );
void set_py(double pyy)
Set y-component of momentum.
void set_px(double pxx)
Set x-component of momentum.
double px() const
x-component of momentum
double py() const
y-component of momentum
double p3mod() const
Magnitude of p3 = (px, py, pz) vector.
double pz() const
z-component of momentum
void set_pz(double pzz)
Set z-component of momentum.
double e() const
Energy component of momentum.
void set_e(double ee)
Set energy component of momentum.
Stores particle-related information.
void set_momentum(const FourVector &momentum)
Set momentum.
const FourVector & momentum() const
Get momentum.
double generated_mass() const
Get generated mass.
Base class for all exceptions thrown by MARLEY functions.