274 #include <TGeoVolume.h>
275 #include <TGeoShape.h>
299 #ifdef __GENIE_FLUX_DRIVERS_ENABLED__
315 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
326 using std::ostringstream;
328 using namespace genie;
379 std::cerr <<
"Caught SIGTERM" << std::endl;
383 int main(
int argc,
char ** argv)
396 LOG(
"gmkspl",
pFATAL) <<
" No TuneId in RunOption";
424 TGeoVolume * topvol = rgeom->
GetGeometry()->GetTopVolume();
426 LOG(
"gevgen_numi",
pFATAL) <<
"Null top ROOT geometry volume!";
460 if (
gOptFidCut.find(
"rock") != std::string::npos )
483 if ( ! flux_driver ) {
485 std::ostringstream
s;
486 s <<
"Known FluxDrivers:\n";
487 const std::vector<std::string>& known =
489 std::vector<std::string>::const_iterator itr = known.begin();
490 for ( ; itr != known.end(); ++itr ) s <<
" " << (*itr) <<
"\n";
492 <<
"Failed to get any flux driver from GFluxDriverFactory";
498 if ( ! flux_file_config ) {
500 <<
"Failed to get GFluxFileConfigI driver from GFluxDriverFactory";
527 if ( ! rgeom ) assert(0);
534 <<
"Using ROOTGeomAnalyzer: geom scan using flux: nparticles=" <<
gOptNScan;
540 <<
"Using ROOTGeomAnalyzer: geom scan using box: npoints=nrays=" << nabs;
568 std::ofstream mpfile(maxplfile.c_str(), std::ios_base::app);
571 <<
"<!-- this file is only relevant for a setup compatible with:"
579 <<
"nscan: " <<
gOptNScan <<
" (0>= use flux, <0 use box |nscan| points/rays)"
581 <<
"zmin: " <<
gOptZmin <<
" (if |zmin| > 1e30, leave ray on flux window)"
599 std::vector<TBranch*> extraBranches;
600 std::vector<std::string> branchNames;
601 std::vector<std::string> branchClassNames;
602 std::vector<void**> branchObjPointers;
606 if ( fluxFileConfigI ) {
609 size_t nn = branchNames.size();
610 size_t nc = branchClassNames.size();
611 size_t np = branchObjPointers.size();
612 if ( nn != nc || nc != np ) {
614 <<
"Inconsistent info back from flux driver "
615 <<
"for branch info: " << nn <<
" " << nc <<
" " << np;
617 for (
size_t ii = 0; ii < nn; ++ii) {
618 const char* bname = branchNames[ii].c_str();
619 const char* cname = branchClassNames[ii].c_str();
620 void**& optr = branchObjPointers[ii];
621 if ( ! optr || ! *optr )
continue;
624 <<
"Adding extra branch \"" << bname <<
"\" of type \""
625 << cname <<
"\" (" << optr <<
") to output tree";
626 TBranch* bptr = ntpw.
EventTree()->Branch(bname,cname,optr,32000,split);
627 extraBranches.push_back(bptr);
631 bptr->SetAutoDelete(
false);
634 <<
"FAILED to add extra branch \"" << bname <<
"\" of type \""
635 << cname <<
"\" to output tree";
656 <<
" *** Generating event............ " << ievent;
660 if ( ievent ==
gOptNev )
break;
668 if ( ! event && flux_driver->
End() ) {
670 <<
"** The flux driver read all the input flux entries: End()==true";
675 <<
"Got a null generated neutino event! Retrying ...";
679 <<
"Generated event: " << *event;
687 mcjmonitor.
Update(ievent,event);
694 if ( fluxFileConfigI ) {
697 size_t nmeta = t1->GetEntries();
698 TTree* t2 = (TTree*)t1->Clone(0);
699 for (
size_t i = 0; i < nmeta; ++i) {
708 <<
"The GENIE MC job is done generating events - Cleaning up & exiting...";
737 vector<string> extraLibs;
742 extraLibs.push_back(
"libdk2nuTree");
743 extraLibs.push_back(
"libdk2nuGenie");
753 Int_t prevErrorLevel = gErrorIgnoreLevel;
754 gErrorIgnoreLevel = kFatal;
755 for (
size_t ilib=0; ilib < extraLibs.size(); ++ilib) {
758 int loadStatus = gSystem->Load(extraLibs[ilib].c_str());
759 const char* statWords =
"failed to load";
760 if ( loadStatus == 0 ) { statWords =
"successfully loaded"; }
761 else if ( loadStatus == 1 ) { statWords =
"already had loaded"; }
762 else if ( loadStatus == -1 ) { statWords =
"couldn't find library"; }
763 else if ( loadStatus == -2 ) { statWords =
"mismatched version"; }
766 << statWords <<
" (" << loadStatus <<
") " << extraLibs[ilib];
769 gErrorIgnoreLevel = prevErrorLevel;
776 LOG(
"gevgen_lardm",
pINFO) <<
"Parsing command line arguments";
787 bool help = parser.OptionExists(
'h');
794 if ( parser.OptionExists(
'r') ) {
795 LOG(
"gevgen_lardm",
pDEBUG) <<
"Reading MC run number";
799 <<
"Unspecified run number - Using default";
809 if( parser.OptionExists(
'g') ) {
810 LOG(
"gevgen_lardm",
pDEBUG) <<
"Getting input geometry";
811 geom = parser.ArgAsString(
'g');
814 bool accessible_geom_file =
815 ! (gSystem->AccessPathName(geom.c_str()));
816 if (accessible_geom_file) {
822 <<
"No geometry option specified - Exiting";
828 if( parser.OptionExists(
'M') ) {
829 LOG(
"gevgen_lardm",
pINFO) <<
"Reading dark matter mass";
832 LOG(
"gevgen_lardm",
pFATAL) <<
"Unspecified dark matter mass - Exiting";
838 if( parser.OptionExists(
'c') ) {
839 LOG(
"gevgen_lardm",
pINFO) <<
"Reading mediator coupling";
842 LOG(
"gevgen_lardm",
pINFO) <<
"Unspecified mediator coupling - Using value from config file";
847 if( parser.OptionExists(
'v') ) {
848 LOG(
"gevgen_lardm",
pINFO) <<
"Reading mediator mass ratio";
851 LOG(
"gevgen_lardm",
pINFO) <<
"Unspecified mediator mass ratio - Using default";
859 if( parser.OptionExists(
'L') ) {
861 <<
"Checking for input geometry length units";
862 lunits = parser.ArgAsString(
'L');
864 LOG(
"gevgen_lardm",
pDEBUG) <<
"Using default geometry length units";
868 if( parser.OptionExists(
'D') ) {
870 <<
"Checking for input geometry density units";
871 dunits = parser.ArgAsString(
'D');
873 LOG(
"gevgen_lardm",
pDEBUG) <<
"Using default geometry density units";
881 if( parser.OptionExists(
't') ) {
882 LOG(
"gevgen_lardm",
pDEBUG) <<
"Checking for input volume name";
885 LOG(
"gevgen_lardm",
pDEBUG) <<
"Using the <master volume>";
892 if ( parser.OptionExists(
'm') ) {
894 <<
"Checking for maximum path lengths XML file";
905 <<
"Will compute the maximum path lengths at job init";
910 if( parser.OptionExists(
'F') ) {
911 LOG(
"gevgen_lardm",
pDEBUG) <<
"Using Fiducial cut?";
914 LOG(
"gevgen_lardm",
pDEBUG) <<
"No fiducial volume cut";
919 if( parser.OptionExists(
'S') ) {
920 LOG(
"gevgen_lardm",
pDEBUG) <<
"Reading requested geom scan count";
923 LOG(
"gevgen_lardm",
pDEBUG) <<
"No geom scan count was requested";
928 if( parser.OptionExists(
'z') ) {
929 LOG(
"gevgen_lardm",
pDEBUG) <<
"Reading requested zmin";
932 LOG(
"gevgen_lardm",
pDEBUG) <<
"No zmin was requested";
937 if ( parser.OptionExists(
'd') ) {
938 LOG(
"gevgen_lardm",
pDEBUG) <<
"Reading debug flag value";
941 LOG(
"gevgen_lardm",
pDEBUG) <<
"Unspecified debug flags - Using default";
955 if(tgtmix.size()==1) {
956 int pdg = atoi(tgtmix[0].c_str());
958 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
960 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
961 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
962 string tgt_with_wgt = *tgtmix_iter;
963 string::size_type open_bracket = tgt_with_wgt.find(
"[");
964 string::size_type close_bracket = tgt_with_wgt.find(
"]");
965 if (open_bracket ==string::npos ||
966 close_bracket==string::npos)
969 <<
"You made an error in specifying the target mix";
973 string::size_type ibeg = 0;
974 string::size_type iend = open_bracket;
975 string::size_type jbeg = open_bracket+1;
976 string::size_type jend = close_bracket;
977 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend-ibeg).c_str());
978 double wgt = atof(tgt_with_wgt.substr(jbeg,jend-jbeg).c_str());
980 <<
"Adding to target mix: pdg = " << pdg <<
", wgt = " << wgt;
981 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
990 if ( parser.OptionExists(
'f') ) {
991 LOG(
"gevgen_lardm",
pDEBUG) <<
"Getting input flux";
994 LOG(
"gevgen_lardm",
pFATAL) <<
"No flux info was specified - Exiting";
1000 if( parser.OptionExists(
'n') ) {
1002 <<
"Reading limit on number of events to generate";
1003 gOptNev = parser.ArgAsInt(
'n');
1006 <<
"Will keep on generating events till the flux driver stops";
1011 if( parser.OptionExists(
'o') ) {
1012 LOG(
"gevgen_lardm",
pDEBUG) <<
"Reading the event filename prefix";
1016 <<
"Will set the default event filename prefix";
1022 if( parser.OptionExists(
"seed") ) {
1023 LOG(
"gevgen_lardm",
pINFO) <<
"Reading random number seed";
1026 LOG(
"gevgen_lardm",
pINFO) <<
"Unspecified random number seed - Using default";
1031 if( parser.OptionExists(
"cross-sections") ) {
1032 LOG(
"gevgen_lardm",
pINFO) <<
"Reading cross-section file";
1035 LOG(
"gevgen_lardm",
pINFO) <<
"Unspecified cross-section file";
1045 ostringstream gminfo;
1047 gminfo <<
"Using ROOT geometry - file = " <<
gOptRootGeom
1048 <<
", top volume = "
1050 <<
", max{PL} file = "
1052 <<
", length units = " << lunits
1053 <<
", density units = " << dunits;
1055 gminfo <<
"Using target mix: ";
1056 map<int,double>::const_iterator iter;
1058 int pdg_code = iter->first;
1059 double wgt = iter->second;
1060 TParticlePDG * p = pdglib->
Find(pdg_code);
1062 string name = p->GetName();
1063 gminfo <<
"(" << name <<
") -> " << 100*wgt <<
"% / ";
1068 ostringstream fluxinfo;
1071 ostringstream exposure;
1073 exposure <<
"Number of events = " <<
gOptNev;
1083 <<
"\n - Flux @ " << fluxinfo.str()
1084 <<
"\n - Geometry @ " << gminfo.str()
1085 <<
"\n - Exposure @ " << exposure.str();
1094 <<
"\n gevgen_lardm [-h] [-r run#]"
1095 <<
"\n -f flux -g geometry -M dm_mass"
1096 <<
"\n [-c zp_coupling] [-v med_ratio]"
1097 <<
"\n [-t top_volume_name_at_geom] [-m max_path_lengths_xml_file]"
1098 <<
"\n [-L length_units_at_geom] [-D density_units_at_geom]"
1099 <<
"\n [-n n_of_events] "
1100 <<
"\n [-o output_event_file_prefix]"
1101 <<
"\n [-F fid_cut_string] [-S nrays_scan]"
1102 <<
"\n [-z zmin_start]"
1103 <<
"\n [--seed random_number_seed]"
1104 <<
"\n --cross-sections xml_file"
1105 <<
"\n [--event-generator-list list_name]"
1106 <<
"\n [--message-thresholds xml_file]"
1107 <<
"\n [--unphysical-event-mask mask]"
1108 <<
"\n [--event-record-print-level level]"
1109 <<
"\n [--mc-job-status-refresh-rate rate]"
1110 <<
"\n [--cache-file root_file]"
1112 <<
" Please also read the detailed documentation at "
1113 <<
"$GENIE/src/Apps/gFNALExptEvGen.cxx"
1149 <<
"Can not create GeomVolSelectorFiduction,"
1150 <<
" geometry driver is not ROOTGeomAnalyzer";
1154 LOG(
"gevgen_lardm",
pNOTICE) <<
"-F " << fidcut;
1162 std::transform(fidcut.begin(),fidcut.end(),fidcut.begin(),::tolower);
1165 if ( strtok.size() != 2 ) {
1167 <<
"Can not create GeomVolSelectorFiduction,"
1168 <<
" no \":\" separating type from values. nsplit=" << strtok.size();
1169 for (
unsigned int i=0; i < strtok.size(); ++i )
1171 <<
"strtok[" << i <<
"] = \"" << strtok[i] <<
"\"";
1176 string stype = strtok[0];
1177 bool reverse = ( stype.find(
"0") != string::npos );
1178 bool master = ( stype.find(
"m") != string::npos );
1181 vector<double> vals;
1183 vector<string>::const_iterator iter = valstrs.begin();
1184 for ( ; iter != valstrs.end(); ++iter ) {
1185 const string& valstr1 = *iter;
1186 if ( valstr1 !=
"" ) vals.push_back(atof(valstr1.c_str()));
1188 size_t nvals = vals.size();
1190 std::cout <<
"ivals = [";
1191 for (
unsigned int i=0; i < nvals; ++i) {
1192 if (i>0) cout <<
",";
1193 std::cout << vals[i];
1195 std::cout <<
"]" << std::endl;
1199 if ( stype.find(
"zcyl") != string::npos ) {
1202 LOG(
"gevgen_lardm",
pFATAL) <<
"MakeZCylinder needs 5 values, not " << nvals
1203 <<
" fidcut=\"" << fidcut <<
"\"";
1204 fidsel->
MakeZCylinder(vals[0],vals[1],vals[2],vals[3],vals[4]);
1206 }
else if ( stype.find(
"box") != string::npos ) {
1209 LOG(
"gevgen_lardm",
pFATAL) <<
"MakeBox needs 6 values, not " << nvals
1210 <<
" fidcut=\"" << fidcut <<
"\"";
1211 double xyzmin[3] = { vals[0], vals[1], vals[2] };
1212 double xyzmax[3] = { vals[3], vals[4], vals[5] };
1213 fidsel->
MakeBox(xyzmin,xyzmax);
1215 }
else if ( stype.find(
"zpoly") != string::npos ) {
1218 LOG(
"gevgen_lardm",
pFATAL) <<
"MakeZPolygon needs 7 values, not " << nvals
1219 <<
" fidcut=\"" << fidcut <<
"\"";
1220 int nfaces = (int)vals[0];
1222 LOG(
"gevgen_lardm",
pFATAL) <<
"MakeZPolygon needs nfaces>=3, not " << nfaces
1223 <<
" fidcut=\"" << fidcut <<
"\"";
1224 fidsel->
MakeZPolygon(nfaces,vals[1],vals[2],vals[3],vals[4],vals[5],vals[6]);
1226 }
else if ( stype.find(
"sphere") != string::npos ) {
1229 LOG(
"gevgen_lardm",
pFATAL) <<
"MakeZSphere needs 4 values, not " << nvals
1230 <<
" fidcut=\"" << fidcut <<
"\"";
1231 fidsel->
MakeSphere(vals[0],vals[1],vals[2],vals[3]);
1235 <<
"Can not create GeomVolSelectorFiduction for shape \"" << stype <<
"\"";
1240 LOG(
"gevgen_lardm",
pNOTICE) <<
"Convert fiducial volume from master to topvol coords";
1244 LOG(
"gevgen_lardm",
pNOTICE) <<
"Reverse sense of fiducial volume cut";
1253 if( fidcut.find_first_not_of(
" \t\n") != 0)
1254 fidcut.erase( 0, fidcut.find_first_not_of(
" \t\n") );
1257 std::transform(fidcut.begin(),fidcut.end(),fidcut.begin(),::tolower);
1263 <<
"Can not create GeomVolSelectorRockBox,"
1264 <<
" geometry driver is not ROOTGeomAnalyzer";
1268 LOG(
"gevgen_numi",
pWARN) <<
"fiducial (rock) cut: " << fidcut;
1275 if ( strtok.size() != 2 ) {
1277 <<
"Can not create GeomVolSelectorRockBox,"
1278 <<
" no \":\" separating type from values. nsplit=" << strtok.size();
1279 for (
unsigned int i=0; i < strtok.size(); ++i )
1281 <<
"strtok[" << i <<
"] = \"" << strtok[i] <<
"\"";
1285 string stype = strtok[0];
1288 vector<double> vals;
1290 vector<string>::const_iterator iter = valstrs.begin();
1291 for ( ; iter != valstrs.end(); ++iter ) {
1292 const string& valstr1 = *iter;
1293 if ( valstr1 !=
"" ) {
1294 double aval = atof(valstr1.c_str());
1295 LOG(
"gevgen_numi",
pWARN) <<
"rock value [" << vals.size() <<
"] "
1297 vals.push_back(aval);
1300 size_t nvals = vals.size();
1312 LOG(
"gevgen_numi",
pFATAL) <<
"rockbox needs at "
1313 <<
"least 6 values, found "
1315 << strtok[1] <<
"\"";
1319 double xyzmin[3] = { vals[0], vals[1], vals[2] };
1320 double xyzmax[3] = { vals[3], vals[4], vals[5] };
1322 bool rockonly =
true;
1323 double wallmin = 800.;
1324 double dedx = 2.5 * 1.7e-3;
1325 double fudge = 1.05;
1327 if ( nvals >= 7 ) rockonly = vals[6];
1328 if ( nvals >= 8 ) wallmin = vals[7];
1329 if ( nvals >= 9 ) dedx = vals[8];
1330 if ( nvals >= 10 ) fudge = vals[9];
1341 if ( ! rockonly ) rocksel->
MakeSphere(0,0,0,1.0
e-10);
1342 else rocksel->
MakeBox(xyzmin,xyzmax);
1344 rgeom->AdoptGeomVolSelector(rocksel);
void MakeSphere(Double_t x0, Double_t y0, Double_t z0, Double_t radius)
void RandGen(long int seed)
static void SetPrintLevel(int print_level)
GENIE Interface for user-defined volume selector functors Trim path segments based on the intersectio...
void XSecTable(string inpfile, bool require_table)
virtual GeomVolSelectorI * AdoptGeomVolSelector(GeomVolSelectorI *selector)
configure processing to perform path segment trimming
void CreateRockBoxSelection(string fidcut, GeomAnalyzerI *geom_driver)
virtual void LoadBeamSimData(const std::vector< std::string > &filenames, const std::string &det_loc)=0
void AddDarkMatter(double mass, double med_ratio)
void MakeZCylinder(Double_t x0, Double_t y0, Double_t radius, Double_t zmin, Double_t zmax)
string gOptRootGeomMasterVol
void SetEventGeneratorList(string listname)
void DetermineFluxDriver(string fopt)
void ReadFromCommandLine(int argc, char **argv)
virtual const PathLengthList & GetMaxPathLengths(void) const
static constexpr double s
virtual void ConvertShapeMaster2Top(const ROOTGeomAnalyzer *rgeom)
void Update(int iev, const EventRecord *event)
const std::vector< std::string > & AvailableFluxDrivers() const
void SetMinimumWall(Double_t w)
map< int, double > gOptTgtMix
virtual void SetNumOfCycles(long int ncycle)
limit cycling through input files
virtual void SetScannerNParticles(int np)
Registry * CommonList(const string &file_id, const string &set_name) const
int main(int argc, char **argv)
void CreateFidSelection(string fidcut, GeomAnalyzerI *geom_driver)
virtual void SetUpstreamZ(double z0)
void SetRefreshRate(int rate)
string kDefOptEvFilePrefix
void UseFluxDriver(GFluxI *flux)
Object to be filled with the neutrino path-length, for all detector geometry materials, when starting from a position x and travelling along the direction of the neutrino 4-momentum.
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
virtual TTree * GetMetaDataTree()
A GENIE `MC Job Driver'. Can be used for setting up complicated event generation cases involving deta...
void SaveAsXml(string filename) const
void SetDeDx(Double_t dedx)
void ParseFluxFileConfig(string fopt)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
string gOptRootGeomTopVol
void ForceSingleProbScale(void)
virtual void SetScannerNRays(int nr)
bool UseMaxPathLengths(string xml_filename)
double UnitFromString(string u)
GENIE Interface for limiting vertex selection in the rock to a volume that depends (in part) on the n...
void SetRemoveEntries(bool rmset)
static void gsSIGTERMhandler(int)
void Configure(bool calc_prob_scales=true)
void MakeZPolygon(Int_t n, Double_t x0, Double_t y0, Double_t inradius, Double_t phi0deg, Double_t zmin, Double_t zmax)
A ROOT/GEANT4 geometry driver.
void Save(void)
get the even tree
void Lock(void)
locks the registry
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
void BuildTune()
build tune and inform XSecSplineList
EventRecord * GenerateEvent(void)
virtual void GetBranchInfo(std::vector< std::string > &branchNames, std::vector< std::string > &branchClassNames, std::vector< void ** > &branchObjPointers)
void SetExpandFromInclusion(bool how=false)
void UnLock(void)
unlocks the registry (doesn't unlock items)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
void CustomizeFilenamePrefix(string prefix)
void LoadExtraOptions(void)
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.
A registry. Provides the container for algorithm configuration parameters.
virtual void SetScannerNPoints(int np)
set geometry driver's configuration options
virtual void SetScannerFlux(GFluxI *f)
static GFluxDriverFactory & Instance()
virtual bool End(void)=0
true if no more flux nu's can be thrown (eg reaching end of beam sim ntuples)
void SetReverseFiducial(Bool_t reverse=true)
NtpMCFormat_t kDefOptNtpFormat
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
A vector of EventGeneratorI objects.
virtual void SetFluxParticles(const PDGCodeList &particles)
specify list of flux neutrino species
void MesgThresholds(string inpfile)
TParticlePDG * Find(int pdgc, bool must_exist=true)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
void SetRockBoxMinimal(Double_t *xyzmin, Double_t *xyzmax)
void MakeBox(Double_t *xyzmin, Double_t *xyzmax)
void GetCommandLineArgs(int argc, char **argv)
Defines the GENIE Geometry Analyzer Interface.
void Set(RgIMapPair entry)
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...
void ParseFluxHst(string fopt)
void CacheFile(string inpfile)
void EnableBareXSecPreCalc(bool flag)
void push_back(int pdg_code)
virtual TGeoManager * GetGeometry(void) const
static AlgConfigPool * Instance()
genie::GFluxI * GetFluxDriver(const std::string &)
GENIE Interface for user-defined flux classes.