15#include <TStopwatch.h>
18#include "Framework/Conventions/GBuild.h"
53 map<int,TH1D*>::iterator pmax_iter =
fPmax.begin();
54 for( ; pmax_iter !=
fPmax.end(); ++pmax_iter) {
55 TH1D * pmax = pmax_iter->second;
57 delete pmax; pmax = 0;
69 <<
"Setting event generator list: " << listname;
114 <<
"UseMaxPathLengths could not find file: \"" << xml_filename <<
"\"";
123 <<
"Keep on throwing flux neutrinos till one interacts? : "
133 <<
"Number of bins in energy used for the xsec splines: "
142 <<
"Pmax will be store in histogram with logarithmic energy bins";
150 <<
"Number of bins in energy used for maximum int. probability: "
169 <<
"GMCJDriver will generate weighted events forcing the interaction. ";
180 <<
"GMCJDriver will generate un-weighted events. "
181 <<
"Note: That does not force unweighted event kinematics!";
211 "Skipping pre-generation of flux interaction probabilities - "<<
212 "using pre-generated file";
221 LOG(
"GMCJDriver",
pFATAL) <<
"Cannot overwrite an existing file. Exiting!";
228 "Tree storing pre-calculated flux interaction probs");
242 TStopwatch stopwatch;
244 long int first_index = -1;
245 bool first_loop =
true;
252 LOG(
"GMCJDriver",
pWARN) <<
"*** Couldn't generate next flux ray! ";
258 bool already_been_here = first_loop ? false : first_index ==
fFluxDriver->Index();
259 if(already_been_here)
break;
282 <<
"Finished pre-calculating flux interaction probabilities. "
283 <<
"Total CPU time to process "<<
fFluxIntTree->GetEntries()
284 <<
" entries: "<< stopwatch.CpuTime();
295 double safety_factor = 1.01;
310 "Updated global probability scale to fGlobPmax = "<<
fGlobPmax;
314 "Saving pre-generated interaction probabilities to file: "<<
323 "Cannot build index using branch \"FluxIndex\" for flux prob tree!";
331 LOG(
"GMCJDriver",
pNOTICE) <<
"Successfully generated/loaded pre-calculate flux interaction probabilities";
353 <<
"Can't load flux interaction prob file as one is already loaded";
372 <<
"Successfully loaded pre-generated flux interaction probabilities";
378 "Cannot find expected branches in input flux probability tree!";
386 <<
"Unable to load flux interaction probabilities file";
445 LOG(
"GMCJDriver",
pNOTICE) <<
"Finished configuring GMCJDriver\n\n";
523 <<
"Asking the flux driver for its list of neutrinos";
530 <<
"Asking the geometry driver for its list of targets";
540 <<
"Loading external max path-length list for input geometry from "
546 <<
"Querying the geometry driver to compute the max path-length list";
557 <<
"Querying the flux driver for the maximum energy of flux neutrinos";
561 <<
"Maximum flux neutrino energy = " <<
fEmax <<
" GeV";
567 <<
"Creating GEVGPool & adding a GEVGDriver object per init-state";
572 PDGCodeList::const_iterator nuiter;
573 PDGCodeList::const_iterator tgtiter;
575 for(nuiter =
fNuList.begin(); nuiter !=
fNuList.end(); ++nuiter) {
578 int target_pdgc = *tgtiter;
579 int neutrino_pdgc = *nuiter;
584 <<
"\n\n ---- Creating a GEVGDriver object configured for init-state: "
585 << init_state.
AsString() <<
" ----\n\n";
592 LOG(
"GMCJDriver",
pDEBUG) <<
"Adding new GEVGDriver object to GEVGPool";
593 fGPool->insert( GEVGPool::value_type(init_state.
AsString(), evgdriver) );
598 <<
"All necessary GEVGDriver object were pushed into GEVGPool\n";
609 <<
"Asking event generation drivers to compute all needed xsec splines";
611 PDGCodeList::const_iterator nuiter;
612 PDGCodeList::const_iterator tgtiter;
615 int target_pdgc = *tgtiter;
616 int neutrino_pdgc = *nuiter;
619 <<
"Computing all splines needed for init-state: "
625 LOG(
"GMCJDriver",
pINFO) <<
"Finished creating cross section splines\n";
634 <<
"Summing-up splines to get total cross section for each init state";
636 GEVGPool::iterator diter;
637 for(diter =
fGPool->begin(); diter !=
fGPool->end(); ++diter) {
638 string init_state = diter->first;
642 <<
"**** Summing xsec splines for init-state = " << init_state;
647 <<
" rE (validEnergyRange) [" << rE.
min <<
"," << rE.
max <<
"] "
648 <<
" fEmax " <<
fEmax;
656 double max = TMath::Min(rE.
max,
fEmax);
667 <<
"Finished summing all interaction xsec splines per initial state";
684 <<
"Computing the max. interaction probability (probability scale)";
690 map<int,TH1D*>::iterator pmax_iter =
fPmax.begin();
691 for( ; pmax_iter !=
fPmax.end(); ++pmax_iter) {
692 TH1D * pmax = pmax_iter->second;
694 delete pmax; pmax = 0;
705 for(
int i=0; i<=
fPmaxNbins; i++) ebins[i] = TMath::Power(10., TMath::Log10(emin) + i * de);
712 double emax =
fEmax + de;
718 PDGCodeList::const_iterator nuiter;
719 PDGCodeList::const_iterator tgtiter;
722 for(nuiter =
fNuList.begin(); nuiter !=
fNuList.end(); ++nuiter) {
723 int neutrino_pdgc = *nuiter;
724 TH1D * pmax_hst =
new TH1D(
"pmax_hst",
725 "max interaction probability vs E | geom",
fPmaxNbins,ebins);
726 pmax_hst->SetDirectory(0);
729 for(
int ie = 1; ie <= pmax_hst->GetNbinsX(); ie++) {
730 double EvLow = pmax_hst->GetBinCenter(ie) - 0.5*pmax_hst->GetBinWidth(ie);
731 double EvHigh = pmax_hst->GetBinCenter(ie) + 0.5*pmax_hst->GetBinWidth(ie);
738 int target_pdgc = *tgtiter;
743 <<
"Computing Pmax for init-state: " << init_state.
AsString() <<
" E from " << EvLow <<
"-" << EvHigh;
760 double pmax = pmaxHigh;
761 if ( pmaxLow > pmaxHigh){
764 <<
"Lower energy neutrinos have a higher probability of interacting than those at higher energy."
765 <<
" pmaxLow(E=" << EvLow <<
")=" << pmaxLow <<
" and " <<
" pmaxHigh(E=" << EvHigh <<
")=" << pmaxHigh;
768 pmax_hst->SetBinContent(ie, pmax_hst->GetBinContent(ie) + pmax);
771 <<
"Pmax[" << init_state.
AsString() <<
", Ev from " << EvLow <<
"-" << EvHigh <<
"] = " << pmax;
777 <<
"Pmax[nu=" << neutrino_pdgc <<
", Ev from " << EvLow <<
"-" << EvHigh <<
"] = "
778 << pmax_hst->GetBinContent(ie);
781 fPmax.insert(map<int,TH1D*>::value_type(neutrino_pdgc,pmax_hst));
791 for(nuiter =
fNuList.begin(); nuiter !=
fNuList.end(); ++nuiter) {
792 int neutrino_pdgc = *nuiter;
793 map<int,TH1D*>::const_iterator pmax_iter =
fPmax.find(neutrino_pdgc);
794 assert(pmax_iter !=
fPmax.end());
795 TH1D * pmax_hst = pmax_iter->second;
798 double pmax = pmax_hst->GetMaximum();
817 LOG(
"GMCJDriver",
pNOTICE) <<
"Generating next event...";
825 <<
"No more neutrinos can be thrown by the flux driver";
830 if(event)
return event;
834 <<
"Flux neutrino didn't interact - Trying the next one...";
840 LOG(
"GMCJDriver",
pINFO) <<
"Returning NULL event!";
850 double Pno=0, Psum=0;
851 double R = rnd->
RndEvg().Rndm();
852 LOG(
"GMCJDriver",
pDEBUG) <<
"Rndm [0,1] = " << R;
858 <<
"** Rejecting current flux neutrino (flux driver err)";
865 LOG(
"GMCJDriver",
pFATAL) <<
"** Cannot calculate path lenths!";
870 <<
"** Rejecting current flux neutrino (misses generation volume)";
875 <<
"The interaction probability is: " << Psum;
887 <<
"Computing interaction probabilities for max. path lengths";
892 <<
"The no-interaction probability (max. path lengths) is: "
896 <<
"Negative no-interaction probability! (P = " << 100*Pno <<
" %)"
897 <<
" Particle E=" <<
fFluxDriver->Momentum().E() <<
" type=" <<
fFluxDriver->PdgCode() <<
"Psum=" << Psum;
903 <<
"** Rejecting current flux neutrino";
922 <<
"** Rejecting current flux neutrino (err computing path-lengths)";
927 <<
"** Rejecting current flux neutrino (misses generation volume)";
936 <<
"** Rejecting current flux neutrino (has null interaction probability)";
943 <<
"The actual 'no interaction' probability is: " << 100*Pno <<
" %";
946 <<
"Negative no interactin probability! (P = " << 100*Pno <<
" %)";
950 const TLorentzVector & nup4 =
fFluxDriver -> Momentum ();
951 const TLorentzVector & nux4 =
fFluxDriver -> Position ();
954 <<
"\n [-] Problematic neutrino: "
955 <<
"\n |----o PDG-code : " << nupdg
958 <<
"\n Emax : " <<
fEmax;
970 <<
"** Rejecting current flux neutrino";
983 LOG(
"GMCJDriver",
pFATAL) <<
"** Cannot calculate path lenths!";
990 "** Mismatch between pre-calculated and current interaction "<<
1001 <<
"** Rejecting current flux neutrino (failed to select tgt!)";
1010 <<
"** Couldn't generate kinematics for selected interaction";
1026 double weight = 1. - TMath::Exp(-Psum);
1027 fCurEvt->SetProbability(Psum);
1042 LOG(
"GMCJDriver",
pNOTICE) <<
"Generating a flux neutrino";
1047 <<
"*** The flux driver couldn't generate a flux neutrino!!";
1053 const TLorentzVector & nup4 =
fFluxDriver -> Momentum ();
1054 const TLorentzVector & nux4 =
fFluxDriver -> Position ();
1057 <<
"\n [-] Generated flux neutrino: "
1058 <<
"\n |----o PDG-code : " << nupdg
1062 if(nup4.Energy() >
fEmax) {
1064 <<
"\n *** Flux driver error ***"
1065 <<
"\n Generated flux v with E = " << nup4.Energy() <<
" GeV"
1066 <<
"\n Max v energy (declared by flux driver) = " <<
fEmax <<
" GeV"
1067 <<
"\n My interaction probability scaling is invalidated!!";
1070 if(!
fNuList.ExistsInPDGCodeList(nupdg)) {
1072 <<
"\n *** Flux driver error ***"
1073 <<
"\n Generated flux v with pdg = " << nupdg
1074 <<
"\n It does not belong to the declared list of flux neutrinos"
1075 <<
"\n I was not configured to handle this!!";
1089 const TLorentzVector & nup4 =
fFluxDriver -> Momentum ();
1090 const TLorentzVector & nux4 =
fFluxDriver -> Position ();
1098 <<
"\n *** Geometry driver error ***"
1099 <<
"\n Got an empty PathLengthList - No material found in geometry?";
1105 <<
"current flux v doesn't cross any geometry material...";
1113 <<
"Computing relative interaction probabilities for each material";
1117 const TLorentzVector & nup4 =
fFluxDriver->Momentum();
1125 PathLengthList::const_iterator pliter;
1127 for(pliter = path_length_list.begin();
1128 pliter != path_length_list.end(); ++pliter) {
1129 int mpdg = pliter->first;
1130 double pl = pliter->second;
1141 <<
"\n * The MC Job driver isn't properly configured!"
1142 <<
"\n * No event generation driver could be found for init state: "
1151 <<
"\n * The MC Job driver isn't properly configured!"
1152 <<
"\n * Couldn't retrieve total cross section spline for init state: "
1156 xsec = totxsecspl->
Evaluate( nup4.Energy() );
1160 <<
" (xsec, pl, A)=(" << xsec <<
"," << pl <<
"," << A <<
")";
1169 map<int,TH1D*>::const_iterator pmax_iter =
fPmax.find(nupdg);
1170 assert(pmax_iter !=
fPmax.end());
1171 TH1D * pmax_hst = pmax_iter->second;
1173 int ie = pmax_hst->FindBin(nup4.Energy());
1174 pmax = pmax_hst->GetBinContent(ie);
1181#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
1183 <<
"tgt: " << mpdg <<
" -> TotXSec = "
1184 << xsec/
units::cm2 <<
" cm^2, Norm.Prob = " << 100*probn <<
"%";
1198 LOG(
"GMCJDriver",
pNOTICE) <<
"Selecting target material";
1202 double prob = probiter->second;
1204 tgtpdg = probiter->first;
1206 <<
"Selected target material = " << tgtpdg;
1211 <<
"Could not select target material for an interacting neutrino";
1218 const TLorentzVector & nup4 =
fFluxDriver->Momentum();
1226 <<
"No GEVGDriver object for init state: " << init_state.
AsString();
1236 <<
"Asking the selected GEVGDriver object to generate an event";
1245 <<
"Asking the geometry analyzer to generate a vertex";
1247 const TLorentzVector & p4 =
fFluxDriver->Momentum ();
1248 const TLorentzVector & x4 =
fFluxDriver->Position ();
1252 TVector3 origin(x4.X(), x4.Y(), x4.Z());
1255 double dL = origin.Mag();
1260 <<
"|vtx - origin|: dL = " << dL <<
" m, dt = " << dt <<
" sec";
1262 fCurVtx.SetXYZT(vtx.x(), vtx.y(), vtx.z(), x4.T() + dt);
1272 double xsec =
fCurEvt->XSec();
1276 double path_length = pliter->second;
1289 int nu_pdg = nu->
Pdg();
1290 double Ev = nu->
P4()->Energy();
1292 double weight = 1.0;
1294 map<int,TH1D*>::const_iterator pmax_iter =
fPmax.find(nu_pdg);
1295 assert(pmax_iter !=
fPmax.end());
1296 TH1D * pmax_hst = pmax_iter->second;
1298 double pmax = pmax_hst->GetBinContent(pmax_hst->FindBin(Ev));
1318 return kNA*(xsec*pL)/A;
1329 "Cannot get pre-computed flux interaction probability as no tree!";
1338 bool enu_match =
false;
1343 if(enu_match ==
false){
1345 "Mismatch between: Enu_curr = "<<
fFluxDriver->Momentum().E() <<
1350 LOG(
"GMCJDriver",
pERROR) <<
"Cannot find flux entry in interaction prob tree!";
1354 bool success = found_entry && enu_match;
1357 "Cannot find pre-generated interaction probability! Check you "<<
1358 "are using the correct pre-generated interaction prob file " <<
1359 "generated using current flux input file with same input " <<
1360 "config (same geom TopVol, neutrino species list)";
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
static AlgConfigPool * Instance()
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void SetUnphysEventMask(const TBits &mask)
void Configure(int nu_pdgc, int Z, int A)
void CreateSplines(int nknots=-1, double emax=-1, bool inLogE=true)
const Spline * XSecSumSpline(void) const
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
void CreateXSecSumSpline(int nk, double Emin, double Emax, bool inlogE=true)
void SetEventGeneratorList(string listname)
Range1D_t ValidEnergyRange(void) const
A pool of GEVGDriver objects with an initial state key.
GENIE Interface for user-defined flux classes.
static unsigned int NFlags(void)
STDHEP-like event record entry that can fit a particle or a nucleus.
const TLorentzVector * P4(void) const
bool fUseLogE
[config] build splines = f(logE) (rather than f(E)) ?
bool fPmaxLogBinning
[config] maximum interaction probability is computed in logarithmic energy bins
PathLengthList fMaxPathLengths
[declared by the geom driver] maximum path length list
bool fPreSelect
[config] set whether to pre-select events using max interaction paths
bool LoadFluxProbabilities(string filename)
bool fForceInteraction
[config] force intearction?
double fPmaxSafetyFactor
[config] safety factor to compute the maximum interaction probability
double fEmax
[declared by the flux driver] maximum neutrino energy
void SetXSecSplineNbins(int nbins)
bool fUseSplines
[config] compute all needed & not-loaded splines at init
string fMaxPlXmlFilename
[config] input file with max density-weighted path lengths for all materials
bool PreCalcFluxProbabilities(void)
void BootstrapXSecSplines(void)
void GenerateVertexPosition(void)
void InitEventGeneration(void)
void GenerateEventKinematics(void)
void ForceSingleProbScale(void)
int fBrFluxIndex
corresponding entry in flux input tree (set to address of branch:"FluxEntry")
void UseFluxDriver(GFluxI *flux)
double fNFluxNeutrinos
[current] number of flux nuetrinos fired by the flux driver so far
string fFluxIntFileName
whether to save pre-generated flux tree for use in later jobs
void UseGeomAnalyzer(GeomAnalyzerI *geom)
string fEventGenList
[config] list of event generators loaded by this driver (what used to be the $GEVGL setting)
EventRecord * GenerateEvent1Try(void)
map< int, double > fCurCumulProbMap
[current] cummulative interaction probabilities
bool GenerateFluxNeutrino(void)
double fGlobPmax
[computed at init] global interaction probability scale for given flux & geometry
TBits * fUnphysEventMask
[config] controls whether unphysical events are returned (what used to be the $GUNPHYSMASK setting)
double ComputeInteractionProbabilities(bool use_max_path_length)
int fSelTgtPdg
[current] selected target material PDG code
TTree * fFluxIntTree
[computed-or-loaded] pre-computed flux interaction probabilities (expected tree name is "gFlxIntProbs...
void SetPmaxSafetyFactor(double sf)
void Configure(bool calc_prob_scales=true)
bool ComputePathLengths(void)
void GetMaxFluxEnergy(void)
GFluxI * fFluxDriver
[input] neutrino flux driver
map< int, double > fSumFluxIntProbs
map where the key is flux pdg code and the value is sum of fBrFluxWeight * fBrFluxIntProb for all the...
void GetParticleLists(void)
void ForceInteraction(void)
double fBrFluxIntProb
flux interaction probability (set to branch:"FluxIntProb")
void SaveFluxProbabilities(string outfilename)
bool UseMaxPathLengths(string xml_filename)
void PopulateEventGenDriverPool(void)
void UseSplines(bool useLogE=true)
GeomAnalyzerI * fGeomAnalyzer
[input] detector geometry analyzer
bool fGenerateUnweighted
[config] force single probability scale?
int fBrFluxPDG
corresponding flux pdg code (set to address of branch: "FluxPDG")
string fFluxIntTreeName
name for tree holding flux probabilities
int SelectTargetMaterial(double R)
TLorentzVector fCurVtx
[current] interaction vertex
PathLengthList fCurPathLengths
[current] path length list for current flux neutrino
map< int, TH1D * > fPmax
[computed at init] interaction probability scale /neutrino /energy for given geometry
double fBrFluxWeight
corresponding flux weight (set to address of branch: "FluxWeight")
void ComputeEventProbability(void)
bool fUseExtMaxPl
[config] using external max path length estimate?
void PreSelectEvents(bool preselect=true)
void BootstrapXSecSplineSummation(void)
EventRecord * fCurEvt
[current] generated event
GEVGPool * fGPool
A pool of GEVGDrivers properly configured event generation drivers / one per init state.
void SetUnphysEventMask(const TBits &mask)
void SetEventGeneratorList(string listname)
bool fKeepThrowingFluxNu
[config] keep firing flux neutrinos till one of them interacts
PDGCodeList fNuList
[declared by the flux driver] list of neutrino codes
void SetPmaxNbins(int nbins)
PDGCodeList fTgtList
[declared by the geom driver] list of target codes
int fPmaxNbins
[config] number of bins in energy used in the maximum interaction probability
void ComputeProbScales(void)
int fXSecSplineNbins
[config] number of bins in energy used in the xsec splines
EventRecord * GenerateEvent(void)
double PreGenFluxInteractionProbability(void)
void GetMaxPathLengthList(void)
double fBrFluxEnu
corresponding flux P4 (set to address of branch:"FluxP4")
void SetPmaxLogBinning(void)
TFile * fFluxIntProbFile
[input] pre-generated flux interaction probability file
void KeepOnThrowingFluxNeutrinos(bool keep_on)
double InteractionProbability(double xsec, double pl, int A)
Defines the GENIE Geometry Analyzer Interface.
Initial State information.
string AsString(void) const
static Messenger * Instance(void)
Object to be filled with the neutrino path-length, for all detector geometry materials,...
A singleton holding random number generator classes. All random number generation in GENIE should tak...
TRandom3 & RndEvg(void) const
rnd number generator used by the event generation drivers
static RandomGen * Instance()
Access instance.
A simple [min,max] interval for doubles.
A numeric analysis tool class for interpolating 1-D functions.
double Evaluate(double x) const
static const double kLightSpeed
static const double kASmallNum
int IonPdgCodeToA(int pdgc)
static constexpr double gram
static constexpr double cm2
static constexpr double kilogram
static constexpr double meter
static constexpr double second
static constexpr double m2
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
string X4AsString(const TLorentzVector *x)
string BoolAsYNString(bool b)
string P4AsString(const TLorentzVector *p)
THE MAIN GENIE PROJECT NAMESPACE