154 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
161 #include <TVector3.h>
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__
202 using std::ostringstream;
204 using namespace genie;
205 using namespace genie::controls;
211 #ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
212 void GenerateEventsUsingFluxOrTgtMix();
214 GFluxI * FluxDriver (
void);
215 GFluxI * MonoEnergeticFluxDriver (
void);
216 GFluxI * PowerLawFluxDriver (
void);
217 GFluxI * TH1FluxDriver (
void);
245 int 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__
365 void 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();
451 GFluxI * MonoEnergeticFluxDriver(
void)
461 GFluxI * PowerLawFluxDriver(
void)
466 assert(fv.size()==2);
468 double spectralindex = atof(fv[1].c_str());
476 GFluxI * 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()));
646 LOG(
"gevgen",
pINFO) <<
"Parsing command line arguments";
657 bool help = parser.OptionExists(
'h');
664 if( parser.OptionExists(
'n') ) {
665 LOG(
"gevgen",
pINFO) <<
"Reading number of events to generate";
669 <<
"Unspecified number of events to generate - Using default";
674 if( parser.OptionExists(
'r') ) {
675 LOG(
"gevgen",
pINFO) <<
"Reading MC run number";
678 LOG(
"gevgen",
pINFO) <<
"Unspecified run number - Using default";
683 if( parser.OptionExists(
'o') ) {
684 LOG(
"gevgen",
pINFO) <<
"Reading output file name";
696 bool using_flux =
false;
697 if( parser.OptionExists(
'f') ) {
698 LOG(
"gevgen",
pINFO) <<
"Reading flux function";
702 if (parser.OptionExists(
'F') ) {
703 LOG(
"gevgen",
pINFO) <<
"Reading flux factors";
707 if(parser.OptionExists(
's')) {
709 <<
"-s option no longer available. Please read the revised code documentation";
719 gOptForceInt = parser.OptionExists(
"force-flux-ray-interaction");
722 if( parser.OptionExists(
'e') ) {
723 LOG(
"gevgen",
pINFO) <<
"Reading neutrino energy";
724 string nue = parser.ArgAsString(
'e');
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);
735 gOptNuEnergyRange = emax-emin;
738 <<
"No flux was specified but an energy range was input!";
740 <<
"Events will be generated at fixed E = " <<
gOptNuEnergy <<
" GeV";
741 gOptNuEnergyRange = -1;
745 gOptNuEnergyRange = -1;
748 LOG(
"gevgen",
pFATAL) <<
"Unspecified neutrino energy - Exiting";
754 if( parser.OptionExists(
'p') ) {
755 LOG(
"gevgen",
pINFO) <<
"Reading neutrino PDG code";
758 LOG(
"gevgen",
pFATAL) <<
"Unspecified neutrino PDG code - Exiting";
764 bool using_tgtmix =
false;
765 if( parser.OptionExists(
't') ) {
766 LOG(
"gevgen",
pINFO) <<
"Reading target mix";
767 string stgtmix = parser.ArgAsString(
't');
770 if(tgtmix.size()==1) {
771 int pdg = atoi(tgtmix[0].c_str());
773 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
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;
789 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
794 LOG(
"gevgen",
pFATAL) <<
"Unspecified target PDG code - Exiting";
802 if( parser.OptionExists(
"seed") ) {
803 LOG(
"gevgen",
pINFO) <<
"Reading random number seed";
806 LOG(
"gevgen",
pINFO) <<
"Unspecified random number seed - Using default";
811 if( parser.OptionExists(
"cross-sections") ) {
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;
849 if(gOptNuEnergyRange>0) {
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]"
void RandGen(long int seed)
static void SetPrintLevel(int print_level)
void XSecTable(string inpfile, bool require_table)
void SetUnphysEventMask(const TBits &mask)
void ForceInteraction(void)
static RandomGen * Instance()
Access instance.
void SetEventGeneratorList(string listname)
void CustomizeFilename(string filename)
void ReadFromCommandLine(int argc, char **argv)
A numeric analysis tool class for interpolating 1-D functions.
void Update(int iev, const EventRecord *event)
void CustomizeFilename(string filename)
map< int, double > gOptTgtMix
double Evaluate(double x) const
A simple GENIE flux driver for neutrinos following a power law spectrum. Can handle a mix of neutrino...
A singleton holding random number generator classes. All random number generation in GENIE should tak...
int main(int argc, char **argv)
void SetRefreshRate(int rate)
void UseFluxDriver(GFluxI *flux)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
A GENIE `MC Job Driver'. Can be used for setting up complicated event generation cases involving deta...
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void SetEventGeneratorList(string listname)
void ForceSingleProbScale(void)
A generic GENIE flux driver. Generates a 'cylindrical' neutrino beam along the input direction...
static std::string RunOptSyntaxString(bool include_generator_specific)
A simple GENIE flux driver for monoenergetic neutrinos along the z direction. Can handle a mix of neu...
void Configure(bool calc_prob_scales=true)
void Save(void)
get the even tree
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void SetTransverseRadius(double Rt)
void SetNuDirection(const TVector3 &direction)
void BuildTune()
build tune and inform XSecSplineList
EventRecord * GenerateEvent(void)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
void Initialize(void)
add event
static RunOpt * Instance(void)
vector< string > Split(string input, string delim)
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records...
bool gOptUsingFluxOrTgtMix
TRandom3 & RndGen(void) const
rnd number generator for generic usage
void Configure(int nu_pdgc, int Z, int A)
NtpMCFormat_t kDefOptNtpFormat
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
A vector of EventGeneratorI objects.
void GenerateEventsAtFixedInitState(void)
void SetBeamSpot(const TVector3 &spot)
void MesgThresholds(string inpfile)
void AddEnergySpectrum(int nu_pdgc, TH1D *spectrum)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
void GetCommandLineArgs(int argc, char **argv)
Defines the GENIE Geometry Analyzer Interface.
static const unsigned int kRjMaxIterations
void SetUnphysEventMask(const TBits &mask)
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void UseSplines(bool useLogE=true)
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
void CacheFile(string inpfile)
void EnableBareXSecPreCalc(bool flag)
Initial State information.
GENIE Interface for user-defined flux classes.
EventRecord * GenerateEvent(const TLorentzVector &nu4p)