242 #include <TRotation.h> 244 #include <TGeoShape.h> 245 #include <TGeoBBox.h> 267 #ifdef __GENIE_FLUX_DRIVERS_ENABLED__ 273 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__ 282 using std::ostringstream;
285 using 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.";
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!";
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);
533 for( ; file_iter != gOptFluxFiles.end(); ++file_iter) {
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);
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);
742 gOptFluxFiles.insert(
743 map<int,string>::value_type(atoi(neutrino_pdg.c_str()), flux_filename));
745 if(gOptFluxFiles.size() == 0) {
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";
784 string lunits, dunits;
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());
862 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
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;
886 gOptTgtMix.insert(map<int, double>::value_type(pdg, 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 - ";
982 for(iter = gOptTgtMix.begin(); iter != gOptTgtMix.end(); ++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: ";
996 for( ; file_iter != gOptFluxFiles.end(); ++file_iter) {
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"
void RandGen(long int seed)
static void SetPrintLevel(int print_level)
void XSecTable(string inpfile, bool require_table)
double ArgAsDouble(char opt)
map< int, string > gOptFluxFiles
string ArgAsString(char opt)
THE MAIN GENIE PROJECT NAMESPACE
void SetEventGeneratorList(string listname)
double GetFluxSurfaceArea(void)
bool FileExists(string filename)
void ReadFromCommandLine(int argc, char **argv)
void Update(int iev, const EventRecord *event)
void SetRadii(double Rlongitudinal, double Rtransverse)
map< int, double > gOptTgtMix
double GetTotalFluxInEnergyRange(void)
Q_EXPORT QTSManip setprecision(int p)
int main(int argc, char **argv)
GAtmoFlux * GetFlux(void)
void SetRefreshRate(int rate)
string kDefOptEvFilePrefix
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...
double GlobProbScale(void) const
A flux driver for the FLUKA 3-D Atmospheric Neutrino Flux.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void ForceMaxEnergy(double emax)
string gOptRootGeomTopVol
void ForceSingleProbScale(void)
static constexpr double GeV
virtual double LengthUnits(void) const
double UnitFromString(string u)
void Configure(bool calc_prob_scales=true)
A ROOT/GEANT4 geometry driver.
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void BuildTune()
build tune and inform XSecSplineList
EventRecord * GenerateEvent(void)
long int NFluxNeutrinos(void) const
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
void SetUserCoordSystem(TRotation &rotation)
Rotation: Topocentric Horizontal -> User-defined Topocentric Coord System.
void CustomizeFilenamePrefix(string prefix)
void Initialize(void)
add event
static PDGLibrary * Instance(void)
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...
Singleton class to load & serve a TDatabasePDG.
void AddFluxFile(int neutrino_pdg, string filename)
A driver for the HAKKM 3-D atmospheric neutrino flux (commonly known as the `Honda flux') ...
NtpMCFormat_t kDefOptNtpFormat
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
A vector of EventGeneratorI objects.
void MesgThresholds(string inpfile)
TParticlePDG * Find(int pdgc, bool must_exist=true)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
double gOptKtonYrExposure
void GetCommandLineArgs(int argc, char **argv)
Defines the GENIE Geometry Analyzer Interface.
A base class for the FLUKA, BGLRS and ATMNC atmo. nu. flux drivers. The driver depends on data files ...
void ForceMinEnergy(double emin)
A flux driver for the Bartol Atmospheric Neutrino Flux.
void RecursiveExhaust(TGeoVolume *topvol, string volnames, bool exhaust)
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...
bool OptionExists(char opt)
was option set?
void CacheFile(string inpfile)
Event finding and building.
virtual TGeoManager * GetGeometry(void) const
GENIE Interface for user-defined flux classes.
GeomAnalyzerI * GetGeometry(void)