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)