242#include <TRotation.h>
244#include <TGeoShape.h>
267#ifdef __GENIE_FLUX_DRIVERS_ENABLED__
273#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
282using std::ostringstream;
283using std::setprecision;
285using namespace genie;
330 double total_flux, expected_neutrinos;
336 LOG(
"gmkspl",
pFATAL) <<
" No TuneId in RunOption";
352 LOG(
"gevgen_atmo",
pWARN) <<
"Warning! Flux surface transverse radius not specified so using default value of " <<
gOptRT <<
" meters!";
357 LOG(
"gevgen_atmo",
pWARN) <<
"Warning! Flux surface longitudinal radius not specified so using default value of " <<
gOptRL <<
" meters!";
364 GFluxI *flux_driver =
dynamic_cast<GFluxI *
>(atmo_flux_driver);
392 LOG(
"gevgen_atmo",
pNOTICE) <<
"Total atmospheric neutrino flux is " << setprecision(2) << total_flux <<
" neutrinos per m^2 per second.";
398 LOG(
"gevgen_atmo",
pNOTICE) <<
"Simulating an exposure of " << setprecision(0) <<
gOptSecExposure <<
" seconds which corresponds to a total of " << setprecision(0) << expected_neutrinos <<
" neutrinos.";
408 LOG(
"gevgen_atmo",
pNOTICE) <<
"Generated event: " << *event;
412 mcjmonitor.
Update(iev,event);
427 delete atmo_flux_driver;
437#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
452 TGeoVolume * topvol = rgeom->
GetGeometry()->GetTopVolume();
454 LOG(
"gevgen_atmo",
pFATAL) <<
" ** Null top ROOT geometry volume!";
461 TGeoShape *bounding_box = topvol->GetShape();
462 TGeoBBox *box = (TGeoBBox *) bounding_box;
468 gOptRL = TMath::Sqrt(dx*dx + dy*dy + dz*dz);
470 LOG(
"gevgen_atmo",
pNOTICE) <<
"Setting flux longitudinal and transverse radius to " << setprecision(2) <<
gOptRL <<
" meters based on bounding box of ROOT geometry.";
496 LOG(
"gevgen_atmo",
pFATAL) <<
"You need to enable the GENIE geometry drivers first!";
497 LOG(
"gevgen_atmo",
pFATAL) <<
"Use --enable-geom-drivers at the configuration step.";
507#ifdef __GENIE_FLUX_DRIVERS_ENABLED__
513 atmo_flux_driver =
dynamic_cast<GAtmoFlux *
>(fluka_flux);
517 atmo_flux_driver =
dynamic_cast<GAtmoFlux *
>(bartol_flux);
521 atmo_flux_driver =
dynamic_cast<GAtmoFlux *
>(honda_flux);
532 map<int,string>::const_iterator file_iter =
gOptFluxFiles.begin();
534 int neutrino_code = file_iter->first;
535 string filename = file_iter->second;
536 atmo_flux_driver->
AddFluxFile(neutrino_code, filename);
540 LOG(
"gevgen_atmo",
pFATAL) <<
"Error loading flux data. Quitting...";
554 LOG(
"gevgen_atmo",
pFATAL) <<
"You need to enable the GENIE flux drivers first!";
555 LOG(
"gevgen_atmo",
pFATAL) <<
"Use --enable-flux-drivers at the configuration step.";
560 return atmo_flux_driver;
569 LOG(
"gevgen_atmo",
pNOTICE) <<
"Parsing command line arguments";
584 LOG(
"gevgen_atmo",
pDEBUG) <<
"Reading MC run number";
587 LOG(
"gevgen_atmo",
pDEBUG) <<
"Unspecified run number - Using default";
596 bool have_required_statistics =
false;
599 <<
"Reading number of events to generate";
601 have_required_statistics =
true;
605 if(have_required_statistics) {
607 <<
"Can't request exposure both in terms of number of events and kton*yrs"
608 <<
"\nUse just one of the -n and -e options";
614 <<
"Reading requested exposure in kton*yrs";
616 have_required_statistics =
true;
620 if (have_required_statistics) {
622 <<
"Can't request exposure both in terms of number of events or kton*yrs and time"
623 <<
"\nUse just one of the -n, -e, or -T options";
629 <<
"Reading requested exposure in seconds";
631 have_required_statistics =
true;
634 if(!have_required_statistics) {
636 <<
"You must request exposure either in terms of number of events and kton*yrs"
637 <<
"\nUse any of the -n, -e options";
647 LOG(
"gevgen_atmo",
pDEBUG) <<
"Reading the event filename prefix";
651 <<
"Will set the default event filename prefix";
659 LOG(
"gevgen_atmo",
pINFO) <<
"Reading neutrino energy range";
663 if(nue.find(
",") != string::npos) {
666 assert(nurange.size() == 2);
667 double emin = atof(nurange[0].c_str());
668 double emax = atof(nurange[1].c_str());
669 assert(emax>emin && emin>=0.);
674 <<
"Invalid energy range. Use `-E emin,emax', eg `-E 0.5,100.";
681 <<
"No -e option. Using default energy range";
693 LOG(
"gevgen_atmo",
pDEBUG) <<
"Getting input flux files";
698 string::size_type jsimend =
flux.find_first_of(
":",0);
699 if(jsimend==string::npos) {
701 <<
"You need to specify the flux file source";
707 for(string::size_type i=0; i<
gOptFluxSim.size(); i++) {
714 <<
"The flux file source needs to be one of <FLUKA,BGLRS,HAKKM>";
720 flux.erase(0,jsimend+1);
722 vector<string>::const_iterator fluxiter = fluxv.begin();
723 for( ; fluxiter != fluxv.end(); ++fluxiter) {
724 string filename_and_pdg = *fluxiter;
725 string::size_type open_bracket = filename_and_pdg.find(
"[");
726 string::size_type close_bracket = filename_and_pdg.find(
"]");
727 if (open_bracket ==string::npos ||
728 close_bracket==string::npos)
731 <<
"You made an error in specifying the flux info";
736 string::size_type ibeg = 0;
737 string::size_type iend = open_bracket;
738 string::size_type jbeg = open_bracket+1;
739 string::size_type jend = close_bracket;
740 string flux_filename = filename_and_pdg.substr(ibeg,iend-ibeg);
741 string neutrino_pdg = filename_and_pdg.substr(jbeg,jend-jbeg);
743 map<int,string>::value_type(atoi(neutrino_pdg.c_str()), flux_filename));
747 <<
"You must specify at least one flux file!";
754 LOG(
"gevgen_atmo",
pFATAL) <<
"No flux info was specified! Use the -f option.";
762 if( parser.
OptionExists(
"flux-ray-generation-surface-distance") ) {
764 <<
"Reading distance of flux ray generation surface";
768 <<
"Unspecified distance of flux ray generation surface - Using default";
771 if( parser.
OptionExists(
"flux-ray-generation-surface-radius") ) {
773 <<
"Reading radius of flux ray generation surface";
777 <<
"Unspecified radius of flux ray generation surface - Using default";
786 LOG(
"gevgen_atmo",
pDEBUG) <<
"Getting input geometry";
790 bool accessible_geom_file =
792 if (accessible_geom_file) {
798 <<
"No geometry option specified - Exiting";
810 <<
"Checking for input geometry length units";
813 LOG(
"gevgen_atmo",
pDEBUG) <<
"Using default geometry length units";
819 <<
"Checking for input geometry density units";
822 LOG(
"gevgen_atmo",
pDEBUG) <<
"Using default geometry density units";
831 LOG(
"gevgen_atmo",
pDEBUG) <<
"Checking for input volume name";
834 LOG(
"gevgen_atmo",
pDEBUG) <<
"Using the <master volume>";
842 <<
"Checking for maximum path lengths XML file";
846 <<
"Will compute the maximum path lengths at job init";
859 if(tgtmix.size()==1) {
860 int pdg = atoi(tgtmix[0].c_str());
864 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
865 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
866 string tgt_with_wgt = *tgtmix_iter;
867 string::size_type open_bracket = tgt_with_wgt.find(
"[");
868 string::size_type close_bracket = tgt_with_wgt.find(
"]");
869 if (open_bracket ==string::npos ||
870 close_bracket==string::npos)
873 <<
"You made an error in specifying the target mix";
878 string::size_type ibeg = 0;
879 string::size_type iend = open_bracket;
880 string::size_type jbeg = open_bracket+1;
881 string::size_type jend = close_bracket;
882 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend-ibeg).c_str());
883 double wgt = atof(tgt_with_wgt.substr(jbeg,jend-jbeg).c_str());
885 <<
"Adding to target mix: pdg = " <<
pdg <<
", wgt = " << wgt;
899 string::size_type j = rotarg.find_first_of(
":",0);
900 string convention =
"";
901 if(j==string::npos) { convention =
"X"; }
902 else { convention = rotarg.substr(0,j); }
906 if(euler_angles.size() != 3) {
908 <<
"You didn't specify all 3 Euler angles using the -R option";
913 double phi = atof(euler_angles[0].c_str());
914 double theta = atof(euler_angles[1].c_str());
915 double psi = atof(euler_angles[2].c_str());
917 if(convention.find(
"X")!=string::npos ||
918 convention.find(
"x")!=string::npos)
920 LOG(
"gevgen_atmo",
pNOTICE) <<
"Using X-convention for input Euler angles";
921 gOptRot.SetXEulerAngles(phi,theta,psi);
923 if(convention.find(
"Y")!=string::npos ||
924 convention.find(
"y")!=string::npos)
926 LOG(
"gevgen_atmo",
pNOTICE) <<
"Using Y-convention for input Euler angles";
927 gOptRot.SetYEulerAngles(phi,theta,psi);
930 <<
"Unknown Euler angle convention. Please use the X- or Y-convention";
936 if(convention.find(
"^-1")!=string::npos) {
937 LOG(
"gevgen_atmo",
pNOTICE) <<
"Inverting rotation matrix";
946 LOG(
"gevgen_atmo",
pINFO) <<
"Reading random number seed";
949 LOG(
"gevgen_atmo",
pINFO) <<
"Unspecified random number seed - Using default";
957 LOG(
"gevgen_atmo",
pINFO) <<
"Reading cross-section file";
960 LOG(
"gevgen_atmo",
pINFO) <<
"Unspecified cross-section file";
970 ostringstream gminfo;
972 gminfo <<
"Using ROOT geometry - file: " <<
gOptRootGeom
975 <<
", max{PL} file: "
977 <<
", length units: " <<
lunits
978 <<
", density units: " << dunits;
980 gminfo <<
"Using target mix - ";
981 map<int,double>::const_iterator iter;
983 int pdg_code = iter->first;
984 double wgt = iter->second;
985 TParticlePDG * p = pdglib->
Find(pdg_code);
987 string name = p->GetName();
988 gminfo <<
"(" << name <<
") -> " << 100*wgt <<
"% / ";
993 ostringstream fluxinfo;
994 fluxinfo <<
"Using " <<
gOptFluxSim <<
" flux files: ";
995 map<int,string>::const_iterator file_iter =
gOptFluxFiles.begin();
997 int neutrino_code = file_iter->first;
998 string filename = file_iter->second;
999 TParticlePDG * p = pdglib->
Find(neutrino_code);
1001 string name = p->GetName();
1002 fluxinfo <<
"(" << name <<
") -> " << filename <<
" / ";
1005 fluxinfo <<
"Flux ray generation surface - Distance = "
1008 ostringstream expinfo;
1012 ostringstream rotation;
1027 <<
"\n\t" << gminfo.str()
1029 <<
"\n\t" << fluxinfo.str()
1031 <<
"\n\t" << expinfo.str()
1034 <<
"\n @@ Coordinate transformation (Rotation THZ -> User-defined coordinate system)"
1035 <<
"\n" << rotation.str()
1043 <<
"\n Option to set exposure in terms of kton*yrs not supported just yet!"
1044 <<
"\n Try the -n option instead";
1055 <<
"\n gevgen_atmo [-h]"
1057 <<
"\n -f simulation:flux_file[neutrino_code],..."
1059 <<
"\n [-R coordinate_rotation_matrix]"
1060 <<
"\n [-t geometry_top_volume_name]"
1061 <<
"\n [-m max_path_lengths_xml_file]"
1062 <<
"\n [-L geometry_length_units]"
1063 <<
"\n [-D geometry_density_units]"
1064 <<
"\n <-n n_of_events,"
1065 <<
"\n -e exposure_in_kton_x_yrs"
1066 <<
"\n -T exposure_in_seconds>"
1067 <<
"\n -E min_energy,max_energy"
1068 <<
"\n [-o output_event_file_prefix]"
1069 <<
"\n [--flux-ray-generation-surface-distance]"
1070 <<
"\n [--flux-ray-generation-surface-radius]"
1071 <<
"\n [--seed random_number_seed]"
1072 <<
"\n --cross-sections xml_file"
1073 <<
"\n [--event-generator-list list_name]"
1074 <<
"\n [--message-thresholds xml_file]"
1075 <<
"\n [--unphysical-event-mask mask]"
1076 <<
"\n [--event-record-print-level level]"
1077 <<
"\n [--mc-job-status-refresh-rate rate]"
1078 <<
"\n [--cache-file root_file]"
1080 <<
" Please also read the detailed documentation at http://www.genie-mc.org"
#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)
double ArgAsDouble(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 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...
double GlobProbScale(void) const
void ForceSingleProbScale(void)
void UseFluxDriver(GFluxI *flux)
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void Configure(bool calc_prob_scales=true)
void UseSplines(bool useLogE=true)
long int NFluxNeutrinos(void) const
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 Update(int iev, const EventRecord *event)
void SetRefreshRate(int rate)
Defines the GENIE Geometry Analyzer Interface.
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
void Initialize(void)
add event
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void CustomizeFilenamePrefix(string prefix)
Singleton class to load & serve a TDatabasePDG.
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
void ReadFromCommandLine(int argc, char **argv)
void BuildTune()
build tune and inform XSecSplineList
static RunOpt * Instance(void)
A base class for the FLUKA, BGLRS and ATMNC atmo. nu. flux drivers. The driver depends on data files ...
void AddFluxFile(int neutrino_pdg, string filename)
void ForceMaxEnergy(double emax)
double GetTotalFluxInEnergyRange(void)
double GetFluxSurfaceArea(void)
void ForceMinEnergy(double emin)
void SetRadii(double Rlongitudinal, double Rtransverse)
void SetUserCoordSystem(TRotation &rotation)
Rotation: Topocentric Horizontal -> User-defined Topocentric Coord System.
A flux driver for the Bartol Atmospheric Neutrino Flux.
A flux driver for the FLUKA 3-D Atmospheric Neutrino Flux.
A driver for the HAKKM 3-D atmospheric neutrino flux (commonly known as the ‘Honda flux’)
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
A ROOT/GEANT4 geometry driver.
virtual TGeoManager * GetGeometry(void) const
virtual double LengthUnits(void) const
GeomAnalyzerI * GetGeometry(void)
map< int, string > gOptFluxFiles
double gOptKtonYrExposure
string kDefOptEvFilePrefix
NtpMCFormat_t kDefOptNtpFormat
map< int, double > gOptTgtMix
void GetCommandLineArgs(int argc, char **argv)
GAtmoFlux * GetFlux(void)
string gOptRootGeomTopVol
Utilities for improving the code readability when using PDG codes.
static constexpr double GeV
void XSecTable(string inpfile, bool require_table)
void RandGen(long int seed)
void MesgThresholds(string inpfile)
void CacheFile(string inpfile)
void RecursiveExhaust(TGeoVolume *topvol, string volnames, bool exhaust)
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
vector< string > Split(string input, string delim)
bool FileExists(string filename)
double UnitFromString(string u)
THE MAIN GENIE PROJECT NAMESPACE
enum genie::ENtpMCFormat NtpMCFormat_t