19#include "marley/Generator.hh"
20#include "marley/Logger.hh"
21#include "marley/NeutrinoSource.hh"
28 double gamma_pdf_unnorm(
double E,
double Emean,
double alpha,
29 double Emin,
double Emax)
31 if (E < Emin || E > Emax)
return 0.;
32 if (E == 0. && alpha < 0.)
return 0.;
33 return std::pow(E / Emean, alpha)
34 * std::exp(-(alpha + 1.) * E / Emean);
40 "Creating a neutrino source object that produces"
41 " particles with PDG ID number " + std::to_string(particle_id)
42 +
" is not allowed.");
43 else pid_ = particle_id;
48const std::set<int> marley::NeutrinoSource::pids_ = {
49 marley_utils::ELECTRON_NEUTRINO,
50 marley_utils::ELECTRON_ANTINEUTRINO,
51 marley_utils::MUON_NEUTRINO,
52 marley_utils::MUON_ANTINEUTRINO,
53 marley_utils::TAU_NEUTRINO,
54 marley_utils::TAU_ANTINEUTRINO
60 static double max = marley_utils::UNKNOWN_MAX;
67 double Emin,
double Emax,
double temp,
double eta)
74 double integral = marley_utils::num_integrate(
75 [
this](
double E) ->
double {
return this->
pdf(E); },
Emin_,
Emax_);
83 if (E < Emin_ || E >
Emax_)
return 0.;
89 double Emin,
double Emax,
double Emean,
double alpha)
94 throw marley::Error(
"For an \"alpha-fit\" neutrino source, alpha must be"
95 " > -1. This condition is required for the energy distribution to be"
100 MARLEY_LOG(WARN,
"init.config.source") <<
"For an alpha-fit source with"
101 " alpha < 0 and Emin = 0, the PDF diverges at E = 0.";
107 double integral = marley_utils::num_integrate(
108 [
this](
double E) ->
double {
return this->
pdf(E); },
Emin_,
Emax_);
120 double Emin,
double Emax,
double Emean,
double beta)
125 throw marley::Error(
"For a \"beta-fit\" neutrino source, a value of"
126 " the fit parameter beta <= 0 prevents normalization of the"
127 " energy distribution. Please choose a positive value and try again.");
131 MARLEY_LOG(WARN,
"init.config.source") <<
"For a beta-fit source with"
132 " beta < 1 (i.e., alpha < 0) and Emin = 0, the PDF diverges at E = 0.";
138 double integral = marley_utils::num_integrate(
139 [
this](
double E) ->
double {
return this->
pdf(E); },
Emin_,
Emax_);
151 double Emin,
double Emax, std::function<
double(
double)> prob_dens_func)
157 double integral = marley_utils::num_integrate(prob_dens_func, Emin, Emax);
158 probability_density_ = [prob_dens_func, integral](
double E)
159 ->
double {
return prob_dens_func(E) / integral; };
165 int abs_pid = std::abs(particle_id);
166 if ( abs_pid != marley_utils::ELECTRON_NEUTRINO &&
167 abs_pid != marley_utils::MUON_NEUTRINO )
170 + marley_utils::get_particle_symbol(particle_id) +
" requested"
171 " for a muon decay-at-rest neutrino source");
176 if (E < Emin_ || E > Emax_)
return 0.;
181 int abs_pid = std::abs(
pid_);
182 if (abs_pid == marley_utils::ELECTRON_NEUTRINO)
183 return 96. * std::pow(E, 2) * m_mu_to_the_minus_four_
186 else return 16. * std::pow(E, 2) * m_mu_to_the_minus_four_
192void marley::GridNeutrinoSource::check_for_errors() {
193 size_t grid_size = grid_.size();
194 if (grid_size < 2)
throw marley::Error(std::string(
"Grid with")
195 +
" less than 2 gridpoints passed to the constructor of"
196 +
" marley::GridNeutrinoSource.");
198 double sum_of_PDs = 0.;
199 for (
size_t j = 0; j < grid_size; ++j) {
200 auto& pair = grid_.at(j);
201 if (pair.first < 0.)
throw marley::Error(std::string(
"All energy")
202 +
" values used in a marley::GridNeutrinoSource"
203 +
" object must be nonnegative");
207 else if (pair.first == 0.) pair.first = std::nextafter(0.,
208 marley_utils::infinity);
209 if (pair.second < 0.)
throw marley::Error(std::string(
"All PDF")
210 +
" values used in a marley::GridNeutrinoSource object must be"
212 else sum_of_PDs += pair.second;
215 if (sum_of_PDs <= 0.)
throw marley::Error(std::string(
"All probability")
216 +
" density grid point values are zero for the neutrino source");
double C_
dimensionless normalization constant
AlphaFitNeutrinoSource(int particle_id=marley_utils::ELECTRON_NEUTRINO, double Emin=0., double Emax=50., double Emean=13., double alpha=2.)
double Emin_
minimum neutrino energy (MeV)
virtual double pdf(double E) const override
Probability density function describing the incident neutrino energy distribution.
double Emean_
mean neutrino energy
double alpha_
dimensionless pinching parameter
virtual double pdf(double E) const override
Probability density function describing the incident neutrino energy distribution.
double C_
dimensionless normalization constant
double alpha_
pinching parameter (stored as alpha = beta - 1)
double Emean_
mean neutrino energy
double Emin_
minimum neutrino energy (MeV)
BetaFitNeutrinoSource(int particle_id=marley_utils::ELECTRON_NEUTRINO, double Emin=0., double Emax=50., double Emean=13., double beta=4.5)
DecayAtRestNeutrinoSource(int particle_id=marley_utils::ELECTRON_NEUTRINO)
virtual double pdf(double E) const override
Probability density function describing the incident neutrino energy distribution.
Base class for all exceptions thrown by MARLEY functions.
FermiDiracNeutrinoSource(int particle_id=marley_utils::ELECTRON_NEUTRINO, double Emin=0., double Emax=50., double temp=3.5, double eta=0.)
double eta_
dimensionless pinching parameter
double Emin_
minimum neutrino energy (MeV)
double C_
normalization constant (MeV2)
double Emax_
maximum neutrino energy (MeV)
virtual double pdf(double E) const override
Probability density function describing the incident neutrino energy distribution.
double temperature_
temperature (MeV)
FunctionNeutrinoSource(int particle_id=marley_utils::ELECTRON_NEUTRINO, double Emin=0., double Emax=50., std::function< double(double)> prob_dens_func=[](double) -> double { return 1.;})
The MARLEY Event generator.
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 ...
virtual double get_Emax() const =0
Get the maximum neutrino energy (MeV) that can be sampled by this source.
NeutrinoSource(int particle_id)
int pid_
PDG particle ID for the neutrinos produced by this source.
virtual double get_Emin() const =0
Get the minimum neutrino energy (MeV) that can be sampled by this source.
virtual double pdf(double E) const =0
Probability density function describing the incident neutrino energy distribution.
virtual double sample_incident_neutrino(int &pdg, marley::Generator &gen) const
Samples an incident neutrino energy and loads pdg with the PDG code of the appropriate neutrino type.
static bool pdg_is_allowed(const int pdg)