diff --git a/src/InputHandler/GENIEInputHandler.cxx b/src/InputHandler/GENIEInputHandler.cxx
index 36b63d2..60ef26f 100644
--- a/src/InputHandler/GENIEInputHandler.cxx
+++ b/src/InputHandler/GENIEInputHandler.cxx
@@ -1,635 +1,636 @@
// Copyright 2016-2021 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NUISANCE. If not, see .
*******************************************************************************/
#ifdef __GENIE_ENABLED__
#include "GENIEInputHandler.h"
#ifdef GENIE_PRE_R3
#include "Messenger/Messenger.h"
#else
#include "Framework/Messenger/Messenger.h"
#endif
#include "InputUtils.h"
GENIEGeneratorInfo::~GENIEGeneratorInfo() { DeallocateParticleStack(); }
void GENIEGeneratorInfo::AddBranchesToTree(TTree *tn) {
tn->Branch("GenieParticlePDGs", &fGenieParticlePDGs, "GenieParticlePDGs/I");
}
void GENIEGeneratorInfo::SetBranchesFromTree(TTree *tn) {
tn->SetBranchAddress("GenieParticlePDGs", &fGenieParticlePDGs);
}
void GENIEGeneratorInfo::AllocateParticleStack(int stacksize) {
fGenieParticlePDGs = new int[stacksize];
}
void GENIEGeneratorInfo::DeallocateParticleStack() {
delete fGenieParticlePDGs;
}
void GENIEGeneratorInfo::FillGeneratorInfo(NtpMCEventRecord *ntpl) {
Reset();
// Check for GENIE Event
if (!ntpl)
return;
if (!ntpl->event)
return;
// Cast Event Record
GHepRecord *ghep = static_cast(ntpl->event);
if (!ghep)
return;
// Fill Particle Stack
GHepParticle *p = 0;
TObjArrayIter iter(ghep);
// Loop over all particles
int i = 0;
while ((p = (dynamic_cast((iter).Next())))) {
if (!p)
continue;
// Get PDG
fGenieParticlePDGs[i] = p->Pdg();
i++;
}
}
void GENIEGeneratorInfo::Reset() {
for (int i = 0; i < kMaxParticles; i++) {
fGenieParticlePDGs[i] = 0;
}
}
+bool GENIEInputHandler::IsPrimary(GHepParticle *p) {
+
+ // If initial state nucleon, or nucleon target, it is definintely primary!
+ if (p->Status() == genie::kIStInitialState ||
+ p->Status() == genie::kIStNucleonTarget) return true;
+
+ // Reject intermediate resonant state or pre-DIS state
+ if (p->Status() == genie::kIStDISPreFragmHadronicState || // DIS before fragmentation
+ p->Status() == genie::kIStPreDecayResonantState || // pre decay resonance state
+ p->Status() == genie::kIStIntermediateState || // intermediate state
+ p->Status() == genie::kIStDecayedState || // Decayed state
+ p->Status() == genie::kIStUndefined) return false; // undefined state
+
+ // Check if the mother is the neutrino or IS nucleon
+ if (p->FirstMother() < 2) return true;
+
+ // We've now filtered off intermediate states and obvious initial states
+
+ // Loop over this particle's mothers, grandmothers, and so on cleaning out intermediate particles
+ // Set the starting particle to be our particle
+ GHepParticle *mother = fGenieGHep->Particle(p->FirstMother());
+ while (mother->FirstMother() > 1) {
+ // It could be that the mother's status is actually a decayed state linked back to the vertex
+ if (mother->Status() == genie::kIStDecayedState || // A decayed state
+ mother->Status() == genie::kIStDISPreFragmHadronicState || // A DIS state before fragmentation
+ mother->Status() == genie::kIStPreDecayResonantState ) { // A pre-decay resonant state
+ mother = fGenieGHep->Particle(mother->FirstMother());
+ } else { // If not, move out of the loop
+ break;
+ }
+ }
+
+ // Then do a simple check of mother is associated with the primary
+ int MotherID = mother->FirstMother();
+ if (MotherID > 2) return false;
+
+ // Finally, this should mean that our partcile is marked for transport through the nucleus
+ // Could also be interactions of free proton
+ if (p->Status() == genie::kIStHadronInTheNucleus || // Then require the particle to be paseed to FSI
+ (p->Status() == genie::kIStStableFinalState && // Can also have interaction on free proton
+ fGenieGHep->Summary()->InitState().TgtPtr()->A() == 1 &&
+ fGenieGHep->Summary()->InitState().TgtPtr()->Z() == 1) ) {
+ return true;
+ }
+
+ return false;
+}
+
GENIEInputHandler::GENIEInputHandler(std::string const &handle,
- std::string const &rawinputs) {
+ std::string const &rawinputs) {
NUIS_LOG(SAM, "Creating GENIEInputHandler : " << handle);
// Plz no shouting
StopTalking();
genie::Messenger::Instance()->SetPriorityLevel("GHepUtils", pFATAL);
StartTalking();
// Shout all you want
// Run a joint input handling
fName = handle;
// Setup the TChain
fGENIETree = new TChain("gtree");
fSaveExtra = FitPar::Config().GetParB("SaveExtraGenie");
fCacheSize = FitPar::Config().GetParI("CacheSize");
fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
- // Are we running with NOvA weights
- fNOvAWeights = FitPar::Config().GetParB("NOvA_Weights");
- MAQEw = 1.0;
- NonResw = 1.0;
- RPAQEw = 1.0;
- RPARESw = 1.0;
- MECw = 1.0;
- DISw = 1.0;
- NOVAw = 1.0;
-
// Loop over all inputs and grab flux, eventhist, and nevents
std::vector inputs = InputUtils::ParseInputFileList(rawinputs);
for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
// Open File for histogram access
TFile *inp_file = new TFile(
InputUtils::ExpandInputDirectories(inputs[inp_it]).c_str(), "READ");
if (!inp_file or inp_file->IsZombie()) {
NUIS_ABORT(
"GENIE File IsZombie() at : '"
<< inputs[inp_it] << "'" << std::endl
<< "Check that your file paths are correct and the file exists!"
<< std::endl
<< "$ ls -lh " << inputs[inp_it]);
}
// Get Flux/Event hist
TH1D *fluxhist = (TH1D *)inp_file->Get("nuisance_flux");
TH1D *eventhist = (TH1D *)inp_file->Get("nuisance_events");
if (!fluxhist or !eventhist) {
NUIS_ERR(FTL, "Input File Contents: " << inputs[inp_it]);
inp_file->ls();
NUIS_ABORT("GENIE FILE doesn't contain flux/xsec info."
- << std::endl
- << "Try running the app PrepareGENIE first on :"
- << inputs[inp_it] << std::endl
- << "$ PrepareGENIE -h");
+ << std::endl
+ << "Try running the app PrepareGENIE first on :"
+ << inputs[inp_it] << std::endl
+ << "$ PrepareGENIE -h");
}
// Get N Events
TTree *genietree = (TTree *)inp_file->Get("gtree");
if (!genietree) {
NUIS_ERR(FTL, "gtree not located in GENIE file: " << inputs[inp_it]);
NUIS_ABORT(
"Check your inputs, they may need to be completely regenerated!");
}
int nevents = genietree->GetEntries();
if (nevents <= 0) {
NUIS_ABORT("Trying to a TTree with "
- << nevents << " to TChain from : " << inputs[inp_it]);
- }
-
- // Check for precomputed weights
- TTree *weighttree = (TTree *)inp_file->Get("nova_wgts");
- if (fNOvAWeights) {
- if (!weighttree) {
- NUIS_ABORT("Did not find nova_wgts tree in file "
- << inputs[inp_it] << " but you specified it" << std::endl);
- } else {
- NUIS_LOG(FIT, "Found nova_wgts tree in file " << inputs[inp_it]);
- }
+ << nevents << " to TChain from : " << inputs[inp_it]);
}
// Register input to form flux/event rate hists
RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist);
// Add To TChain
fGENIETree->AddFile(inputs[inp_it].c_str());
- if (weighttree != NULL)
- fGENIETree->AddFriend(weighttree);
}
// Registor all our file inputs
SetupJointInputs();
// Assign to tree
fEventType = kGENIE;
fGenieNtpl = NULL;
fGENIETree->SetBranchAddress("gmcrec", &fGenieNtpl);
- // Set up the custom weights
- if (fNOvAWeights) {
- fGENIETree->SetBranchAddress("MAQEwgt", &MAQEw);
- fGENIETree->SetBranchAddress("nonResNormWgt", &NonResw);
- fGENIETree->SetBranchAddress("RPAQEWgt", &RPAQEw);
- fGENIETree->SetBranchAddress("RPARESWgt", &RPARESw);
- fGENIETree->SetBranchAddress("MECWgt", &MECw);
- fGENIETree->SetBranchAddress("DISWgt", &DISw);
- fGENIETree->SetBranchAddress("nova2018CVWgt", &NOVAw);
- }
-
// Libraries should be seen but not heard...
StopTalking();
fGENIETree->GetEntry(0);
StartTalking();
// Create Fit Event
fNUISANCEEvent = new FitEvent();
fNUISANCEEvent->SetGenieEvent(fGenieNtpl);
if (fSaveExtra) {
fGenieInfo = new GENIEGeneratorInfo();
fNUISANCEEvent->AddGeneratorInfo(fGenieInfo);
}
fNUISANCEEvent->HardReset();
};
GENIEInputHandler::~GENIEInputHandler() {
// if (fGenieGHep) delete fGenieGHep;
// if (fGenieNtpl) delete fGenieNtpl;
// if (fGENIETree) delete fGENIETree;
// if (fGenieInfo) delete fGenieInfo;
}
void GENIEInputHandler::CreateCache() {
if (fCacheSize > 0) {
// fGENIETree->SetCacheEntryRange(0, fNEvents);
fGENIETree->AddBranchToCache("*", 1);
fGENIETree->SetCacheSize(fCacheSize);
}
}
void GENIEInputHandler::RemoveCache() {
// fGENIETree->SetCacheEntryRange(0, fNEvents);
fGENIETree->AddBranchToCache("*", 0);
fGENIETree->SetCacheSize(0);
}
FitEvent *GENIEInputHandler::GetNuisanceEvent(const UInt_t ent,
- const bool lightweight) {
+ const bool lightweight) {
UInt_t entry = ent + fSkip;
if (entry >= (UInt_t)fNEvents)
return NULL;
// Clear the previous event (See Note 1 in ROOT TClonesArray documentation)
if (fGenieNtpl) {
fGenieNtpl->Clear();
}
// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
fGENIETree->GetEntry(entry);
// Run NUISANCE Vector Filler
if (!lightweight) {
CalcNUISANCEKinematics();
}
#ifdef __PROB3PP_ENABLED__
else {
// Check for GENIE Event
if (!fGenieNtpl)
return NULL;
if (!fGenieNtpl->event)
return NULL;
// Cast Event Record
fGenieGHep = static_cast(fGenieNtpl->event);
if (!fGenieGHep)
return NULL;
TObjArrayIter iter(fGenieGHep);
genie::GHepParticle *p;
while ((p = (dynamic_cast((iter).Next())))) {
if (!p) {
continue;
}
// Get Status
int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode);
if (state != genie::kIStInitialState) {
continue;
}
fNUISANCEEvent->probe_E = p->E() * 1.E3;
fNUISANCEEvent->probe_pdg = p->Pdg();
break;
}
}
#endif
// Setup Input scaling for joint inputs
fNUISANCEEvent->InputWeight = GetInputWeight(entry);
return fNUISANCEEvent;
}
int GENIEInputHandler::GetGENIEParticleStatus(genie::GHepParticle *p,
- int mode) {
+ int mode) {
/*
kIStUndefined = -1,
kIStInitialState = 0, / generator-level initial state /
kIStStableFinalState = 1, / generator-level final state:
particles to be tracked by detector-level MC /
kIStIntermediateState = 2,
kIStDecayedState = 3,
kIStCorrelatedNucleon = 10,
kIStNucleonTarget = 11,
kIStDISPreFragmHadronicState = 12,
kIStPreDecayResonantState = 13,
kIStHadronInTheNucleus = 14, / hadrons inside the nucleus: marked
for hadron transport modules to act on /
kIStFinalStateNuclearRemnant = 15, / low energy nuclear fragments
entering the record collectively as a 'hadronic blob' pseudo-particle /
kIStNucleonClusterTarget = 16, // for composite nucleons before
phase space decay
*/
int state = kUndefinedState;
switch (p->Status()) {
- case genie::kIStNucleonTarget:
- case genie::kIStInitialState:
- case genie::kIStCorrelatedNucleon:
- case genie::kIStNucleonClusterTarget:
- state = kInitialState;
- break;
-
- case genie::kIStStableFinalState:
- state = kFinalState;
- break;
-
- case genie::kIStHadronInTheNucleus:
- if (abs(mode) == 2)
+ case genie::kIStNucleonTarget:
+ case genie::kIStInitialState:
+ case genie::kIStCorrelatedNucleon:
+ case genie::kIStNucleonClusterTarget:
state = kInitialState;
- else
+ break;
+
+ case genie::kIStStableFinalState:
+ state = kFinalState;
+ break;
+
+ case genie::kIStHadronInTheNucleus:
+ if (abs(mode) == 2)
+ state = kInitialState;
+ else
+ state = kFSIState;
+ break;
+
+ case genie::kIStPreDecayResonantState:
+ case genie::kIStDISPreFragmHadronicState:
+ case genie::kIStIntermediateState:
state = kFSIState;
- break;
-
- case genie::kIStPreDecayResonantState:
- case genie::kIStDISPreFragmHadronicState:
- case genie::kIStIntermediateState:
- state = kFSIState;
- break;
-
- case genie::kIStFinalStateNuclearRemnant:
- case genie::kIStUndefined:
- case genie::kIStDecayedState:
- default:
- break;
+ break;
+
+ case genie::kIStFinalStateNuclearRemnant:
+ case genie::kIStUndefined:
+ case genie::kIStDecayedState:
+ default:
+ break;
}
// Flag to remove nuclear part in genie
- if (p->Pdg() > 1000000) {
- if (state == kInitialState)
- state = kNuclearInitial;
- else if (state == kFinalState)
- state = kNuclearRemnant;
+ if (kRemoveNuclearParticles) {
+ if (p->Pdg() > 1000000 &&
+ pdg::IsNeutronOrProton(
+ fGenieGHep->Summary()->InitState().TgtPtr()->HitNucPdg())) { // Check that it isn't coherent! Want to keep initial state if so
+ if (state == kInitialState)
+ state = kNuclearInitial;
+ else if (state == kFinalState)
+ state = kNuclearRemnant;
+ }
}
return state;
}
#endif
#ifdef __GENIE_ENABLED__
int GENIEInputHandler::ConvertGENIEReactionCode(GHepRecord *gheprec) {
// I randomly picked 53 here because NEUT doesn't have an appropriate mode...
if (gheprec->Summary()->ProcInfo().IsNuElectronElastic()){
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 53;
else return -53;
}
// And the same story for 54
if (gheprec->Summary()->ProcInfo().IsIMDAnnihilation()){
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 54;
else return -54;
}
// Electron Scattering
if (gheprec->Summary()->ProcInfo().IsEM()) {
if (gheprec->Summary()->InitState().ProbePdg() == 11) {
if (gheprec->Summary()->ProcInfo().IsQuasiElastic())
return 1;
else if (gheprec->Summary()->ProcInfo().IsMEC())
return 2;
else if (gheprec->Summary()->ProcInfo().IsResonant())
return 13;
else if (gheprec->Summary()->ProcInfo().IsDeepInelastic())
return 26;
else {
NUIS_ERR(WRN,
- "Unknown GENIE Electron Scattering Mode!"
- << std::endl
- << "ScatteringTypeId = "
- << gheprec->Summary()->ProcInfo().ScatteringTypeId() << " "
- << "InteractionTypeId = "
- << gheprec->Summary()->ProcInfo().InteractionTypeId()
- << std::endl
- << genie::ScatteringType::AsString(
- gheprec->Summary()->ProcInfo().ScatteringTypeId())
- << " "
- << genie::InteractionType::AsString(
- gheprec->Summary()->ProcInfo().InteractionTypeId())
- << " " << gheprec->Summary()->ProcInfo().IsMEC());
+ "Unknown GENIE Electron Scattering Mode!"
+ << std::endl
+ << "ScatteringTypeId = "
+ << gheprec->Summary()->ProcInfo().ScatteringTypeId() << " "
+ << "InteractionTypeId = "
+ << gheprec->Summary()->ProcInfo().InteractionTypeId()
+ << std::endl
+ << genie::ScatteringType::AsString(
+ gheprec->Summary()->ProcInfo().ScatteringTypeId())
+ << " "
+ << genie::InteractionType::AsString(
+ gheprec->Summary()->ProcInfo().InteractionTypeId())
+ << " " << gheprec->Summary()->ProcInfo().IsMEC());
return 0;
}
}
// Weak CC
} else if (gheprec->Summary()->ProcInfo().IsWeakCC()) {
// CC MEC
if (gheprec->Summary()->ProcInfo().IsMEC()) {
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return 2;
else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return -2;
#ifndef GENIE_PRE_R3
} else if (gheprec->Summary()->ProcInfo().IsDiffractive()) {
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return 15;
else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return -15;
#endif
// CC OTHER
} else {
return utils::ghep::NeutReactionCode(gheprec);
}
// Weak NC
} else if (gheprec->Summary()->ProcInfo().IsWeakNC()) {
// NC MEC
if (gheprec->Summary()->ProcInfo().IsMEC()) {
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return 32;
else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return -32;
#ifndef GENIE_PRE_R3
} else if (gheprec->Summary()->ProcInfo().IsDiffractive()) {
if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return 35;
else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg()))
return -35;
#endif
// NC OTHER
} else {
return utils::ghep::NeutReactionCode(gheprec);
}
}
return 0;
}
void GENIEInputHandler::CalcNUISANCEKinematics() {
// Reset all variables
fNUISANCEEvent->ResetEvent();
// Check for GENIE Event
if (!fGenieNtpl)
return;
if (!fGenieNtpl->event)
return;
// Cast Event Record
fGenieGHep = static_cast(fGenieNtpl->event);
if (!fGenieGHep)
return;
// Convert GENIE Reaction Code
fNUISANCEEvent->Mode = ConvertGENIEReactionCode(fGenieGHep);
if (!fNUISANCEEvent->Mode) {
NUIS_ERR(WRN, "Failed to determine mode for GENIE event: ");
std::cout << *fGenieGHep << std::endl;
}
// Set Event Info
fNUISANCEEvent->fEventNo = 0.0;
fNUISANCEEvent->fTotCrs = fGenieGHep->XSec();
+
// Have a bool storing if interaction happened on free or bound nucleon
bool IsFree = false;
+
// Set the TargetPDG
if (fGenieGHep->TargetNucleus() != NULL) {
fNUISANCEEvent->fTargetPDG = fGenieGHep->TargetNucleus()->Pdg();
IsFree = false;
// Sometimes GENIE scatters off free nucleons, electrons, photons
// In which TargetNucleus is NULL and we need to find the initial state
// particle
} else {
// Check the particle is an initial state particle
// Follows GHepRecord::TargetNucleusPosition but doesn't do check on
// pdg::IsIon
GHepParticle *p = fGenieGHep->Particle(1);
// Check that particle 1 actually exists
if (!p) {
NUIS_ABORT("Can't find particle 1 for GHepRecord");
}
// If not an ion but is an initial state particle
if (!pdg::IsIon(p->Pdg()) && p->Status() == kIStInitialState) {
IsFree = true;
fNUISANCEEvent->fTargetPDG = p->Pdg();
// Catch if something strange happens:
// Here particle 1 is not an initial state particle OR
// particle 1 is an ion OR
// both
} else {
if (pdg::IsIon(p->Pdg())) {
NUIS_ABORT(
"Particle 1 in GHepRecord stack is an ion but isn't an initial "
"state particle");
} else {
NUIS_ABORT(
"Particle 1 in GHepRecord stack is not an ion but is an initial "
"state particle");
}
}
}
// Set the A and Z and H from the target PDG
// Depends on if we scattered off a free or bound nucleon
if (!IsFree) {
fNUISANCEEvent->fTargetA =
- TargetUtils::GetTargetAFromPDG(fNUISANCEEvent->fTargetPDG);
+ TargetUtils::GetTargetAFromPDG(fNUISANCEEvent->fTargetPDG);
fNUISANCEEvent->fTargetZ =
- TargetUtils::GetTargetZFromPDG(fNUISANCEEvent->fTargetPDG);
+ TargetUtils::GetTargetZFromPDG(fNUISANCEEvent->fTargetPDG);
fNUISANCEEvent->fTargetH = 0;
} else {
// If free proton scattering
if (fNUISANCEEvent->fTargetPDG == 2212) {
fNUISANCEEvent->fTargetA = 1;
fNUISANCEEvent->fTargetZ = 1;
fNUISANCEEvent->fTargetH = 1;
// If free neutron scattering
} else if (fNUISANCEEvent->fTargetPDG == 2112) {
fNUISANCEEvent->fTargetA = 0;
fNUISANCEEvent->fTargetZ = 1;
fNUISANCEEvent->fTargetH = 0;
// If neither
} else {
fNUISANCEEvent->fTargetA = 0;
fNUISANCEEvent->fTargetZ = 0;
fNUISANCEEvent->fTargetH = 0;
}
}
fNUISANCEEvent->fBound = !IsFree;
fNUISANCEEvent->InputWeight =
- 1.0; //(1E+38 / genie::units::cm2) * fGenieGHep->XSec();
-
- // And the custom weights
- if (fNOvAWeights) {
- fNUISANCEEvent->CustomWeight = NOVAw;
- fNUISANCEEvent->CustomWeightArray[0] = MAQEw;
- fNUISANCEEvent->CustomWeightArray[1] = NonResw;
- fNUISANCEEvent->CustomWeightArray[2] = RPAQEw;
- fNUISANCEEvent->CustomWeightArray[3] = RPARESw;
- fNUISANCEEvent->CustomWeightArray[4] = MECw;
- fNUISANCEEvent->CustomWeightArray[5] = NOVAw;
- } else {
- fNUISANCEEvent->CustomWeight = 1.0;
- fNUISANCEEvent->CustomWeightArray[0] = 1.0;
- fNUISANCEEvent->CustomWeightArray[1] = 1.0;
- fNUISANCEEvent->CustomWeightArray[2] = 1.0;
- fNUISANCEEvent->CustomWeightArray[3] = 1.0;
- fNUISANCEEvent->CustomWeightArray[4] = 1.0;
- fNUISANCEEvent->CustomWeightArray[5] = 1.0;
- }
+ 1.0; //(1E+38 / genie::units::cm2) * fGenieGHep->XSec();
// Get N Particle Stack
unsigned int npart = fGenieGHep->GetEntries();
unsigned int kmax = fNUISANCEEvent->kMaxParticles;
if (npart > kmax) {
NUIS_ERR(WRN, "GENIE has too many particles, expanding stack.");
fNUISANCEEvent->ExpandParticleStack(npart);
}
// Fill Particle Stack
GHepParticle *p = 0;
TObjArrayIter iter(fGenieGHep);
fNUISANCEEvent->fNParticles = 0;
// Loop over all particles
while ((p = (dynamic_cast((iter).Next())))) {
if (!p)
continue;
// Get Status
int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode);
// Remove Undefined
if (kRemoveUndefParticles && state == kUndefinedState)
continue;
// Remove FSI
if (kRemoveFSIParticles && state == kFSIState)
continue;
if (kRemoveNuclearParticles &&
(state == kNuclearInitial || state == kNuclearRemnant))
continue;
// Fill Vectors
int curpart = fNUISANCEEvent->fNParticles;
fNUISANCEEvent->fParticleState[curpart] = state;
// Mom
fNUISANCEEvent->fParticleMom[curpart][0] = p->Px() * 1.E3;
fNUISANCEEvent->fParticleMom[curpart][1] = p->Py() * 1.E3;
fNUISANCEEvent->fParticleMom[curpart][2] = p->Pz() * 1.E3;
fNUISANCEEvent->fParticleMom[curpart][3] = p->E() * 1.E3;
// PDG
fNUISANCEEvent->fParticlePDG[curpart] = p->Pdg();
// Set if the particle was on the fundamental vertex
- fNUISANCEEvent->fPrimaryVertex[curpart] = (p->FirstMother() < 2);
+ fNUISANCEEvent->fPrimaryVertex[curpart] = IsPrimary(p);
// Add to N particle count
fNUISANCEEvent->fNParticles++;
// Extra Check incase GENIE fails.
if ((UInt_t)fNUISANCEEvent->fNParticles == kmax) {
NUIS_ERR(WRN, "Number of GENIE Particles exceeds maximum!");
NUIS_ERR(WRN, "Extend kMax, or run without including FSI particles!");
break;
}
}
// Fill Extra Stack
if (fSaveExtra)
fGenieInfo->FillGeneratorInfo(fGenieNtpl);
// Run Initial, FSI, Final, Other ordering.
fNUISANCEEvent->OrderStack();
FitParticle *ISAnyLepton = fNUISANCEEvent->GetHMISAnyLeptons();
if (ISAnyLepton) {
fNUISANCEEvent->probe_E = ISAnyLepton->E();
fNUISANCEEvent->probe_pdg = ISAnyLepton->PDG();
}
return;
}
void GENIEInputHandler::Print() {}
#endif
diff --git a/src/InputHandler/GENIEInputHandler.h b/src/InputHandler/GENIEInputHandler.h
index a09cda0..44d5d1a 100644
--- a/src/InputHandler/GENIEInputHandler.h
+++ b/src/InputHandler/GENIEInputHandler.h
@@ -1,130 +1,121 @@
// Copyright 2016-2021 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NUISANCE. If not, see .
*******************************************************************************/
#ifndef GENIEINPUTHANDLER_H
#define GENIEINPUTHANDLER_H
/*!
* \addtogroup InputHandler
* @{
*/
#ifdef __GENIE_ENABLED__
#include "InputHandler.h"
#include "InputUtils.h"
#include "PlotUtils.h"
#ifdef GENIE_PRE_R3
#include "GHEP/GHepParticle.h"
#include "PDG/PDGUtils.h"
#include "GHEP/GHepUtils.h"
#include "Conventions/Units.h"
#include "EVGCore/EventRecord.h"
#include "GHEP/GHepRecord.h"
#include "Ntuple/NtpMCEventRecord.h"
#else
#include "Framework/GHEP/GHepParticle.h"
#include "Framework/ParticleData/PDGUtils.h"
#include "Framework/GHEP/GHepUtils.h"
#include "Framework/Conventions/Units.h"
#include "Framework/EventGen/EventRecord.h"
#include "Framework/GHEP/GHepRecord.h"
#include "Framework/Ntuple/NtpMCEventRecord.h"
#endif
using namespace genie;
/// GENIE Generator Container to save extra particle status codes.
class GENIEGeneratorInfo : public GeneratorInfoBase {
-public:
- GENIEGeneratorInfo() {};
- virtual ~GENIEGeneratorInfo();
+ public:
+ GENIEGeneratorInfo() {};
+ virtual ~GENIEGeneratorInfo();
- /// Assigns information to branches
- void AddBranchesToTree(TTree* tn);
+ /// Assigns information to branches
+ void AddBranchesToTree(TTree* tn);
- /// Setup reading information from branches
- void SetBranchesFromTree(TTree* tn);
+ /// Setup reading information from branches
+ void SetBranchesFromTree(TTree* tn);
- /// Allocate any dynamic arrays for a new particle stack size
- void AllocateParticleStack(int stacksize);
+ /// Allocate any dynamic arrays for a new particle stack size
+ void AllocateParticleStack(int stacksize);
- /// Clear any dynamic arrays
- void DeallocateParticleStack();
+ /// Clear any dynamic arrays
+ void DeallocateParticleStack();
- /// Read extra genie information from the event
- void FillGeneratorInfo(NtpMCEventRecord* ntpl);
+ /// Read extra genie information from the event
+ void FillGeneratorInfo(NtpMCEventRecord* ntpl);
- /// Reset extra information to default/empty values
- void Reset();
+ /// Reset extra information to default/empty values
+ void Reset();
- int kMaxParticles; ///< Number of particles in stack
- int* fGenieParticlePDGs; ///< GENIE Particle PDGs (example)
+ int kMaxParticles; ///< Number of particles in stack
+ int* fGenieParticlePDGs; ///< GENIE Particle PDGs (example)
};
/// Main GENIE InputHandler
class GENIEInputHandler : public InputHandlerBase {
-public:
+ public:
- /// Standard constructor given a name and input files
- GENIEInputHandler(std::string const& handle, std::string const& rawinputs);
- virtual ~GENIEInputHandler();
+ /// Standard constructor given a name and input files
+ GENIEInputHandler(std::string const& handle, std::string const& rawinputs);
+ virtual ~GENIEInputHandler();
- /// Create a TTree Cache to speed up file read
- void CreateCache();
+ /// Create a TTree Cache to speed up file read
+ void CreateCache();
- /// Remove TTree Cache to save memory
- void RemoveCache();
-
- /// Returns a NUISANCE format event from the GENIE TTree. If !lightweight
- /// then CalcNUISANCEKinematics() is called to convert the GENIE event into
- /// a standard NUISANCE format.
- FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+ /// Remove TTree Cache to save memory
+ void RemoveCache();
- /// Converts GENIE event into standard NUISANCE FitEvent by looping over all
- /// particles in the event and adding them to stack in fNUISANCEEvent.
- void CalcNUISANCEKinematics();
+ /// Returns a NUISANCE format event from the GENIE TTree. If !lightweight
+ /// then CalcNUISANCEKinematics() is called to convert the GENIE event into
+ /// a standard NUISANCE format.
+ FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
- /// Placeholder for GENIE related event printing.
- void Print();
+ /// Converts GENIE event into standard NUISANCE FitEvent by looping over all
+ /// particles in the event and adding them to stack in fNUISANCEEvent.
+ void CalcNUISANCEKinematics();
- /// Converts GENIE particle status codes into NUISANCE status codes.
- int GetGENIEParticleStatus(genie::GHepParticle* part, int mode = 0);
+ /// Placeholder for GENIE related event printing.
+ void Print();
- /// Converts GENIE event reaction codes into NUISANCE reaction codes.
- int ConvertGENIEReactionCode(GHepRecord* gheprec);
+ /// Converts GENIE particle status codes into NUISANCE status codes.
+ int GetGENIEParticleStatus(genie::GHepParticle* part, int mode = 0);
- GHepRecord* fGenieGHep; ///< Pointer to actual event record
- NtpMCEventRecord* fGenieNtpl; ///< Ntpl Wrapper Class
+ /// Converts GENIE event reaction codes into NUISANCE reaction codes.
+ int ConvertGENIEReactionCode(GHepRecord* gheprec);
- TChain* fGENIETree; ///< Main GENIE Event TTree
- bool fSaveExtra; ///< Flag to save Extra GENIE info into Nuisance Event
- GENIEGeneratorInfo* fGenieInfo; ///< Extra GENIE Generator Info Writer
+ GHepRecord* fGenieGHep; ///< Pointer to actual event record
+ NtpMCEventRecord* fGenieNtpl; ///< Ntpl Wrapper Class
- bool fNOvAWeights; ///< Flag to save nova weights or not
+ TChain* fGENIETree; ///< Main GENIE Event TTree
+ bool fSaveExtra; ///< Flag to save Extra GENIE info into Nuisance Event
+ GENIEGeneratorInfo* fGenieInfo; ///< Extra GENIE Generator Info Writer
- // Extra weights from Jeremy for NOvA weights
- double MAQEw;
- double NonResw;
- double RPAQEw;
- double RPARESw;
- double MECw;
- double DISw;
- double NOVAw;
+ bool IsPrimary(GHepParticle *p);
};
/*! @} */
#endif
#endif