20 #include <TChainElement.h> 
   22 #include <TStopwatch.h> 
   26 #include "Framework/Conventions/GBuild.h" 
   54 using namespace genie;
 
   55 using namespace genie::flux;
 
   73 GSimpleNtpFlux::~GSimpleNtpFlux()
 
   97      bool end = this->
End();
 
   99        LOG(
"Flux", 
pNOTICE) << 
"GenerateNext signaled End() ";
 
  106      if ( ! nextok ) 
continue;
 
  128          << 
"** Fractional weight = " << f
 
  129          << 
" > 1 !! Bump fMaxWeight estimate to " << 
fMaxWeight 
  131        std::cout << std::flush;
 
  133      double r = (f < 1.) ? rnd->
RndFlux().Rndm() : 0;
 
  134      bool accept = ( r < f );
 
  137 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  139          << 
"Generated beam neutrino: " 
  163           << 
"The flux driver has not been properly configured";
 
  172   if ( fIUse < fNUse && fIEntry >= 0 ) {
 
  189           << 
"No more entries in input flux neutrino ntuple, cycle " 
  201 #ifdef USE_INDEX_FOR_META 
  202       int nbmeta = 
fNuMetaTree->GetEntryWithIndex(metakey);
 
  211       for (
int imeta = 0; imeta < nmeta; ++imeta ) {
 
  218         LOG(
"Flux",
pERROR) << 
"Failed to find right metakey=" << metakey
 
  219                            << 
" (was " << oldkey << 
") out of " << nmeta
 
  223       LOG(
"Flux",
pDEBUG) << 
"Get meta " << metakey
 
  224                          << 
" (was " << oldkey << 
") " 
  226                          << 
" nb " << nbytes << 
" " << nbmeta;
 
  227 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  231 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  235       << 
" ifile " << ifile << 
" nbytes " << nbytes
 
  268           << 
"Encountered neutrino specie (" << badpdg
 
  269           << 
") that wasn't in SetFluxParticles() list, " 
  270           << 
"\nDeclared list of neutrino species: " << *
fPdgCList;
 
  287           << 
"Flux neutrino energy exceeds declared maximum neutrino energy" 
  288           << 
"\nEv = " << Ev << 
"(> Ev{max} = " << 
fMaxEv << 
")";
 
  294 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  296     << 
"Generated neutrino: " << 
fIEntry 
  308       << 
"Generated neutrino had E_nu = " << Ev << 
" > " << 
fMaxEv 
  328   double pzusr    = 
fP4.Pz();
 
  329   if ( TMath::Abs(pzusr) < 1.0
e-30 ) {
 
  332       << 
"MoveToZ0(" << z0usr << 
") not possible due to pz_usr (" << pzusr << 
")";
 
  337   double dz = z0usr - 
fX4.Z();
 
  338   double scale = dz / pzusr;
 
  345   TVector3 dx3( scale*
fP4.Vect() );
 
  350   double dt = 
fP4.P() * dz / ( pzusr * v );
 
  353   TLorentzVector dx4( dx3, dt );
 
  378           << 
"The flux driver has not been properly configured";
 
  386                                      const std::string&         config )
 
  391   std::vector<int> nfiles_from_pattern;
 
  395   std::set<std::string> fnames;
 
  397   LOG(
"Flux", 
pINFO) << 
"LoadBeamSimData was passed " << patterns.size()
 
  400   for (
size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
 
  401     string pattern = patterns[ipatt];
 
  402     nfiles_from_pattern.push_back(0);
 
  404         << 
"Loading flux tree from ROOT file pattern [" 
  405         << std::setw(3) << ipatt << 
"] \"" << pattern << 
"\"";
 
  408     string dirname = gSystem->UnixPathName(gSystem->WorkingDirectory());
 
  409     size_t slashpos = pattern.find_last_of(
"/");
 
  411     if ( slashpos != std::string::npos ) {
 
  412       dirname = pattern.substr(0,slashpos);
 
  413       LOG(
"Flux", 
pDEBUG) << 
"Look for flux using directory " << dirname;
 
  414       fbegin = slashpos + 1;
 
  415     } 
else { fbegin = 0; }
 
  417     void* dirp = gSystem->OpenDirectory(gSystem->ExpandPathName(dirname.c_str()));
 
  419       std::string basename =
 
  420         pattern.substr(fbegin,pattern.size()-fbegin);
 
  421       TRegexp re(basename.c_str(),kTRUE);
 
  423       while ( ( onefile = gSystem->GetDirEntry(dirp) ) ) {
 
  424         TString afile = onefile;
 
  425         if ( afile==
"." || afile==
".." ) 
continue;
 
  426         if ( basename!=afile && afile.Index(re) == kNPOS ) 
continue;
 
  427         std::string fullname = dirname + 
"/" + afile.Data();
 
  428         fnames.insert(fullname);
 
  429         nfiles_from_pattern[ipatt]++;
 
  431       gSystem->FreeDirectory(dirp);
 
  436   std::set<string>::const_iterator sitr = fnames.begin();
 
  437   for ( ; sitr != fnames.end(); ++sitr, ++indx) {
 
  438     string filename = *sitr;
 
  445     if ( ! isok ) 
continue;
 
  447     LOG(
"Flux", 
pINFO) << 
"Load file " <<  filename;
 
  449     TFile* tf = TFile::Open(filename.c_str(),
"READ");
 
  450     TTree* etree = (TTree*)tf->Get(
"flux");
 
  452       TTree* mtree = (TTree*)tf->Get(
"meta");
 
  454       LOG(
"Flux", 
pDEBUG) << 
"AddFile " << filename
 
  455                           << 
" etree " << etree << 
" meta " << mtree;
 
  456       this->
AddFile(etree,mtree,filename);
 
  468       << 
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
 
  470       << 
"Loaded flux tree contains " <<  
fNEntries << 
" entries";
 
  472       << 
"Was passed the file patterns: ";
 
  473     for (
size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
 
  474       string pattern = patterns[ipatt];
 
  476         << 
"  [" << std::setw(3) << ipatt <<
"] " << pattern;
 
  479       << 
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
 
  482       << 
"Loaded flux tree contains " <<  
fNEntries << 
" entries" 
  483       << 
" from " << fnames.size() << 
" unique files";
 
  484     for (
size_t ipatt = 0; ipatt < patterns.size(); ++ipatt ) {
 
  485       string pattern = patterns[ipatt];
 
  487         << 
" pattern: " << pattern << 
" yielded " 
  488         << nfiles_from_pattern[ipatt] << 
" files";
 
  492   int sba_status[3] = { -999, -999, -999 };
 
  494 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0) 
  498 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0) 
  499   if ( sba_status[0] < 0 ) {
 
  501       << 
"flux chain has no \"entry\" branch " << sba_status[0];
 
  509 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0) 
  518 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0) 
  527     << 
" SetBranchAddress status: " 
  528     << 
" \"entry\"=" << sba_status[0]
 
  529     << 
" \"numi\"=" << sba_status[1]
 
  530     << 
" \"aux\"=" << sba_status[2];
 
  536        << 
"Run ProcessMeta() as part of LoadBeamSimData";
 
  547   if ( config.find(
"no-offset-index") != string::npos ) {
 
  548     LOG(
"Flux",
pINFO) << 
"Config saw \"no-offset-index\"";
 
  559   LOG(
"Flux",
pDEBUG) << 
"about to CalcEffPOTsPerNu";
 
  565                                    std::vector<std::string>& branchClassNames,
 
  566                                    std::vector<void**>&      branchObjPointers)
 
  574     branchNames.push_back(
"simple");
 
  575     branchClassNames.push_back(
"genie::flux::GSimpleNtpEntry");
 
  576     branchObjPointers.push_back((
void**)&
fCurEntry);
 
  580     branchNames.push_back(
"numi");
 
  581     branchClassNames.push_back(
"genie::flux::GSimpleNtpNuMI");
 
  582     branchObjPointers.push_back((
void**)&
fCurNuMI);
 
  586     branchNames.push_back(
"aux");
 
  587     branchClassNames.push_back(
"genie::flux::GSimpleNtpAux");
 
  588     branchObjPointers.push_back((
void**)&
fCurAux);
 
  599   double minwgt = +1.0e10;
 
  600   double maxwgt = -1.0e10;
 
  607 #ifdef USE_INDEX_FOR_META 
  609     LOG(
"Flux", 
pDEBUG) << 
"ProcessMeta() BuildIndex nindices " << nindices;
 
  612     for (
int imeta = 0; imeta < nmeta; ++imeta ) {
 
  614 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  615       LOG(
"Flux", 
pNOTICE) << 
"ProcessMeta() ifile " << imeta
 
  619       minwgt = TMath::Min(minwgt,fCurMeta->minWgt);
 
  620       maxwgt = TMath::Max(maxwgt,fCurMeta->maxWgt);
 
  621       maxenu = TMath::Max(maxenu,fCurMeta->maxEnergy);
 
  623       for (
size_t i = 0; i < fCurMeta->pdglist.size(); ++i)
 
  632     LOG(
"Flux", 
pFATAL) << 
"ProcessMeta() not all files have metadata";
 
  636 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ 
  638                        << 
", energy = " << 
fMaxEv 
  649   fMaxEv = TMath::Max(0.,Ev);
 
  652     << 
"Declared maximum flux neutrino energy: " << 
fMaxEv;
 
  660   fNUse    = TMath::Max(1L, nuse);
 
  689   LOG(
"Flux", 
pWARN) << 
"GSimpleNtpFlux::Clear(" << opt << 
") called";
 
  709   LOG(
"Flux", 
pINFO) << 
"Initializing GSimpleNtpFlux driver";
 
  764   LOG(
"Flux", 
pINFO) << 
"Setting default GSimpleNtpFlux driver options";
 
  784   LOG(
"Flux", 
pINFO) << 
"Cleaning up...";
 
  805   if ( ! fluxtree ) 
return;
 
  807   ULong64_t nentries = fluxtree->GetEntries();
 
  810   if ( metatree ) 
fNuMetaTree->AddFile(fname.c_str());
 
  814     << 
"flux->AddFile() of " << nentries
 
  815     << 
" " << ((metatree)?
"[+meta]":
"[no-meta]")
 
  816     << 
" [status=" << stat << 
"]" 
  817     << 
" entries in file: " << fname;
 
  819   if ( stat != 1 ) 
return;
 
  832       << 
"no request for \"" << name <<
"\" branch ";
 
  836   if ( ( 
fNuFluxTree->GetBranch(name.c_str()) ) ) 
return true;
 
  839     << 
"no \"" << name << 
"\" branch in the \"flux\" tree";
 
  865   std::cout << *
this << std::endl;
 
  889   std::cout << *
this << std::endl;
 
  903   std::cout << *
this << std::endl;
 
  949   for (
size_t i=0; i < 
pdglist.size(); ++i)
 
  950     if ( 
pdglist[i] == nupdg) found = 
true;
 
  951   if ( ! found ) 
pdglist.push_back(nupdg);
 
  969   std::cout << *
this << std::endl;
 
  981       stream << 
"\nGSimpleNtpEntry " 
  982              << 
" PDG " << entry.
pdg 
  983              << 
" wgt " << entry.
wgt 
  984              << 
" ( metakey " << entry.
metakey << 
" )" 
  985              << 
"\n   vtx [" << entry.
vtxx << 
"," << entry.
vtxy << 
"," 
  986              << entry.
vtxz << 
", t=" << entry.
vtxt << 
"] dist " << entry.
dist 
  987              << 
"\n   p4  [" << entry.
px << 
"," << entry.
py << 
"," 
  988              << entry.
pz << 
"," << entry.
E << 
"]";
 
  996   stream << 
"\nGSimpleNtpNuMI " 
  997          << 
"run " << numi.
run 
  998          << 
" evtno " << numi.
evtno 
 1000          << 
"\n   ndecay " << numi.
ndecay  << 
" ptype " << numi.
ptype 
 1002          << 
"\n  tp[xyz] [" << numi.
tpx  << 
"," << numi.
tpy  << 
"," << numi.
tpz  << 
"]" 
 1003          << 
"\n   v[xyz] [" << numi.
vx   << 
"," << numi.
vy   << 
"," << numi.
vz   << 
"]" 
 1004          << 
"\n  pd[xyz] [" << numi.
pdpx << 
"," << numi.
pdpy << 
"," << numi.
pdpz << 
"]" 
 1005          << 
"\n  pp[xyz] [" << numi.
pppx << 
"," << numi.
pppy << 
"," << numi.
pppz << 
"]" 
 1013       stream << 
"\nGSimpleNtpAux ";
 
 1014       size_t nInt = aux.
auxint.size();
 
 1015       stream << 
"\n   ints: ";
 
 1016       for (
size_t ijInt=0; ijInt < nInt; ++ijInt)
 
 1017         stream << 
" " << aux.
auxint[ijInt];
 
 1018       size_t nDbl = aux.
auxdbl.size();
 
 1019       stream << 
"\n   doubles: ";
 
 1020       for (
size_t ijDbl=0; ijDbl < nDbl; ++ijDbl)
 
 1021         stream << 
" " << aux.
auxdbl[ijDbl];
 
 1029       size_t nf = meta.
pdglist.size();
 
 1030       stream << 
"\nGSimpleNtpMeta " << nf << 
" flavors: ";
 
 1031       for (
size_t i=0; i<nf; ++i) stream << 
" " << meta.
pdglist[i];
 
 1037       stream << 
"\n maxEnergy " << meta.
maxEnergy 
 1039              << 
" protons " << meta.
protons 
 1040              << 
" metakey " << meta.
metakey 
 1041              << 
"\n windowBase [" << meta.
windowBase[0] << 
"," 
 1043              << 
"\n windowDir1 [" << meta.
windowDir1[0] << 
"," 
 1045              << 
"\n windowDir2 [" << meta.
windowDir2[0] << 
"," 
 1049       if ( nInt > 0 ) stream << 
"\n aux ints:    ";
 
 1050       for (
size_t ijInt=0; ijInt < nInt; ++ijInt)
 
 1054       if ( nDbl > 0 ) stream << 
"\n aux doubles: ";
 
 1055       for (
size_t ijDbl=0; ijDbl < nDbl; ++ijDbl)
 
 1058       size_t nfiles = meta.
infiles.size();
 
 1059       stream << 
"\n " << nfiles << 
" input files: ";
 
 1060       UInt_t nprint = TMath::Min(UInt_t(nfiles),
 
 1062       for (UInt_t ifiles=0; ifiles < nprint; ++ifiles)
 
 1063         stream << 
"\n    " << meta.
infiles[ifiles];
 
 1065       stream << 
"\n input seed: " << meta.
seed;
 
 1079   std::ostringstream 
s;
 
 1080   PDGCodeList::const_iterator itr = 
fPdgCList->begin();
 
 1081   for ( ; itr != 
fPdgCList->end(); ++itr) s << (*itr) << 
" ";
 
 1084   for ( ; itr != 
fPdgCListRej->end(); ++itr) s << (*itr) << 
" ";
 
 1087   std::ostringstream fpattout;
 
 1091   std::ostringstream flistout;
 
 1093   for (
size_t i = 0; i < flist.size(); ++i)
 
 1094     flistout << 
"\n [" << std::setw(3) << i << 
"] " << flist[i];
 
 1097     << 
"GSimpleNtpFlux Config:" 
 1098     << 
"\n Enu_max " << 
fMaxEv 
 1099     << 
"\n pdg-codes: " << s.str() << 
"\n " 
 1100     << 
"\"flux\" " << 
fNEntries << 
" entries, " 
 1101     << 
"\"meta\" " << 
fNFiles << 
" entries" 
 1102     << 
" (FilePOTs " << 
fFilePOTs << 
") in files:" 
 1104     <<  
"\n from file patterns: " 
 1107     << 
"\n Z0 pushback " << 
fZ0 
 1113     << 
"\n GenWeighted \"" << (
fGenWeighted?
"true":
"false") << 
"\"" 
 1114     << 
" AlreadyUnwgt \"" << (
fAlreadyUnwgt?
"true":
"false") << 
"\"" 
 1115     << 
" AllFilesMeta \"" << (
fAllFilesMeta?
"true":
"false") << 
"\"";
 
 1122   std::vector<std::string> flist;
 
 1123   TObjArray *fileElements=
fNuFluxTree->GetListOfFiles();
 
 1124   TIter next(fileElements);
 
 1125   TChainElement *chEl=0;
 
 1126   while (( chEl=(TChainElement*)next() )) {
 
 1127     flist.push_back(chEl->GetTitle());
 
double UsedPOTs(void) const 
of protons-on-target used
void GetFluxWindow(TVector3 &p1, TVector3 &p2, TVector3 &p3) const 
3 points define a plane in beam coordinate 
Double_t E
energy in lab frame 
GSimpleNtpAux * fCurAux
current "aux" branch extra info 
Int_t fIFileNumber
which file for the current entry 
void Clear(Option_t *opt)
reset state variables based on opt 
virtual long int NFluxNeutrinos() const 
of rays generated
std::vector< string > fNuFluxFilePatterns
(potentially wildcarded) path(s) 
string P4AsShortString(const TLorentzVector *p)
long int fNNeutrinos
number of flux neutrinos thrown so far 
void AddFile(TTree *fluxtree, TTree *metatree, string fname)
void PrintCurrent(void)
print current entry from leaves 
GSimpleNtpMeta * fCurMeta
current meta data 
Double_t pdpx
nu parent momentum at time of decay 
void SetEntryReuse(long int nuse=1)
of times to use entry before moving to next
long int fIUse
current # of times an entry has been used 
Double_t px
x momentum in lab frame (GeV) 
static RandomGen * Instance()
Access instance. 
A GENIE flux driver using a simple ntuple format. 
double fSumWeight
sum of weights for nus thrown so far 
Double_t vtxy
y position in lab frame 
Double_t vx
vertex position of hadron/muon decay 
static constexpr double s
void CalcEffPOTsPerNu(void)
bool ExistsInPDGCodeList(int pdg_code) const 
Int_t tptype
parent particle type at target exit 
bool End(void)
true if no more flux nu's can be thrown (eg reaching end of beam sim ntuples) 
std::vector< Double_t > auxdbl
additional doubles associated w/ entry 
virtual void SetNumOfCycles(long int ncycle)
limit cycling through input files 
A singleton holding random number generator classes. All random number generation in GENIE should tak...
std::vector< Int_t > auxint
additional ints associated w/ entry 
virtual TTree * GetMetaDataTree()
void GenerateWeighted(bool gen_weighted)
set whether to generate weighted or unweighted neutrinos 
void MoveToZ0(double z0)
move ray origin to user coord Z0 
virtual void SetUpstreamZ(double z0)
Double_t vtxt
time of ray start (seconds) 
ostream & operator<<(ostream &stream, const genie::flux::GJPARCNuFluxPassThroughInfo &info)
const genie::flux::GSimpleNtpEntry * GetCurrentEntry(void)
GSimpleNtpEntry. 
Double_t pppx
nu parent momentum at production point 
void ProcessMeta(void)
scan for max flux energy, weight 
static constexpr double second
bool OptionalAttachBranch(std::string bname)
PDGCodeList * fPdgCList
list of neutrino pdg-codes to generate 
bool fIncludeVtxt
does fX4 include CurEntry.vtxt or 0 
std::vector< std::string > GetFileList()
list of files currently part of chain 
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
TLorentzVector fX4
reconstituted position vector 
bool fAllFilesMeta
do all files in chain have meta data 
Double_t fFilePOTs
of protons-on-target represented by all files
bool fGenWeighted
does GenerateNext() give weights? 
Double_t vtxz
z position in lab frame 
GENIE interface for uniform flux exposure iterface. 
Int_t ppmedium
tracking medium where parent was produced 
virtual double GetTotalExposure() const 
GFluxExposureI interface. 
GSimpleNtpNuMI * fCurNuMICopy
current "numi" branch extra info 
long int fNEntriesUsed
number of entries read from files 
bool GenerateNext(void)
generate the next flux neutrino (return false in err) 
long int fNCycles
times to cycle through the ntuple(s)
void PrintConfig()
print the current configuration 
Double_t tpx
parent particle px at target exit 
void SetMaxEnergy(double Ev)
specify maximum flx neutrino energy 
GSimpleNtpNuMI * fCurNuMI
current "numi" branch extra info 
int fNFiles
number of files in chain 
virtual void GetBranchInfo(std::vector< std::string > &branchNames, std::vector< std::string > &branchClassNames, std::vector< void ** > &branchObjPointers)
static const double kLightSpeed
double fMaxWeight
max flux neutrino weight in input file 
PDGCodeList * fPdgCListRej
list of nu pdg-codes seen but rejected 
double fWeight
current neutrino weight 
TChain * fNuMetaTree
TTree // REF ONLY. 
GSimpleNtpEntry * fCurEntry
current entry 
TLorentzVector fP4
reconstituted p4 vector 
static constexpr double meter
bool fAlreadyUnwgt
are input files already unweighted 
Long64_t fIEntry
current flux ntuple entry 
Long64_t fNEntries
number of flux ntuple entries 
Double_t vtxx
x position in lab frame (meters) 
Double_t pz
z momentum in lab frame 
GSimpleNtpAux * fCurAuxCopy
current "aux" branch extra info 
long int fNUse
how often to use same entry in a row 
Double_t dist
distance from hadron decay 
GSimpleNtpEntry * fCurEntryCopy
current entry 
double fEffPOTsPerNu
what a entry is worth ... 
double GetDecayDist() const 
dist (user units) from dk to current pos 
string fNuFluxBranchRequest
list of requested branches "entry,numi,au" 
bool fEnd
end condition reached 
TRandom3 & RndFlux(void) const 
rnd number generator used by flux drivers 
string X4AsString(const TLorentzVector *x)
virtual void LoadBeamSimData(const std::vector< string > &filenames, const std::string &det_loc)
double fMaxEv
maximum energy 
UInt_t metakey
key to meta data 
void Print(const Option_t *opt="") const 
Double_t py
y momentum in lab frame 
double Weight(void)
returns the flux neutrino weight (if any) 
double fAccumPOTs
POTs used so far. 
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
#define FLUXDRIVERREG4(_nsa, _nsb, _name, _fqname)
void Print(const Option_t *opt="") const 
void push_back(int pdg_code)
TChain * fNuFluxTree
TTree // REF ONLY. 
bool GenerateNext_weighted(void)
void Print(const Option_t *opt="") const 
Int_t ptype
parent type (PDG)