154#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
166#include "Framework/Conventions/GBuild.h"
189#ifdef __GENIE_FLUX_DRIVERS_ENABLED__
190#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
191#define __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
202using std::ostringstream;
204using namespace genie;
211#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
212void GenerateEventsUsingFluxOrTgtMix();
214GFluxI * FluxDriver (
void);
215GFluxI * MonoEnergeticFluxDriver (
void);
216GFluxI * PowerLawFluxDriver (
void);
217GFluxI * TH1FluxDriver (
void);
245int main(
int argc,
char ** argv)
251#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
252 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
259#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
260 GenerateEventsUsingFluxOrTgtMix();
263 <<
"\n To be able to generate neutrino events from a flux and/or a target mix"
264 <<
"\n you need to add the following config options at your GENIE installation:"
265 <<
"\n --enable-flux-drivers --enable-geom-drivers \n" ;
277 LOG(
"gevgen",
pFATAL) <<
" No TuneId in RunOption";
298 TLorentzVector nu_p4(0.,0.,Ev,Ev);
330 <<
"\n ** Will generate " <<
gOptNevents <<
" events for \n"
331 << init_state <<
" at Ev = " << Ev <<
" GeV";
337 <<
" *** Generating event............ " << ievent;
344 <<
"Last attempt failed. Re-trying....";
349 <<
"Generated Event GHEP Record: " << *event;
353 mcjmonitor.
Update(ievent,event);
363#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
365void GenerateEventsUsingFluxOrTgtMix(
void)
368 GFluxI * flux_driver = FluxDriver();
408 LOG(
"gevgen",
pNOTICE) <<
" *** Generating event............ " << ievent;
413 LOG(
"gevgen",
pNOTICE) <<
"Generated Event GHEP Record: " << *event;
416 ntpw.AddEventRecord(ievent, event);
417 mcjmonitor.Update(ievent,event);
445 else if(
gOptFlux.find(
"POWERLAW") != string::npos) flux_driver = PowerLawFluxDriver();
446 else flux_driver = TH1FluxDriver();
451GFluxI * MonoEnergeticFluxDriver(
void)
461GFluxI * PowerLawFluxDriver(
void)
466 assert(fv.size()==2);
468 double spectralindex = atof(fv[1].c_str());
476GFluxI * TH1FluxDriver(
void)
483 int flux_entries = 100000;
491 bool input_is_text_file = ! gSystem->AccessPathName(
gOptFlux.c_str());
492 bool input_is_root_file =
gOptFlux.find(
".root") != string::npos &&
494 if(input_is_text_file) {
500 double estep = (emax-emin)/(n-1);
501 double ymax = -1, ry = -1, gy = -1,
e = -1;
502 for(
int i=0; i<n; i++) {
504 ymax = TMath::Max(ymax, input_flux->
Evaluate(
e));
509 spectrum =
new TH1D(
"spectrum",
"neutrino flux", 300, emin, emax);
510 spectrum->SetDirectory(0);
512 for(
int ientry=0; ientry<flux_entries; ientry++) {
518 LOG(
"gevgen",
pFATAL) <<
"Couldn't generate a flux histogram";
521 e = emin + de * r->
RndGen().Rndm();
522 gy = ymax * r->
RndGen().Rndm();
525 if(accept) spectrum->Fill(
e);
530 else if(input_is_root_file) {
535 assert(fv.size()==2 || fv.size()==3);
536 assert( !gSystem->AccessPathName(fv[0].c_str()) );
538 LOG(
"gevgen",
pNOTICE) <<
"Getting input flux from root file: " << fv[0];
539 TFile * flux_file =
new TFile(fv[0].c_str(),
"read");
541 LOG(
"gevgen",
pNOTICE) <<
"Flux name: " << fv[1];
542 TH1D * hst = (TH1D *)flux_file->Get(fv[1].c_str());
544 LOG(
"gevgen",
pFATAL) <<
"Could not load the flux histogram \"" << fv[1]
545 <<
"\" from the input ROOT file: " << fv[0];
549 std::string extra = (fv.size()==3) ? fv[2] :
"";
550 std::transform(extra.begin(),extra.end(),extra.begin(),::toupper);
555 spectrum = (TH1D*)hst->Clone();
556 spectrum->SetNameTitle(
"spectrum",
"neutrino_flux");
557 spectrum->SetDirectory(0);
558 for(
int ibin = 1; ibin <= hst->GetNbinsX(); ibin++) {
559 if(hst->GetBinLowEdge(ibin) + hst->GetBinWidth(ibin) > emax ||
560 hst->GetBinLowEdge(ibin) < emin) {
561 spectrum->SetBinContent(ibin, 0);
564 bool force_binwidth =
false;
565#if ROOT_VERSION_CODE <= ROOT_VERSION(9,99,99)
570 TAxis* xaxis = spectrum->GetXaxis();
571 if (xaxis->IsVariableBinSize()) force_binwidth =
true;
573 if ( extra ==
"WIDTH" ) force_binwidth =
true;
574 if ( extra ==
"NOWIDTH" ) force_binwidth =
false;
575 if ( force_binwidth ) {
577 <<
"multiplying by bin width for histogram " << fv[1]
578 <<
" as " << spectrum->GetName()
579 <<
" from " << fv[0];
580 for(
int ibin = 1; ibin <= spectrum->GetNbinsX(); ++ibin) {
581 double data = spectrum->GetBinContent(ibin);
582 double width = spectrum->GetBinWidth(ibin);
583 spectrum->SetBinContent(ibin,data*width);
587 LOG(
"gevgen",
pNOTICE) << spectrum->GetEntries();
592 LOG(
"gevgen",
pNOTICE) << spectrum->GetEntries();
598 TF1 * input_func =
new TF1(
"input_func",
gOptFlux.c_str(), emin, emax);
599 spectrum =
new TH1D(
"spectrum",
"neutrino flux", 300, emin, emax);
600 spectrum->SetDirectory(0);
601 spectrum->FillRandom(
"input_func", flux_entries);
606 TFile f(
"./input-flux.root",
"recreate");
610 TVector3 bdir (0,0,1);
612 TVector3 bspot(0,0,0);
617 if ( fv.size() >= 3 ) {
618 bdir.SetX(atoi(fv[0].c_str()));
619 bdir.SetY(atoi(fv[1].c_str()));
620 bdir.SetZ(atoi(fv[2].c_str()));
621 if ( fv.size() >= 4 ) {
622 radius = atoi(fv[3].c_str());
623 if ( fv.size() >= 7 ) {
624 bspot.SetX(atoi(fv[4].c_str()));
625 bspot.SetY(atoi(fv[5].c_str()));
626 bspot.SetZ(atoi(fv[6].c_str()));
632 flux->SetNuDirection (bdir);
633 flux->SetTransverseRadius (radius);
634 flux->SetBeamSpot (bspot);
646 LOG(
"gevgen",
pINFO) <<
"Parsing command line arguments";
665 LOG(
"gevgen",
pINFO) <<
"Reading number of events to generate";
669 <<
"Unspecified number of events to generate - Using default";
675 LOG(
"gevgen",
pINFO) <<
"Reading MC run number";
678 LOG(
"gevgen",
pINFO) <<
"Unspecified run number - Using default";
684 LOG(
"gevgen",
pINFO) <<
"Reading output file name";
696 bool using_flux =
false;
698 LOG(
"gevgen",
pINFO) <<
"Reading flux function";
703 LOG(
"gevgen",
pINFO) <<
"Reading flux factors";
709 <<
"-s option no longer available. Please read the revised code documentation";
723 LOG(
"gevgen",
pINFO) <<
"Reading neutrino energy";
727 if(nue.find(
",") != string::npos) {
730 assert(nurange.size() == 2);
731 double emin = atof(nurange[0].c_str());
732 double emax = atof(nurange[1].c_str());
733 assert(emax>emin && emin>=0);
738 <<
"No flux was specified but an energy range was input!";
740 <<
"Events will be generated at fixed E = " <<
gOptNuEnergy <<
" GeV";
748 LOG(
"gevgen",
pFATAL) <<
"Unspecified neutrino energy - Exiting";
755 LOG(
"gevgen",
pINFO) <<
"Reading neutrino PDG code";
758 LOG(
"gevgen",
pFATAL) <<
"Unspecified neutrino PDG code - Exiting";
764 bool using_tgtmix =
false;
766 LOG(
"gevgen",
pINFO) <<
"Reading target mix";
770 if(tgtmix.size()==1) {
771 int pdg = atoi(tgtmix[0].c_str());
776 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
777 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
778 string tgt_with_wgt = *tgtmix_iter;
779 string::size_type open_bracket = tgt_with_wgt.find(
"[");
780 string::size_type close_bracket = tgt_with_wgt.find(
"]");
781 string::size_type ibeg = 0;
782 string::size_type iend = open_bracket;
783 string::size_type jbeg = open_bracket+1;
784 string::size_type jend = close_bracket-1;
785 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend).c_str());
786 double wgt = atof(tgt_with_wgt.substr(jbeg,jend).c_str());
788 <<
"Adding to target mix: pdg = " <<
pdg <<
", wgt = " << wgt;
794 LOG(
"gevgen",
pFATAL) <<
"Unspecified target PDG code - Exiting";
803 LOG(
"gevgen",
pINFO) <<
"Reading random number seed";
806 LOG(
"gevgen",
pINFO) <<
"Unspecified random number seed - Using default";
812 LOG(
"gevgen",
pINFO) <<
"Reading cross-section file";
815 LOG(
"gevgen",
pINFO) <<
"Unspecified cross-section file";
832 <<
"Random number seed was not set, using default";
841 <<
"No input cross-section spline file";
848 <<
"Force interaction of all flux rays? " <<
gOptForceInt;
851 <<
"Neutrino energy: ["
860 <<
"Target code (PDG) & weight fraction (in case of multiple targets): ";
861 map<int,double>::const_iterator iter;
863 int tgtpdgc = iter->first;
864 double wgt = iter->second;
866 <<
" >> " << tgtpdgc <<
" (weight fraction = " << wgt <<
")";
877 <<
"\n\n" <<
"Syntax:" <<
"\n"
881 <<
"\n -e energy (or energy range) "
882 <<
"\n -p neutrino_pdg"
883 <<
"\n -t target_pdg "
884 <<
"\n [-f flux_description]"
885 <<
"\n [-o outfile_name]"
887 <<
"\n [--force-flux-ray-interaction]"
888 <<
"\n [--seed random_number_seed]"
889 <<
"\n [--cross-sections xml_file]"
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
Command line argument parser.
string ArgAsString(char opt)
bool OptionExists(char opt)
was option set?
A vector of EventGeneratorI objects.
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void SetUnphysEventMask(const TBits &mask)
void Configure(int nu_pdgc, int Z, int A)
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
void SetEventGeneratorList(string listname)
GENIE Interface for user-defined flux classes.
static void SetPrintLevel(int print_level)
A GENIE ‘MC Job Driver’. Can be used for setting up complicated event generation cases involving deta...
void ForceSingleProbScale(void)
void UseFluxDriver(GFluxI *flux)
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void Configure(bool calc_prob_scales=true)
void ForceInteraction(void)
void UseSplines(bool useLogE=true)
void SetUnphysEventMask(const TBits &mask)
void SetEventGeneratorList(string listname)
EventRecord * GenerateEvent(void)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
void CustomizeFilename(string filename)
void Update(int iev, const EventRecord *event)
void SetRefreshRate(int rate)
Defines the GENIE Geometry Analyzer Interface.
Initial State information.
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
void CustomizeFilename(string filename)
void Initialize(void)
add event
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
A singleton holding random number generator classes. All random number generation in GENIE should tak...
static RandomGen * Instance()
Access instance.
TRandom3 & RndGen(void) const
rnd number generator for generic usage
void ReadFromCommandLine(int argc, char **argv)
static std::string RunOptSyntaxString(bool include_generator_specific)
void BuildTune()
build tune and inform XSecSplineList
void EnableBareXSecPreCalc(bool flag)
static RunOpt * Instance(void)
A numeric analysis tool class for interpolating 1-D functions.
double Evaluate(double x) const
A generic GENIE flux driver. Generates a 'cylindrical' neutrino beam along the input direction,...
A simple GENIE flux driver for monoenergetic neutrinos along the z direction. Can handle a mix of neu...
A simple GENIE flux driver for neutrinos following a power law spectrum. Can handle a mix of neutrino...
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
NtpMCFormat_t kDefOptNtpFormat
map< int, double > gOptTgtMix
void GenerateEventsAtFixedInitState(void)
void GetCommandLineArgs(int argc, char **argv)
bool gOptUsingFluxOrTgtMix
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
Utilities for improving the code readability when using PDG codes.
void XSecTable(string inpfile, bool require_table)
void RandGen(long int seed)
void MesgThresholds(string inpfile)
void CacheFile(string inpfile)
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
vector< string > Split(string input, string delim)
THE MAIN GENIE PROJECT NAMESPACE
enum genie::ENtpMCFormat NtpMCFormat_t