438 #include <TGeoVolume.h>
439 #include <TGeoShape.h>
465 #ifdef __GENIE_FLUX_DRIVERS_ENABLED__
470 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
479 using std::ostringstream;
481 using namespace genie;
524 int main(
int argc,
char ** argv)
531 LOG(
"gmkspl",
pFATAL) <<
" No TuneId in RunOption";
550 double zmin=0, zmax=0;
565 TGeoVolume * topvol = rgeom->
GetGeometry()->GetTopVolume();
566 TGeoShape * bounding_box = topvol->GetShape();
567 bounding_box->GetAxisRange(3, zmin, zmax);
574 LOG(
"gevgen_t2k",
pFATAL) <<
"Null top ROOT geometry volume!";
619 if(!beam_sim_data_success) {
621 <<
"The flux driver has not been properly configured. Exiting";
635 flux_driver =
dynamic_cast<GFluxI *
> (jparc_flux_driver);
643 TVector3 bdir (0,0,1);
644 TVector3 bspot(0,0,0);
651 int pdg_code = it->first;
652 TH1D * spectrum =
new TH1D(*(it->second));
656 flux_driver =
dynamic_cast<GFluxI *
> (hst_flux_driver);
680 bool success =
false;
686 string name = basename.substr(0, basename.rfind(
"."));
690 name +=
".master.flxprobs.root";
706 <<
"Successfully calculated/loaded flux interaction probabilities!";
710 map<int, double>::const_iterator sum_probs_it = sum_probs_map.begin();
711 double ntot_per_pot = 0.0;
712 double ntot_per_cycle = 0.0;
714 double pot_1cycle = jparc_flux_driver->
POT_1cycle();
716 "Expected event rates based on flux interaction probabilities:";
717 for(; sum_probs_it != sum_probs_map.end(); sum_probs_it++){
718 double sum_probs = sum_probs_it->second;
719 double nevts_per_cycle = sum_probs / pscale;
720 double nevts_per_pot = sum_probs/pot_1cycle;
721 ntot_per_pot += nevts_per_pot;
722 ntot_per_cycle += nevts_per_cycle;
724 " PDG "<< sum_probs_it->first <<
": " << nevts_per_cycle <<
725 " Events/Cycle, "<< nevts_per_pot <<
" Events/POT";
727 LOG(
"T2KProdInfo",
pNOTICE) <<
" -----------";
729 " All neutrino species: " << ntot_per_cycle <<
730 " Events/Cycle, "<< ntot_per_pot <<
" Events/POT";
732 "N.B. This assumes input flux file corresponds to "<< pot_1cycle <<
733 "POT, ensure this is correct if using these numbers!";
737 <<
"Failed to calculated/loaded flux interaction probabilities!";
744 <<
"Will not generate events - just pre-calculating flux interaction"
758 double fpot_1c = jparc_flux_driver->
POT_1cycle();
760 double pot_1c = fpot_1c / psc;
761 int ncycles = (int) TMath::Max(1., TMath::Ceil(
gOptPOT/pot_1c));
764 <<
" *** POT/cycle: " << pot_1c;
766 <<
" *** Requested POT will be accumulated in: "
767 << ncycles <<
" flux ntuple cycles";
795 TBranch * flux = ntpw.
EventTree()->Branch(
"flux",
796 "genie::flux::GJPARCNuFluxPassThroughInfo", &flux_info, 32000, 1);
798 flux->SetAutoDelete(kFALSE);
813 <<
" *** Generating event............ " << ievent;
827 double pot = fpot / psc;
837 if(!event && jparc_flux_driver->
End()) {
839 <<
"** The JPARC flux driver read all the input flux ntuple entries";
844 <<
"Got a null generated neutino event! Retrying ...";
848 <<
"Generated event: " << *event;
859 <<
"Pass-through flux info associated with generated event: "
865 mcjmonitor.
Update(ievent,event);
867 if(flux_info)
delete flux_info;
872 <<
"The GENIE MC job is done generaing events - Cleaning up & exiting...";
885 double pot = fpot / psc;
889 long int nflx_evg = mcj_driver -> NFluxNeutrinos();
890 long int nflx = jparc_flux_driver -> NFluxNeutrinos();
891 long int nev = ievent;
894 <<
"\n >> Actual JNUBEAM flux file normalization: " << fpot
896 <<
"\n >> Interaction probability scaling factor: " << psc
897 <<
"\n >> N of flux v read-in by flux driver: " << nflx
898 <<
"\n >> N of flux v thrown to event gen driver: " << nflx_evg
899 <<
"\n >> N of generated v interactions: " << nev
900 <<
"\n ** Normalization for generated sample: " << pot
901 <<
" POT * " << ((gOptDetectorLocation ==
"sk") ?
"cm^2" :
"det");
923 ntpw.
EventTree()->GetUserInfo()->Add(metadata);
938 TH1D * spectrum = it->second;
939 if(spectrum)
delete spectrum;
950 LOG(
"gevgen_t2k",
pINFO) <<
"Parsing command line arguments";
961 bool help = parser.OptionExists(
'h');
968 if( parser.OptionExists(
'r') ) {
969 LOG(
"gevgen_t2k",
pDEBUG) <<
"Reading MC run number";
972 LOG(
"gevgen_t2k",
pDEBUG) <<
"Unspecified run number - Using default";
982 if( parser.OptionExists(
'g') ) {
983 LOG(
"gevgen_t2k",
pDEBUG) <<
"Getting input geometry";
984 geom = parser.ArgAsString(
'g');
987 bool accessible_geom_file =
988 ! (gSystem->AccessPathName(geom.c_str()));
989 if (accessible_geom_file) {
995 <<
"No geometry option specified - Exiting";
1004 if( parser.OptionExists(
'L') ) {
1006 <<
"Checking for input geometry length units";
1007 lunits = parser.ArgAsString(
'L');
1009 LOG(
"gevgen_t2k",
pDEBUG) <<
"Using default geometry length units";
1013 if( parser.OptionExists(
'D') ) {
1015 <<
"Checking for input geometry density units";
1016 dunits = parser.ArgAsString(
'D');
1018 LOG(
"gevgen_t2k",
pDEBUG) <<
"Using default geometry density units";
1026 if( parser.OptionExists(
't') ) {
1027 LOG(
"gevgen_t2k",
pDEBUG) <<
"Checking for input volume name";
1030 LOG(
"gevgen_t2k",
pDEBUG) <<
"Using the <master volume>";
1036 if( parser.OptionExists(
'm') ) {
1038 <<
"Checking for maximum path lengths XML file";
1042 <<
"Will compute the maximum path lengths at job init";
1055 if(tgtmix.size()==1) {
1056 int pdg = atoi(tgtmix[0].c_str());
1058 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
1060 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
1061 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
1062 string tgt_with_wgt = *tgtmix_iter;
1063 string::size_type open_bracket = tgt_with_wgt.find(
"[");
1064 string::size_type close_bracket = tgt_with_wgt.find(
"]");
1065 if (open_bracket ==string::npos ||
1066 close_bracket==string::npos)
1069 <<
"You made an error in specifying the target mix";
1073 string::size_type ibeg = 0;
1074 string::size_type iend = open_bracket;
1075 string::size_type jbeg = open_bracket+1;
1076 string::size_type jend = close_bracket;
1077 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend-ibeg).c_str());
1078 double wgt = atof(tgt_with_wgt.substr(jbeg,jend-jbeg).c_str());
1080 <<
"Adding to target mix: pdg = " << pdg <<
", wgt = " << wgt;
1081 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
1091 if( parser.OptionExists(
'f') ) {
1092 LOG(
"gevgen_t2k",
pDEBUG) <<
"Getting input flux";
1093 string flux = parser.ArgAsString(
'f');
1103 if(fluxv.size()<2) {
1105 <<
"You need to specify both a flux ntuple ROOT file "
1106 <<
" _AND_ a detector location";
1115 for(
unsigned int inu = 2; inu < fluxv.size(); inu++)
1130 if(fluxv.size()<2) {
1132 <<
"You need to specify both a flux ntuple ROOT file "
1133 <<
" _AND_ a detector location";
1138 bool accessible_flux_file =
1140 if (!accessible_flux_file) {
1148 for(
unsigned int inu=1; inu<fluxv.size(); inu++) {
1149 string nutype_and_histo = fluxv[inu];
1150 string::size_type open_bracket = nutype_and_histo.find(
"[");
1151 string::size_type close_bracket = nutype_and_histo.find(
"]");
1152 if (open_bracket ==string::npos ||
1153 close_bracket==string::npos)
1156 <<
"You made an error in specifying the flux histograms";
1160 string::size_type ibeg = 0;
1161 string::size_type iend = open_bracket;
1162 string::size_type jbeg = open_bracket+1;
1163 string::size_type jend = close_bracket;
1164 string nutype = nutype_and_histo.substr(ibeg,iend-ibeg);
1165 string histo = nutype_and_histo.substr(jbeg,jend-jbeg);
1166 string extra = nutype_and_histo.substr(jend+1,string::npos);
1167 std::transform(extra.begin(),extra.end(),extra.begin(),::toupper);
1169 TH1D * ihst = (TH1D*) flux_file.Get(histo.c_str());
1172 <<
"Can not find histogram: " << histo
1178 TString origname = ihst->GetName();
1179 TString tmpname; tmpname.Form(
"%s_", origname.Data());
1182 TH1D* spectrum = (TH1D*)ihst->Clone();
1183 spectrum->SetNameTitle(tmpname.Data(),ihst->GetName());
1184 spectrum->SetDirectory(0);
1189 spectrum->SetName(origname.Data());
1191 bool force_binwidth =
false;
1192 #if ROOT_VERSION_CODE <= ROOT_VERSION(9,99,99)
1197 TAxis* xaxis = spectrum->GetXaxis();
1198 if (xaxis->IsVariableBinSize()) force_binwidth =
true;
1200 if ( extra ==
"WIDTH" ) force_binwidth =
true;
1201 if ( extra ==
"NOWIDTH" ) force_binwidth =
false;
1202 if ( force_binwidth ) {
1204 <<
"multiplying by bin width for histogram " << histo
1205 <<
" as " << spectrum->GetName() <<
" for nutype " << nutype
1207 for(
int ibin = 1; ibin <= spectrum->GetNbinsX(); ++ibin) {
1208 double data = spectrum->GetBinContent(ibin);
1209 double width = spectrum->GetBinWidth(ibin);
1210 spectrum->SetBinContent(ibin,data*width);
1215 int pdg = atoi(nutype.c_str());
1218 <<
"Unknown neutrino type: " << nutype;
1224 <<
"Adding energy spectrum for flux neutrino: pdg = " << pdg;
1225 gOptFluxHst.insert(map<int, TH1D*>::value_type(pdg, spectrum));
1229 <<
"You have not specified any flux histogram!";
1237 LOG(
"gevgen_t2k",
pFATAL) <<
"No flux info was specified - Exiting";
1250 if( parser.OptionExists(
'P') ){
1265 <<
"No flux interaction probabilites were specified - exiting";
1272 if( parser.OptionExists(
'S') ){
1280 <<
"Cannot specify both the -P and -S options at the same time!";
1287 <<
"Using pre-calculated flux interaction probabilities only makes "
1288 <<
"sense when using JNUBEAM flux option!";
1294 if( parser.OptionExists(
'p') ) {
1295 LOG(
"gevgen_t2k",
pDEBUG) <<
"Reading flux file normalization";
1299 <<
"Setting standard normalization for JNUBEAM flux ntuples";
1304 if( parser.OptionExists(
'c') ) {
1305 LOG(
"gevgen_t2k",
pDEBUG) <<
"Reading number of flux ntuple cycles";
1309 <<
"Setting standard number of cycles for JNUBEAM flux ntuples";
1314 if( parser.OptionExists(
'n') ) {
1316 <<
"Reading limit on number of events to generate";
1317 gOptNev = parser.ArgAsInt(
'n');
1320 <<
"Will keep on generating events till the flux driver stops";
1325 bool uppc_e = parser.OptionExists(
'E');
1326 char pot_args =
'e';
1327 bool pot_exit =
true;
1333 if( parser.OptionExists(pot_args) ) {
1334 LOG(
"gevgen_t2k",
pDEBUG) <<
"Reading requested exposure in POT";
1335 gOptPOT = parser.ArgAsDouble(pot_args);
1337 LOG(
"gevgen_t2k",
pDEBUG) <<
"No POT exposure was requested";
1342 if( parser.OptionExists(
'o') ) {
1343 LOG(
"gevgen_t2k",
pDEBUG) <<
"Reading the event filename prefix";
1347 <<
"Will set the default event filename prefix";
1353 if( parser.OptionExists(
"seed") ) {
1354 LOG(
"gevgen_t2k",
pINFO) <<
"Reading random number seed";
1357 LOG(
"gevgen_t2k",
pINFO) <<
"Unspecified random number seed - Using default";
1362 if( parser.OptionExists(
"cross-sections") ) {
1363 LOG(
"gevgen_t2k",
pINFO) <<
"Reading cross-section file";
1366 LOG(
"gevgen_t2k",
pINFO) <<
"Unspecified cross-section file";
1387 <<
"** To use a JNUBEAM flux ntuple you need to specify an exposure, "
1388 <<
"either via the -c, -e or -n options";
1390 <<
"** gevgen_t2k automatically sets the exposure via '-c 1'";
1395 <<
"You can not specify more than one of the -c, -e or -n options";
1405 <<
"If you're using flux from histograms you need to specify the -n option";
1416 <<
"You may not use the -e, -E options "
1417 <<
"without a detailed detector geometry description input";
1427 ostringstream gminfo;
1429 gminfo <<
"Using ROOT geometry - file: " <<
gOptRootGeom
1432 <<
", max{PL} file: "
1434 <<
", length units: " << lunits
1435 <<
", density units: " << dunits;
1437 gminfo <<
"Using target mix - ";
1438 map<int,double>::const_iterator iter;
1440 int pdg_code = iter->first;
1441 double wgt = iter->second;
1442 TParticlePDG * p = pdglib->
Find(pdg_code);
1444 string name = p->GetName();
1445 gminfo <<
"(" << name <<
") -> " << 100*wgt <<
"% / ";
1450 ostringstream fluxinfo;
1452 fluxinfo <<
"Using flux histograms - ";
1453 map<int,TH1D*>::const_iterator iter;
1455 int pdg_code = iter->first;
1456 TH1D * spectrum = iter->second;
1457 TParticlePDG * p = pdglib->
Find(pdg_code);
1459 string name = p->GetName();
1460 fluxinfo <<
"(" << name <<
") -> " << spectrum->GetName() <<
" / ";
1464 fluxinfo <<
"Using JNUBEAM flux ntuple - "
1465 <<
"file: " << gOptFluxFile
1470 fluxinfo <<
", ** this job is considering only: ";
1473 if(inu < gOptFluxNtpNuList.size()-1) fluxinfo <<
",";
1479 ostringstream exposure;
1481 exposure <<
"Number of POTs = " <<
gOptPOT;
1485 exposure <<
"Number of events = " <<
gOptNev;
1495 <<
"\n - Flux @ " << fluxinfo.str()
1496 <<
"\n - Geometry @ " << gminfo.str()
1497 <<
"\n - Exposure @ " << exposure.str();
1506 <<
"\n gevgen_t2k [-h] "
1510 <<
"\n [-p pot_normalization_of_flux_file]"
1511 <<
"\n [-t top_volume_name_at_geom]"
1512 <<
"\n [-P pre_gen_prob_file]"
1513 <<
"\n [-S] [output_name]"
1514 <<
"\n [-m max_path_lengths_xml_file]"
1515 <<
"\n [-L length_units_at_geom]"
1516 <<
"\n [-D density_units_at_geom]"
1517 <<
"\n [-n n_of_events]"
1518 <<
"\n [-c flux_cycles]"
1519 <<
"\n [-e, -E exposure_in_POTs]"
1520 <<
"\n [-o output_event_file_prefix]"
1522 <<
"\n [--seed random_number_seed]"
1523 <<
"\n --cross-sections xml_file"
1524 <<
"\n [--event-generator-list list_name]"
1525 <<
"\n [--message-thresholds xml_file]"
1526 <<
"\n [--unphysical-event-mask mask]"
1527 <<
"\n [--event-record-print-level level]"
1528 <<
"\n [--mc-job-status-refresh-rate rate]"
1529 <<
"\n [--cache-file root_file]"
1531 <<
" Please also read the detailed documentation at http://www.genie-mc.org"
1532 <<
" or look at the source code: $GENIE/src/Apps/gT2KEvGen.cxx"
void RandGen(long int seed)
static void SetPrintLevel(int print_level)
double POT_curravg(void)
current average POT
void XSecTable(string inpfile, bool require_table)
bool PreCalcFluxProbabilities(void)
map< int, double > SumFluxIntProbs(void) const
bool IsNeutrino(int pdgc)
bool LoadBeamSimData(string filename, string det_loc)
load a jnubeam root flux ntuple
bool End(void)
true if no more flux nu's can be thrown (eg reaching end of beam sim ntuples)
void SetUpstreamZ(double z0)
set flux neutrino initial z position (upstream of the detector)
void SetEventGeneratorList(string listname)
double POT_1cycle(void)
flux POT per cycle
void ReadFromCommandLine(int argc, char **argv)
string gOptDetectorLocation
void Update(int iev, const EventRecord *event)
map< int, double > gOptTgtMix
void SetFluxParticles(const PDGCodeList &particles)
specify list of flux neutrino species
string gOptFluxProbFileName
int main(int argc, char **argv)
A GENIE flux driver encapsulating the JPARC neutrino flux. It reads-in the official JPARC neutrino fl...
void SetRefreshRate(int rate)
string kDefOptEvFilePrefix
void UseFluxDriver(GFluxI *flux)
bool gOptRandomFluxOffset
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
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
string gOptRootGeomTopVol
void ForceSingleProbScale(void)
void SetFilePOT(double pot)
flux file norm is in /N POT/det [ND] or /N POT/cm^2 [FD]. Specify N (typically 1E+21) ...
virtual double LengthUnits(void) const
A generic GENIE flux driver. Generates a 'cylindrical' neutrino beam along the input direction...
bool IsAntiNeutrino(int pdgc)
bool UseMaxPathLengths(string xml_filename)
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 SetTransverseRadius(double Rt)
void DisableOffset(void)
switch off random offset, must be called before LoadBeamSimData to have any effect ...
void SetNuDirection(const TVector3 &direction)
void BuildTune()
build tune and inform XSecSplineList
PDGCodeList gOptFluxNtpNuList(false)
string gOptSaveFluxProbsFileName
EventRecord * GenerateEvent(void)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
void CustomizeFilenamePrefix(string prefix)
bool gOptSaveFluxProbsFile
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.
bool LoadFluxProbabilities(string filename)
void SetNumOfCycles(int n)
set how many times to cycle through the ntuple (default: 1 / n=0 means 'infinite') ...
NtpMCFormat_t kDefOptNtpFormat
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
A vector of EventGeneratorI objects.
void SetBeamSpot(const TVector3 &spot)
void MesgThresholds(string inpfile)
void AddEnergySpectrum(int nu_pdgc, TH1D *spectrum)
TParticlePDG * Find(int pdgc, bool must_exist=true)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
bool gOptExitAtEndOfFullFluxCycles
void GetCommandLineArgs(int argc, char **argv)
Defines the GENIE Geometry Analyzer Interface.
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 CacheFile(string inpfile)
void SaveFluxProbabilities(string outfilename)
void EnableBareXSecPreCalc(bool flag)
const GJPARCNuFluxPassThroughInfo & PassThroughInfo(void)
GJPARCNuFluxPassThroughInfo.
void push_back(int pdg_code)
map< int, TH1D * > gOptFluxHst
virtual TGeoManager * GetGeometry(void) const
GENIE Interface for user-defined flux classes.