17#include "marley/marley_utils.hh"
18#include "marley/ElectronReaction.hh"
19#include "marley/Generator.hh"
20#include "marley/Logger.hh"
21#include "marley/hepmc3_utils.hh"
26 constexpr double COS_MIN = -1.;
27 constexpr double COS_MAX = 1.;
31marley::ElectronReaction::ElectronReaction(
int pdg_a,
int target_atom_pdg,
32 const std::string& source_file)
33 : Reaction( source_file ), atom_( target_atom_pdg )
35 process_type_ = ProcessType::NuElectronElastic;
38 pdg_b_ = marley_utils::ELECTRON;
39 pdg_c_ = get_ejectile_pdg(pdg_a_, process_type_);
40 pdg_d_ = marley_utils::ELECTRON;
43 description_ = marley_utils::get_particle_symbol( pdg_a_ )
44 +
" + " + marley_utils::get_particle_symbol( pdg_b_ );
45 description_ +=
" --> " + marley_utils::get_particle_symbol( pdg_c_ );
46 description_ +=
" + " + marley_utils::get_particle_symbol( pdg_d_ );
49 ma_ = mt.get_particle_mass( pdg_a_ );
50 mb_ = mt.get_particle_mass( pdg_b_ );
51 mc_ = mt.get_particle_mass( pdg_c_ );
52 md_ = mt.get_particle_mass( pdg_d_ );
54 this->set_coupling_constants();
58 KEa_threshold_ = ( std::pow(mc_ + md_, 2)
59 - std::pow(ma_ + mb_, 2) ) / ( 2.*mb_ );
61 MARLEY_LOG( DEBUG,
"physics.reaction" ) <<
"ElectronReaction: "
62 << description_ <<
", g1 = " << g1_ <<
", g2 = " << g2_
63 <<
", threshold KE = " << KEa_threshold_ <<
" MeV";
66void marley::ElectronReaction::set_coupling_constants()
68 if (
pdg_a_ == marley_utils::ELECTRON_NEUTRINO) {
69 g1_ = marley_utils::ONE_HALF + marley_utils::sin2thetaw;
70 g2_ = marley_utils::sin2thetaw;
72 else if (
pdg_a_ == marley_utils::ELECTRON_ANTINEUTRINO) {
73 g1_ = marley_utils::sin2thetaw;
74 g2_ = marley_utils::ONE_HALF + marley_utils::sin2thetaw;
76 else if (
pdg_a_ == marley_utils::MUON_NEUTRINO ||
77 pdg_a_ == marley_utils::TAU_NEUTRINO)
79 g1_ = -marley_utils::ONE_HALF + marley_utils::sin2thetaw;
80 g2_ = marley_utils::sin2thetaw;
82 else if (
pdg_a_ == marley_utils::MUON_ANTINEUTRINO ||
83 pdg_a_ == marley_utils::TAU_ANTINEUTRINO)
85 g1_ = marley_utils::sin2thetaw;
86 g2_ = -marley_utils::ONE_HALF + marley_utils::sin2thetaw;
88 else throw marley::Error(
"Unrecognized projectile PDG code "
89 + std::to_string(
pdg_a_) +
" encountered in marley::Electron"
90 "Reaction::set_coupling_constants()");
100 if ( KEa < KEa_threshold_ )
return 0.;
103 if ( KEa <= 0. )
return 0.;
106 double s = std::pow(
ma_ +
mb_, 2) + 2.*
mb_*KEa;
109 double Ec_cm = (s +
mc_*
mc_ -
md_*
md_) / ( 2. * std::sqrt(s) );
112 double me2_over_s =
md_*
md_ / s;
113 double g2_squared_over_three = g2_*g2_ / 3.;
116 double xs = (4. / marley_utils::pi) * std::pow(marley_utils::GF * Ec_cm, 2)
117 * (std::pow(g1_, 2) + (g2_squared_over_three - g1_*g2_)*me2_over_s
118 + g2_squared_over_three*(1. + std::pow(me2_over_s, 2)));
128 double cos_theta_c_cm)
const
134 if ( KEa < KEa_threshold_ )
return 0.;
137 if ( KEa <= 0. )
return 0.;
140 double s = std::pow(
ma_ +
mb_, 2) + 2.*
mb_*KEa;
143 double Ec_cm = (s +
mc_*
mc_ -
md_*
md_) / ( 2. * std::sqrt(s) );
146 double me2_over_s =
md_*
md_ / s;
147 double overall_factor = (2. / marley_utils::pi)
148 * std::pow(marley_utils::GF * Ec_cm, 2);
149 double terms = std::pow(g1_, 2) + g1_*g2_*me2_over_s*(cos_theta_c_cm - 1.)
150 + std::pow(g2_ * (1. + marley_utils::ONE_HALF*(1. - me2_over_s)
151 * (cos_theta_c_cm - 1.)), 2);
154 double diff_xsec = overall_factor * terms;
159 diff_xsec *= atom_.Z();
172 " not create this event. The requested projectile PDG code "
173 + std::to_string(
pdg_a) +
" does not match the value "
174 + std::to_string(
pdg_a_) +
" stored in the Reaction object.");
177 if ( KEa < KEa_threshold_ )
throw marley::Error(
"Could not create"
178 " this event. The kinetic energy (" + std::to_string(KEa) +
" MeV)"
179 " of the projectile is below the reaction threshold of "
180 + std::to_string(KEa_threshold_) +
" MeV.");
182 double s, Ec_cm, pc_cm, Ed_cm;
193 double me2_over_s =
md_*
md_ / s;
194 double B = marley_utils::ONE_HALF * std::pow(g2_*(1. - me2_over_s), 2);
195 double A = g1_*g2_*me2_over_s + g2_*g2_*(1. - me2_over_s) - B;
202 double dxs_at_cth = std::numeric_limits<double>::lowest();
205 if ( cth >= COS_MIN && cth <= COS_MAX ) {
213 max = std::max( { dxs_at_min, dxs_at_max, dxs_at_cth } );
217 [
this,
pdg_a, KEa](
double ctheta) ->
double
218 {
return this->
diff_xs(
pdg_a, KEa, ctheta); }, COS_MIN, COS_MAX, max);
225 MARLEY_LOG( DEBUG,
"physics.reaction" ) <<
"ElectronReaction::create_event:"
226 " KEa = " << KEa <<
" MeV, sampled cos_theta_cm = " << cos_theta_c_cm
227 <<
", phi_cm = " << phi_c_cm;
231 marley_hepmc3::NUHEPMC_FINAL_STATE_STATUS );
virtual double diff_xs(int pdg_a, double KEa, double cos_theta_c_cm) const
virtual std::shared_ptr< HepMC3::GenEvent > create_event(int particle_id_a, double KEa, marley::Generator &gen) const override
Create an event object for this reaction.
virtual double total_xs(int pdg_a, double KEa) const override
Compute the reaction's total cross section (MeV -2)
Base class for all exceptions thrown by MARLEY functions.
The MARLEY Event generator.
double uniform_random_double(double min, double max, bool inclusive)
Sample a random number uniformly on either [min, max) or [min, max].
double rejection_sample(const std::function< double(double)> &f, double xmin, double xmax, double &fmax, double safety_factor=1.01, double max_search_tolerance=DEFAULT_REJECTION_SAMPLING_TOLERANCE_)
Sample from a given 1D probability density function f(x) on the interval [xmin, xmax] using a simple ...
static const MassTable & Instance()
Get a const reference to the singleton instance of the MassTable.
int pdg_a_
PDG code for the projectile.
double md_
Residue mass (MeV)
double mc_
Ejectile mass (MeV)
void two_two_scatter(double KEa, double &s, double &Ec_cm, double &pc_cm, double &Ed_cm) const
Helper function that handles CM frame kinematics for the reaction.
virtual std::shared_ptr< HepMC3::GenEvent > make_event_object(double KEa, double pc_cm, double cos_theta_c_cm, double phi_c_cm, double Ec_cm, double Ed_cm, int residue_status) const
Helper function that makes an event object.
int pdg_a() const
Get the projectile PDG code.
double ma_
Projectile mass (MeV)
double mb_
Target mass (MeV)