LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
evgen::MarleyTimeGen Class Reference
Inheritance diagram for evgen::MarleyTimeGen:
art::EDProducer art::ProducerBase art::Consumer art::EngineCreator art::ProductRegistryHelper

Classes

struct  Config
 Collection of configuration parameters for the module. More...
 
class  FitParameters
 Stores parsed fit parameters from a single time bin and neutrino type in a "fit"-format spectrum file. More...
 
class  TimeFit
 Stores fitting parameters for all neutrino types from a single time bin in a "fit"-format spectrum file. More...
 

Public Types

using Name = fhicl::Name
 
using Comment = fhicl::Comment
 
using Parameters = art::EDProducer::Table< Config >
 
using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
template<typename UserConfig , typename KeysToIgnore = void>
using Table = ProducerBase::Table< UserConfig, KeysToIgnore >
 

Public Member Functions

 MarleyTimeGen (const Parameters &p)
 
virtual ~MarleyTimeGen ()
 
virtual void produce (art::Event &e) override
 
virtual void beginRun (art::Run &run) override
 
virtual void reconfigure (const Parameters &p)
 
template<typename PROD , BranchType B = InEvent>
ProductID getProductID (std::string const &instanceName={}) const
 
template<typename PROD , BranchType B>
ProductID getProductID (ModuleDescription const &moduleDescription, std::string const &instanceName) const
 
bool modifiesEvent () const
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > consumes (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > consumesView (InputTag const &it)
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > mayConsume (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > mayConsumeView (InputTag const &it)
 
base_engine_tcreateEngine (seed_t seed)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make, label_t const &engine_label)
 
seed_t get_seed_value (fhicl::ParameterSet const &pset, char const key[]="seed", seed_t const implicit_seed=-1)
 

Static Public Member Functions

static cet::exempt_ptr< Consumernon_module_context ()
 

Protected Types

enum  TimeGenSamplingMode { TimeGenSamplingMode::HISTOGRAM, TimeGenSamplingMode::UNIFORM_TIME, TimeGenSamplingMode::UNIFORM_ENERGY }
 Enumerated type that defines the allowed ways that a neutrino's energy and arrival time may be sampled. More...
 
enum  PinchParamType { PinchParamType::ALPHA, PinchParamType::BETA }
 Enumerated type that defines the pinching parameter conventions that are understood by this module. More...
 
enum  SpectrumFileFormat { SpectrumFileFormat::RootTH2D, SpectrumFileFormat::FIT }
 Enumerated type that defines the allowed neutrino spectrum input file formats. More...
 

Protected Member Functions

simb::MCTruth make_uniform_energy_mctruth (double E_min, double E_max, double &E_nu, const TLorentzVector &vertex_pos)
 Creates a simb::MCTruth object using a uniformly-sampled neutrino energy. More...
 
std::unique_ptr< marley::NeutrinoSource > source_from_time_fit (const TimeFit &fit)
 Create a MARLEY neutrino source object using a set of fit parameters for a particular time bin. More...
 
void create_truths_th2d (simb::MCTruth &mc_truth, sim::SupernovaTruth &sn_truth, const TLorentzVector &vertex_pos)
 Create simb::MCTruth and sim::SupernovaTruth objects using spectrum information from a ROOT TH2D. More...
 
void create_truths_time_fit (simb::MCTruth &mc_truth, sim::SupernovaTruth &sn_truth, const TLorentzVector &vertex_pos)
 Create simb::MCTruth and sim::SupernovaTruth objects using a neutrino spectrum described by a previously-parsed "fit"-format file. More...
 
void make_final_timefit (double time)
 Helper function that makes a final dummy TimeFit object so that the final real time bin can have a right edge. More...
 
void make_nu_emission_histograms () const
 Makes ROOT histograms showing the emitted neutrinos in each time bin when using a "fit"-format spectrum file. More...
 
CurrentProcessingContext const * currentContext () const
 
void validateConsumedProduct (BranchType const bt, ProductInfo const &pi)
 
void prepareForJob (fhicl::ParameterSet const &pset)
 
void showMissingConsumes () const
 

Protected Attributes

std::unique_ptr< evgen::MARLEYHelperfMarleyHelper
 Object that provides an interface to the MARLEY event generator. More...
 
std::unique_ptr< evgen::ActiveVolumeVertexSamplerfVertexSampler
 Algorithm that allows us to sample vertex locations within the active volume(s) of the detector. More...
 
std::unique_ptr< marley::Event > fEvent
 unique_ptr to the current event created by MARLEY More...
 
std::unique_ptr< TH2D > fSpectrumHist
 ROOT TH2D that contains the time-dependent spectrum to use when sampling neutrino times and energies. More...
 
std::vector< TimeFitfTimeFits
 Vector that contains the fit parameter information for each time bin when using a "fit"-format spectrum file. More...
 
TimeGenSamplingMode fSamplingMode
 Represents the sampling mode to use when selecting neutrino times and energies. More...
 
PinchParamType fPinchType
 The pinching parameter convention to use when interpreting the time-dependent fits. More...
 
SpectrumFileFormat fSpectrumFileFormat
 Format to assume for the neutrino spectrum input file. More...
 
TTree * fEventTree
 The event TTree created by MARLEY. More...
 
uint_fast32_t fRunNumber
 Run number from the art::Event being processed. More...
 
uint_fast32_t fSubRunNumber
 Subrun number from the art::Event being processed. More...
 
uint_fast32_t fEventNumber
 Event number from the art::Event being processed. More...
 
double fTNu
 Time since the supernova core bounce for the current MARLEY neutrino vertex. More...
 
double fWeight
 Statistical weight for the current MARLEY neutrino vertex. More...
 
double fFluxAveragedCrossSection
 Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined reactions) used by MARLEY to generate neutrino vertices. More...
 
unsigned int fNeutrinosPerEvent
 The number of MARLEY neutrino vertices to generate in each art::Event. More...
 
double fFitEmin
 Minimum neutrino energy to consider when using a "fit"-format spectrum file. More...
 
double fFitEmax
 Maximum neutrino energy to consider when using a "fit"-format spectrum file. More...
 

Detailed Description

Definition at line 115 of file MARLEYTimeGen_module.cc.

Member Typedef Documentation

using art::EDProducer::ModuleType = EDProducer
inherited

Definition at line 34 of file EDProducer.h.

template<typename UserConfig , typename KeysToIgnore = void>
using art::EDProducer::Table = ProducerBase::Table<UserConfig, KeysToIgnore>
inherited

Definition at line 43 of file EDProducer.h.

using art::EDProducer::WorkerType = WorkerT<EDProducer>
inherited

Definition at line 35 of file EDProducer.h.

Member Enumeration Documentation

Enumerated type that defines the pinching parameter conventions that are understood by this module.

Enumerator
ALPHA 
BETA 

Definition at line 466 of file MARLEYTimeGen_module.cc.

466 { ALPHA, BETA };

Enumerated type that defines the allowed neutrino spectrum input file formats.

Enumerator
RootTH2D 
FIT 

Definition at line 487 of file MARLEYTimeGen_module.cc.

487 { RootTH2D, FIT };

Enumerated type that defines the allowed ways that a neutrino's energy and arrival time may be sampled.

Enumerator
HISTOGRAM 
UNIFORM_TIME 
UNIFORM_ENERGY 

Definition at line 435 of file MARLEYTimeGen_module.cc.

435 { HISTOGRAM, UNIFORM_TIME, UNIFORM_ENERGY };

Constructor & Destructor Documentation

evgen::MarleyTimeGen::MarleyTimeGen ( const Parameters p)
explicit

Definition at line 531 of file MARLEYTimeGen_module.cc.

References fEvent, fEventNumber, fEventTree, fRunNumber, fSubRunNumber, fTNu, fWeight, art::TFileDirectory::make(), and reconfigure().

532  : fEvent(new marley::Event), fRunNumber(0), fSubRunNumber(0),
534 {
535  // Configure the module (including MARLEY itself) using the FHiCL parameters
536  this->reconfigure(p);
537 
538  // Create a ROOT TTree using the TFileService that will store the MARLEY
539  // event objects (useful for debugging purposes)
541  fEventTree = tfs->make<TTree>("MARLEY_event_tree",
542  "Neutrino events generated by MARLEY");
543  fEventTree->Branch("event", "marley::Event", fEvent.get());
544 
545  // Add branches that give the art::Event run, subrun, and event numbers for
546  // easy match-ups between the MARLEY and art TTrees. All three are recorded
547  // as 32-bit unsigned integers.
548  fEventTree->Branch("run_number", &fRunNumber, "run_number/i");
549  fEventTree->Branch("subrun_number", &fSubRunNumber, "subrun_number/i");
550  fEventTree->Branch("event_number", &fEventNumber, "event_number/i");
551  fEventTree->Branch("tSN", &fTNu, "tSN/D");
552  fEventTree->Branch("weight", &fWeight, "weight/D");
553 
554  produces< std::vector<simb::MCTruth> >();
555  produces< std::vector<sim::SupernovaTruth> >();
556  produces< art::Assns<simb::MCTruth, sim::SupernovaTruth> >();
557  produces< sumdata::RunData, art::InRun >();
558 }
uint_fast32_t fEventNumber
Event number from the art::Event being processed.
virtual void reconfigure(const Parameters &p)
double fFluxAveragedCrossSection
Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined ...
double fWeight
Statistical weight for the current MARLEY neutrino vertex.
TTree * fEventTree
The event TTree created by MARLEY.
uint_fast32_t fSubRunNumber
Subrun number from the art::Event being processed.
uint_fast32_t fRunNumber
Run number from the art::Event being processed.
double fTNu
Time since the supernova core bounce for the current MARLEY neutrino vertex.
std::unique_ptr< marley::Event > fEvent
unique_ptr to the current event created by MARLEY
T * make(ARGS...args) const
evgen::MarleyTimeGen::~MarleyTimeGen ( )
virtual

Definition at line 561 of file MARLEYTimeGen_module.cc.

562 {
563 }

Member Function Documentation

void evgen::MarleyTimeGen::beginRun ( art::Run run)
overridevirtual

Reimplemented from art::EDProducer.

Definition at line 566 of file MARLEYTimeGen_module.cc.

References geo::GeometryCore::DetectorName(), and art::Run::put().

566  {
567  // grab the geometry object to see what geometry we are using
569  std::unique_ptr<sumdata::RunData>
570  runcol(new sumdata::RunData(geo->DetectorName()));
571 
572  run.put(std::move(runcol));
573 }
art::ProductID put(std::unique_ptr< PROD > &&)
Definition: Run.h:148
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
Namespace collecting geometry-related classes utilities.
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::consumes ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::consumes ( InputTag const &  it)
inherited

Definition at line 147 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

148 {
149  if (!moduleContext_)
150  return ProductToken<T>::invalid();
151 
152  consumables_[BT].emplace_back(ConsumableType::Product,
153  TypeID{typeid(T)},
154  it.label(),
155  it.instance(),
156  it.process());
157  return ProductToken<T>{it};
158 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::consumesMany ( )
inherited

Definition at line 162 of file Consumer.h.

163 {
164  if (!moduleContext_)
165  return;
166 
167  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
168 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::consumesView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::consumesView ( InputTag const &  it)
inherited

Definition at line 172 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

173 {
174  if (!moduleContext_)
175  return ViewToken<T>::invalid();
176 
177  consumables_[BT].emplace_back(ConsumableType::ViewElement,
178  TypeID{typeid(T)},
179  it.label(),
180  it.instance(),
181  it.process());
182  return ViewToken<T>{it};
183 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
void evgen::MarleyTimeGen::create_truths_th2d ( simb::MCTruth mc_truth,
sim::SupernovaTruth sn_truth,
const TLorentzVector &  vertex_pos 
)
protected

Create simb::MCTruth and sim::SupernovaTruth objects using spectrum information from a ROOT TH2D.

Definition at line 576 of file MARLEYTimeGen_module.cc.

References fEvent, fFluxAveragedCrossSection, fMarleyHelper, fSamplingMode, fSpectrumHist, fTNu, fWeight, HISTOGRAM, sim::kUnbiased, sim::kUniformEnergy, sim::kUniformTime, make_uniform_energy_mctruth(), UNIFORM_ENERGY, and UNIFORM_TIME.

Referenced by produce().

578 {
579  // Get a reference to the generator object created by MARLEY (we'll need
580  // to do a few fancy things with it other than just creating events)
581  marley::Generator& gen = fMarleyHelper->get_generator();
582 
584  {
585  // Generate a MARLEY event using the time-integrated spectrum
586  // (the generator was already configured to use it by reconfigure())
587  mc_truth = fMarleyHelper->create_MCTruth(vertex_pos,
588  fEvent.get());
589 
590  // Find the time distribution corresponding to the selected energy bin
591  double E_nu = fEvent->projectile().total_energy();
592  int E_bin_index = fSpectrumHist->GetYaxis()->FindBin(E_nu);
593  TH1D* t_hist = fSpectrumHist->ProjectionX("dummy_time_hist", E_bin_index,
594  E_bin_index);
595  double* time_bin_weights = t_hist->GetArray();
596 
597  // Sample a time bin from the distribution
598  std::discrete_distribution<int> time_dist;
599  std::discrete_distribution<int>::param_type time_params(time_bin_weights,
600  &(time_bin_weights[t_hist->GetNbinsX() + 1]));
601  int time_bin_index = gen.sample_from_distribution(time_dist, time_params);
602 
603  // Sample a time uniformly from within the selected time bin
604  double t_min = t_hist->GetBinLowEdge(time_bin_index);
605  double t_max = t_min + t_hist->GetBinWidth(time_bin_index);
606  // sample a time on [ t_min, t_max )
607  fTNu = gen.uniform_random_double(t_min, t_max, false);
608  // Unbiased sampling was used, so assign this neutrino vertex a
609  // unit statistical weight
610  fWeight = ONE;
611 
614  }
615 
617  {
618  // Generate a MARLEY event using the time-integrated spectrum
619  // (the generator was already configured to use it by reconfigure())
620  mc_truth = fMarleyHelper->create_MCTruth(vertex_pos,
621  fEvent.get());
622 
623  // Sample a time uniformly
624  TAxis* time_axis = fSpectrumHist->GetXaxis();
625  // underflow bin has index zero
626  double t_min = time_axis->GetBinLowEdge(1);
627  double t_max = time_axis->GetBinLowEdge(time_axis->GetNbins() + 1);
628  // sample a time on [ t_min, t_max )
629  fTNu = gen.uniform_random_double(t_min, t_max, false);
630 
631  // Get the value of the true dependent probability density (probability
632  // of the sampled time given the sampled energy) to use as a biasing
633  // correction in the neutrino vertex weight.
634  double E_nu = fEvent->projectile().total_energy();
635  int E_bin_index = fSpectrumHist->GetYaxis()->FindBin(E_nu);
636  TH1D* t_hist = fSpectrumHist->ProjectionX("dummy_time_hist", E_bin_index,
637  E_bin_index);
638  int t_bin_index = t_hist->FindBin(fTNu);
639  double weight_bias = t_hist->GetBinContent(t_bin_index) * (t_max - t_min)
640  / ( t_hist->Integral() * t_hist->GetBinWidth(t_bin_index) );
641 
642  fWeight = weight_bias;
643 
646  }
647 
649  {
650  // Select a time bin using the energy-integrated spectrum
651  TH1D* t_hist = fSpectrumHist->ProjectionX("dummy_time_hist");
652  double* time_bin_weights = t_hist->GetArray();
653 
654  // Sample a time bin from the distribution
655  std::discrete_distribution<int> time_dist;
656  std::discrete_distribution<int>::param_type time_params(time_bin_weights,
657  &(time_bin_weights[t_hist->GetNbinsX() + 1]));
658  int time_bin_index = gen.sample_from_distribution(time_dist, time_params);
659 
660  // Sample a time uniformly from within the selected time bin
661  double t_min = t_hist->GetBinLowEdge(time_bin_index);
662  double t_max = t_min + t_hist->GetBinWidth(time_bin_index);
663  // sample a time on [ t_min, t_max )
664  fTNu = gen.uniform_random_double(t_min, t_max, false);
665 
666  // Sample an energy uniformly over the entire allowed range
667  // underflow bin has index zero
668  TAxis* energy_axis = fSpectrumHist->GetYaxis();
669  double E_min = energy_axis->GetBinLowEdge(1);
670  double E_max = energy_axis->GetBinLowEdge(energy_axis->GetNbins() + 1);
671 
672  double E_nu = std::numeric_limits<double>::lowest();
673 
674  // Generate a MARLEY event using a uniformly sampled energy
675  mc_truth = make_uniform_energy_mctruth(E_min, E_max, E_nu, vertex_pos);
676 
677  // Get the value of the true dependent probability density (probability
678  // of the sampled energy given the sampled time) to use as a biasing
679  // correction in the neutrino vertex weight.
680  //
681  // Get a 1D projection of the energy spectrum for the sampled time bin
682  TH1D* energy_spect = fSpectrumHist->ProjectionY("energy_spect",
683  time_bin_index, time_bin_index);
684 
685  // Create a new MARLEY neutrino source object using this projection (this
686  // will create a normalized probability density that we can use) and load
687  // it into the generator.
688  auto nu_source = marley_root::make_root_neutrino_source(
689  marley_utils::ELECTRON_NEUTRINO, energy_spect);
690  double new_source_E_min = nu_source->get_Emin();
691  double new_source_E_max = nu_source->get_Emax();
692  gen.set_source(std::move(nu_source));
693  // NOTE: The marley::Generator object normalizes the E_pdf to unity
694  // automatically, but just in case, we redo it here.
695  double E_pdf_integ = integrate([&gen](double E_nu)
696  -> double { return gen.E_pdf(E_nu); }, new_source_E_min,
697  new_source_E_max);
698 
699  // Compute the likelihood ratio that we need to bias the neutrino vertex
700  // weight
701  double weight_bias = (gen.E_pdf(E_nu) / E_pdf_integ) * (E_max - E_min);
702 
703  fWeight = weight_bias;
704 
707  }
708 
709  else {
710  throw cet::exception("MARLEYTimeGen") << "Unrecognized sampling mode"
711  << " encountered in evgen::MarleyTimeGen::produce()";
712  }
713 
714 }
std::unique_ptr< evgen::MARLEYHelper > fMarleyHelper
Object that provides an interface to the MARLEY event generator.
double fFluxAveragedCrossSection
Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined ...
double fWeight
Statistical weight for the current MARLEY neutrino vertex.
Arrival times were sampled uniformly.
double fTNu
Time since the supernova core bounce for the current MARLEY neutrino vertex.
simb::MCTruth make_uniform_energy_mctruth(double E_min, double E_max, double &E_nu, const TLorentzVector &vertex_pos)
Creates a simb::MCTruth object using a uniformly-sampled neutrino energy.
std::unique_ptr< TH2D > fSpectrumHist
ROOT TH2D that contains the time-dependent spectrum to use when sampling neutrino times and energies...
std::unique_ptr< marley::Event > fEvent
unique_ptr to the current event created by MARLEY
Sample directly from cross-section weighted spectrum.
TimeGenSamplingMode fSamplingMode
Represents the sampling mode to use when selecting neutrino times and energies.
Neutrino energies were sampled uniformly.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void evgen::MarleyTimeGen::create_truths_time_fit ( simb::MCTruth mc_truth,
sim::SupernovaTruth sn_truth,
const TLorentzVector &  vertex_pos 
)
protected

Create simb::MCTruth and sim::SupernovaTruth objects using a neutrino spectrum described by a previously-parsed "fit"-format file.

Definition at line 1054 of file MARLEYTimeGen_module.cc.

References fEvent, fFitEmax, fFitEmin, fFluxAveragedCrossSection, fMarleyHelper, fSamplingMode, fTimeFits, fTNu, fWeight, HISTOGRAM, sim::kUnbiased, sim::kUniformEnergy, sim::kUniformTime, evgen::MarleyTimeGen::TimeFit::make_FitParameters_iterator(), evgen::MarleyTimeGen::FitParameters::make_luminosity_iterator(), make_uniform_energy_mctruth(), max, source_from_time_fit(), UNIFORM_ENERGY, and UNIFORM_TIME.

Referenced by produce().

1056 {
1057  // Get a reference to the generator object created by MARLEY (we'll need
1058  // to do a few fancy things with it other than just creating events)
1059  marley::Generator& gen = fMarleyHelper->get_generator();
1060 
1061  // Initialize the time bin index to something absurdly large. This will help
1062  // us detect strange bugs that arise when it is sampled incorrectly.
1063  size_t time_bin_index = std::numeric_limits<size_t>::max();
1064 
1065  // Create an object to represent the discrete time distribution given in
1066  // the spectrum file. Use the luminosity for each bin as its sampling weight.
1067  // This distribution will actually be used to sample a neutrino arrival time
1068  // unless we're using the uniform time sampling mode, in which case it will
1069  // be used to help calculate the neutrino vertex weight.
1070  int source_pdg_code = gen.get_source().get_pid();
1071 
1072  const auto fit_params_begin = TimeFit::make_FitParameters_iterator(
1073  source_pdg_code, fTimeFits.begin() );
1074  const auto fit_params_end = TimeFit::make_FitParameters_iterator(
1075  source_pdg_code, fTimeFits.end() );
1076 
1077  const auto lum_begin = FitParameters::make_luminosity_iterator(
1078  fit_params_begin);
1079  const auto lum_end = FitParameters::make_luminosity_iterator(
1080  fit_params_end);
1081 
1082  std::discrete_distribution<size_t> time_dist(lum_begin, lum_end);
1083 
1086  {
1087  time_bin_index = gen.sample_from_distribution(time_dist);
1088  }
1089 
1091  int last_time_index = 0;
1092  if (fTimeFits.size() > 0) last_time_index = fTimeFits.size() - 1;
1093  std::uniform_int_distribution<size_t> uid(0, last_time_index);
1094  // for c2: time_bin_index has already been declared
1095  time_bin_index = gen.sample_from_distribution(uid);
1096  }
1097 
1098  else {
1099  throw cet::exception("MARLEYTimeGen") << "Unrecognized sampling mode"
1100  << " encountered in evgen::MarleyTimeGen::produce()";
1101  }
1102 
1103  // Sample a time uniformly from within the selected time bin. Note that
1104  // the entries in fTimeFits use the time_ member to store the bin left
1105  // edges. The module creates fTimeFits in such a way that its last element
1106  // will always have luminosity_ == 0. (zero sampling weight), so we may
1107  // always add one to the sampled bin index without worrying about going
1108  // off the edge.
1109  double t_min = fTimeFits.at(time_bin_index).Time();
1110  double t_max = fTimeFits.at(time_bin_index + 1).Time();
1111  // sample a time on [ t_min, t_max )
1112  fTNu = gen.uniform_random_double(t_min, t_max, false);
1113 
1114  // Create a "beta-fit" neutrino source using the correct parameters for the
1115  // sampled time bin. This will be used to sample a neutrino energy unless
1116  // we're using the uniform time sampling mode. For uniform time sampling,
1117  // it will be used to determine the neutrino event weight.
1118  const auto& fit = fTimeFits.at(time_bin_index);
1119  std::unique_ptr<marley::NeutrinoSource> nu_source = source_from_time_fit(fit);
1120 
1123  {
1124  // Replace the generator's old source with the new one for the current
1125  // time bin
1126  gen.set_source(std::move(nu_source));
1127 
1128  // Generate a MARLEY event using the updated source
1129  mc_truth = fMarleyHelper->create_MCTruth(vertex_pos, fEvent.get());
1130 
1132  // Unbiased sampling creates neutrino vertices with unit weight
1133  fWeight = ONE;
1135  sim::kUnbiased);
1136  }
1137  else {
1138  // fSamplingMode == TimeGenSamplingMode::UNIFORM_TIME
1139 
1140  // Multiply by the likelihood ratio in order to correct for uniform
1141  // time sampling if we're using that biasing method
1142  double weight_bias = time_dist.probabilities().at(time_bin_index)
1143  / (t_max - t_min) * ( fTimeFits.back().Time()
1144  - fTimeFits.front().Time() );
1145 
1146  fWeight = weight_bias;
1149  }
1150  }
1151 
1153  {
1154  double E_nu = std::numeric_limits<double>::lowest();
1155  mc_truth = make_uniform_energy_mctruth(fFitEmin, fFitEmax, E_nu,
1156  vertex_pos);
1157 
1158  // Get the value of the true dependent probability density (probability
1159  // of the sampled energy given the sampled time) to use as a biasing
1160  // correction in the neutrino vertex weight.
1161 
1162  // Load the generator with the neutrino source that represents the
1163  // true (i.e., unbiased) energy probability distribution. This will
1164  // create a normalized probability density that we can use to determine
1165  // the neutrino vertex weight.
1166  double nu_source_E_min = nu_source->get_Emin();
1167  double nu_source_E_max = nu_source->get_Emax();
1168  gen.set_source(std::move(nu_source));
1169 
1170  // NOTE: The marley::Generator object normalizes the E_pdf to unity
1171  // automatically, but just in case, we redo it here.
1172  double E_pdf_integ = integrate([&gen](double E_nu)
1173  -> double { return gen.E_pdf(E_nu); }, nu_source_E_min,
1174  nu_source_E_max);
1175 
1176  // Compute the likelihood ratio that we need to bias the neutrino vertex
1177  // weight
1178  double weight_bias = (gen.E_pdf(E_nu) / E_pdf_integ)
1179  * (fFitEmax - fFitEmin);
1180 
1181  fWeight = weight_bias;
1184  }
1185 
1186  else {
1187  throw cet::exception("MARLEYTimeGen") << "Unrecognized sampling mode"
1188  << " encountered in evgen::MarleyTimeGen::produce()";
1189  }
1190 
1191 }
std::unique_ptr< evgen::MARLEYHelper > fMarleyHelper
Object that provides an interface to the MARLEY event generator.
static marley::IteratorToMember< It, TimeFit, FitParameters > make_FitParameters_iterator(int pdg_code, It iterator)
Converts an iterator that points to a TimeFit object into an iterator that points to the appropriate ...
double fFluxAveragedCrossSection
Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined ...
double fWeight
Statistical weight for the current MARLEY neutrino vertex.
Arrival times were sampled uniformly.
Int_t max
Definition: plot.C:27
std::unique_ptr< marley::NeutrinoSource > source_from_time_fit(const TimeFit &fit)
Create a MARLEY neutrino source object using a set of fit parameters for a particular time bin...
double fTNu
Time since the supernova core bounce for the current MARLEY neutrino vertex.
simb::MCTruth make_uniform_energy_mctruth(double E_min, double E_max, double &E_nu, const TLorentzVector &vertex_pos)
Creates a simb::MCTruth object using a uniformly-sampled neutrino energy.
double fFitEmax
Maximum neutrino energy to consider when using a "fit"-format spectrum file.
static marley::IteratorToMember< It, FitParameters, double > make_luminosity_iterator(It it)
Converts an iterator that points to a FitParameters object into an iterator that points to that objec...
std::unique_ptr< marley::Event > fEvent
unique_ptr to the current event created by MARLEY
Sample directly from cross-section weighted spectrum.
TimeGenSamplingMode fSamplingMode
Represents the sampling mode to use when selecting neutrino times and energies.
double fFitEmin
Minimum neutrino energy to consider when using a "fit"-format spectrum file.
std::vector< TimeFit > fTimeFits
Vector that contains the fit parameter information for each time bin when using a "fit"-format spectr...
Neutrino energies were sampled uniformly.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make 
)
inherited

Definition at line 32 of file EngineCreator.cc.

References art::EngineCreator::rng().

34 {
35  return rng()->createEngine(
36  placeholder_schedule_id(), seed, kind_of_engine_to_make);
37 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make,
label_t const &  engine_label 
)
inherited

Definition at line 40 of file EngineCreator.cc.

References art::EngineCreator::rng().

43 {
44  return rng()->createEngine(
45  placeholder_schedule_id(), seed, kind_of_engine_to_make, engine_label);
46 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
CurrentProcessingContext const * art::EDProducer::currentContext ( ) const
protectedinherited

Definition at line 120 of file EDProducer.cc.

References art::EDProducer::current_context_.

121  {
122  return current_context_.get();
123  }
CPC_exempt_ptr current_context_
Definition: EDProducer.h:116
EngineCreator::seed_t EngineCreator::get_seed_value ( fhicl::ParameterSet const &  pset,
char const  key[] = "seed",
seed_t const  implicit_seed = -1 
)
inherited

Definition at line 49 of file EngineCreator.cc.

References fhicl::ParameterSet::get().

Referenced by art::MixFilter< T >::initEngine_().

52 {
53  auto const& explicit_seeds = pset.get<std::vector<int>>(key, {});
54  return explicit_seeds.empty() ? implicit_seed : explicit_seeds.front();
55 }
template<typename PROD , BranchType B>
ProductID art::EDProducer::getProductID ( std::string const &  instanceName = {}) const
inlineinherited

Definition at line 123 of file EDProducer.h.

References art::EDProducer::moduleDescription_.

124  {
125  return ProducerBase::getProductID<PROD, B>(moduleDescription_,
126  instanceName);
127  }
ModuleDescription moduleDescription_
Definition: EDProducer.h:115
template<typename PROD , BranchType B>
ProductID art::ProducerBase::getProductID ( ModuleDescription const &  moduleDescription,
std::string const &  instanceName 
) const
inherited

Definition at line 56 of file ProducerBase.h.

References B, and art::ModuleDescription::moduleLabel().

Referenced by art::ProducerBase::modifiesEvent().

58  {
59  auto const& pd =
60  get_ProductDescription<PROD>(B, md.moduleLabel(), instanceName);
61  return pd.productID();
62  }
Int_t B
Definition: plot.C:25
void evgen::MarleyTimeGen::make_final_timefit ( double  time)
protected

Helper function that makes a final dummy TimeFit object so that the final real time bin can have a right edge.

Definition at line 1269 of file MARLEYTimeGen_module.cc.

References fTimeFits.

Referenced by reconfigure().

1270 {
1271  // The final time bin has zero luminosity, and therefore zero sampling
1272  // weight. We need it to be present so that the last nonzero weight bin
1273  // has a right edge.
1274  fTimeFits.emplace_back(time, 0., 0., 0., 0., 0., 0., 0., 0., 0.);
1275 }
std::vector< TimeFit > fTimeFits
Vector that contains the fit parameter information for each time bin when using a "fit"-format spectr...
void evgen::MarleyTimeGen::make_nu_emission_histograms ( ) const
protected

Makes ROOT histograms showing the emitted neutrinos in each time bin when using a "fit"-format spectrum file.

Definition at line 1278 of file MARLEYTimeGen_module.cc.

References DEFINE_ART_MODULE, f, fTimeFits, evgen::MarleyTimeGen::TimeFit::GetFitParameters(), evgen::MarleyTimeGen::FitParameters::Luminosity(), art::TFileDirectory::make(), evgen::MarleyTimeGen::TimeFit::Time(), x_max, and x_min.

Referenced by reconfigure().

1279 {
1280  // To make a histogram with variable size bins, ROOT needs the bin
1281  // low edges to be contiguous in memory. This is not true of the
1282  // stored times in fTimeFits, so we'll need to make a temporary copy
1283  // of them.
1284  std::vector<double> temp_times;
1285  for (const auto& fit : fTimeFits) temp_times.push_back(fit.Time());
1286 
1287  // If, for some reason, there are fewer than two time bins, just return
1288  // without making the histograms.
1289  // TODO: consider throwing an exception here
1290  if (temp_times.size() < 2) return;
1291 
1292  // Get the number of time bins
1293  int num_bins = temp_times.size() - 1;
1294 
1295  // Create some ROOT TH1D objects using the TFileService. These will store
1296  // the number of emitted neutrinos of each type in each time bin
1298  TH1D* nue_hist = tfs->make<TH1D>("NueEmission",
1299  "Number of emitted #nu_{e}; time (s); number of neutrinos in time bin",
1300  num_bins, temp_times.data());
1301  TH1D* nuebar_hist = tfs->make<TH1D>("NuebarEmission",
1302  "Number of emitted #bar{#nu}_{e}; time (s); number of neutrinos in"
1303  " time bin", num_bins, temp_times.data());
1304  TH1D* nux_hist = tfs->make<TH1D>("NuxEmission",
1305  "Number of emitted #nu_{x}; time (s); number of neutrinos in time bin",
1306  num_bins, temp_times.data());
1307 
1308  // Load the histograms with the emitted neutrino counts
1309  for (size_t b = 1; b < temp_times.size(); ++b) {
1310  const TimeFit& current_fit = fTimeFits.at(b - 1);
1311  const TimeFit& next_fit = fTimeFits.at(b);
1312  double bin_deltaT = next_fit.Time() - current_fit.Time();
1313 
1314  const auto& nue_params = current_fit.GetFitParameters(
1315  marley_utils::ELECTRON_NEUTRINO);
1316  const auto& nuebar_params = current_fit.GetFitParameters(
1317  marley_utils::ELECTRON_ANTINEUTRINO);
1318  const auto& nux_params = current_fit.GetFitParameters(
1319  marley_utils::MUON_NEUTRINO);
1320 
1321  // Convert from bin luminosity to number of neutrinos by
1322  // multiplying by the bin time interval and dividing by the
1323  // mean neutrino energy
1324  double num_nue = 0.;
1325  double num_nuebar = 0.;
1326  double num_nux = 0.;
1327  if (nue_params.Emean() != 0.) num_nue = nue_params.Luminosity()
1328  * bin_deltaT / (nue_params.Emean() * MeV_to_erg);
1329  if (nuebar_params.Emean() != 0.) num_nuebar = nuebar_params.Luminosity()
1330  * bin_deltaT / (nuebar_params.Emean() * MeV_to_erg);
1331  if (nux_params.Emean() != 0.) num_nux = nux_params.Luminosity()
1332  * bin_deltaT / (nux_params.Emean() * MeV_to_erg);
1333 
1334  nue_hist->SetBinContent(b, num_nue);
1335  nuebar_hist->SetBinContent(b, num_nuebar);
1336  nux_hist->SetBinContent(b, num_nux);
1337  }
1338 
1339 }
T * make(ARGS...args) const
std::vector< TimeFit > fTimeFits
Vector that contains the fit parameter information for each time bin when using a "fit"-format spectr...
simb::MCTruth evgen::MarleyTimeGen::make_uniform_energy_mctruth ( double  E_min,
double  E_max,
double &  E_nu,
const TLorentzVector &  vertex_pos 
)
protected

Creates a simb::MCTruth object using a uniformly-sampled neutrino energy.

This function samples a reacting neutrino energy uniformly from the full range of energies allowed by the incident spectrum and the currently defined reactions.

Definition at line 1222 of file MARLEYTimeGen_module.cc.

References fEvent, and fMarleyHelper.

Referenced by create_truths_th2d(), and create_truths_time_fit().

1224 {
1225  marley::Generator& gen = fMarleyHelper->get_generator();
1226 
1227  // Sample an energy uniformly over the entire allowed range
1228  double total_xs;
1229  int j = 0;
1230  do {
1231  // We have to check that the cross section is nonzero for the sampled
1232  // energy (otherwise we'll generate an unphysical event). However, if the
1233  // user has given us a histogram that is below threshold, the
1234  // program could get stuck here endlessly, sampling rejected energy
1235  // after rejected energy. Just in case, we cap the total number of tries
1236  // and quit if things don't work out.
1237  if (j >= MAX_UNIFORM_ENERGY_ITERATIONS) {
1238  throw cet::exception("MARLEYTimeGen") << "Exceeded the maximum of "
1239  << MAX_UNIFORM_ENERGY_ITERATIONS << " while attempting to sample"
1240  << " a neutrino energy uniformly.";
1241  }
1242  // Sample an energy uniformly on [ E_min, E_max )
1243  E_nu = gen.uniform_random_double(E_min, E_max, false);
1244  total_xs = 0.;
1245  // Check that at least one defined reaction has a non-zero total
1246  // cross section at the sampled energy. If this is not the case, try
1247  // again.
1248  for (const auto& react : gen.get_reactions()) {
1249  total_xs += react->total_xs(marley_utils::ELECTRON_NEUTRINO, E_nu);
1250  }
1251 
1252  ++j;
1253  } while (total_xs <= 0.);
1254 
1255  // Replace the existing neutrino source with a monoenergetic one at the
1256  // neutrino energy that was just sampled above
1257  std::unique_ptr<marley::NeutrinoSource> nu_source
1258  = std::make_unique<marley::MonoNeutrinoSource>(
1259  marley_utils::ELECTRON_NEUTRINO, E_nu);
1260  gen.set_source(std::move(nu_source));
1261 
1262  // Generate a MARLEY event using the new monoenergetic source
1263  auto mc_truth = fMarleyHelper->create_MCTruth(vertex_pos, fEvent.get());
1264 
1265  return mc_truth;
1266 }
std::unique_ptr< evgen::MARLEYHelper > fMarleyHelper
Object that provides an interface to the MARLEY event generator.
std::unique_ptr< marley::Event > fEvent
unique_ptr to the current event created by MARLEY
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::mayConsume ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::mayConsume ( InputTag const &  it)
inherited

Definition at line 190 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

191 {
192  if (!moduleContext_)
193  return ProductToken<T>::invalid();
194 
195  consumables_[BT].emplace_back(ConsumableType::Product,
196  TypeID{typeid(T)},
197  it.label(),
198  it.instance(),
199  it.process());
200  return ProductToken<T>{it};
201 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::mayConsumeMany ( )
inherited

Definition at line 205 of file Consumer.h.

206 {
207  if (!moduleContext_)
208  return;
209 
210  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
211 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::mayConsumeView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::mayConsumeView ( InputTag const &  it)
inherited

Definition at line 215 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

216 {
217  if (!moduleContext_)
218  return ViewToken<T>::invalid();
219 
220  consumables_[BT].emplace_back(ConsumableType::ViewElement,
221  TypeID{typeid(T)},
222  it.label(),
223  it.instance(),
224  it.process());
225  return ViewToken<T>{it};
226 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
bool art::ProducerBase::modifiesEvent ( ) const
inlineinherited

Definition at line 40 of file ProducerBase.h.

References art::ProducerBase::getProductID().

41  {
42  return true;
43  }
void art::Consumer::prepareForJob ( fhicl::ParameterSet const &  pset)
protectedinherited

Definition at line 89 of file Consumer.cc.

References fhicl::ParameterSet::get_if_present().

Referenced by art::EDProducer::doBeginJob(), art::EDFilter::doBeginJob(), and art::EDAnalyzer::doBeginJob().

90 {
91  if (!moduleContext_)
92  return;
93 
94  pset.get_if_present("errorOnMissingConsumes", requireConsumes_);
95  for (auto& consumablesPerBranch : consumables_) {
96  cet::sort_all(consumablesPerBranch);
97  }
98 }
bool requireConsumes_
Definition: Consumer.h:137
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
void evgen::MarleyTimeGen::produce ( art::Event e)
overridevirtual

Implements art::EDProducer.

Definition at line 717 of file MARLEYTimeGen_module.cc.

References create_truths_th2d(), create_truths_time_fit(), util::CreateAssn(), art::Event::event(), fEventNumber, fEventTree, FIT, fNeutrinosPerEvent, fRunNumber, fSpectrumFileFormat, fSubRunNumber, fTNu, fVertexSampler, n, art::Event::put(), RootTH2D, art::Event::run(), and art::Event::subRun().

718 {
720 
721  // Get the run, subrun, and event numbers from the current art::Event
722  fRunNumber = e.run();
723  fSubRunNumber = e.subRun();
724  fEventNumber = e.event();
725 
726  // Prepare associations and vectors of truth objects that will be produced
727  // and loaded into the current art::Event
728  std::unique_ptr< std::vector<simb::MCTruth> >
729  truthcol(new std::vector<simb::MCTruth>);
730 
731  std::unique_ptr< std::vector<sim::SupernovaTruth> >
732  sn_truthcol(new std::vector<sim::SupernovaTruth>);
733 
734  std::unique_ptr< art::Assns<simb::MCTruth, sim::SupernovaTruth> >
736 
737  // Create temporary truth objects that we will use to load the event
738  simb::MCTruth truth;
739  sim::SupernovaTruth sn_truth;
740 
741  for (unsigned int n = 0; n < fNeutrinosPerEvent; ++n) {
742 
743  // Sample a primary vertex location for this event
744  TLorentzVector vertex_pos = fVertexSampler->sample_vertex_pos(*geo);
745 
746  // Reset the neutrino's time-since-supernova to a bogus value (for now)
747  fTNu = std::numeric_limits<double>::lowest();
748 
750  create_truths_th2d(truth, sn_truth, vertex_pos);
751  }
753  create_truths_time_fit(truth, sn_truth, vertex_pos);
754  }
755  else {
756  throw cet::exception("MARLEYTimeGen") << "Invalid spectrum file"
757  << " format encountered in evgen::MarleyTimeGen::produce()";
758  }
759 
760  // Write the marley::Event object to the event tree
761  fEventTree->Fill();
762 
763  // Add the truth objects to the appropriate vectors
764  truthcol->push_back(truth);
765 
766  sn_truthcol->push_back(sn_truth);
767 
768  // Associate the last entries in each of the truth object vectors (the
769  // truth objects that were just created for the current neutrino vertex)
770  // with each other
771  util::CreateAssn(*this, e, *truthcol, *sn_truthcol, *truth_assns,
772  truthcol->size() - 1, truthcol->size()/*, sn_truthcol->size() - 1*/);
773  }
774 
775  // Load the completed truth object vectors and associations into the event
776  e.put(std::move(truthcol));
777 
778  e.put(std::move(sn_truthcol));
779 
780  e.put(std::move(truth_assns));
781 }
SubRunNumber_t subRun() const
Definition: Event.h:72
SpectrumFileFormat fSpectrumFileFormat
Format to assume for the neutrino spectrum input file.
uint_fast32_t fEventNumber
Event number from the art::Event being processed.
void create_truths_time_fit(simb::MCTruth &mc_truth, sim::SupernovaTruth &sn_truth, const TLorentzVector &vertex_pos)
Create simb::MCTruth and sim::SupernovaTruth objects using a neutrino spectrum described by a previou...
std::unique_ptr< evgen::ActiveVolumeVertexSampler > fVertexSampler
Algorithm that allows us to sample vertex locations within the active volume(s) of the detector...
TTree * fEventTree
The event TTree created by MARLEY.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
uint_fast32_t fSubRunNumber
Subrun number from the art::Event being processed.
uint_fast32_t fRunNumber
Run number from the art::Event being processed.
void create_truths_th2d(simb::MCTruth &mc_truth, sim::SupernovaTruth &sn_truth, const TLorentzVector &vertex_pos)
Create simb::MCTruth and sim::SupernovaTruth objects using spectrum information from a ROOT TH2D...
double fTNu
Time since the supernova core bounce for the current MARLEY neutrino vertex.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
EventNumber_t event() const
Definition: Event.h:67
unsigned int fNeutrinosPerEvent
The number of MARLEY neutrino vertices to generate in each art::Event.
Char_t n[5]
Event generator information.
Definition: MCTruth.h:30
RunNumber_t run() const
Definition: Event.h:77
Namespace collecting geometry-related classes utilities.
size_t size() const
Definition: DataViewImpl.cc:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void evgen::MarleyTimeGen::reconfigure ( const Parameters p)
virtual

Definition at line 784 of file MARLEYTimeGen_module.cc.

References ALPHA, BETA, fFitEmax, fFitEmin, fFluxAveragedCrossSection, FIT, fMarleyHelper, fNeutrinosPerEvent, fPinchType, fSamplingMode, fSpectrumFileFormat, fSpectrumHist, fTimeFits, fVertexSampler, evgen::MarleyTimeGen::TimeFit::GetFitParameters(), HISTOGRAM, LOG_INFO, LOG_WARNING, evgen::MarleyTimeGen::FitParameters::Luminosity(), make_final_timefit(), make_nu_emission_histograms(), RootTH2D, s, source_from_time_fit(), UNIFORM_ENERGY, and UNIFORM_TIME.

Referenced by MarleyTimeGen().

785 {
786  const auto& seed_service = art::ServiceHandle<rndm::NuRandomService>();
787  const auto& geom_service = art::ServiceHandle<geo::Geometry>();
788 
789  // Create a new evgen::ActiveVolumeVertexSampler object based on the current
790  // configuration
791  fVertexSampler = std::make_unique<evgen::ActiveVolumeVertexSampler>(
792  p().vertex_, *seed_service, *geom_service, "MARLEY_Vertex_Sampler");
793 
794  // Create a new marley::Generator object based on the current configuration
795  fMarleyHelper = std::make_unique<MARLEYHelper>(p().marley_parameters_,
796  *seed_service, "MARLEY");
797 
798  // Get the number of neutrino vertices per event from the FHiCL parameters
799  fNeutrinosPerEvent = p().nu_per_event_();
800 
801  // Determine the current sampling mode from the FHiCL parameters
802  const std::string& samp_mode_str = p().sampling_mode_();
803  if (samp_mode_str == "histogram")
805  else if (samp_mode_str == "uniform time")
807  else if (samp_mode_str == "uniform energy")
809  else throw cet::exception("MARLEYTimeGen")
810  << "Invalid sampling mode \"" << samp_mode_str << "\""
811  << " specified for the MARLEYTimeGen module.";
812 
813  LOG_INFO("MARLEYTimeGen") << fNeutrinosPerEvent << " neutrino vertices"
814  << " will be generated for each art::Event using the \"" << samp_mode_str
815  << "\" sampling mode.";
816 
817  // Retrieve the time-dependent neutrino spectrum from the spectrum file.
818  // Use different methods depending on the file's format.
819  std::string spectrum_file_format = marley_utils::to_lowercase(
820  p().spectrum_file_format_());
821 
822  if (spectrum_file_format == "th2d")
824  else if (spectrum_file_format == "fit") {
826 
827  std::string pinch_type;
828  if ( !p().pinching_parameter_type_(pinch_type) ) {
829  throw cet::exception("MARLEYTimeGen") << "Missing pinching parameter"
830  << " type for a \"fit\" format spectrum file";
831  }
832 
833  marley_utils::to_lowercase_inplace(pinch_type);
834  if (pinch_type == "alpha") fPinchType = PinchParamType::ALPHA;
835  else if (pinch_type == "beta") fPinchType = PinchParamType::BETA;
836  else throw cet::exception("MARLEYTimeGen")
837  << "Invalid pinching parameter type \"" << pinch_type
838  << "\" specified for the MARLEYTimeGen module.";
839 
840  if ( !p().fit_Emin_(fFitEmin) ) throw cet::exception("MARLEYTimeGen")
841  << "Missing minimum energy for a \"fit\" format spectrum"
842  << " used by the MARLEYTimeGen module.";
843 
844  if ( !p().fit_Emax_(fFitEmax) ) throw cet::exception("MARLEYTimeGen")
845  << "Missing maximum energy for a \"fit\" format spectrum"
846  << " used by the MARLEYTimeGen module.";
847 
848  if (fFitEmax < fFitEmin) throw cet::exception("MARLEYTimeGen")
849  << "Maximum energy is less than the minimum energy for"
850  << " a \"fit\" format spectrum used by the MARLEYTimeGen module.";
851  }
852  else throw cet::exception("MARLEYTimeGen")
853  << "Invalid spectrum file format \"" << p().spectrum_file_format_()
854  << "\" specified for the MARLEYTimeGen module.";
855 
856  // Determine the full file name (including path) of the spectrum file
857  std::string full_spectrum_file_name
858  = fMarleyHelper->find_file(p().spectrum_file_(), "spectrum");
859 
860  marley::Generator& gen = fMarleyHelper->get_generator();
861 
863 
864  // Retrieve the time-dependent neutrino flux from a ROOT file
865  std::unique_ptr<TFile> spectrum_file
866  = std::make_unique<TFile>(full_spectrum_file_name.c_str(), "read");
867  TH2D* temp_h2 = nullptr;
868  std::string namecycle;
869  if ( !p().namecycle_(namecycle) ) {
870  throw cet::exception("MARLEYTimeGen") << "Missing namecycle for"
871  << " a TH2D spectrum file";
872  }
873 
874  spectrum_file->GetObject(namecycle.c_str(), temp_h2);
875  fSpectrumHist.reset(temp_h2);
876 
877  // Disassociate the TH2D from its parent TFile. If we fail to do this,
878  // then ROOT will auto-delete the TH2D when the TFile goes out of scope.
879  fSpectrumHist->SetDirectory(nullptr);
880 
881  // Compute the flux-averaged total cross section using MARLEY. This will be
882  // used to compute neutrino vertex weights for the sim::SupernovaTruth
883  // objects.
884 
885  // Get a 1D projection of the energy spectrum (integrated over time)
886  TH1D* energy_spect = fSpectrumHist->ProjectionY("energy_spect");
887 
888  // Create a new MARLEY neutrino source object using this projection
889  // TODO: replace the hard-coded electron neutrino PDG code here (and in
890  // several other places in this source file) when you're ready to use
891  // MARLEY with multiple neutrino flavors
892  std::unique_ptr<marley::NeutrinoSource> nu_source
893  = marley_root::make_root_neutrino_source(marley_utils::ELECTRON_NEUTRINO,
894  energy_spect);
895 
896  // Factor of hbar_c^2 converts from MeV^(-2) to fm^2
897  fFluxAveragedCrossSection = marley_utils::hbar_c2
898  * flux_averaged_total_xs(*nu_source, gen);
899 
900  // For speed, sample energies first whenever possible (and then sample from
901  // an energy-dependent timing distribution). This avoids unnecessary calls
902  // to MARLEY to change the energy spectrum.
905  {
906  gen.set_source(std::move(nu_source));
907  }
908 
909  } // spectrum_file_format == "th2d"
910 
912 
913  // Clear out the old parameterized spectrum, if one exists
914  fTimeFits.clear();
915 
916  std::ifstream fit_file(full_spectrum_file_name);
917  std::string line;
918 
919  bool found_end = false;
920 
921  // current line number
922  int line_num = 0;
923  // number of lines checked in last call to marley_utils::get_next_line()
924  int lines_checked = 0;
925 
926  double old_time = std::numeric_limits<double>::lowest();
927 
928  while ( line = marley_utils::get_next_line(fit_file, rx_comment_or_empty,
929  false, lines_checked), line_num += lines_checked, !line.empty() )
930  {
931  if (found_end) {
932  LOG_WARNING("MARLEYTimeGen") << "Trailing content after last time"
933  << " bin found on line " << line_num << " of the spectrum file "
934  << full_spectrum_file_name;
935  }
936 
937  double time;
938  double Emean_nue, alpha_nue, luminosity_nue;
939  double Emean_nuebar, alpha_nuebar, luminosity_nuebar;
940  double Emean_nux, alpha_nux, luminosity_nux;
941  std::istringstream iss(line);
942  bool ok_first = static_cast<bool>( iss >> time );
943 
944  if (time <= old_time) throw cet::exception("MARLEYTimeGen")
945  << "Time bin left edges given in the spectrum file must be"
946  << " strictly increasing. Invalid time bin value found on line "
947  << line_num << " of the spectrum file " << full_spectrum_file_name;
948  else old_time = time;
949 
950  bool ok_rest = static_cast<bool>( iss >> Emean_nue >> alpha_nue
951  >> luminosity_nue >> Emean_nuebar >> alpha_nuebar >> luminosity_nuebar
952  >> Emean_nux >> alpha_nux >> luminosity_nux
953  );
954 
955  if (ok_first) {
956  // We haven't reached the final bin, so add another time bin
957  // in the typical way.
958  if (ok_rest) {
959  fTimeFits.emplace_back(time, Emean_nue, alpha_nue, luminosity_nue,
960  Emean_nuebar, alpha_nuebar, luminosity_nuebar, Emean_nux,
961  alpha_nux, luminosity_nux);
962  }
963  else {
964  make_final_timefit(time);
965  found_end = true;
966  }
967  }
968  else throw cet::exception("MARLEYTimeGen") << "Parse error on line "
969  << line_num << " of the spectrum file " << full_spectrum_file_name;
970  }
971 
972  if (!found_end) {
973 
974  size_t num_time_bins = fTimeFits.size();
975  if (num_time_bins < 2) throw cet::exception("MARLEYTimeGen")
976  << "Missing right edge for the final time bin in the spectrum file "
977  << full_spectrum_file_name << ". Unable to guess a bin width for the "
978  << " final bin.";
979 
980  // Guess that the width of the penultimate time bin and the width of
981  // the final time bin are the same
982  double delta_t_bin = fTimeFits.back().Time()
983  - fTimeFits.at(num_time_bins - 2).Time();
984 
985  double last_bin_right_edge = fTimeFits.back().Time() + delta_t_bin;
986 
987  make_final_timefit(last_bin_right_edge);
988 
989  LOG_WARNING("MARLEYTimeGen") << "Missing right"
990  << " edge for the final time bin in the spectrum file "
991  << full_spectrum_file_name << ". Assuming a width of "
992  << delta_t_bin << " s for the final bin.";
993  }
994 
995 
996  // Compute the flux-averaged total cross section for the fitted spectrum.
997  // We will need this to compute neutrino vertex weights.
998  std::vector< std::unique_ptr< marley::NeutrinoSource > > fit_sources;
999  for (const auto& fit : fTimeFits) {
1000  fit_sources.emplace_back( source_from_time_fit(fit) );
1001  }
1002 
1003  // TODO: add handling for non-nu_e neutrino types when suitable data become
1004  // available in MARLEY
1005  auto temp_source = std::make_unique<marley::FunctionNeutrinoSource>(
1006  marley_utils::ELECTRON_NEUTRINO, fFitEmin, fFitEmax,
1007  [&fit_sources, this](double E_nu) -> double {
1008  double flux = 0.;
1009  for (size_t s = 0; s < fit_sources.size(); ++s) {
1010 
1011  const TimeFit& current_fit = this->fTimeFits.at(s);
1012  const auto& current_source = fit_sources.at(s);
1013  const FitParameters& params = current_fit.GetFitParameters(
1014  current_source->get_pid() );
1015 
1016  double lum = params.Luminosity();
1017 
1018  // Skip entries with zero luminosity, since they won't contribute
1019  // anything to the overall integral. Skip negative luminosity ones as
1020  // well, just in case.
1021  if (lum <= 0.) continue;
1022 
1023  flux += lum * current_source->pdf(E_nu);
1024  }
1025  return flux;
1026  }
1027  );
1028 
1029  double flux_integ = 0.;
1030  double tot_xs_integ = 0.;
1031  flux_averaged_total_xs(*temp_source, gen, flux_integ, tot_xs_integ);
1032 
1033  // Factor of hbar_c^2 converts from MeV^(-2) to fm^2
1034  fFluxAveragedCrossSection = marley_utils::hbar_c2
1035  * tot_xs_integ / flux_integ;
1036 
1038 
1039  } // spectrum_file_format == "fit"
1040 
1041  else {
1042  throw cet::exception("MARLEYTimeGen") << "Unrecognized neutrino spectrum"
1043  << " file format \"" << p().spectrum_file_format_() << "\" encountered"
1044  << " in evgen::MarleyTimeGen::reconfigure()";
1045  }
1046 
1047  LOG_INFO("MARLEYTimeGen") << "The flux-averaged total cross section"
1048  << " predicted by MARLEY for the current supernova spectrum is "
1049  << fFluxAveragedCrossSection << " fm^2";
1050 
1051 }
Float_t s
Definition: plot.C:23
#define LOG_INFO(category)
SpectrumFileFormat fSpectrumFileFormat
Format to assume for the neutrino spectrum input file.
PinchParamType fPinchType
The pinching parameter convention to use when interpreting the time-dependent fits.
std::unique_ptr< evgen::ActiveVolumeVertexSampler > fVertexSampler
Algorithm that allows us to sample vertex locations within the active volume(s) of the detector...
std::unique_ptr< evgen::MARLEYHelper > fMarleyHelper
Object that provides an interface to the MARLEY event generator.
double fFluxAveragedCrossSection
Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined ...
std::unique_ptr< marley::NeutrinoSource > source_from_time_fit(const TimeFit &fit)
Create a MARLEY neutrino source object using a set of fit parameters for a particular time bin...
double fFitEmax
Maximum neutrino energy to consider when using a "fit"-format spectrum file.
#define LOG_WARNING(category)
std::unique_ptr< TH2D > fSpectrumHist
ROOT TH2D that contains the time-dependent spectrum to use when sampling neutrino times and energies...
unsigned int fNeutrinosPerEvent
The number of MARLEY neutrino vertices to generate in each art::Event.
TimeGenSamplingMode fSamplingMode
Represents the sampling mode to use when selecting neutrino times and energies.
double fFitEmin
Minimum neutrino energy to consider when using a "fit"-format spectrum file.
void make_final_timefit(double time)
Helper function that makes a final dummy TimeFit object so that the final real time bin can have a ri...
std::vector< TimeFit > fTimeFits
Vector that contains the fit parameter information for each time bin when using a "fit"-format spectr...
void make_nu_emission_histograms() const
Makes ROOT histograms showing the emitted neutrinos in each time bin when using a "fit"-format spectr...
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void art::Consumer::showMissingConsumes ( ) const
protectedinherited

Definition at line 125 of file Consumer.cc.

Referenced by art::EDProducer::doEndJob(), art::EDFilter::doEndJob(), art::EDAnalyzer::doEndJob(), and art::RootOutput::endJob().

126 {
127  if (!moduleContext_)
128  return;
129 
130  // If none of the branches have missing consumes statements, exit early.
131  if (std::all_of(cbegin(missingConsumes_),
132  cend(missingConsumes_),
133  [](auto const& perBranch) { return perBranch.empty(); }))
134  return;
135 
136  constexpr cet::HorizontalRule rule{60};
137  mf::LogPrint log{"MTdiagnostics"};
138  log << '\n'
139  << rule('=') << '\n'
140  << "The following consumes (or mayConsume) statements are missing from\n"
141  << module_context(moduleDescription_) << '\n'
142  << rule('-') << '\n';
143 
144  cet::for_all_with_index(
145  missingConsumes_, [&log](std::size_t const i, auto const& perBranch) {
146  for (auto const& pi : perBranch) {
147  log << " "
148  << assemble_consumes_statement(static_cast<BranchType>(i), pi)
149  << '\n';
150  }
151  });
152  log << rule('=');
153 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139
std::unique_ptr< marley::NeutrinoSource > evgen::MarleyTimeGen::source_from_time_fit ( const TimeFit fit)
protected

Create a MARLEY neutrino source object using a set of fit parameters for a particular time bin.

Definition at line 1195 of file MARLEYTimeGen_module.cc.

References evgen::MarleyTimeGen::FitParameters::Alpha(), ALPHA, beta, BETA, evgen::MarleyTimeGen::FitParameters::Emean(), fFitEmax, fFitEmin, fPinchType, and evgen::MarleyTimeGen::TimeFit::GetFitParameters().

Referenced by create_truths_time_fit(), and reconfigure().

1196 {
1197  // Create a "beta-fit" neutrino source using the given fit parameters.
1198 
1199  // The two common fitting schemes (alpha and beta) differ in their
1200  // definitions by \beta = \alpha + 1.
1201  // TODO: add handling for non-nu_e neutrino types
1202  const FitParameters& nue_parameters
1203  = fit.GetFitParameters(marley_utils::ELECTRON_NEUTRINO);
1204 
1205  double beta = nue_parameters.Alpha();
1206  if (fPinchType == PinchParamType::ALPHA) beta += 1.;
1207  else if (fPinchType != PinchParamType::BETA) {
1208  throw cet::exception("MARLEYTimeGen") << "Unreognized pinching parameter"
1209  << " type encountered in evgen::MarleyTimeGen::source_from_time_fit()";
1210  }
1211 
1212  // Create the new source
1213  std::unique_ptr<marley::NeutrinoSource> nu_source
1214  = std::make_unique<marley::BetaFitNeutrinoSource>(
1215  marley_utils::ELECTRON_NEUTRINO, fFitEmin, fFitEmax,
1216  nue_parameters.Emean(), beta);
1217 
1218  return nu_source;
1219 }
PinchParamType fPinchType
The pinching parameter convention to use when interpreting the time-dependent fits.
Double_t beta
double fFitEmax
Maximum neutrino energy to consider when using a "fit"-format spectrum file.
double fFitEmin
Minimum neutrino energy to consider when using a "fit"-format spectrum file.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void art::Consumer::validateConsumedProduct ( BranchType const  bt,
ProductInfo const &  pi 
)
protectedinherited

Definition at line 101 of file Consumer.cc.

References art::errors::ProductRegistrationFailure.

103 {
104  // Early exits if consumes tracking has been disabled or if the
105  // consumed product is an allowed consumable.
106  if (!moduleContext_)
107  return;
108 
109  if (cet::binary_search_all(consumables_[bt], pi))
110  return;
111 
112  if (requireConsumes_) {
114  "Consumer: an error occurred during validation of a "
115  "retrieved product\n\n")
116  << "The following consumes (or mayConsume) statement is missing from\n"
117  << module_context(moduleDescription_) << ":\n\n"
118  << " " << assemble_consumes_statement(bt, pi) << "\n\n";
119  }
120 
121  missingConsumes_[bt].insert(pi);
122 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
bool requireConsumes_
Definition: Consumer.h:137
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139

Member Data Documentation

std::unique_ptr<marley::Event> evgen::MarleyTimeGen::fEvent
protected

unique_ptr to the current event created by MARLEY

Definition at line 406 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), make_uniform_energy_mctruth(), and MarleyTimeGen().

uint_fast32_t evgen::MarleyTimeGen::fEventNumber
protected

Event number from the art::Event being processed.

Definition at line 503 of file MARLEYTimeGen_module.cc.

Referenced by MarleyTimeGen(), and produce().

TTree* evgen::MarleyTimeGen::fEventTree
protected

The event TTree created by MARLEY.

This tree will be saved to the "hist" output file for validation purposes. The tree contains the same information as the generated simb::MCTruth objects, but in MARLEY's internal format

Definition at line 496 of file MARLEYTimeGen_module.cc.

Referenced by MarleyTimeGen(), and produce().

double evgen::MarleyTimeGen::fFitEmax
protected

Maximum neutrino energy to consider when using a "fit"-format spectrum file.

Definition at line 527 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_time_fit(), reconfigure(), and source_from_time_fit().

double evgen::MarleyTimeGen::fFitEmin
protected

Minimum neutrino energy to consider when using a "fit"-format spectrum file.

Definition at line 523 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_time_fit(), reconfigure(), and source_from_time_fit().

double evgen::MarleyTimeGen::fFluxAveragedCrossSection
protected

Flux-averaged total cross section (fm2, average is taken over all energies and times for all defined reactions) used by MARLEY to generate neutrino vertices.

Definition at line 515 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), and reconfigure().

std::unique_ptr<evgen::MARLEYHelper> evgen::MarleyTimeGen::fMarleyHelper
protected

Object that provides an interface to the MARLEY event generator.

Definition at line 399 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), make_uniform_energy_mctruth(), and reconfigure().

unsigned int evgen::MarleyTimeGen::fNeutrinosPerEvent
protected

The number of MARLEY neutrino vertices to generate in each art::Event.

Definition at line 519 of file MARLEYTimeGen_module.cc.

Referenced by produce(), and reconfigure().

PinchParamType evgen::MarleyTimeGen::fPinchType
protected

The pinching parameter convention to use when interpreting the time-dependent fits.

Definition at line 470 of file MARLEYTimeGen_module.cc.

Referenced by reconfigure(), and source_from_time_fit().

uint_fast32_t evgen::MarleyTimeGen::fRunNumber
protected

Run number from the art::Event being processed.

Definition at line 499 of file MARLEYTimeGen_module.cc.

Referenced by MarleyTimeGen(), and produce().

TimeGenSamplingMode evgen::MarleyTimeGen::fSamplingMode
protected

Represents the sampling mode to use when selecting neutrino times and energies.

Definition at line 439 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), and reconfigure().

SpectrumFileFormat evgen::MarleyTimeGen::fSpectrumFileFormat
protected

Format to assume for the neutrino spectrum input file.

Definition at line 490 of file MARLEYTimeGen_module.cc.

Referenced by produce(), and reconfigure().

std::unique_ptr<TH2D> evgen::MarleyTimeGen::fSpectrumHist
protected

ROOT TH2D that contains the time-dependent spectrum to use when sampling neutrino times and energies.

This member is only used when reading the spectrum from a ROOT file.

Definition at line 412 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), and reconfigure().

uint_fast32_t evgen::MarleyTimeGen::fSubRunNumber
protected

Subrun number from the art::Event being processed.

Definition at line 501 of file MARLEYTimeGen_module.cc.

Referenced by MarleyTimeGen(), and produce().

std::vector<TimeFit> evgen::MarleyTimeGen::fTimeFits
protected

Vector that contains the fit parameter information for each time bin when using a "fit"-format spectrum file.

This member is unused when the spectrum is read from a ROOT file.

Definition at line 418 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_time_fit(), make_final_timefit(), make_nu_emission_histograms(), and reconfigure().

double evgen::MarleyTimeGen::fTNu
protected

Time since the supernova core bounce for the current MARLEY neutrino vertex.

Definition at line 507 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), MarleyTimeGen(), and produce().

std::unique_ptr<evgen::ActiveVolumeVertexSampler> evgen::MarleyTimeGen::fVertexSampler
protected

Algorithm that allows us to sample vertex locations within the active volume(s) of the detector.

Definition at line 403 of file MARLEYTimeGen_module.cc.

Referenced by produce(), and reconfigure().

double evgen::MarleyTimeGen::fWeight
protected

Statistical weight for the current MARLEY neutrino vertex.

Definition at line 510 of file MARLEYTimeGen_module.cc.

Referenced by create_truths_th2d(), create_truths_time_fit(), and MarleyTimeGen().


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