15 #include <TStopwatch.h>
18 #include "Framework/Conventions/GBuild.h"
39 using namespace genie;
40 using namespace genie::constants;
50 if(fUnphysEventMask)
delete fUnphysEventMask;
51 if (fGPool)
delete fGPool;
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;
62 if(fFluxIntTree)
delete fFluxIntTree;
63 if(fFluxIntProbFile)
delete fFluxIntProbFile;
69 <<
"Setting event generator list: " << listname;
71 fEventGenList = listname;
76 *fUnphysEventMask = mask;
80 <<
" -> 0) : " << *fUnphysEventMask;
85 fFluxDriver = flux_driver;
90 fGeomAnalyzer = geom_analyzer;
106 fMaxPlXmlFilename = xml_filename;
108 bool is_accessible = !(gSystem->AccessPathName(fMaxPlXmlFilename.c_str()));
110 if ( is_accessible ) fUseExtMaxPl =
true;
112 fUseExtMaxPl =
false;
114 <<
"UseMaxPathLengths could not find file: \"" << xml_filename <<
"\"";
123 <<
"Keep on throwing flux neutrinos till one interacts? : "
125 fKeepThrowingFluxNu = keep_on;
130 fXSecSplineNbins = nbins;
133 <<
"Number of bins in energy used for the xsec splines: "
139 fPmaxLogBinning =
true;
142 <<
"Pmax will be store in histogram with logarithmic energy bins";
150 <<
"Number of bins in energy used for maximum int. probability: "
156 fPmaxSafetyFactor = sf;
159 <<
"Pmax safety factor = " << fPmaxSafetyFactor;
166 fForceInteraction =
true;
169 <<
"GMCJDriver will generate weighted events forcing the interaction. ";
177 fGenerateUnweighted =
true;
180 <<
"GMCJDriver will generate un-weighted events. "
181 <<
"Note: That does not force unweighted event kinematics!";
189 fPreSelect = preselect;
203 bool save_to_file = fFluxIntProbFile == 0 && fFluxIntFileName.size()>0;
206 fSumFluxIntProbs.clear();
211 "Skipping pre-generation of flux interaction probabilities - "<<
212 "using pre-generated file";
219 fFluxIntProbFile =
new TFile(fFluxIntFileName.c_str(),
"CREATE");
220 if(fFluxIntProbFile->IsZombie()){
221 LOG(
"GMCJDriver",
pFATAL) <<
"Cannot overwrite an existing file. Exiting!";
227 fFluxIntTree =
new TTree(fFluxIntTreeName.c_str(),
228 "Tree storing pre-calculated flux interaction probs");
229 fFluxIntTree->Branch(
"FluxIndex", &fBrFluxIndex,
"FluxIndex/I");
230 fFluxIntTree->Branch(
"FluxIntProb", &fBrFluxIntProb,
"FluxIntProb/D");
231 fFluxIntTree->Branch(
"FluxEnu", &fBrFluxEnu,
"FluxEnu/D");
232 fFluxIntTree->Branch(
"FluxWeight", &fBrFluxWeight,
"FluxWeight/D");
233 fFluxIntTree->Branch(
"FluxPDG", &fBrFluxPDG,
"FluxPDG/I");
235 if(save_to_file) fFluxIntTree->SetDirectory(fFluxIntProbFile);
237 fFluxDriver->GenerateWeighted(
true);
242 TStopwatch stopwatch;
244 long int first_index = -1;
245 bool first_loop =
true;
247 while(fFluxDriver->End() ==
false){
250 bool gotnext = fFluxDriver->GenerateNext();
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;
262 if(this->ComputePathLengths() ==
false){ success =
false;
break;}
265 double psum = this->ComputeInteractionProbabilities(
false );
267 fBrFluxIntProb = psum;
268 fBrFluxIndex = fFluxDriver->Index();
269 fBrFluxEnu = fFluxDriver->Momentum().E();
270 fBrFluxWeight = fFluxDriver->Weight();
271 fBrFluxPDG = fFluxDriver->PdgCode();
272 fFluxIntTree->Fill();
276 first_index = fFluxDriver->Index();
282 <<
"Finished pre-calculating flux interaction probabilities. "
283 <<
"Total CPU time to process "<< fFluxIntTree->GetEntries()
284 <<
" entries: "<< stopwatch.CpuTime();
288 fFluxDriver->Clear(
"CycleHistory");
295 double safety_factor = 1.01;
296 for(
int i = 0; i< fFluxIntTree->GetEntries(); i++){
297 fFluxIntTree->GetEntry(i);
302 fGlobPmax = TMath::Max(fGlobPmax, fBrFluxIntProb*safety_factor);
304 if(fSumFluxIntProbs.find(fBrFluxPDG) == fSumFluxIntProbs.end()){
305 fSumFluxIntProbs[fBrFluxPDG] = 0.0;
307 fSumFluxIntProbs[fBrFluxPDG] += fBrFluxIntProb * fBrFluxWeight;
310 "Updated global probability scale to fGlobPmax = "<< fGlobPmax;
314 "Saving pre-generated interaction probabilities to file: "<<
315 fFluxIntProbFile->GetName();
316 fFluxIntProbFile->cd();
317 fFluxIntTree->Write();
321 if(fFluxIntTree->BuildIndex(
"FluxIndex") != fFluxIntTree->GetEntries()){
323 "Cannot build index using branch \"FluxIndex\" for flux prob tree!";
329 this->PreSelectEvents(
false);
331 LOG(
"GMCJDriver",
pNOTICE) <<
"Successfully generated/loaded pre-calculate flux interaction probabilities";
334 else if(fFluxIntTree){
351 if(fFluxIntProbFile){
353 <<
"Can't load flux interaction prob file as one is already loaded";
357 fFluxIntProbFile =
new TFile(filename.c_str(),
"OPEN");
359 if(fFluxIntProbFile){
360 fFluxIntTree =
dynamic_cast<TTree*
>(fFluxIntProbFile->Get(fFluxIntTreeName.c_str()));
363 fFluxIntTree->SetBranchAddress(
"FluxIntProb", &fBrFluxIntProb) >= 0 &&
364 fFluxIntTree->SetBranchAddress(
"FluxIndex", &fBrFluxIndex) >= 0 &&
365 fFluxIntTree->SetBranchAddress(
"FluxPDG", &fBrFluxPDG) >= 0 &&
366 fFluxIntTree->SetBranchAddress(
"FluxWeight", &fBrFluxWeight) >= 0 &&
367 fFluxIntTree->SetBranchAddress(
"FluxEnu", &fBrFluxEnu) >= 0;
370 if(this->PreCalcFluxProbabilities()) {
372 <<
"Successfully loaded pre-generated flux interaction probabilities";
378 "Cannot find expected branches in input flux probability tree!";
379 delete fFluxIntTree; fFluxIntTree = 0;
382 <<
"Cannot find tree: "<< fFluxIntTreeName.c_str();
386 <<
"Unable to load flux interaction probabilities file";
396 fFluxIntFileName = outfilename;
406 this->GetParticleLists();
409 this->GetMaxFluxEnergy();
416 this->PopulateEventGenDriverPool();
428 this->BootstrapXSecSplines();
433 this->BootstrapXSecSplineSummation();
435 if(calc_prob_scales && !fForceInteraction){
438 this->GetMaxPathLengthList();
442 this->ComputeProbScales();
444 if (fForceInteraction) fGlobPmax = 1.;
445 LOG(
"GMCJDriver",
pNOTICE) <<
"Finished configuring GMCJDriver\n\n";
450 fEventGenList =
"Default";
455 fUnphysEventMask->SetBitNumber(i,
true);
462 fMaxPlXmlFilename =
"";
463 fUseExtMaxPl =
false;
467 fXSecSplineNbins = 100;
468 fPmaxLogBinning =
false;
470 fPmaxSafetyFactor = 1.2;
474 fForceInteraction =
false;
475 fGenerateUnweighted =
false;
480 fCurVtx.SetXYZT(0.,0.,0.,0.);
482 fFluxIntProbFile = 0;
483 fFluxIntTreeName =
"gFlxIntProb";
484 fFluxIntFileName =
"";
486 fBrFluxIntProb = -1.;
491 fSumFluxIntProbs.clear();
495 this->KeepOnThrowingFluxNeutrinos(
true);
515 fMaxPathLengths.clear();
516 fCurPathLengths.clear();
523 <<
"Asking the flux driver for its list of neutrinos";
524 fNuList = fFluxDriver->FluxParticles();
526 LOG(
"GMCJDriver",
pNOTICE) <<
"Flux particles: " << fNuList;
530 <<
"Asking the geometry driver for its list of targets";
531 fTgtList = fGeomAnalyzer->ListOfTargetNuclei();
533 LOG(
"GMCJDriver",
pNOTICE) <<
"Target materials: " << fTgtList;
540 <<
"Loading external max path-length list for input geometry from "
541 << fMaxPlXmlFilename;
542 fMaxPathLengths.LoadFromXml(fMaxPlXmlFilename);
546 <<
"Querying the geometry driver to compute the max path-length list";
547 fMaxPathLengths = fGeomAnalyzer->ComputeMaxPathLengths();
551 <<
"Maximum path length list: " << fMaxPathLengths;
557 <<
"Querying the flux driver for the maximum energy of flux neutrinos";
558 fEmax = fFluxDriver->MaxEnergy();
561 <<
"Maximum flux neutrino energy = " << fEmax <<
" GeV";
567 <<
"Creating GEVGPool & adding a GEVGDriver object per init-state";
569 if (fGPool)
delete fGPool;
572 PDGCodeList::const_iterator nuiter;
573 PDGCodeList::const_iterator tgtiter;
575 for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter) {
576 for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
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";
606 if(!fUseSplines)
return;
609 <<
"Asking event generation drivers to compute all needed xsec splines";
611 PDGCodeList::const_iterator nuiter;
612 PDGCodeList::const_iterator tgtiter;
613 for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter){
614 for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
615 int target_pdgc = *tgtiter;
616 int neutrino_pdgc = *nuiter;
619 <<
"Computing all splines needed for init-state: "
621 GEVGDriver * evgdriver = fGPool->FindDriver(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;
645 if (fEmax>rE.
max || fEmax<rE.
min)
647 <<
" rE (validEnergyRange) [" << rE.
min <<
"," << rE.
max <<
"] "
648 <<
" fEmax " << fEmax;
649 assert(fEmax<rE.max && fEmax>rE.
min);
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;
701 if (fPmaxLogBinning) {
703 double de = (TMath::Log10(fEmax) - TMath::Log10(emin)) / fPmaxNbins;
704 ebins =
new double[fPmaxNbins+1];
705 for(
int i=0; i<=fPmaxNbins; i++) ebins[i] = TMath::Power(10., TMath::Log10(emin) + i * de);
710 double de = fEmax/fPmaxNbins;
712 double emax = fEmax + de;
714 ebins =
new double[fPmaxNbins+1];
715 for(
int i=0; i<=fPmaxNbins; i++) ebins[i] = emin + i * (emax-emin)/fPmaxNbins;
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);
737 for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
738 int target_pdgc = *tgtiter;
743 <<
"Computing Pmax for init-state: " << init_state.
AsString() <<
" E from " << EvLow <<
"-" << EvHigh;
746 GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
753 double plmax = fMaxPathLengths.PathLength(target_pdgc);
757 double pmaxLow = this->InteractionProbability(sxsecLow, plmax, A);
758 double pmaxHigh = this->InteractionProbability(sxsecHigh, plmax, A);
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;
774 pmax_hst->SetBinContent(ie, fPmaxSafetyFactor * pmax_hst->GetBinContent(ie));
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();
801 fGlobPmax = TMath::Max(pmax, fGlobPmax);
803 LOG(
"GMCJDriver",
pNOTICE) <<
"*** Probability scale = " << fGlobPmax;
809 fCurPathLengths.clear();
812 fCurVtx.SetXYZT(0.,0.,0.,0.);
817 LOG(
"GMCJDriver",
pNOTICE) <<
"Generating next event...";
819 this->InitEventGeneration();
822 bool flux_end = fFluxDriver->End();
825 <<
"No more neutrinos can be thrown by the flux driver";
830 if(event)
return event;
832 if(fKeepThrowingFluxNu) {
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;
855 bool flux_ok = this->GenerateFluxNeutrino();
858 <<
"** Rejecting current flux neutrino (flux driver err)";
862 if (fForceInteraction) {
863 bool pl_ok = this->ComputePathLengths();
865 LOG(
"GMCJDriver",
pFATAL) <<
"** Cannot calculate path lenths!";
868 if(fCurPathLengths.AreAllZero()) {
870 <<
"** Rejecting current flux neutrino (misses generation volume)";
873 Psum = this->ComputeInteractionProbabilities(
false);
875 <<
"The interaction probability is: " << Psum;
887 <<
"Computing interaction probabilities for max. path lengths";
889 Psum = this->ComputeInteractionProbabilities(
true );
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";
913 Psum = this->PreGenFluxInteractionProbability();
919 pl_ok = this->ComputePathLengths();
922 <<
"** Rejecting current flux neutrino (err computing path-lengths)";
925 if(fCurPathLengths.AreAllZero()) {
927 <<
"** Rejecting current flux neutrino (misses generation volume)";
930 Psum = this->ComputeInteractionProbabilities(
false );
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 <<
" %)";
949 int nupdg = fFluxDriver ->
PdgCode ();
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;
961 <<
"\n Problematic path lengths:" << fCurPathLengths;
964 <<
"\n Maximum path lengths:" << fMaxPathLengths;
970 <<
"** Rejecting current flux neutrino";
981 pl_ok = this->ComputePathLengths();
983 LOG(
"GMCJDriver",
pFATAL) <<
"** Cannot calculate path lenths!";
986 double Psum_curr = this->ComputeInteractionProbabilities(
false );
990 "** Mismatch between pre-calculated and current interaction "<<
998 fSelTgtPdg = this->SelectTargetMaterial(R);
1001 <<
"** Rejecting current flux neutrino (failed to select tgt!)";
1007 this->GenerateEventKinematics();
1010 <<
"** Couldn't generate kinematics for selected interaction";
1016 this->GenerateVertexPosition();
1025 if(fForceInteraction) {
1026 double weight = 1. - TMath::Exp(-Psum);
1027 fCurEvt->SetProbability(Psum);
1028 fCurEvt->SetWeight(weight * fCurEvt->Weight());
1031 this->ComputeEventProbability();
1042 LOG(
"GMCJDriver",
pNOTICE) <<
"Generating a flux neutrino";
1044 bool ok = fFluxDriver->GenerateNext();
1047 <<
"*** The flux driver couldn't generate a flux neutrino!!";
1052 int nupdg = fFluxDriver ->
PdgCode ();
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!!";
1087 fCurPathLengths.clear();
1089 const TLorentzVector & nup4 = fFluxDriver -> Momentum ();
1090 const TLorentzVector & nux4 = fFluxDriver -> Position ();
1092 fCurPathLengths = fGeomAnalyzer->ComputePathLengths(nux4, nup4);
1094 LOG(
"GMCJDriver",
pNOTICE) << fCurPathLengths;
1096 if(fCurPathLengths.size() == 0) {
1098 <<
"\n *** Geometry driver error ***"
1099 <<
"\n Got an empty PathLengthList - No material found in geometry?";
1103 if(fCurPathLengths.AreAllZero()) {
1105 <<
"current flux v doesn't cross any geometry material...";
1113 <<
"Computing relative interaction probabilities for each material";
1116 int nupdg = fFluxDriver->PdgCode();
1117 const TLorentzVector & nup4 = fFluxDriver->Momentum();
1119 fCurCumulProbMap.clear();
1122 (use_max_path_length) ? fMaxPathLengths : fCurPathLengths;
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;
1138 GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
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() );
1158 prob = this->InteractionProbability(xsec,pl,A);
1160 <<
" (xsec, pl, A)=(" << xsec <<
"," << pl <<
"," << A <<
")";
1166 if(fForceInteraction) pmax = 1.;
1167 else if(fGenerateUnweighted) pmax = fGlobPmax;
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 <<
"%";
1188 fCurCumulProbMap.insert(map<int,double>::value_type(mpdg,probsum));
1198 LOG(
"GMCJDriver",
pNOTICE) <<
"Selecting target material";
1200 map<int,double>::const_iterator probiter = fCurCumulProbMap.begin();
1201 for( ; probiter != fCurCumulProbMap.end(); ++probiter) {
1202 double prob = probiter->second;
1204 tgtpdg = probiter->first;
1206 <<
"Selected target material = " << tgtpdg;
1211 <<
"Could not select target material for an interacting neutrino";
1217 int nupdg = fFluxDriver->PdgCode();
1218 const TLorentzVector & nup4 = fFluxDriver->Momentum();
1223 GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
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 ();
1250 const TVector3 & vtx = fGeomAnalyzer->GenerateVertex(x4, p4, fSelTgtPdg);
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);
1264 fCurEvt->SetVertex(fCurVtx);
1272 double xsec = fCurEvt->XSec();
1275 PathLengthList::const_iterator pliter = fCurPathLengths.find(fSelTgtPdg);
1276 double path_length = pliter->second;
1282 double P = this->InteractionProbability(xsec, path_length, A);
1289 int nu_pdg = nu->
Pdg();
1290 double Ev = nu->
P4()->Energy();
1292 double weight = 1.0;
1293 if(!fGenerateUnweighted) {
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));
1300 weight = pmax/fGlobPmax;
1304 fCurEvt->SetProbability(P);
1305 fCurEvt->SetWeight(weight * fCurEvt->Weight());
1318 return kNA*(xsec*pL)/A;
1329 "Cannot get pre-computed flux interaction probability as no tree!";
1333 assert(fFluxDriver->Index() >= 0);
1337 bool found_entry = fFluxIntTree->GetEntryWithIndex(fFluxDriver->Index()) > 0;
1338 bool enu_match =
false;
1340 double rel_err = fBrFluxEnu-fFluxDriver->Momentum().E();
1343 if(enu_match ==
false){
1345 "Mismatch between: Enu_curr = "<< fFluxDriver->Momentum().E() <<
1346 ", Enu_pre_gen = "<< fBrFluxEnu;
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)";
1364 return fBrFluxIntProb/fGlobPmax;
void CreateXSecSumSpline(int nk, double Emin, double Emax, bool inlogE=true)
void SetUnphysEventMask(const TBits &mask)
void ForceInteraction(void)
void PopulateEventGenDriverPool(void)
bool PreCalcFluxProbabilities(void)
void GetMaxPathLengthList(void)
static RandomGen * Instance()
Access instance.
void SetEventGeneratorList(string listname)
const TLorentzVector * P4(void) const
static constexpr double gram
void InitEventGeneration(void)
A simple [min,max] interval for doubles.
string BoolAsYNString(bool b)
A numeric analysis tool class for interpolating 1-D functions.
int IonPdgCodeToA(int pdgc)
bool GenerateFluxNeutrino(void)
bool ComputePathLengths(void)
string P4AsString(const TLorentzVector *p)
const Spline * XSecSumSpline(void) const
double Evaluate(double x) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
void ComputeEventProbability(void)
Range1D_t ValidEnergyRange(void) const
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.
void KeepOnThrowingFluxNeutrinos(bool keep_on)
void GetMaxFluxEnergy(void)
static constexpr double second
static unsigned int NFlags(void)
int PdgCode(Resonance_t res, int Q)
(resonance id, charge) -> PDG code
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
static constexpr double kilogram
void SetEventGeneratorList(string listname)
static constexpr double m2
static constexpr double A
void SetPmaxSafetyFactor(double sf)
static constexpr double cm2
void ForceSingleProbScale(void)
double PreGenFluxInteractionProbability(void)
static Messenger * Instance(void)
bool UseMaxPathLengths(string xml_filename)
void Configure(bool calc_prob_scales=true)
string AsString(void) const
static const double kASmallNum
TRandom3 & RndEvg(void) const
rnd number generator used by the event generation drivers
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
void SetPmaxLogBinning(void)
void BootstrapXSecSplines(void)
double ComputeInteractionProbabilities(bool use_max_path_length)
static const double kLightSpeed
EventRecord * GenerateEvent(void)
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
double InteractionProbability(double xsec, double pl, int A)
void SetPmaxNbins(int nbins)
void PreSelectEvents(bool preselect=true)
static constexpr double meter
void GenerateEventKinematics(void)
int SelectTargetMaterial(double R)
void GenerateVertexPosition(void)
void SetXSecSplineNbins(int nbins)
void ComputeProbScales(void)
void Configure(int nu_pdgc, int Z, int A)
bool LoadFluxProbabilities(string filename)
EventRecord * GenerateEvent1Try(void)
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
void CreateSplines(int nknots=-1, double emax=-1, bool inLogE=true)
void BootstrapXSecSplineSummation(void)
Defines the GENIE Geometry Analyzer Interface.
string X4AsString(const TLorentzVector *x)
void SetUnphysEventMask(const TBits &mask)
STDHEP-like event record entry that can fit a particle or a nucleus.
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void UseSplines(bool useLogE=true)
void SaveFluxProbabilities(string outfilename)
void GetParticleLists(void)
static AlgConfigPool * Instance()
Initial State information.
GENIE Interface for user-defined flux classes.
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
A pool of GEVGDriver objects with an initial state key.