MARLEY (Model of Argon Reaction Low Energy Yields) v2.0.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
Loading...
Searching...
No Matches
marley::Generator Class Reference

The MARLEY Event generator. More...

#include <Generator.hh>

Public Member Functions

 Generator ()
 Create a Generator using default settings.
 
void add_reaction (std::unique_ptr< marley::Reaction > reaction)
 Take ownership of a new Reaction.
 
void add_state_to_event (HepMC3::GenEvent &ev) const
 Attach the current random number generator state to the input event as a string attribute.
 
void assign_run_info (HepMC3::GenEvent &event) const
 Associates the owned GenRunInfo object with the input event.
 
void clear_reactions ()
 Clear the vector of Reaction objects owned by this Generator.
 
std::shared_ptr< HepMC3::GenEventcreate_event (bool attach_state=false)
 Create an Event using the NeutrinoSource, Target, Reaction, and StructureDatabase objects owned by this Generator.
 
std::shared_ptr< HepMC3::GenEventcreate_event (int pdg_a, double KEa, int pdg_atom, const std::array< double, 3 > &dir_vec, bool attach_state=false)
 Creates an event object for a fixed projectile species, kinetic energy, and atomic target.
 
double E_pdf (double E)
 Probability density function that describes the distribution of reacting neutrino energies.
 
void finish_event_metadata (HepMC3::GenEvent &ev, bool attach_state=false)
 Add final pieces of metadata (e.g., the RNG state) to an otherwise complete event.
 
double flux_averaged_total_xs () const
 Computes the flux-averaged total cross section for all enabled neutrino reactions, taking target atom fractions into account as appropriate.
 
const std::vector< std::unique_ptr< marley::Reaction > > & get_reactions () const
 Get a const reference to the vector of Reaction objects owned by this Generator.
 
marley::ProjectileDirectionRotatorget_rotator ()
 Provides access to the owned ProjectileDirectionRotator.
 
uint_fast64_t get_seed () const
 Get the seed used to initialize this Generator.
 
const marley::NeutrinoSourceget_source () const
 Get a const reference to the NeutrinoSource owned by this Generator.
 
std::string get_state_string () const
 Get a string that represents the current internal state of this Generator.
 
marley::StructureDatabaseget_structure_db ()
 Get a reference to the StructureDatabase owned by this Generator.
 
const marley::Targetget_target () const
 Get a const reference to the Target owned by this Generator.
 
marley::Weighterget_weighter ()
 Get a non-const reference to the owned Weighter object.
 
const marley::Weighterget_weighter () const
 Get a const reference to the owned Weighter object.
 
double inverse_transform_sample (const marley::InterpolatingFunction &cdf, double xmin, double xmax, double bisection_tolerance=1e-12)
 Sample from a given 1D cumulative density function cdf(x) on the interval [xmin, xmax] using bisection.
 
double inverse_transform_sample (const std::function< double(double)> &f, double xmin, double xmax, double bisection_tolerance=1e-12)
 Sample from a given 1D probability density function f(x) on the interval [xmin, xmax] using an inverse transform technique.
 
const std::string & json_config () const
 
const std::array< double, 3 > & neutrino_direction ()
 Gets the direction of the incident neutrinos that is used when generating events.
 
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 rejection method.
 
void reseed (uint_fast64_t seed)
 Reseeds the Generator.
 
const std::shared_ptr< HepMC3::GenRunInfo > & run_info () const
 
double sample_decay_time (double partial_width)
 Sample a random decay time given a partial decay width.
 
template<class RandomNumberDistribution>
auto sample_from_distribution (RandomNumberDistribution &rnd) -> decltype(std::declval< RandomNumberDistribution & >().operator()(std::declval< std::mt19937_64 & >()))
 Sample from an arbitrary probability distribution (defined here as any object that implements an operator()(std::mt19937_64&) function) @detail This template function is based on https://stackoverflow.com/a/9154394/4081973.
 
template<class RandomNumberDistribution, typename ParamType>
auto sample_from_distribution (RandomNumberDistribution &rnd, const ParamType &params) -> decltype(std::declval< RandomNumberDistribution & >().operator()(std::declval< std::mt19937_64 & >(), std::declval< const ParamType & >()))
 Sample from an arbitrary probability distribution (defined here as any object that implements an operator()(std::mt19937_64&, const ParamType&) function) using the parameters params.
 
marley::Reactionsample_reaction (double &E)
 Sample a Reaction and an energy for the reacting neutrino.
 
void seed_using_state_string (const std::string &state_string)
 Use a string to set this Generator's internal state.
 
void set_do_deexcitations (bool do_them)
 Sets the value of the do_deexcitations flag.
 
void set_neutrino_direction (const std::array< double, 3 > &dir_vec)
 Sets the direction of the incident neutrinos to use when generating events.
 
void set_run_info (const std::shared_ptr< HepMC3::GenRunInfo > &run_info)
 
void set_source (std::unique_ptr< marley::NeutrinoSource > source)
 Take ownership of a new NeutrinoSource, replacing any existing source owned by this Generator.
 
void set_target (std::unique_ptr< marley::Target > target)
 Take ownership of a new Target, replacing any existing target owned by this Generator.
 
void set_up_run_info ()
 Initializes the owned GenRunInfo object that will be used to associate run metadata with the output events.
 
void set_weight_flux (bool should_we_weight)
 Sets the value of the weight_flux flag.
 
void set_weighter (std::shared_ptr< marley::Weighter > w)
 Replace the owned Weighter object.
 
double total_xs (int pdg_a, double KEa) const
 Computes the abundance-weighted total cross section at fixed energy for all configured reactions.
 
double total_xs (int pdg_a, double KEa, int pdg_atom) const
 Computes the total cross section at fixed energy for all configured reactions involving a particular target atom.
 
double uniform_random_double (double min, double max, bool inclusive)
 Sample a random number uniformly on either [min, max) or [min, max].
 

Static Public Member Functions

static void add_state_to_event (HepMC3::GenEvent &ev, const std::string &state)
 Attach a user-supplied random number generator state string to the input event as a string attribute.
 

Detailed Description

The MARLEY Event generator.

Definition at line 54 of file Generator.hh.

Constructor & Destructor Documentation

◆ Generator()

marley::Generator::Generator ( )

Create a Generator using default settings.

Definition at line 45 of file Generator.cc.

46 : seed_( std::chrono::system_clock::now().time_since_epoch().count() ),
47 source_( new marley::MonoNeutrinoSource ),
48 structure_db_( new marley::StructureDatabase )
49{
50 print_logo();
51 reseed( seed_ );
52}
void reseed(uint_fast64_t seed)
Reseeds the Generator.
Definition Generator.cc:156

References reseed().

Member Function Documentation

◆ add_reaction()

void marley::Generator::add_reaction ( std::unique_ptr< marley::Reaction > reaction)

Take ownership of a new Reaction.

Parameters
reactionA pointer to the new Reaction to use

Definition at line 479 of file Generator.cc.

481{
482 // If we're passed a nullptr, then don't bother to do anything
483 if ( reaction ) {
484
485 // Transfer ownership to a new unique_ptr in the reactions vector, leaving
486 // the original empty
487 reactions_.push_back( std::move(reaction) );
488
489 // Add a new entry in the reaction cross sections vector
490 total_xs_values_.push_back( 0. );
491
492 // TODO: consider adding a check to see whether source_ is non-null.
493 // Right now, this shouldn't be possible, but an explicit check might
494 // be good.
495
496 // Update the neutrino energy probability density function by including the
497 // cross section for the new reaction
498 normalize_E_pdf();
499 }
500}

◆ add_state_to_event() [1/2]

void marley::Generator::add_state_to_event ( HepMC3::GenEvent & ev) const

Attach the current random number generator state to the input event as a string attribute.

Definition at line 880 of file Generator.cc.

880 {
881
882 // Query the random number generator for its current state string
883 std::string state = this->get_state_string();
884
885 // Attach the random number generator state string to the event as a
886 // string attribute
887 this->add_state_to_event( ev, state );
888}
void add_state_to_event(HepMC3::GenEvent &ev) const
Attach the current random number generator state to the input event as a string attribute.
Definition Generator.cc:880
std::string get_state_string() const
Get a string that represents the current internal state of this Generator.
Definition Generator.cc:168

References add_state_to_event(), and get_state_string().

Referenced by add_state_to_event(), marley::CommandHandler::cmd_generate(), and finish_event_metadata().

◆ add_state_to_event() [2/2]

void marley::Generator::add_state_to_event ( HepMC3::GenEvent & ev,
const std::string & state )
static

Attach a user-supplied random number generator state string to the input event as a string attribute.

Definition at line 890 of file Generator.cc.

892{
893 ev.add_attribute( "MARLEY.GeneratorState",
894 std::make_shared< HepMC3::StringAttribute >( state )
895 );
896}
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)

References HepMC3::GenEvent::add_attribute().

◆ assign_run_info()

void marley::Generator::assign_run_info ( HepMC3::GenEvent & event) const

Associates the owned GenRunInfo object with the input event.

Definition at line 854 of file Generator.cc.

854 {
855 event.set_run_info( run_info_ );
856}

Referenced by finish_event_metadata().

◆ clear_reactions()

void marley::Generator::clear_reactions ( )

Clear the vector of Reaction objects owned by this Generator.

Definition at line 502 of file Generator.cc.

502 {
503 reactions_.clear();
504 total_xs_values_.clear();
505 // Reset the normalization factor to 1. We don't need it until we define
506 // one or more new reactions.
507 norm_ = 1.;
508}

◆ create_event() [1/2]

std::shared_ptr< HepMC3::GenEvent > marley::Generator::create_event ( bool attach_state = false)

Create an Event using the NeutrinoSource, Target, Reaction, and StructureDatabase objects owned by this Generator.

Parameters
attach_stateWhether to attach the random number generator state to the event as a string attribute

Definition at line 77 of file Generator.cc.

79{
80 // (0) Initialize the run information if it has not been set up yet
81 if ( !run_info_ ) {
82 this->set_up_run_info();
83 }
84
85 // (1) Select a reacting neutrino energy and reaction using the
86 // flux-weighted total cross section(s)
87 double E_nu;
88 marley::Reaction& r = sample_reaction( E_nu );
89
90 // (2) Create the prompt two-two scattering event using the
91 // sampled reaction object
92 int pdg_a = source_->get_pid();
93 std::shared_ptr< HepMC3::GenEvent > ev = r.create_event( pdg_a, E_nu, *this );
94
95 // E.C.2 and E.C.3
96 // Save total and reaction cross sections as metadata in the event.
97 // NOTE: the expected value for NuHepMC3 E.C.2 is the total cross section for
98 // the selected projectile and target, so we loop over relevant reactions
99 // manually to avoid imposing target fraction weighting to this particular
100 // calculation.
101 double totXS = 0.;
102 for ( const auto& temp_r : reactions_ ) {
103
104 // Skip reactions which involve a different target atom from the selected
105 // one
106 if ( temp_r->atomic_target().pdg() != r.atomic_target().pdg() ) continue;
107
108 // Skip reactions which involve a different projectile
109 if ( temp_r->pdg_a() != r.pdg_a() ) continue;
110
111 double temp_xsec = temp_r->total_xs( pdg_a, E_nu );
112 if ( temp_xsec > 0. ) {
113 totXS += temp_xsec;
114 }
115
116 }
117
118 // Convert to picobarns
119 totXS *= marley_utils::hbar_c2 * marley_utils::fm2_to_picobarn;
120
121 ev->add_attribute( "tot_xs",
122 std::make_shared< HepMC3::DoubleAttribute >( totXS )
123 );
124
125 double procXS = r.total_xs( pdg_a, E_nu ) * marley_utils::hbar_c2
126 * marley_utils::fm2_to_picobarn;
127
128 ev->add_attribute( "proc_xs",
129 std::make_shared< HepMC3::DoubleAttribute >( procXS )
130 );
131
132 // (3) If needed, de-excite the final-state residue
133 if ( do_deexcitations_ ) {
134 marley::NucleusDecayer nd;
135 nd.process_event( *ev, *this );
136 }
137
138 // (4) If needed, rotate the event to match the desired projectile direction
139 rotator_.process_event( *ev, *this );
140
141 // (5) Finish adding metadata to the event object
142 this->finish_event_metadata( *ev, attach_state );
143
144 // Return the completed event object
145 return ev;
146}
void set_up_run_info()
Initializes the owned GenRunInfo object that will be used to associate run metadata with the output e...
Definition Generator.cc:769
marley::Reaction & sample_reaction(double &E)
Sample a Reaction and an energy for the reacting neutrino.
Definition Generator.cc:390
void finish_event_metadata(HepMC3::GenEvent &ev, bool attach_state=false)
Add final pieces of metadata (e.g., the RNG state) to an otherwise complete event.
Definition Generator.cc:827
virtual void process_event(HepMC3::GenEvent &event, marley::Generator &gen) override
Processes an input GenEvent object.
virtual double total_xs(int pdg_a, double KEa) const =0
Compute the reaction's total cross section (MeV -2)
virtual marley::TargetAtom atomic_target() const =0
Returns the target atom involved in this reaction.
virtual std::shared_ptr< HepMC3::GenEvent > create_event(int pdg_a, double KEa, marley::Generator &gen) const =0
Create an event object for this reaction.
int pdg_a() const
Get the projectile PDG code.
Definition Reaction.hh:109
int pdg() const
Returns the nuclear PDG code of the target atom.
Definition TargetAtom.hh:73

References HepMC3::GenEvent::add_attribute(), marley::Reaction::atomic_target(), marley::Reaction::create_event(), finish_event_metadata(), marley::TargetAtom::pdg(), marley::Reaction::pdg_a(), marley::NucleusDecayer::process_event(), sample_reaction(), set_up_run_info(), and marley::Reaction::total_xs().

◆ create_event() [2/2]

std::shared_ptr< HepMC3::GenEvent > marley::Generator::create_event ( int pdg_a,
double KEa,
int pdg_atom,
const std::array< double, 3 > & dir_vec,
bool attach_state = false )

Creates an event object for a fixed projectile species, kinetic energy, and atomic target.

If no energetically-accessible reaction is available for the given input parameters, then a marley::Error will be thrown.

Note
This function is not used as part of the normal MARLEY workflow. It serves as part of an API that enables MARLEY to be interfaced with an external flux driver.
Parameters
pdg_aThe PDG code for the projectile
KEaThe kinetic energy of the projectile (MeV)
pdg_atomThe nuclear PDG code for the atomic target
dir_vecDirection three-vector of the projectile
attach_stateWhether to attach the random number generator state to the event as a string attribute

Definition at line 667 of file Generator.cc.

670{
671 // (0) Initialize the run information if it has not been set up yet
672 if ( !run_info_ ) {
673 this->set_up_run_info();
674 }
675
676 // (1) Sample a reaction mode from all configured reactions that can handle
677 // the given initial-state parameters
678 std::vector<size_t> indices;
679 std::vector<double> xsecs;
680 double tot_xsec = this->total_xs( pdg_a, KEa, pdg_atom, &indices, &xsecs );
681
682 if ( xsecs.empty() || tot_xsec <= 0. ) throw marley::Error(
683 "Cannot create an event for a projectile with kinetic energy = "
684 + std::to_string(KEa) + " MeV and PDG code " + std::to_string(pdg_a)
685 + " striking an atom with PDG code " + std::to_string(pdg_atom)
686 + ". The total cross section vanishes for all configured reactions" );
687
688 // The total cross section values and indices in the full reactions_ vector
689 // have already been loaded into temporary vectors, so we can immediately use
690 // those to sample a reaction using a discrete distribution.
691 std::discrete_distribution< size_t > react_dist( xsecs.begin(), xsecs.end() );
692 size_t sampled_index = react_dist( rand_gen_ );
693 auto& r = reactions_.at( indices.at(sampled_index) );
694
695 // (2) Create the prompt two-two scattering event using the sampled reaction
696 // object
697 std::shared_ptr< HepMC3::GenEvent > ev = r->create_event( pdg_a, KEa, *this );
698
699 // E.C.2 and E.C.3
700 // Save total and reaction cross sections as metadata in the event
701 double totXS = tot_xsec * marley_utils::hbar_c2
702 * marley_utils::fm2_to_picobarn;
703
704 ev->add_attribute( "tot_xs",
705 std::make_shared< HepMC3::DoubleAttribute >( totXS )
706 );
707
708 double procXS = xsecs.at( sampled_index ) * marley_utils::hbar_c2
709 * marley_utils::fm2_to_picobarn;
710
711 ev->add_attribute( "proc_xs",
712 std::make_shared< HepMC3::DoubleAttribute >( procXS )
713 );
714
715 // Do the usual post-processing
716
717 // (3) If needed, de-excite the final-state residue
718 if ( do_deexcitations_ ) {
719 marley::NucleusDecayer nd;
720 nd.process_event( *ev, *this );
721 }
722
723 // (4) If needed, rotate the event to match the desired projectile direction
724 // Set the incident neutrino direction for this event
725 static marley::ProjectileDirectionRotator my_rotator;
726 my_rotator.set_projectile_direction( dir_vec );
727
728 // Rotate the coordinate system of the event if needed
729 my_rotator.process_event( *ev, *this );
730
731 // (5) Finish adding metadata to the event object
732 this->finish_event_metadata( *ev, attach_state );
733
734 // Return the completed event object
735 return ev;
736}
double total_xs(int pdg_a, double KEa, int pdg_atom) const
Computes the total cross section at fixed energy for all configured reactions involving a particular ...
Definition Generator.cc:629
virtual void process_event(HepMC3::GenEvent &ev, marley::Generator &gen) override
Rotates all 3-momenta in the input event so that the projectile 3-momentum lies along dir_vec_ in the...

References HepMC3::GenEvent::add_attribute(), finish_event_metadata(), marley::NucleusDecayer::process_event(), marley::ProjectileDirectionRotator::process_event(), set_up_run_info(), and total_xs().

◆ E_pdf()

double marley::Generator::E_pdf ( double E)

Probability density function that describes the distribution of reacting neutrino energies.

This function computes the cross-section weighted neutrino flux (normalized to unity between source_->E_min and source_->E_max) including cross-section contributions from all Reactions owned by this Generator. For the distribution of incident neutrino energies, use marley::NeutrinoSource::pdf()

Parameters
ETotal energy of the reacting neutrino
Returns
Probability density (MeV -1)

Definition at line 335 of file Generator.cc.

335 {
336
337 // Initialize the return value to zero
338 double pdf = 0.;
339
340 // Sum all of the reaction total cross sections, saving
341 // each individual value along the way. Take weighting
342 // by atom fraction in the target material into account.
343 for ( size_t j = 0, s = reactions_.size(); j < s; ++j ) {
344
345 // Get the current reaction
346 const auto& react = reactions_.at( j );
347
348 // Compute the total cross section for the current reaction for a single
349 // target atom
350 double tot_xs = react->total_xs( source_->get_pid(), E );
351
352 // If the target_ member has not been initialized, don't bother doing any
353 // weighting by atom fraction (equivalent to a weight of unity for all
354 // target atoms)
355 if ( target_ ) {
356 // If it has been configured, then apply the appropriate atom fraction
357 // weight from the target as appropriate.
358 tot_xs *= target_->atom_fraction( react->atomic_target() );
359 }
360
361 // Cache the atom-fraction-weighted total cross section for sampling a
362 // reaction mode later
363 total_xs_values_.at( j ) = tot_xs;
364
365 // Add the weighted total cross section value to the total
366 pdf += tot_xs;
367 }
368
369 // Normally, we want to fold the flux with the reaction cross section(s)
370 // in order to obtain the distribution of reacting neutrino energies
371 if ( weight_flux_ ) {
372 // Multiply the total cross section by the neutrino spectrum
373 // from the source object to get the (unnormalized) PDF
374 // for sampling reacting neutrino energies.
375 pdf *= source_->pdf( E );
376 }
377 else {
378 // If the user has specifically requested it, don't weight the
379 // energy PDF by the cross section(s), as long as at least one of them
380 // is non-vanishing
381 if ( pdf <= 0. ) return 0.;
382 pdf = source_->pdf( E );
383 }
384
385 // Divide by the normalization factor (computed when this source
386 // was made available to the Generator) to obtain the normalized PDF.
387 return pdf / norm_;
388}

Referenced by sample_reaction().

◆ finish_event_metadata()

void marley::Generator::finish_event_metadata ( HepMC3::GenEvent & ev,
bool attach_state = false )

Add final pieces of metadata (e.g., the RNG state) to an otherwise complete event.

Parameters
attach_stateWhether to attach the random number generator state to the event as a string attribute

Definition at line 827 of file Generator.cc.

829{
830 // Associate the owned run information with the event
831 this->assign_run_info( ev );
832
833 // Calculate any needed weight(s) for the event
834 weighter_->process_event( ev, *this );
835
836 // Add the generator state after the event was completed as a string
837 // attribute. This allows resuming an interrupted job from where it left off.
838 if ( attach_state ) this->add_state_to_event( ev );
839
840 // E.R.5
841 // TODO: revisit spatial position when MARLEY is interfaced with a
842 // detector geometry simulation
843 const std::vector< double > lab_pos = { 0., 0., 0. };
844 ev.add_attribute( "lab_pos",
845 std::make_shared< HepMC3::VectorDoubleAttribute >( lab_pos )
846 );
847
848}
void assign_run_info(HepMC3::GenEvent &event) const
Associates the owned GenRunInfo object with the input event.
Definition Generator.cc:854

References HepMC3::GenEvent::add_attribute(), add_state_to_event(), and assign_run_info().

Referenced by marley::CommandHandler::cmd_decay(), create_event(), and create_event().

◆ flux_averaged_total_xs()

double marley::Generator::flux_averaged_total_xs ( ) const

Computes the flux-averaged total cross section for all enabled neutrino reactions, taking target atom fractions into account as appropriate.

If flux weighting is disabled (via a call to set_weight_flux()) then this function will return zero

Returns
Total cross section (MeV -2)

Definition at line 587 of file Generator.cc.

587 {
588 // If we've disabled weighting the neutrino energy PDF
589 // by the total cross section, just return zero
590 if ( !weight_flux_ ) return 0.;
591
592 double avg_total_xs = 0.;
593
594 // For a monoenergetic source, don't bother to do the full
595 // integral
596 double Emin = source_->get_Emin();
597 double Emax = source_->get_Emax();
598 if ( Emin == Emax ) {
599 avg_total_xs = norm_ / source_->pdf( Emin );
600 }
601 else {
602 double source_norm = marley_utils::num_integrate(
603 [this](double Ev) -> double { return this->source_->pdf(Ev); },
604 Emin, Emax );
605
606 // Use the precomputed integral of the reacting neutrino energy PDF
607 avg_total_xs = norm_ / source_norm;
608 }
609 return avg_total_xs;
610}

Referenced by set_up_run_info().

◆ get_reactions()

const std::vector< std::unique_ptr< marley::Reaction > > & marley::Generator::get_reactions ( ) const
inline

Get a const reference to the vector of Reaction objects owned by this Generator.

Definition at line 468 of file Generator.hh.

468{ return reactions_; }

Referenced by marley::StrengthVariationWeightCalculator::create_instances(), and marley::StrengthVariationWeightCalculator::ensure_initialized().

◆ get_rotator()

marley::ProjectileDirectionRotator & marley::Generator::get_rotator ( )
inline

Provides access to the owned ProjectileDirectionRotator.

Definition at line 287 of file Generator.hh.

288 { return rotator_; }

◆ get_seed()

uint_fast64_t marley::Generator::get_seed ( ) const
inline

Get the seed used to initialize this Generator.

Definition at line 465 of file Generator.hh.

465{ return seed_; }

◆ get_source()

const marley::NeutrinoSource & marley::Generator::get_source ( ) const

Get a const reference to the NeutrinoSource owned by this Generator.

Throws a marley::Error if this Generator does not own a NeutrinoSource object.

Definition at line 449 of file Generator.cc.

449 {
450 if ( source_ ) return *source_;
451 else throw marley::Error( "Error in marley::Generator::get_source()."
452 " The member variable source_ == nullptr." );
453}

◆ get_state_string()

std::string marley::Generator::get_state_string ( ) const

Get a string that represents the current internal state of this Generator.

Definition at line 168 of file Generator.cc.

168 {
169 std::stringstream ss;
170 ss << rand_gen_;
171 return ss.str();
172}

Referenced by add_state_to_event().

◆ get_structure_db()

marley::StructureDatabase & marley::Generator::get_structure_db ( )

Get a reference to the StructureDatabase owned by this Generator.

Definition at line 510 of file Generator.cc.

510 {
511 if ( structure_db_ ) return *structure_db_;
512 else throw marley::Error( "Error in marley::Generator::get_structure_db()."
513 " The member variable structure_db_ == nullptr." );
514}

Referenced by marley::CommandHandler::cmd_decay(), marley::DiscreteNuclearReaction::create_event(), and marley::NucleusDecayer::process_event().

◆ get_target()

const marley::Target & marley::Generator::get_target ( ) const

Get a const reference to the Target owned by this Generator.

Throws a marley::Error if this Generator does not own a Target object.

Definition at line 455 of file Generator.cc.

455 {
456 if ( target_ ) return *target_;
457 else throw marley::Error( "Error in marley::Generator::get_target()."
458 " The member variable target_ == nullptr." );
459}

◆ get_weighter() [1/2]

marley::Weighter & marley::Generator::get_weighter ( )
inline

Get a non-const reference to the owned Weighter object.

Definition at line 317 of file Generator.hh.

317{ return *weighter_; }

◆ get_weighter() [2/2]

const marley::Weighter & marley::Generator::get_weighter ( ) const
inline

Get a const reference to the owned Weighter object.

Definition at line 313 of file Generator.hh.

314 { return *weighter_; }

◆ inverse_transform_sample() [1/2]

double marley::Generator::inverse_transform_sample ( const marley::InterpolatingFunction & cdf,
double xmin,
double xmax,
double bisection_tolerance = 1e-12 )

Sample from a given 1D cumulative density function cdf(x) on the interval [xmin, xmax] using bisection.

Parameters
cdfCumulative density function to use for sampling
xminLower bound of the sampling interval
xmaxUpper bound of the sampling interval
Returns
Sampled value of x

Definition at line 552 of file Generator.cc.

555{
556 // Sample a probability value uniformly on [0, 1]
557 double prob = uniform_random_double(0., 1., true);
558
559 // If we chose an endpoint, we're done, so just return the appropriate one
560 if ( prob == 0. ) return xmin;
561 else if ( prob == 1. ) return xmax;
562
563 // A properly normalized CDF should evaluate to unity at x = xmax. We enforce
564 // this here so that the user doesn't have to do it in advance.
565 double norm = cdf.evaluate( xmax );
566
567 // Find the x value corresponding to the sampled probability via bisection
568 // (slow but robust)
569 double a = xmin;
570 double b = xmax;
571 while ( (b - a) > bisection_tolerance ) {
572 double midpoint = (a + b) / 2.;
573 double mid_cdf = cdf.evaluate( midpoint ) / norm;
574 // If the CDF at the midpoint exactly matches our sampled
575 // probability, we're done. Just return the midpoint.
576 if ( mid_cdf == prob ) return midpoint;
577 // Otherwise, shrink the bisection interval and try again
578 else if ( mid_cdf > prob ) b = midpoint;
579 else a = midpoint; // mid_cdf < prob
580 }
581
582 // Return the midpoint of the bisection interval as our sampled x value
583 double x = (a + b) / 2.;
584 return x;
585}
double uniform_random_double(double min, double max, bool inclusive)
Sample a random number uniformly on either [min, max) or [min, max].
Definition Generator.cc:235
virtual double evaluate(double x) const =0
Returns an approximate value of the represented function.

References marley::InterpolatingFunction::evaluate(), and uniform_random_double().

Referenced by inverse_transform_sample().

◆ inverse_transform_sample() [2/2]

double marley::Generator::inverse_transform_sample ( const std::function< double(double)> & f,
double xmin,
double xmax,
double bisection_tolerance = 1e-12 )

Sample from a given 1D probability density function f(x) on the interval [xmin, xmax] using an inverse transform technique.

Parameters
fProbability density function to use for sampling
xminLower bound of the sampling interval
xmaxUpper bound of the sampling interval
Returns
Sampled value of x
Todo
Remove hard-coded number of points here

Definition at line 536 of file Generator.cc.

539{
540 // Build an approximate CDF corresponding to the integral of the input PDF.
541 // Use a polynomial approximant at Chebyshev points to do it.
543 marley::ChebyshevInterpolatingFunction func(f, xmin, xmax,
544 DEFAULT_N_CHEBYSHEV);
545 auto cdf = func.cdf();
546
547 // Now that we have a CDF to use for sampling, delegate the rest of the
548 // action to the overloaded version of this function.
549 return this->inverse_transform_sample(cdf, xmin, xmax, bisection_tolerance);
550}
double inverse_transform_sample(const marley::InterpolatingFunction &cdf, double xmin, double xmax, double bisection_tolerance=1e-12)
Sample from a given 1D cumulative density function cdf(x) on the interval [xmin, xmax] using bisectio...
Definition Generator.cc:552

References inverse_transform_sample().

◆ json_config()

const std::string & marley::Generator::json_config ( ) const
inline

Definition at line 290 of file Generator.hh.

290{ return json_config_; }

◆ neutrino_direction()

const std::array< double, 3 > & marley::Generator::neutrino_direction ( )
inline

Gets the direction of the incident neutrinos that is used when generating events.

Definition at line 470 of file Generator.hh.

471 { return rotator_.projectile_direction(); }

◆ rejection_sample()

double marley::Generator::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 rejection method.

Parameters
fProbability density function to use for sampling
xminLower bound of the sampling interval
xmaxUpper bound of the sampling interval
max_search_toleranceTolerance to use when finding the maximum of f(x) using Brent's method
Returns
Sampled value of x

The rejection method used by this function consists of the following steps:

  1. Find the maximum of the function f(x) on [xmin, xmax]
  2. Sample an x value uniformly over f(x)'s domain
  3. Sample a y value uniformly over [0, max(f(x))]
  4. If y <= f(x), accept the sampled x value
  5. If y > f(x), reject the sampled x value, and return to step 2 to try again

Note that f(x) does not need to be normalized, but its range must be nonnegative. In the first step, an iterative method (Brent's method) is used to find the maximum of f(x). The iterations will continue until two successive iterations agree within max_search_tolerance on the location of the maximum of f(x). To avoid problems with functions that yield double values that are small compared to a typical value of max_search_tolerance (say, max_search_tolerance = 1e-8, while many neutrino cross sections of interest for MARLEY are less than 1e-40 cm^2), MARLEY normalizes all probability density functions to unity before using rejection sampling.

Definition at line 281 of file Generator.cc.

284{
285 // If we were passed the value marley_utils::UNKNOWN_MAX for fmax, then this
286 // signals that we need to search for the function maximum ourselves.
287 // Otherwise, we'll assume that the value passed over is good.
288 if ( fmax == marley_utils::UNKNOWN_MAX ) {
289 // This variable will be loaded with the value of x
290 // that corresponds to the maximum of f(x).
291 // We don't actually use this, but currently it's
292 // a required parameter of marley_utils::maximize
293 double x_at_max;
294
295 // Maximize the function and multiply by a safety factor just
296 // in case we didn't quite find the exact peak
297 fmax = marley_utils::maximize( f, xmin, xmax, max_search_tolerance,
298 x_at_max ) * safety_factor;
299 }
300
301 MARLEY_LOG( TRACE, "physics.generator.sampling" ) << "rejection_sample:"
302 " xmin = " << xmin << ", xmax = " << xmax << ", initial fmax = " << fmax;
303
304 double x, y, val;
305
306 do {
307 // Sample x value uniformly from [xmin, xmax]
308 x = uniform_random_double( xmin, xmax, true );
309
310 // Sample y uniformly from [0, fmax]
311 y = uniform_random_double( 0., fmax, true );
312
313 val = f( x );
314 MARLEY_LOG( TRACE, "physics.generator.sampling" ) << "rejection_sample:"
315 " trial x = " << x << ", y = " << y << ", f(x) = " << val;
316 if ( val > fmax ) {
317
318 MARLEY_LOG( WARN, "physics.generator.sampling" ) << "PDF value f(x) = "
319 << val << " at x = " << x << " exceeded the estimated maximum"
320 << " fmax = " << fmax << " during rejection sampling.";
321
322 fmax = val * safety_factor;
323 MARLEY_LOG( WARN, "physics.generator.sampling" )
324 << "A new estimate fmax = " << val * safety_factor
325 << " will now be adopted.";
326 }
327 }
328 // Keep sampling until you get a y value less than f(x)
329 // (the probability density function evaluated at the sampled value of x)
330 while ( y > val );
331
332 return x;
333}

References uniform_random_double().

Referenced by marley::ElectronReaction::create_event(), marley::DiscreteNuclearReaction::sample_cos_theta_c_cm(), marley::NeutrinoSource::sample_incident_neutrino(), and sample_reaction().

◆ reseed()

void marley::Generator::reseed ( uint_fast64_t seed)

Reseeds the Generator.

Definition at line 156 of file Generator.cc.

156 {
157 // This is an attempt to do a decent job of seeding the random number
158 // generator, but optimally accomplishing this can be tricky (see, for
159 // example, http://www.pcg-random.org/posts/cpp-seeding-surprises.html)
160 seed_ = seed;
161 std::seed_seq seed_sequence{ seed_ };
162 rand_gen_.seed( seed_sequence );
163
164 MARLEY_LOG( NOTICE, "physics.generator" ) << "Seeded random number generator with "
165 << seed_;
166}

Referenced by Generator().

◆ run_info()

const std::shared_ptr< HepMC3::GenRunInfo > & marley::Generator::run_info ( ) const
inline

Definition at line 292 of file Generator.hh.

293 { return run_info_; }

◆ sample_decay_time()

double marley::Generator::sample_decay_time ( double partial_width)

Sample a random decay time given a partial decay width.

Parameters
partial_widthPartial decay width (MeV) for the decay process of interest
Returns
Time for a decay via this process to occur (MeV -1)

Definition at line 859 of file Generator.cc.

859 {
860 if ( partial_width <= 0. ) throw marley::Error( "Non-positive partial decay"
861 " width passed to marley::Generator::sample_decay_time()" );
862
863 // Mean lifetime (1/MeV)
864 double tau = 1. / partial_width;
865
866 // Find the double value that comes immediately after zero. This allows us
867 // exclude zero and sample uniformly on (0, 1]. Including zero would lead to
868 // the possibility of an infinite decay time. See http://tinyurl.com/n3ocg3p
869 // for more information.
870 double min_to_use = std::nextafter( 0., std::numeric_limits<double>::max() );
871
872 // Choose a random number uniformly on (0, 1].
873 double r = this->uniform_random_double( min_to_use, 1., true );
874
875 // Decay time in MeV^{-1}
876 double t = -tau * std::log( r );
877 return t;
878}

References uniform_random_double().

◆ sample_from_distribution() [1/2]

template<class RandomNumberDistribution>
auto marley::Generator::sample_from_distribution ( RandomNumberDistribution & rnd) -> decltype( std::declval<RandomNumberDistribution&>().operator()( std::declval<std::mt19937_64&>()) )
inline

Sample from an arbitrary probability distribution (defined here as any object that implements an operator()(std::mt19937_64&) function) @detail This template function is based on https://stackoverflow.com/a/9154394/4081973.

Definition at line 193 of file Generator.hh.

196 {
197 return rnd(rand_gen_);
198 }

Referenced by marley::CommandHandler::cmd_decay(), marley::ContinuumNuclearReaction::create_event(), marley::DiscreteNuclearReaction::create_event(), marley::HauserFeshbachDecay::sample_exit_channel(), and marley::Level::sample_gamma().

◆ sample_from_distribution() [2/2]

template<class RandomNumberDistribution, typename ParamType>
auto marley::Generator::sample_from_distribution ( RandomNumberDistribution & rnd,
const ParamType & params ) -> decltype( std::declval<RandomNumberDistribution&>().operator()( std::declval<std::mt19937_64&>(), std::declval<const ParamType&>() ) )
inline

Sample from an arbitrary probability distribution (defined here as any object that implements an operator()(std::mt19937_64&, const ParamType&) function) using the parameters params.

Definition at line 205 of file Generator.hh.

209 {
210 return rnd(rand_gen_, params);
211 }

◆ sample_reaction()

marley::Reaction & marley::Generator::sample_reaction ( double & E)

Sample a Reaction and an energy for the reacting neutrino.

Parameters
[out]ETotal energy of the neutrino undergoing the reaction
Returns
Reference to the sampled Reaction owned by this Generator

Definition at line 390 of file Generator.cc.

390 {
391 if ( reactions_.empty() ) throw marley::Error( "Cannot sample"
392 " a reaction in marley::Generator::sample_reaction(). The vector of"
393 " marley::Reaction objects owned by this generator is empty." );
394
395 // Store the "old" value of E_pdf_max_, i.e., the one we had before calling
396 // rejection_sample(). This will be used to check for problems.
397 double old_max = E_pdf_max_;
398
399 // TODO: protect against source_ changing E_min or E_max after you compute
400 // the normalization factor norm_ in marley::Generator::init()
401 E = rejection_sample( [this](double E_nu)
402 -> double { return this->E_pdf(E_nu); }, source_->get_Emin(),
403 source_->get_Emax(), E_pdf_max_ );
404
405 // If the value of max changed after the call to rejection_sample() and the
406 // old value wasn't UNKNOWN_MAX, then the rejection sampling routine must
407 // have encountered a PDF value that was larger than our estimated maximum.
408 // Alert the user about this and advise them to change the configuration
409 // appropriately to avoid a biased reacting neutrino energy distribution.
410 static bool issued_long_error_message = false;
411 if ( old_max != marley_utils::UNKNOWN_MAX
412 && old_max != E_pdf_max_ )
413 {
414 if ( !issued_long_error_message ) {
415 MARLEY_LOG( ERROR, "physics.generator.sampling" )
416 << "Estimation of the maximum PDF value failed when"
417 << " using a rejection method to sample reacting neutrino energies.\n"
418 << "This may occur when, e.g., an incident neutrino flux"
419 << " is used that includes multiple sharp peaks.\n"
420 << "To avoid biasing the energy distribution, please rerun the"
421 << " simulation after adding the following line to the MARLEY job"
422 << " configuration file:\n"
423 << " energy_pdf_max: " << E_pdf_max_ << ",\n"
424 << "If this error message persists after raising energy_pdf_max to a"
425 << " relatively high value, please contact the MARLEY developers for"
426 << " troubleshooting help.";
427 issued_long_error_message = true;
428 }
429 else {
430 MARLEY_LOG( ERROR, "physics.generator.sampling" )
431 << "The maximum PDF value for sampling reacting"
432 << " neutrino energies was exceeded again. The new estimated maximum is"
433 << "\n energy_pdf_max: " << E_pdf_max_ << ',';
434 }
435 }
436
437 // The atom-fraction-weighted total cross section values have already been
438 // updated by the final call to E_pdf() during rejection sampling, so we can
439 // now sample a reaction type using our discrete distribution object.
440 std::discrete_distribution<size_t>::param_type
441 params( total_xs_values_.begin(), total_xs_values_.end() );
442 size_t r_index = r_index_dist_( rand_gen_, params );
443 auto& sampled_reaction = *reactions_.at( r_index );
444 MARLEY_LOG( DEBUG, "physics.generator" ) << "Sampled reaction: "
445 << sampled_reaction.get_description() << " at E_nu = " << E << " MeV";
446 return sampled_reaction;
447}
double E_pdf(double E)
Probability density function that describes the distribution of reacting neutrino energies.
Definition Generator.cc:335
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 ...
Definition Generator.cc:281

References E_pdf(), and rejection_sample().

Referenced by create_event().

◆ seed_using_state_string()

void marley::Generator::seed_using_state_string ( const std::string & state_string)

Use a string to set this Generator's internal state.

This function is typically used to restore a Generator to a state saved using get_state_string().

Definition at line 148 of file Generator.cc.

150{
151 // TODO: add error handling here (check that state_string is valid)
152 std::stringstream strstr( state_string );
153 strstr >> rand_gen_;
154}

◆ set_do_deexcitations()

void marley::Generator::set_do_deexcitations ( bool do_them)
inline

Sets the value of the do_deexcitations flag.

This should almost always be true. Use only if you know what you are doing.

Definition at line 473 of file Generator.hh.

474 { do_deexcitations_ = do_them; }

◆ set_neutrino_direction()

void marley::Generator::set_neutrino_direction ( const std::array< double, 3 > & dir_vec)

Sets the direction of the incident neutrinos to use when generating events.

Parameters
dir_vecVector that points in the direction of the incident neutrinos
Note
The dir_vec passed to this function does not need to be normalized, but it must have at least one nonzero element or a marley::Error will be thrown.

Definition at line 516 of file Generator.cc.

518{
519 rotator_.set_projectile_direction( dir_vec );
520
521 const auto& normalized_dir_vec = rotator_.projectile_direction();
522
523 // Print a log message announcing the change of direction
524 std::string dir_msg("Incident neutrino direction: (");
525 for ( size_t i = 0; i < 3; ++i ) {
526 dir_msg += std::to_string( normalized_dir_vec[i] );
527 if ( i < 2 ) dir_msg += ", ";
528 }
529 MARLEY_LOG( INFO, "physics.generator" ) << dir_msg << ')';
530}

◆ set_run_info()

void marley::Generator::set_run_info ( const std::shared_ptr< HepMC3::GenRunInfo > & run_info)
inline

Definition at line 298 of file Generator.hh.

299 { run_info_ = run_info; }

◆ set_source()

void marley::Generator::set_source ( std::unique_ptr< marley::NeutrinoSource > source)

Take ownership of a new NeutrinoSource, replacing any existing source owned by this Generator.

Parameters
sourceA pointer to the new NeutrinoSource to use

Definition at line 461 of file Generator.cc.

463{
464 // If we're passed a nullptr, then don't bother to do anything
465 if ( source ) {
466 // Transfer ownership of the neutrino source the generator, leaving
467 // the std::unique_ptr passed to this function null afterwards.
468 source_.reset( source.release() );
469
470 // Don't bother to renormalize if there are no reactions defined yet
471 if ( reactions_.empty() ) return;
472
473 // Update the neutrino energy probability density function based on the
474 // new source spectrum
475 this->normalize_E_pdf();
476 }
477}

◆ set_target()

void marley::Generator::set_target ( std::unique_ptr< marley::Target > target)

Take ownership of a new Target, replacing any existing target owned by this Generator.

Parameters
sourceA pointer to the new Target to use

Definition at line 612 of file Generator.cc.

613{
614 // If we're passed a nullptr, then don't bother to do anything
615 if ( target ) {
616 // Transfer ownership of the neutrino target to the generator, leaving
617 // the std::unique_ptr passed to this function null afterwards.
618 target_.reset( target.release() );
619
620 // Don't bother to renormalize if there are no reactions defined yet
621 if ( reactions_.empty() ) return;
622
623 // Update the neutrino energy probability density function based on the
624 // new target composition
625 this->normalize_E_pdf();
626 }
627}

◆ set_up_run_info()

void marley::Generator::set_up_run_info ( )

Initializes the owned GenRunInfo object that will be used to associate run metadata with the output events.

Definition at line 769 of file Generator.cc.

769 {
770
771 // G.R.1
772 run_info_ = std::make_shared< HepMC3::GenRunInfo >();
773
774 // G.R.2
775 run_info_->add_attribute( "NuHepMC.Version.Major",
776 std::make_shared< HepMC3::IntAttribute >(
777 marley_hepmc3::NUHEPMC_MAJOR_VERSION )
778 );
779
780 run_info_->add_attribute( "NuHepMC.Version.Minor",
781 std::make_shared< HepMC3::IntAttribute >(
782 marley_hepmc3::NUHEPMC_MINOR_VERSION )
783 );
784
785 run_info_->add_attribute( "NuHepMC.Version.Patch",
786 std::make_shared< HepMC3::IntAttribute >(
787 marley_hepmc3::NUHEPMC_PATCH_VERSION )
788 );
789
790 // G.R.3
791 run_info_->tools().emplace_back(
792 HepMC3::GenRunInfo::ToolInfo{ "MARLEY", MARLEY_VERSION,
793 MARLEY_GIT_REVISION }
794 );
795
796 // G.R.8
797 marley_hepmc3::prepare_process_metadata( *run_info_ );
798
799 // G.R.9
800 marley_hepmc3::prepare_vertex_status_metadata( *run_info_ );
801
802 // G.R.10
803 marley_hepmc3::prepare_particle_status_metadata( *run_info_ );
804
805 // G.R.7
806 const auto& wgt_names = weighter_->get_weight_names();
807 run_info_->set_weight_names( wgt_names );
808
809 // G.R.11
810 marley_hepmc3::prepare_non_standard_pdg_code_metadata( *run_info_ );
811
812 // G.R.4, G.R.6, G.C.2, G.C.3
813 double avg_xsec = this->flux_averaged_total_xs(); // MeV^{-2}
814 marley_hepmc3::apply_nuhepmc_runinfo_conventions( *run_info_, avg_xsec );
815
816 // Save the information needed to restore an interrupted MARLEY job
817 run_info_->add_attribute( "MARLEY.RNGseed",
818 std::make_shared< HepMC3::StringAttribute >( std::to_string(seed_) )
819 );
820
821 run_info_->add_attribute( "MARLEY.JSONconfig",
822 std::make_shared< HepMC3::StringAttribute >( json_config_ )
823 );
824
825}
double flux_averaged_total_xs() const
Computes the flux-averaged total cross section for all enabled neutrino reactions,...
Definition Generator.cc:587

References flux_averaged_total_xs().

Referenced by marley::CommandHandler::cmd_decay(), create_event(), and create_event().

◆ set_weight_flux()

void marley::Generator::set_weight_flux ( bool should_we_weight)

Sets the value of the weight_flux flag.

This is potentially dangerous. Use only if you know what you are doing.

Definition at line 532 of file Generator.cc.

532 {
533 weight_flux_ = should_we_weight;
534}

◆ set_weighter()

void marley::Generator::set_weighter ( std::shared_ptr< marley::Weighter > w)
inline

Replace the owned Weighter object.

Definition at line 320 of file Generator.hh.

321 { weighter_ = w; }

Referenced by marley::OutputFile::merge_reweight_provenance_weights().

◆ total_xs() [1/2]

double marley::Generator::total_xs ( int pdg_a,
double KEa ) const

Computes the abundance-weighted total cross section at fixed energy for all configured reactions.

Atom fractions in the owned Target are used to perform the weighting by nuclide abundance

Note
This function is not used as part of the normal MARLEY workflow. It exposes the abundance-weighted total cross section for use by the "marley xsec" subcommand
Parameters
pdg_aThe PDG code for the projectile
KEaThe kinetic energy of the projectile (MeV)
Returns
Abundance-weighted total cross section (MeV -2 / atom)

Definition at line 740 of file Generator.cc.

740 {
741
742 // Initialize the return value to zero
743 double tot_xsec = 0.;
744
745 // Sum all of the reaction total cross sections. Take weighting by atom
746 // fraction in the target material into account.
747 for ( const auto& react : reactions_ ) {
748
749 // Compute the total cross section for the current reaction for a single
750 // target atom
751 double xsec = react->total_xs( pdg_a, KEa );
752
753 // If the target_ member has not been initialized, don't bother doing any
754 // weighting by atom fraction (equivalent to a weight of unity for all
755 // target atoms)
756 if ( target_ ) {
757 // If it has been configured, then apply the appropriate atom fraction
758 // weight from the target as appropriate.
759 xsec *= target_->atom_fraction( react->atomic_target() );
760 }
761
762 // Add the weighted total cross section value to the total
763 tot_xsec += xsec;
764 }
765
766 return tot_xsec;
767}

◆ total_xs() [2/2]

double marley::Generator::total_xs ( int pdg_a,
double KEa,
int pdg_atom ) const

Computes the total cross section at fixed energy for all configured reactions involving a particular target atom.

Atom fractions in the owned Target are ignored by this function.

Note
This function is not used as part of the normal MARLEY workflow. It serves as part of an API that enables MARLEY to be interfaced with an external flux driver.
Parameters
pdg_aThe PDG code for the projectile
KEaThe kinetic energy of the projectile (MeV)
pdg_atomThe nuclear PDG code for the atomic target
Returns
Total cross section (MeV -2 / atom)

Definition at line 629 of file Generator.cc.

630{
631 return this->total_xs( pdg_a, KEa, pdg_atom, nullptr, nullptr );
632}

References total_xs().

Referenced by marley::CommandHandler::cmd_xsec(), create_event(), and total_xs().

◆ uniform_random_double()

double marley::Generator::uniform_random_double ( double min,
double max,
bool inclusive )

Sample a random number uniformly on either [min, max) or [min, max].

Parameters
minLower bound of the sampling interval
maxUpper bound of the sampling interval
inclusiveWhether the upper bound should be included (true) or excluded (false) from the possible sampling outcomes

Definition at line 235 of file Generator.cc.

237{
238 // Defaults to sampling from [0,1). We will always
239 // explicitly supply the upper and lower bounds to
240 // this distribution, so we won't worry about the
241 // default setting.
242 static std::uniform_real_distribution<double> udist;
243
244 double max_to_use;
245
246 if ( inclusive ) { // sample from [min, max]
247
248 // Find the double value that comes immediately after max. This allows us
249 // to sample uniformly on [min, max] rather than [min,max). This trick
250 // comes from http://tinyurl.com/n3ocg3p.
251 max_to_use = std::nextafter( max, std::numeric_limits<double>::max() );
252 }
253 else { // sample from [min, max)
254 max_to_use = max;
255 }
256
257 std::uniform_real_distribution<double>::param_type params( min, max_to_use );
258
259 // Sample a random double from this distribution
260 return udist( rand_gen_, params );
261}

Referenced by marley::CommandHandler::cmd_decay(), marley::ContinuumNuclearReaction::create_event(), marley::DiscreteNuclearReaction::create_event(), marley::ElectronReaction::create_event(), marley::DecayScheme::do_cascade(), inverse_transform_sample(), marley::ExitChannel::prepare_products(), rejection_sample(), and sample_decay_time().


The documentation for this class was generated from the following files: