diff --git a/src/InputHandler/FitEvent.cxx b/src/InputHandler/FitEvent.cxx index fc302aa..13a4e14 100644 --- a/src/InputHandler/FitEvent.cxx +++ b/src/InputHandler/FitEvent.cxx @@ -1,459 +1,459 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is pddrt 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "FitEvent.h" #include <iostream> #include "TObjArray.h" FitEvent::FitEvent() { fGenInfo = NULL; kRemoveFSIParticles = true; kRemoveUndefParticles = true; AllocateParticleStack(400); }; void FitEvent::AddGeneratorInfo(GeneratorInfoBase* gen) { fGenInfo = gen; gen->AllocateParticleStack(kMaxParticles); } void FitEvent::AllocateParticleStack(int stacksize) { LOG(DEB) << "Allocating particle stack of size: " << stacksize << std::endl; kMaxParticles = stacksize; fParticleList = new FitParticle*[kMaxParticles]; fParticleMom = new double*[kMaxParticles]; fParticleState = new UInt_t[kMaxParticles]; fParticlePDG = new int[kMaxParticles]; fOrigParticleMom = new double*[kMaxParticles]; fOrigParticleState = new UInt_t[kMaxParticles]; fOrigParticlePDG = new int[kMaxParticles]; for (size_t i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; fParticleMom[i] = new double[4]; fOrigParticleMom[i] = new double[4]; } if (fGenInfo) fGenInfo->AllocateParticleStack(kMaxParticles); } void FitEvent::ExpandParticleStack(int stacksize) { DeallocateParticleStack(); AllocateParticleStack(stacksize); } void FitEvent::DeallocateParticleStack() { for (size_t i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; delete fParticleMom[i]; delete fOrigParticleMom[i]; } delete fParticleMom; delete fOrigParticleMom; delete fParticleList; delete fParticleState; delete fParticlePDG; delete fOrigParticleState; delete fOrigParticlePDG; if (fGenInfo) fGenInfo -> DeallocateParticleStack(); kMaxParticles = 0; } void FitEvent::ClearFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::FreeFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::ResetParticleList() { for (unsigned int i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::HardReset() { for (unsigned int i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::ResetEvent() { fMode = 9999; Mode = 9999; fEventNo = -1; fTotCrs = -1.0; fTargetA = -1; fTargetZ = -1; fTargetH = -1; fBound = false; fNParticles = 0; if (fGenInfo) fGenInfo->Reset(); for (unsigned int i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; fParticleList[i] = NULL; continue; fParticlePDG[i] = 0; fParticleState[i] = kUndefinedState; fParticleMom[i][0] = 0.0; fParticleMom[i][1] = 0.0; fParticleMom[i][2] = 0.0; fParticleMom[i][3] = 0.0; fOrigParticlePDG[i] = 0; fOrigParticleState[i] = kUndefinedState; fOrigParticleMom[i][0] = 0.0; fOrigParticleMom[i][1] = 0.0; fOrigParticleMom[i][2] = 0.0; fOrigParticleMom[i][3] = 0.0; } } void FitEvent::OrderStack() { // Copy current stack int npart = fNParticles; for (int i = 0; i < npart; i++) { fOrigParticlePDG[i] = fParticlePDG[i]; fOrigParticleState[i] = fParticleState[i]; fOrigParticleMom[i][0] = fParticleMom[i][0]; fOrigParticleMom[i][1] = fParticleMom[i][1]; fOrigParticleMom[i][2] = fParticleMom[i][2]; fOrigParticleMom[i][3] = fParticleMom[i][3]; } // Now run loops for each particle fNParticles = 0; int stateorder[6] = {kInitialState, kFinalState, kFSIState, kNuclearInitial, kNuclearRemnant, kUndefinedState }; for (int s = 0; s < 6; s++) { for (int i = 0; i < npart; i++) { if ((UInt_t)fOrigParticleState[i] != (UInt_t)stateorder[s]) continue; fParticlePDG[fNParticles] = fOrigParticlePDG[i]; fParticleState[fNParticles] = fOrigParticleState[i]; fParticleMom[fNParticles][0] = fOrigParticleMom[i][0]; fParticleMom[fNParticles][1] = fOrigParticleMom[i][1]; fParticleMom[fNParticles][2] = fOrigParticleMom[i][2]; fParticleMom[fNParticles][3] = fOrigParticleMom[i][3]; fNParticles++; } } if (LOG_LEVEL(DEB)) { LOG(DEB) << "Ordered stack" << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(DEB) << "Particle " << i << ". " << fParticlePDG[i] << " " << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " " << fParticleState[i] << std::endl; } } if (fNParticles != npart) { ERR(FTL) << "Dropped some particles when ordering the stack!" << std::endl; } return; } void FitEvent::Print() { if (LOG_LEVEL(FIT)) { LOG(FIT) << "FITEvent print" << std::endl; LOG(FIT) << "Mode: " << fMode << std::endl; LOG(FIT) << "Particles: " << fNParticles << std::endl; LOG(FIT) << " -> Particle Stack " << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(FIT) << " -> -> " << i << ". " << fParticlePDG[i] << " " << fParticleState[i] << " " << " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1] << ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")." << std::endl; } } return; } /* Read/Write own event class */ void FitEvent::SetBranchAddress(TChain* tn) { tn->SetBranchAddress("Mode", &fMode); tn->SetBranchAddress("Mode", &Mode); tn->SetBranchAddress("EventNo", &fEventNo); tn->SetBranchAddress("TotCrs", &fTotCrs); tn->SetBranchAddress("TargetA", &fTargetA); tn->SetBranchAddress("TargetH", &fTargetH); tn->SetBranchAddress("Bound", &fBound); tn->SetBranchAddress("RWWeight", &SavedRWWeight); tn->SetBranchAddress("InputWeight", &InputWeight); // This has to be setup by the handler now :( // tn->SetBranchAddress("NParticles", &fNParticles); // tn->SetBranchAddress("ParticleState", &fParticleState); // tn->SetBranchAddress("ParticlePDG", &fParticlePDG); // tn->SetBranchAddress("ParticleMom", &fParticleMom); } void FitEvent::AddBranchesToTree(TTree* tn) { tn->Branch("Mode", &Mode, "Mode/I"); tn->Branch("EventNo", &fEventNo, "EventNo/i"); tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); tn->Branch("TargetA", &fTargetA, "TargetA/I"); tn->Branch("TargetH", &fTargetH, "TargetH/I"); tn->Branch("Bound", &fBound, "Bound/O"); tn->Branch("RWWeight", &RWWeight, "RWWeight/D"); tn->Branch("InputWeight", &InputWeight, "InputWeight/D"); tn->Branch("NParticles", &fNParticles, "NParticles/I"); tn->Branch("ParticleState", fOrigParticleState, "ParticleState[NParticles]/i"); tn->Branch("ParticlePDG", fOrigParticlePDG, "ParticlePDG[NParticles]/I"); tn->Branch("ParticleMom", fOrigParticleMom, "ParticleMom[NParticles][4]/D"); } // ------- EVENT ACCESS FUNCTION --------- // TLorentzVector FitEvent::GetParticleP4 (int index) const { if (index == -1 or index >= fNParticles) return TLorentzVector(); return TLorentzVector( fParticleMom[index][0], fParticleMom[index][1], fParticleMom[index][2], fParticleMom[index][3] ); } TVector3 FitEvent::GetParticleP3 (int index) const { if (index == -1 or index >= fNParticles) return TVector3(); return TVector3( fParticleMom[index][0], fParticleMom[index][1], fParticleMom[index][2] ); } double FitEvent::GetParticleMom (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return sqrt(fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2]); } double FitEvent::GetParticleMom2 (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fabs((fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2])); } double FitEvent::GetParticleE (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fParticleMom[index][3]; } int FitEvent::GetParticleState (int index) const { if (index == -1 or index >= fNParticles) return kUndefinedState; return (fParticleState[index]); } int FitEvent::GetParticlePDG (int index) const { if (index == -1 or index >= fNParticles) return 0; return (fParticlePDG[index]); } FitParticle* FitEvent::GetParticle (int const i) { // Check Valid Index if (i == -1){ return NULL; } // Check Valid if (i > fNParticles) { ERR(FTL) << "Requesting particle beyond stack!" << std::endl << "i = " << i << " N = " << fNParticles << std::endl << "Mode = " << fMode << std::endl; throw; } if (!fParticleList[i]) { /* std::cout << "Creating particle with values i " << i << " "; std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; std::cout << fParticlePDG[i] << " " << fParticleState[i] << std::endl; */ fParticleList[i] = new FitParticle(fParticleMom[i][0], fParticleMom[i][1], fParticleMom[i][2], fParticleMom[i][3], fParticlePDG[i], fParticleState[i]); } else { /* std::cout << "Filling particle with values i " << i << " "; std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; std::cout << fParticlePDG[i] << " "<< fParticleState[i] <<std::endl; */ - // fParticleList[i]->SetValues(fParticleMom[i][0], fParticleMom[i][1], - // fParticleMom[i][2], fParticleMom[i][3], - // fParticlePDG[i], fParticleState[i]); + fParticleList[i]->SetValues(fParticleMom[i][0], fParticleMom[i][1], + fParticleMom[i][2], fParticleMom[i][3], + fParticlePDG[i], fParticleState[i]); } return fParticleList[i]; } bool FitEvent::HasParticle(int const pdg, int const state) const { bool found = false; for (int i = 0; i < fNParticles; i++) { if (state != -1 && fParticleState[i] != (uint)state) continue; if (fParticlePDG[i] == pdg) found = true; } return found; } int FitEvent::NumParticle(int const pdg, int const state) const { int nfound = 0; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) nfound += 1; } return nfound; } std::vector<int> FitEvent::GetAllParticleIndices (int const pdg, int const state) const { std::vector<int> indexlist; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { indexlist.push_back(i); } } return indexlist; } std::vector<FitParticle*> FitEvent::GetAllParticle(int const pdg, int const state) { std::vector<int> indexlist = GetAllParticleIndices(pdg, state); std::vector<FitParticle*> plist; for (std::vector<int>::iterator iter = indexlist.begin(); iter != indexlist.end(); iter++) { plist.push_back( GetParticle((*iter)) ); } return plist; } int FitEvent::GetHMParticleIndex (int const pdg, int const state) const { double maxmom2 = -9999999.9; int maxind = -1; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { double newmom2 = GetParticleMom2(i); if (newmom2 > maxmom2) { maxind = i; maxmom2 = newmom2; } } } return maxind; } int FitEvent::GetBeamNeutrinoIndex (void) const { for (int i = 0; i < fNParticles; i++){ if (fParticleState[i] != kInitialState) continue; int pdg = abs(fParticlePDG[i]); if (pdg == 12 or pdg == 14 or pdg == 16){ return i; } } return 0; } int FitEvent::GetBeamElectronIndex (void) const { return GetHMISParticleIndex( 11 ); } int FitEvent::GetBeamPionIndex (void) const { return GetHMISParticleIndex( PhysConst::pdg_pions ); } int FitEvent::NumFSMesons() { int nMesons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) >= 111 && abs(fParticlePDG[i]) <= 557) nMesons += 1; } return nMesons; } int FitEvent::NumFSLeptons(void) const{ int nLeptons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) == 11 || abs(fParticlePDG[i]) == 13 || abs(fParticlePDG[i]) == 15) nLeptons += 1; } return nLeptons; } diff --git a/src/InputHandler/FitEvent.h b/src/InputHandler/FitEvent.h index 50bd5be..dc20304 100644 --- a/src/InputHandler/FitEvent.h +++ b/src/InputHandler/FitEvent.h @@ -1,615 +1,640 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #ifndef FITEVENT2_H_SEEN #define FITEVENT2_H_SEEN /*! * \addtogroup InputHandler * @{ */ #include <algorithm> #include <iterator> #include <vector> #include "FitParticle.h" #include "TLorentzVector.h" #include "TSpline.h" #include "FitParameters.h" #include "BaseFitEvt.h" #include "FitLogger.h" #include "TArrayD.h" #include "TTree.h" #include "TChain.h" #include "PhysConst.h" /// Common container for event particles class FitEvent : public BaseFitEvt { public: FitEvent(); ~FitEvent() {}; void FreeFitParticles(); void ClearFitParticles(); void ResetEvent(void); void ResetParticleList(void); void HardReset(); void OrderStack(); void SetBranchAddress(TChain* tn); void AddBranchesToTree(TTree* tn); void Print(); void PrintChris(); void DeallocateParticleStack(); void AllocateParticleStack(int stacksize); void ExpandParticleStack(int stacksize); void AddGeneratorInfo(GeneratorInfoBase* gen); // ---- HELPER/ACCESS FUNCTIONS ---- // /// Return True Interaction ID inline int GetMode (void) const { return fMode; }; /// Return Target Atomic Number inline int GetTargetA (void) const { return fTargetA; }; /// Return Target Nuclear Charge inline int GetTargetZ (void) const { return fTargetZ; }; /// Get Event Total Cross-section inline int GetTotCrs (void) const { return fTotCrs; }; /// Is Event Charged Current? inline bool IsCC() const { return (abs(fMode) <= 30); }; /// Is Event Neutral Current? inline bool IsNC() const { return (abs(fMode) > 30); }; /// Return Particle 4-momentum for given index in particle stack TLorentzVector GetParticleP4 (int index) const; /// Return Particle 3-momentum for given index in particle stack TVector3 GetParticleP3 (int index) const; /// Return Particle absolute momentum for given index in particle stack double GetParticleMom (int index) const; /// Return Particle absolute momentum-squared for given index in particle stack double GetParticleMom2 (int index) const; /// Return Particle energy for given index in particle stack double GetParticleE (int index) const; /// Return Particle State for given index in particle stack int GetParticleState (int index) const; /// Return Particle PDG for given index in particle stack int GetParticlePDG (int index) const; + /// Allows the removal of KE up to total KE. + inline void RemoveKE(int index, double KE){ + + FitParticle *fp = GetParticle(index); + + double mass = fp->M(); + double oKE = fp->KE(); + double nE = mass + (oKE - KE); + if(nE < mass){ // Can't take more KE than it has + nE = mass; + } + double n3Mom = sqrt(nE*nE - mass*mass); + TVector3 np3 = fp->P3().Unit()*n3Mom; + + fParticleMom[index][0] = np3[0]; + fParticleMom[index][1] = np3[1]; + fParticleMom[index][2] = np3[2]; + fParticleMom[index][3] = nE; + + } + + /// Allows the removal of KE up to total KE. + inline void GiveKE(int index, double KE){ + RemoveKE(index,-KE); + } /// Return Particle for given index in particle stack FitParticle* GetParticle(int const index); /// Get Total Number of Particles in stack inline uint NParticles (void) const { return fNParticles; }; /// Check if event contains a particle given a pdg and state. /// If no state is passed all states are considered. bool HasParticle (int const pdg = 0, int const state = -1) const ; template <size_t N> inline bool HasParticle(int const (&pdgs)[N], int const state = -1) const { for (size_t i = 0; i < N; i++) { if (HasParticle( pdgs[i], state )) { return false; } } return false; } /// Get total number of particles given a pdg and state. /// If no state is passed all states are considered. int NumParticle (int const pdg = 0, int const state = -1) const; template <size_t N> inline int NumParticle(int const (&pdgs)[N], int const state = -1) const { int ncount = 0; for (size_t i = 0; i < N; i++) { ncount += NumParticle( pdgs[i], state ); } return ncount; } /// Return a vector of particle indices that can be used with 'GetParticle' /// functions given a particle pdg and state. /// If no state is passed all states are considered. std::vector<int> GetAllParticleIndices (int const pdg = -1, int const state = -1) const; template <size_t N> inline std::vector<int> GetAllParticleIndices(int const (&pdgs)[N], const int state = -1) const { std::vector<int> plist; for (size_t i = 0; i < N; i++) { std::vector<int> plisttemp = GetAllParticleIndices(pdgs[i], state); plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() ); } return plist; } /// Return a vector of FitParticles given a particle pdg and state. /// This is memory intensive and slow than GetAllParticleIndices, /// but is slightly easier to use. std::vector<FitParticle*> GetAllParticle (int const pdg = -1, int const state = -1); template <size_t N> inline std::vector<FitParticle*> GetAllParticle(int const (&pdgs)[N], int const state = -1) { std::vector<FitParticle*> plist; for (size_t i = 0; i < N; i++) { std::vector<FitParticle*> plisttemp = GetAllParticle(pdgs[i], state); plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() ); } return plist; } inline std::vector<int> GetAllNuElectronIndices (void) { return GetAllParticleIndices(12); }; inline std::vector<int> GetAllNuMuonIndices (void) { return GetAllParticleIndices(14); }; inline std::vector<int> GetAllNuTauIndices (void) { return GetAllParticleIndices(16); }; inline std::vector<int> GetAllElectronIndices (void) { return GetAllParticleIndices(11); }; inline std::vector<int> GetAllMuonIndices (void) { return GetAllParticleIndices(13); }; inline std::vector<int> GetAllTauIndices (void) { return GetAllParticleIndices(15); }; inline std::vector<int> GetAllProtonIndices (void) { return GetAllParticleIndices(2212); }; inline std::vector<int> GetAllNeutronIndices (void) { return GetAllParticleIndices(2112); }; inline std::vector<int> GetAllPiZeroIndices (void) { return GetAllParticleIndices(111); }; inline std::vector<int> GetAllPiPlusIndices (void) { return GetAllParticleIndices(211); }; inline std::vector<int> GetAllPiMinusIndices (void) { return GetAllParticleIndices(-211); }; inline std::vector<int> GetAllPhotonIndices (void) { return GetAllParticleIndices(22); }; inline std::vector<FitParticle*> GetAllNuElectron (void) { return GetAllParticle(12); }; inline std::vector<FitParticle*> GetAllNuMuon (void) { return GetAllParticle(14); }; inline std::vector<FitParticle*> GetAllNuTau (void) { return GetAllParticle(16); }; inline std::vector<FitParticle*> GetAllElectron (void) { return GetAllParticle(11); }; inline std::vector<FitParticle*> GetAllMuon (void) { return GetAllParticle(13); }; inline std::vector<FitParticle*> GetAllTau (void) { return GetAllParticle(15); }; inline std::vector<FitParticle*> GetAllProton (void) { return GetAllParticle(2212); }; inline std::vector<FitParticle*> GetAllNeutron (void) { return GetAllParticle(2112); }; inline std::vector<FitParticle*> GetAllPiZero (void) { return GetAllParticle(111); }; inline std::vector<FitParticle*> GetAllPiPlus (void) { return GetAllParticle(211); }; inline std::vector<FitParticle*> GetAllPiMinus (void) { return GetAllParticle(-211); }; inline std::vector<FitParticle*> GetAllPhoton (void) { return GetAllParticle(22); }; // --- Highest Momentum Search Functions --- // /// Returns the Index of the highest momentum particle given a pdg and state. /// If no state is given all states are considered, but that will just return the /// momentum of the beam in most cases so is not advised. int GetHMParticleIndex (int const pdg = 0, int const state = -1) const; template <size_t N> inline int GetHMParticleIndex (int const (&pdgs)[N], int const state = -1) const { double mom = -999.9; int rtnindex = -1; for (size_t i = 0; i < N; ++i) { // Use ParticleMom as doesn't require Particle Mem alloc int pindex = GetHMParticleIndex(pdgs[i], state); if (pindex != -1){ double momnew = GetParticleMom2(pindex); if (momnew > mom) { rtnindex = pindex; mom = momnew; } } } return rtnindex; }; /// Returns the highest momentum particle given a pdg and state. /// If no state is given all states are considered, but that will just return the /// momentum of the beam in most cases so is not advised. inline FitParticle* GetHMParticle(int const pdg = 0, int const state = -1) { return GetParticle( GetHMParticleIndex(pdg, state) ); } template <size_t N> inline FitParticle* GetHMParticle(int const (&pdgs)[N], int const state) { return GetParticle(GetHMParticleIndex(pdgs, state)); }; // ---- Initial State Helpers --- // /// Checks the event has a particle of a given pdg in the initial state. inline bool HasISParticle(int const pdg) const { return HasParticle(pdg, kInitialState); }; template <size_t N> inline bool HasISParticle(int const (&pdgs)[N]) const { return HasParticle(pdgs, kInitialState); }; /// Returns the number of particles with a given pdg in the initial state. inline int NumISParticle(int const pdg = 0) const { return NumParticle(pdg, kInitialState); }; template <size_t N> inline int NumISParticle(int const (&pdgs)[N]) const { return NumParticle(pdgs, kInitialState); }; /// Returns a list of indices for all particles with a given pdg /// in the initial state. These can be used with the 'GetParticle' functions. inline std::vector<int> GetAllISParticleIndices(int const pdg = -1) const { return GetAllParticleIndices(pdg, kInitialState); }; template <size_t N> inline std::vector<int> GetAllISParticleIndices(int const (&pdgs)[N]) const { return GetAllParticleIndices(pdgs, kInitialState); }; /// Returns a list of particles with a given pdg in the initial state. /// This function is more memory intensive and slower than the Indices function. inline std::vector<FitParticle*> GetAllISParticle(int const pdg = -1) { return GetAllParticle(pdg, kInitialState); }; template <size_t N> inline std::vector<FitParticle*> GetAllISParticle(int const (&pdgs)[N]) { return GetAllParticle(pdgs, kInitialState); }; /// Returns the highest momentum particle with a given pdg in the initial state. inline FitParticle* GetHMISParticle(int const pdg) { return GetHMParticle(pdg, kInitialState); }; template <size_t N> inline FitParticle* GetHMISParticle(int const (&pdgs)[N]) { return GetHMParticle(pdgs, kInitialState); }; /// Returns the highest momentum particle index with a given pdg in the initial state. inline int GetHMISParticleIndex(int const pdg) const { return GetHMParticleIndex(pdg, kInitialState); }; template <size_t N> inline int GetHMISParticleIndex(int const (&pdgs)[N]) const { return GetHMParticleIndex(pdgs, kInitialState); }; inline bool HasISNuElectron (void) const { return HasISParticle(12); }; inline bool HasISNuMuon (void) const { return HasISParticle(14); }; inline bool HasISNuTau (void) const { return HasISParticle(16); }; inline bool HasISElectron (void) const { return HasISParticle(11); }; inline bool HasISMuon (void) const { return HasISParticle(13); }; inline bool HasISTau (void) const { return HasISParticle(15); }; inline bool HasISProton (void) const { return HasISParticle(2212); }; inline bool HasISNeutron (void) const { return HasISParticle(2112); }; inline bool HasISPiZero (void) const { return HasISParticle(111); }; inline bool HasISPiPlus (void) const { return HasISParticle(211); }; inline bool HasISPiMinus (void) const { return HasISParticle(-211); }; inline bool HasISPhoton (void) const { return HasISParticle(22); }; inline bool HasISLeptons (void) const { return HasISParticle(PhysConst::pdg_leptons); }; inline bool HasISPions (void) const { return HasISParticle(PhysConst::pdg_pions); }; inline bool HasISChargePions (void) const { return HasISParticle(PhysConst::pdg_charged_pions); }; inline int NumISNuElectron (void) const { return NumISParticle(12); }; inline int NumISNuMuon (void) const { return NumISParticle(14); }; inline int NumISNuTau (void) const { return NumISParticle(16); }; inline int NumISElectron (void) const { return NumISParticle(11); }; inline int NumISMuon (void) const { return NumISParticle(13); }; inline int NumISTau (void) const { return NumISParticle(15); }; inline int NumISProton (void) const { return NumISParticle(2212); }; inline int NumISNeutron (void) const { return NumISParticle(2112); }; inline int NumISPiZero (void) const { return NumISParticle(111); }; inline int NumISPiPlus (void) const { return NumISParticle(211); }; inline int NumISPiMinus (void) const { return NumISParticle(-211); }; inline int NumISPhoton (void) const { return NumISParticle(22); }; inline int NumISLeptons (void) const { return NumISParticle(PhysConst::pdg_leptons); }; inline int NumISPions (void) const { return NumISParticle(PhysConst::pdg_pions); }; inline int NumISChargePions (void) const { return NumISParticle(PhysConst::pdg_charged_pions); }; inline std::vector<int> GetAllISNuElectronIndices (void) const { return GetAllISParticleIndices(12); }; inline std::vector<int> GetAllISNuMuonIndices (void) const { return GetAllISParticleIndices(14); }; inline std::vector<int> GetAllISNuTauIndices (void) const { return GetAllISParticleIndices(16); }; inline std::vector<int> GetAllISElectronIndices (void) const { return GetAllISParticleIndices(11); }; inline std::vector<int> GetAllISMuonIndices (void) const { return GetAllISParticleIndices(13); }; inline std::vector<int> GetAllISTauIndices (void) const { return GetAllISParticleIndices(15); }; inline std::vector<int> GetAllISProtonIndices (void) const { return GetAllISParticleIndices(2212); }; inline std::vector<int> GetAllISNeutronIndices (void) const { return GetAllISParticleIndices(2112); }; inline std::vector<int> GetAllISPiZeroIndices (void) const { return GetAllISParticleIndices(111); }; inline std::vector<int> GetAllISPiPlusIndices (void) const { return GetAllISParticleIndices(211); }; inline std::vector<int> GetAllISPiMinusIndices (void) const { return GetAllISParticleIndices(-211); }; inline std::vector<int> GetAllISPhotonIndices (void) const { return GetAllISParticleIndices(22); }; inline std::vector<int> GetAllISLeptonsIndices (void) const { return GetAllISParticleIndices(PhysConst::pdg_leptons); }; inline std::vector<int> GetAllISPionsIndices (void) const { return GetAllISParticleIndices(PhysConst::pdg_pions); }; inline std::vector<int> GetAllISChargePionsIndices(void) const { return GetAllISParticleIndices(PhysConst::pdg_charged_pions); }; inline std::vector<FitParticle*> GetAllISNuElectron (void) { return GetAllISParticle(12); }; inline std::vector<FitParticle*> GetAllISNuMuon (void) { return GetAllISParticle(14); }; inline std::vector<FitParticle*> GetAllISNuTau (void) { return GetAllISParticle(16); }; inline std::vector<FitParticle*> GetAllISElectron (void) { return GetAllISParticle(11); }; inline std::vector<FitParticle*> GetAllISMuon (void) { return GetAllISParticle(13); }; inline std::vector<FitParticle*> GetAllISTau (void) { return GetAllISParticle(15); }; inline std::vector<FitParticle*> GetAllISProton (void) { return GetAllISParticle(2212); }; inline std::vector<FitParticle*> GetAllISNeutron (void) { return GetAllISParticle(2112); }; inline std::vector<FitParticle*> GetAllISPiZero (void) { return GetAllISParticle(111); }; inline std::vector<FitParticle*> GetAllISPiPlus (void) { return GetAllISParticle(211); }; inline std::vector<FitParticle*> GetAllISPiMinus (void) { return GetAllISParticle(-211); }; inline std::vector<FitParticle*> GetAllISPhoton (void) { return GetAllISParticle(22); }; inline std::vector<FitParticle*> GetAllISLeptons (void) { return GetAllISParticle(PhysConst::pdg_leptons); }; inline std::vector<FitParticle*> GetAllISPions (void) { return GetAllISParticle(PhysConst::pdg_pions); }; inline std::vector<FitParticle*> GetAllISChargePions(void) { return GetAllISParticle(PhysConst::pdg_charged_pions); }; inline FitParticle* GetHMISNuElectron (void) { return GetHMISParticle(12); }; inline FitParticle* GetHMISNuMuon (void) { return GetHMISParticle(14); }; inline FitParticle* GetHMISNuTau (void) { return GetHMISParticle(16); }; inline FitParticle* GetHMISElectron (void) { return GetHMISParticle(11); }; inline FitParticle* GetHMISMuon (void) { return GetHMISParticle(13); }; inline FitParticle* GetHMISTau (void) { return GetHMISParticle(15); }; inline FitParticle* GetHMISAnyLeptons (void) { return GetHMISParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMISProton (void) { return GetHMISParticle(2212); }; inline FitParticle* GetHMISNeutron (void) { return GetHMISParticle(2112); }; inline FitParticle* GetHMISPiZero (void) { return GetHMISParticle(111); }; inline FitParticle* GetHMISPiPlus (void) { return GetHMISParticle(211); }; inline FitParticle* GetHMISPiMinus (void) { return GetHMISParticle(-211); }; inline FitParticle* GetHMISPhoton (void) { return GetHMISParticle(22); }; inline FitParticle* GetHMISLepton (void) { return GetHMISParticle(PhysConst::pdg_leptons); }; inline FitParticle* GetHMISPions (void) { return GetHMISParticle(PhysConst::pdg_pions); }; inline FitParticle* GetHMISChargePions(void) { return GetHMISParticle(PhysConst::pdg_charged_pions); }; inline int GetHMISNuElectronIndex (void) { return GetHMISParticleIndex(12); }; inline int GetHMISNuMuonIndex (void) { return GetHMISParticleIndex(14); }; inline int GetHMISNuTauIndex (void) { return GetHMISParticleIndex(16); }; inline int GetHMISElectronIndex (void) { return GetHMISParticleIndex(11); }; inline int GetHMISMuonIndex (void) { return GetHMISParticleIndex(13); }; inline int GetHMISTauIndex (void) { return GetHMISParticleIndex(15); }; inline int GetHMISProtonIndex (void) { return GetHMISParticleIndex(2212); }; inline int GetHMISNeutronIndex (void) { return GetHMISParticleIndex(2112); }; inline int GetHMISPiZeroIndex (void) { return GetHMISParticleIndex(111); }; inline int GetHMISPiPlusIndex (void) { return GetHMISParticleIndex(211); }; inline int GetHMISPiMinusIndex (void) { return GetHMISParticleIndex(-211); }; inline int GetHMISPhotonIndex (void) { return GetHMISParticleIndex(22); }; inline int GetHMISLeptonsIndex (void) { return GetHMISParticleIndex(PhysConst::pdg_leptons); }; inline int GetHMISPionsIndex (void) { return GetHMISParticleIndex(PhysConst::pdg_pions); }; inline int GetHMISChargePionsIndex(void) { return GetHMISParticleIndex(PhysConst::pdg_charged_pions); }; // ---- Final State Helpers --- // inline bool HasFSParticle(int const pdg) const { return HasParticle(pdg, kFinalState); }; template <size_t N> inline bool HasFSParticle(int const (&pdgs)[N]) const { return HasParticle(pdgs, kFinalState); }; inline int NumFSParticle(int const pdg = 0) const { return NumParticle(pdg, kFinalState); }; template <size_t N> inline int NumFSParticle(int const (&pdgs)[N]) const { return NumParticle(pdgs, kFinalState); }; inline std::vector<int> GetAllFSParticleIndices(int const pdg = -1) const { return GetAllParticleIndices(pdg, kFinalState); }; template <size_t N> inline std::vector<int> GetAllFSParticleIndices(int const (&pdgs)[N]) const { return GetAllParticleIndices(pdgs, kFinalState); }; inline std::vector<FitParticle*> GetAllFSParticle(int const pdg = -1) { return GetAllParticle(pdg, kFinalState); }; template <size_t N> inline std::vector<FitParticle*> GetAllFSParticle(int const (&pdgs)[N]) { return GetAllParticle(pdgs, kFinalState); }; inline FitParticle* GetHMFSParticle(int const pdg) { return GetHMParticle(pdg, kFinalState); }; template <size_t N> inline FitParticle* GetHMFSParticle(int const (&pdgs)[N]) { return GetHMParticle(pdgs, kFinalState); }; inline int GetHMFSParticleIndex(int const pdg) const { return GetHMParticleIndex(pdg, kFinalState); }; template <size_t N> inline int GetHMFSParticleIndex(int const (&pdgs)[N]) const { return GetHMParticleIndex(pdgs, kFinalState); }; inline bool HasFSNuElectron (void) const { return HasFSParticle(12); }; inline bool HasFSNuMuon (void) const { return HasFSParticle(14); }; inline bool HasFSNuTau (void) const { return HasFSParticle(16); }; inline bool HasFSElectron (void) const { return HasFSParticle(11); }; inline bool HasFSMuon (void) const { return HasFSParticle(13); }; inline bool HasFSTau (void) const { return HasFSParticle(15); }; inline bool HasFSProton (void) const { return HasFSParticle(2212); }; inline bool HasFSNeutron (void) const { return HasFSParticle(2112); }; inline bool HasFSPiZero (void) const { return HasFSParticle(111); }; inline bool HasFSPiPlus (void) const { return HasFSParticle(211); }; inline bool HasFSPiMinus (void) const { return HasFSParticle(-211); }; inline bool HasFSPhoton (void) const { return HasFSParticle(22); }; inline bool HasFSLeptons (void) const { return HasFSParticle(PhysConst::pdg_leptons); }; inline bool HasFSPions (void) const { return HasFSParticle(PhysConst::pdg_pions); }; inline bool HasFSChargePions (void) const { return HasFSParticle(PhysConst::pdg_charged_pions); }; inline int NumFSNuElectron (void) const { return NumFSParticle(12); }; inline int NumFSNuMuon (void) const { return NumFSParticle(14); }; inline int NumFSNuTau (void) const { return NumFSParticle(16); }; inline int NumFSElectron (void) const { return NumFSParticle(11); }; inline int NumFSMuon (void) const { return NumFSParticle(13); }; inline int NumFSTau (void) const { return NumFSParticle(15); }; inline int NumFSProton (void) const { return NumFSParticle(2212); }; inline int NumFSNeutron (void) const { return NumFSParticle(2112); }; inline int NumFSPiZero (void) const { return NumFSParticle(111); }; inline int NumFSPiPlus (void) const { return NumFSParticle(211); }; inline int NumFSPiMinus (void) const { return NumFSParticle(-211); }; inline int NumFSPhoton (void) const { return NumFSParticle(22); }; int NumFSLeptons (void) const; // { return NumFSParticle(PhysConst::pdg_leptons); }; inline int NumFSPions (void) const { return NumFSParticle(PhysConst::pdg_pions); }; inline int NumFSChargePions (void) const { return NumFSParticle(PhysConst::pdg_charged_pions); }; inline std::vector<int> GetAllFSNuElectronIndices (void) const { return GetAllFSParticleIndices(12); }; inline std::vector<int> GetAllFSNuMuonIndices (void) const { return GetAllFSParticleIndices(14); }; inline std::vector<int> GetAllFSNuTauIndices (void) const { return GetAllFSParticleIndices(16); }; inline std::vector<int> GetAllFSElectronIndices (void) const { return GetAllFSParticleIndices(11); }; inline std::vector<int> GetAllFSMuonIndices (void) const { return GetAllFSParticleIndices(13); }; inline std::vector<int> GetAllFSTauIndices (void) const { return GetAllFSParticleIndices(15); }; inline std::vector<int> GetAllFSProtonIndices (void) const { return GetAllFSParticleIndices(2212); }; inline std::vector<int> GetAllFSNeutronIndices (void) const { return GetAllFSParticleIndices(2112); }; inline std::vector<int> GetAllFSPiZeroIndices (void) const { return GetAllFSParticleIndices(111); }; inline std::vector<int> GetAllFSPiPlusIndices (void) const { return GetAllFSParticleIndices(211); }; inline std::vector<int> GetAllFSPiMinusIndices (void) const { return GetAllFSParticleIndices(-211); }; inline std::vector<int> GetAllFSPhotonIndices (void) const { return GetAllFSParticleIndices(22); }; inline std::vector<int> GetAllFSLeptonsIndices (void) const { return GetAllFSParticleIndices(PhysConst::pdg_leptons); }; inline std::vector<int> GetAllFSPionsIndices (void) const { return GetAllFSParticleIndices(PhysConst::pdg_pions); }; inline std::vector<int> GetAllFSChargePionsIndices(void) const { return GetAllFSParticleIndices(PhysConst::pdg_charged_pions); }; inline std::vector<FitParticle*> GetAllFSNuElectron (void) { return GetAllFSParticle(12); }; inline std::vector<FitParticle*> GetAllFSNuMuon (void) { return GetAllFSParticle(14); }; inline std::vector<FitParticle*> GetAllFSNuTau (void) { return GetAllFSParticle(16); }; inline std::vector<FitParticle*> GetAllFSElectron (void) { return GetAllFSParticle(11); }; inline std::vector<FitParticle*> GetAllFSMuon (void) { return GetAllFSParticle(13); }; inline std::vector<FitParticle*> GetAllFSTau (void) { return GetAllFSParticle(15); }; inline std::vector<FitParticle*> GetAllFSProton (void) { return GetAllFSParticle(2212); }; inline std::vector<FitParticle*> GetAllFSNeutron (void) { return GetAllFSParticle(2112); }; inline std::vector<FitParticle*> GetAllFSPiZero (void) { return GetAllFSParticle(111); }; inline std::vector<FitParticle*> GetAllFSPiPlus (void) { return GetAllFSParticle(211); }; inline std::vector<FitParticle*> GetAllFSPiMinus (void) { return GetAllFSParticle(-211); }; inline std::vector<FitParticle*> GetAllFSPhoton (void) { return GetAllFSParticle(22); }; inline std::vector<FitParticle*> GetAllFSLeptons (void) { return GetAllFSParticle(PhysConst::pdg_leptons); }; inline std::vector<FitParticle*> GetAllFSPions (void) { return GetAllFSParticle(PhysConst::pdg_pions); }; inline std::vector<FitParticle*> GetAllFSChargePions (void) { return GetAllFSParticle(PhysConst::pdg_charged_pions); }; inline FitParticle* GetHMFSNuElectron (void) { return GetHMFSParticle(12); }; inline FitParticle* GetHMFSNuMuon (void) { return GetHMFSParticle(14); }; inline FitParticle* GetHMFSNuTau (void) { return GetHMFSParticle(16); }; inline FitParticle* GetHMFSElectron (void) { return GetHMFSParticle(11); }; inline FitParticle* GetHMFSMuon (void) { return GetHMFSParticle(13); }; inline FitParticle* GetHMFSTau (void) { return GetHMFSParticle(15); }; inline FitParticle* GetHMFSAnyLeptons (void) { return GetHMFSParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMFSProton (void) { return GetHMFSParticle(2212); }; inline FitParticle* GetHMFSNeutron (void) { return GetHMFSParticle(2112); }; inline FitParticle* GetHMFSPiZero (void) { return GetHMFSParticle(111); }; inline FitParticle* GetHMFSPiPlus (void) { return GetHMFSParticle(211); }; inline FitParticle* GetHMFSPiMinus (void) { return GetHMFSParticle(-211); }; inline FitParticle* GetHMFSPhoton (void) { return GetHMFSParticle(22); }; inline FitParticle* GetHMFSLeptons (void) { return GetHMFSParticle(PhysConst::pdg_leptons); }; inline FitParticle* GetHMFSAnyLepton (void) { return GetHMFSParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMFSPions (void) { return GetHMFSParticle(PhysConst::pdg_pions); }; inline FitParticle* GetHMFSChargePions(void) { return GetHMFSParticle(PhysConst::pdg_charged_pions); }; inline int GetHMFSNuElectronIndex (void) const { return GetHMFSParticleIndex(12); }; inline int GetHMFSNuMuonIndex (void) const { return GetHMFSParticleIndex(14); }; inline int GetHMFSNuTauIndex (void) const { return GetHMFSParticleIndex(16); }; inline int GetHMFSElectronIndex (void) const { return GetHMFSParticleIndex(11); }; inline int GetHMFSMuonIndex (void) const { return GetHMFSParticleIndex(13); }; inline int GetHMFSTauIndex (void) const { return GetHMFSParticleIndex(15); }; inline int GetHMFSProtonIndex (void) const { return GetHMFSParticleIndex(2212); }; inline int GetHMFSNeutronIndex (void) const { return GetHMFSParticleIndex(2112); }; inline int GetHMFSPiZeroIndex (void) const { return GetHMFSParticleIndex(111); }; inline int GetHMFSPiPlusIndex (void) const { return GetHMFSParticleIndex(211); }; inline int GetHMFSPiMinusIndex (void) const { return GetHMFSParticleIndex(-211); }; inline int GetHMFSPhotonIndex (void) const { return GetHMFSParticleIndex(22); }; inline int GetHMFSLeptonsIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_leptons); }; inline int GetHMFSAnyLeptonIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_all_leptons); }; inline int GetHMFSPionsIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_pions); }; inline int GetHMFSChargePionsIndex(void) const { return GetHMFSParticleIndex(PhysConst::pdg_charged_pions); }; // ---- NEUTRINO INCOMING Related Functions int GetBeamNeutrinoIndex (void) const; inline TLorentzVector GetBeamNeutrinoP4 (void) const { return GetParticleP4(GetBeamNeutrinoIndex()); }; inline TVector3 GetBeamNeutrinoP3 (void) const { return GetParticleP3(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoMom (void) const { return GetParticleMom(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoMom2 (void) const { return GetParticleMom2(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoE (void) const { return GetParticleE(GetBeamNeutrinoIndex()); }; inline double Enu (void) const { return GetBeamNeutrinoE(); }; inline int GetBeamNeutrinoPDG (void) const { return GetParticlePDG(GetBeamNeutrinoIndex()); }; inline int PDGnu (void) const { return GetBeamNeutrinoPDG(); }; inline int GetNeutrinoInPos (void) const { return GetBeamNeutrinoIndex(); }; inline FitParticle* GetBeamNeutrino (void) { return GetParticle(GetBeamNeutrinoIndex()); }; inline FitParticle* GetNeutrinoIn (void) { return GetParticle(GetBeamNeutrinoIndex()); }; // ---- Electron INCOMING Related Functions int GetBeamElectronIndex (void) const; inline TLorentzVector GetBeamElectronP4 (void) const { return GetParticleP4(GetBeamElectronIndex()); }; inline TVector3 GetBeamElectronP3 (void) const { return GetParticleP3(GetBeamElectronIndex()); }; inline double GetBeamElectronMom (void) const { return GetParticleMom(GetBeamElectronIndex()); }; inline double GetBeamElectronMom2 (void) const { return GetParticleMom2(GetBeamElectronIndex()); }; inline double GetBeamElectronE (void) const { return GetParticleE(GetBeamElectronIndex()); }; inline FitParticle* GetBeamElectron (void) { return GetParticle(GetBeamElectronIndex()); }; // ---- Pion INCOMING Functions int GetBeamPionIndex (void) const; inline TLorentzVector GetBeamPionP4 (void) const { return GetParticleP4(GetBeamPionIndex()); }; inline TVector3 GetBeamPionP3 (void) const { return GetParticleP3(GetBeamPionIndex()); }; inline double GetBeamPionMom (void) const { return GetParticleMom(GetBeamPionIndex()); }; inline double GetBeamPionMom2 (void) const { return GetParticleMom2(GetBeamPionIndex()); }; inline double GetBeamPionE (void) const { return GetParticleE(GetBeamPionIndex()); }; inline FitParticle* GetBeamPion (void) { return GetParticle(GetBeamPionIndex()); }; /// Legacy Functions inline FitParticle* PartInfo(uint i) { return GetParticle(i); }; inline UInt_t Npart (void) const { return NPart(); }; inline UInt_t NPart (void) const { return fNParticles; }; // Other Functions int NumFSMesons(); inline int GetBeamPartPos(void) const { return 0; }; FitParticle* GetBeamPart(void); int GetLeptonOutPos(void) const; FitParticle* GetLeptonOut(void); // Event Information double weight; // need for silly reason int Mode; // Public access needed int fMode; UInt_t fEventNo; double fTotCrs; int fTargetA; int fTargetZ; int fTargetH; bool fBound; int fDistance; int fTargetPDG; // Reduced Particle Stack UInt_t kMaxParticles; int fNParticles; double** fParticleMom; UInt_t* fParticleState; int* fParticlePDG; FitParticle** fParticleList; double** fOrigParticleMom; UInt_t* fOrigParticleState; int* fOrigParticlePDG; double* fNEUT_ParticleStatusCode; double* fNEUT_ParticleAliveCode; GeneratorInfoBase* fGenInfo; // Config Options for this class bool kRemoveFSIParticles; bool kRemoveUndefParticles; }; /*! @} */ #endif diff --git a/src/InputHandler/FitParticle.h b/src/InputHandler/FitParticle.h index ab1bb4f..fa9c263 100644 --- a/src/InputHandler/FitParticle.h +++ b/src/InputHandler/FitParticle.h @@ -1,127 +1,109 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #ifndef FITPARTICLE_H_SEEN #define FITPARTICLE_H_SEEN /*! * \addtogroup InputHandler * @{ */ #include "TLorentzVector.h" /// Partle state flags for its position in the event enum particle_state{ kUndefinedState = 5, kInitialState = 0, kFSIState = 1, kFinalState = 2, kNuclearInitial = 3, kNuclearRemnant = 4 }; /// Condensed FitParticle class which acts a common format between the generators class FitParticle { public: /// Create particle of given pdg from momentum variables and state FitParticle(double x, double y, double z, double t, int pdg, Int_t state); /// Create empty particle (zero momentum) FitParticle(){}; ~FitParticle(){}; /// Used to change values after creation void SetValues(double x, double y, double z, double t, int pdg, Int_t state); /// Return Status Code according to particle_state enum inline int Status (void) const { return fStatus; }; /// Get Particle PDF inline int PDG (void) const { return fPID; }; /// Check if particle makes it to final state inline bool IsFinalState (void) const { return (fStatus == kFinalState); }; /// Was particle involved in intermediate state inline bool IsFSIState (void) const { return (fStatus == kFSIState); }; /// Was particle incoming inline bool IsInitialState (void) const { return (fStatus == kInitialState); }; /// Get Mass inline double M (void){ return fP.Mag(); }; /// Get Kinetic Energy inline double KE (void){ return fP.E() - fP.Mag(); }; - /// Allows the removal of KE up to total KE. - inline void RemoveKE(double KE){ - double mass = M(); - double oKE = this->KE(); - double nE = mass + (oKE - KE); - if(nE < mass){ // Can't take more KE than it has - nE = mass; - } - double n3Mom = sqrt(nE*nE - mass*mass); - TVector3 np3 = P3().Unit()*n3Mom; - fP.SetXYZT(np3[0],np3[1],np3[2],nE); - } - -/// Allows the removal of KE up to total KE. - inline void GiveKE(double KE){ - RemoveKE(-KE); - } - /// Get Total Energy inline double E (void){ return fP.E(); }; /// Get 4 Momentum inline TLorentzVector P4(void) {return fP;}; /// Get 3 Momentum inline TVector3 P3(void) {return fP.Vect();}; /// Get 3 momentum magnitude inline double p(void) { return fP.Vect().Mag(); }; /// Get 3 momentum magnitude squared inline double p2(void) { return fP.Vect().Mag2(); }; /// Data Members TLorentzVector fP; ///< Particle 4 Momentum int fPID; ///< Particle PDG Code int fIsAlive; ///< Whether the particle is alive at the end of the event (Yes 1, No 0, Other? -1) int fNEUTStatusCode; ///< Particle Status (Incoming 1, FSI 2, Outgoing 0, Other 3) double fMass; ///< Particle Mass int fStatus; ///< State corresponding to particle_state enum }; inline std::ostream& operator<<(std::ostream& os, FitParticle const& p){ return os << " Particle[pdgc:" << p.fPID << ", stat:"<<p.fStatus << ", 4mom:("<< p.fP.X() << "," << p.fP.Y() << "," << p.fP.Z() << "," << p.fP.T() << ")]"; } /*! @} */ #endif diff --git a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx index 8fa021c..88d2530 100644 --- a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx +++ b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx @@ -1,252 +1,475 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "Smear_SVDUnfold_Propagation_Osc.h" #include "SmearceptanceUtils.h" #include "OscWeightEngine.h" //******************************************************************** Smear_SVDUnfold_Propagation_Osc::Smear_SVDUnfold_Propagation_Osc( nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "Simple measurement class for doing fake data oscillation studies.\n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("Osc Studies"); fSettings.SetDescription(descrip); fSettings.SetXTitle("XXX"); fSettings.SetYTitle("Number of events"); fSettings.SetEnuRange(0.0, 50); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.DefineAllowedTargets("*"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") / (fNEvents + 0.); // Plot Setup ------------------------------------------------------- // Check that we have the relevant histograms specified. if (!samplekey.Has("NDDataHist") || !samplekey.Has("FDDataHist") || !samplekey.Has("NDToSpectrumSmearingMatrix")) { THROW( "Expected to attributes named: NDDataHist, FDDataHist, " "NDToSpectrumSmearingMatrix on the Smear_SVDUnfold_Propagation_Osc " "sample " "tag."); } NDDataHist = NULL; FDDataHist = NULL; NDToSpectrumSmearingMatrix = NULL; fMCHist = NULL; fDataHist = NULL; std::vector<std::string> NDHistDescriptor = GeneralUtils::ParseToStr(samplekey.GetS("NDDataHist"), ","); if (NDHistDescriptor.size() == 2) { NDDataHist = PlotUtils::GetTH1DFromRootFile(NDHistDescriptor[0], NDHistDescriptor[1]); + ND_True_Spectrum_Hist = + PlotUtils::GetTH1DFromRootFile(NDHistDescriptor[0], "ELep_rate"); } if (!NDDataHist) { THROW("Attempted to load NDDataHist from the descriptor: \"" << samplekey.GetS("NDDataHist") << "\", but failed. Does it look correct? \"<ROOTFILE>,<HISTNAME>\""); } std::vector<std::string> FDHistDescriptor = GeneralUtils::ParseToStr(samplekey.GetS("FDDataHist"), ","); if (FDHistDescriptor.size() == 2) { FDDataHist = PlotUtils::GetTH1DFromRootFile(FDHistDescriptor[0], FDHistDescriptor[1]); + + FD_True_Spectrum_Hist = + PlotUtils::GetTH1DFromRootFile(FDHistDescriptor[0], "ELep_rate"); } if (!FDDataHist) { THROW("Attempted to load FDDataHist from the descriptor: \"" << samplekey.GetS("FDDataHist") << "\", but failed. Does it look correct? \"<ROOTFILE>,<HISTNAME>\""); } std::vector<std::string> NDToEvSmearingDescriptor = GeneralUtils::ParseToStr( samplekey.GetS("NDToSpectrumSmearingMatrix"), ","); if (NDToEvSmearingDescriptor.size() == 2) { NDToSpectrumSmearingMatrix = PlotUtils::GetTH2DFromRootFile( NDToEvSmearingDescriptor[0], NDToEvSmearingDescriptor[1]); } if (!NDToSpectrumSmearingMatrix) { THROW("Attempted to load NDToSpectrumSmearingMatrix from the descriptor: \"" << samplekey.GetS("NDToSpectrumSmearingMatrix") << "\", but failed. Does it look correct? \"<ROOTFILE>,<HISTNAME>\""); } TMatrixD NDToSpectrumResponseMatrix_l = SmearceptanceUtils::GetMatrix( SmearceptanceUtils::SVDGetInverse(NDToSpectrumSmearingMatrix)); NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; TMatrixD SpectrumToFDResponseMatrix_l = SmearceptanceUtils::GetMatrix(NDToSpectrumSmearingMatrix); SpectrumToFDResponseMatrix.ResizeTo(SpectrumToFDResponseMatrix_l); SpectrumToFDResponseMatrix = SpectrumToFDResponseMatrix_l; - fDataHist = FDDataHist; + fDataHist = static_cast<TH1D *>(FDDataHist->Clone()); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); SetCovarFromDiagonal(); TruncateUpTo = 0; if (samplekey.Has("TruncateUpTo")) { TruncateUpTo = samplekey.GetI("TruncateUpTo"); QLOG(SAM, "Allowed to truncate unfolding matrix by up to " << TruncateUpTo << " singular values to limit negative ENu spectra."); } + if (samplekey.Has("FitRegion_Min")) { + FitRegion_Min = samplekey.GetD("FitRegion_Min"); + } else { + FitRegion_Min = 0xdeadbeef; + } + if (samplekey.Has("FitRegion_Max")) { + FitRegion_Max = samplekey.GetD("FitRegion_Max"); + } else { + FitRegion_Max = 0xdeadbeef; + } + TruncateStart = 0; + if (Config::Get().GetConfigNode("smear.SVD.truncation")) { + TruncateStart = Config::Get().ConfI("smear.SVD.truncation"); + + TMatrixD NDToSpectrumResponseMatrix_l = + SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( + NDToSpectrumSmearingMatrix, TruncateStart)); + + NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); + NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; + } + + if (TruncateStart >= TruncateUpTo) { + TruncateUpTo = TruncateStart + 1; + } + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void Smear_SVDUnfold_Propagation_Osc::FillEventVariables(FitEvent *event){}; bool Smear_SVDUnfold_Propagation_Osc::isSignal(FitEvent *event) { return false; } +void Smear_SVDUnfold_Propagation_Osc::UnfoldToNDETrueSpectrum(void) { + ND_Unfolded_Spectrum_Hist = NDToSpectrumSmearingMatrix->ProjectionY(); + ND_Unfolded_Spectrum_Hist->Clear(); + + TRandom3 rnjesus; + + bool HasNegValue = false; + int truncations = TruncateStart; + do { + if (truncations >= TruncateUpTo) { + THROW("Unfolded enu spectrum had negative values even after " + << truncations << " SVD singular value truncations."); + } + + // Unfold ND ERec -> Enu spectrum + // ------------------------------ + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + NDDataHist, ND_Unfolded_Spectrum_Hist, NDToSpectrumResponseMatrix, 1000, + false); + + HasNegValue = false; + + for (Int_t bi_it = 1; + bi_it < ND_Unfolded_Spectrum_Hist->GetXaxis()->GetNbins() + 1; + ++bi_it) { + if ((FitRegion_Min != 0xdeadbeef) && + (ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinUpEdge(bi_it) <= + FitRegion_Min)) { + continue; + } + if ((FitRegion_Max != 0xdeadbeef) && + (ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinLowEdge(bi_it) > + FitRegion_Max)) { + continue; + } + + if (ND_Unfolded_Spectrum_Hist->GetBinContent(bi_it) < 0) { + HasNegValue = true; + break; + } + } + + if (HasNegValue) { + TMatrixD NDToSpectrumResponseMatrix_l = + SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( + NDToSpectrumSmearingMatrix, truncations)); + + NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); + NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; + } + + truncations++; + } while (HasNegValue); +} + void Smear_SVDUnfold_Propagation_Osc::ConvertEventRates(void) { + // Apply FD/ND weights + // ------------------------------ + OscHist->Write("ND_FD_Corrected_ENuTrue", TObject::kOverwrite); + + // Apply Oscillations + // ------------------------------ + FitWeight *fw = FitBase::GetRW(); + OscWeightEngine *oscWE = + dynamic_cast<OscWeightEngine *>(fw->GetRWEngine(kOSCILLATION)); + + if (!oscWE) { + THROW( + "Couldn't load oscillation weight engine for sample: " + "Smear_SVDUnfold_Propagation_Osc."); + } + + for (Int_t bi_it = 1; bi_it < OscHist->GetXaxis()->GetNbins() + 1; ++bi_it) { + double oscWeight = + oscWE->CalcWeight(OscHist->GetXaxis()->GetBinCenter(bi_it), 14); + OscHist->SetBinContent(bi_it, OscHist->GetBinContent(bi_it) * oscWeight); + } + OscHist->Write("ENuTrue_FD", TObject::kOverwrite); + + TGraph POsc; + + POsc.Set(1E4 - 1); + + double min = OscHist->GetXaxis()->GetBinLowEdge(1); + double step = + (OscHist->GetXaxis()->GetBinUpEdge(OscHist->GetXaxis()->GetNbins()) - + OscHist->GetXaxis()->GetBinLowEdge(1)) / + double(1E4); + + for (size_t i = 1; i < 1E4; ++i) { + double enu = min + i * step; + double ow = oscWE->CalcWeight(enu, 14); + if (ow != ow) { + std::cout << "Bad osc weight for ENu: " << enu << std::endl; + } + POsc.SetPoint(i - 1, enu, ow); + } + + POsc.Write("POsc", TObject::kOverwrite); + + // Forward fold Spectrum -> ERec FD + // ------------------------------ + if (fMCHist) { + fMCHist->SetDirectory(NULL); + delete fMCHist; + } + + fMCHist = static_cast<TH1D *>(FDDataHist->Clone()); + + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + OscHist, fMCHist, SpectrumToFDResponseMatrix, 1000, true); + + fMCHist->SetBinContent(0, 0); + fMCHist->SetBinError(0, 0); + fDataHist->SetBinContent(0, 0); + fDataHist->SetBinError(0, 0); + + fMCHist->SetBinContent(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fMCHist->SetBinError(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fDataHist->SetBinContent(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fDataHist->SetBinError(fMCHist->GetXaxis()->GetNbins() + 1, 0); + + for (Int_t bi_it = 1; bi_it < fMCHist->GetXaxis()->GetNbins() + 1; ++bi_it) { + if ((FitRegion_Min != 0xdeadbeef) && + (fMCHist->GetXaxis()->GetBinUpEdge(bi_it) <= FitRegion_Min)) { + fMCHist->SetBinContent(bi_it, 0); + fMCHist->SetBinError(bi_it, 0); + fDataHist->SetBinContent(bi_it, 0); + fDataHist->SetBinError(bi_it, 0); + } + if ((FitRegion_Max != 0xdeadbeef) && + (fMCHist->GetXaxis()->GetBinLowEdge(bi_it) > FitRegion_Max)) { + fMCHist->SetBinContent(bi_it, 0); + fMCHist->SetBinError(bi_it, 0); + fDataHist->SetBinContent(bi_it, 0); + fDataHist->SetBinError(bi_it, 0); + } + } +} + +void Smear_SVDUnfold_Propagation_Osc::Write(void) { + NDToSpectrumSmearingMatrix->Write("SmearingMatrix_ND", TObject::kOverwrite); + TH1D *OscHist = NDToSpectrumSmearingMatrix->ProjectionY(); OscHist->Clear(); TRandom3 rnjesus; NDDataHist->Write("ERec_ND", TObject::kOverwrite); bool HasNegValue = false; - int truncations = 0; + int truncations = TruncateStart; do { - if (truncations > TruncateUpTo) { + if (truncations >= TruncateUpTo) { THROW("Unfolded enu spectrum had negative values even after " << truncations << " SVD singular value truncations."); } // Unfold ND ERec -> Enu spectrum // ------------------------------ SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( NDDataHist, OscHist, NDToSpectrumResponseMatrix, 1000, false); std::stringstream ss(""); - ss << "Unfolded_ENuTrue_ND_trunc" << truncations; + ss << "Unfolded_ENuTrue_ND_trunc_" << truncations; OscHist->Write(ss.str().c_str(), TObject::kOverwrite); + ss.str(""); + ss << "Response_ND_trunc_" << truncations; + SmearceptanceUtils::SVDGetInverse(NDToSpectrumSmearingMatrix, truncations) + ->Write(ss.str().c_str(), TObject::kOverwrite); HasNegValue = false; for (Int_t bi_it = 1; bi_it < OscHist->GetXaxis()->GetNbins() + 1; ++bi_it) { + if ((FitRegion_Min != 0xdeadbeef) && + (OscHist->GetXaxis()->GetBinUpEdge(bi_it) <= FitRegion_Min)) { + continue; + } + if ((FitRegion_Max != 0xdeadbeef) && + (OscHist->GetXaxis()->GetBinLowEdge(bi_it) > FitRegion_Max)) { + continue; + } + if (OscHist->GetBinContent(bi_it) < 0) { HasNegValue = true; break; } } if (HasNegValue) { TMatrixD NDToSpectrumResponseMatrix_l = SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( NDToSpectrumSmearingMatrix, truncations)); NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; } truncations++; } while (HasNegValue); // Apply FD/ND weights // ------------------------------ OscHist->Write("ND_FD_Corrected_ENuTrue", TObject::kOverwrite); // Apply Oscillations // ------------------------------ FitWeight *fw = FitBase::GetRW(); OscWeightEngine *oscWE = dynamic_cast<OscWeightEngine *>(fw->GetRWEngine(kOSCILLATION)); if (!oscWE) { THROW( "Couldn't load oscillation weight engine for sample: " "Smear_SVDUnfold_Propagation_Osc."); } for (Int_t bi_it = 1; bi_it < OscHist->GetXaxis()->GetNbins() + 1; ++bi_it) { double oscWeight = oscWE->CalcWeight(OscHist->GetXaxis()->GetBinCenter(bi_it), 14); OscHist->SetBinContent(bi_it, OscHist->GetBinContent(bi_it) * oscWeight); } OscHist->Write("ENuTrue_FD", TObject::kOverwrite); TGraph POsc; POsc.Set(1E4 - 1); double min = OscHist->GetXaxis()->GetBinLowEdge(1); double step = (OscHist->GetXaxis()->GetBinUpEdge(OscHist->GetXaxis()->GetNbins()) - OscHist->GetXaxis()->GetBinLowEdge(1)) / double(1E4); for (size_t i = 1; i < 1E4; ++i) { double enu = min + i * step; double ow = oscWE->CalcWeight(enu, 14); if (ow != ow) { std::cout << "Bad osc weight for ENu: " << enu << std::endl; } POsc.SetPoint(i - 1, enu, ow); } POsc.Write("POsc", TObject::kOverwrite); - return; - // Forward fold Spectrum -> ERec FD // ------------------------------ if (fMCHist) { fMCHist->SetDirectory(NULL); delete fMCHist; } fMCHist = static_cast<TH1D *>(FDDataHist->Clone()); SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( - OscHist, fMCHist, SpectrumToFDResponseMatrix, 1000, false); + OscHist, fMCHist, SpectrumToFDResponseMatrix, 1000, true); + + NDToSpectrumSmearingMatrix->Write("SmearingMatrix_FD", TObject::kOverwrite); fMCHist->Write("ERec_FD_pred", TObject::kOverwrite); - FDDataHist->Write("ERec_FD_obs", TObject::kOverwrite); + fDataHist->Write("ERec_FD_obs", TObject::kOverwrite); + + fMCHist->SetBinContent(0, 0); + fMCHist->SetBinError(0, 0); + fDataHist->SetBinContent(0, 0); + fDataHist->SetBinError(0, 0); + + fMCHist->SetBinContent(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fMCHist->SetBinError(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fDataHist->SetBinContent(fMCHist->GetXaxis()->GetNbins() + 1, 0); + fDataHist->SetBinError(fMCHist->GetXaxis()->GetNbins() + 1, 0); + + for (Int_t bi_it = 1; bi_it < fMCHist->GetXaxis()->GetNbins() + 1; ++bi_it) { + if ((FitRegion_Min != 0xdeadbeef) && + (fMCHist->GetXaxis()->GetBinUpEdge(bi_it) <= FitRegion_Min)) { + fMCHist->SetBinContent(bi_it, 0); + fMCHist->SetBinError(bi_it, 0); + fDataHist->SetBinContent(bi_it, 0); + fDataHist->SetBinError(bi_it, 0); + } + if ((FitRegion_Max != 0xdeadbeef) && + (fMCHist->GetXaxis()->GetBinLowEdge(bi_it) > FitRegion_Max)) { + fMCHist->SetBinContent(bi_it, 0); + fMCHist->SetBinError(bi_it, 0); + fDataHist->SetBinContent(bi_it, 0); + fDataHist->SetBinError(bi_it, 0); + } + } + + fMCHist->Write("ERec_FD_pred_masked", TObject::kOverwrite); + fDataHist->Write("ERec_FD_obs_masked", TObject::kOverwrite); + + if (ND_True_Spectrum_Hist) { + ND_True_Spectrum_Hist->Write("ETrue_ND_Spectrum", TObject::kOverwrite); + } + if (FD_True_Spectrum_Hist) { + FD_True_Spectrum_Hist->Write("ETrue_FD_Spectrum", TObject::kOverwrite); + } } diff --git a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h index 0457968..db8f646 100644 --- a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h +++ b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h @@ -1,47 +1,57 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #ifndef Smear_SVDUnfold_Propagation_Osc_H_SEEN #define Smear_SVDUnfold_Propagation_Osc_H_SEEN #include "Measurement1D.h" class Smear_SVDUnfold_Propagation_Osc : public Measurement1D { public: Smear_SVDUnfold_Propagation_Osc(nuiskey samplekey); virtual ~Smear_SVDUnfold_Propagation_Osc(){}; void FillEventVariables(FitEvent *event); bool isSignal(FitEvent *event); void ConvertEventRates(void); TH1D *NDDataHist; TH1D *FDDataHist; + TH1D *ND_Unfolded_Spectrum_Hist; + TH1D *NDFD_Corrected_Spectrum_Hist; + TH1D *FD_Propagated_Spectrum_Hist; + + TH1D *ND_True_Spectrum_Hist; + TH1D *FD_True_Spectrum_Hist; + TH2D *NDToSpectrumSmearingMatrix; TMatrixD NDToSpectrumResponseMatrix; TMatrixD SpectrumToFDResponseMatrix; + Int_t TruncateStart; Int_t TruncateUpTo; + double FitRegion_Min; + double FitRegion_Max; }; #endif diff --git a/src/MCStudies/Smearceptance_Tester.cxx b/src/MCStudies/Smearceptance_Tester.cxx index 6110443..28f498b 100644 --- a/src/MCStudies/Smearceptance_Tester.cxx +++ b/src/MCStudies/Smearceptance_Tester.cxx @@ -1,690 +1,690 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "Smearceptance_Tester.h" #include "SmearceptanceUtils.h" #include "Smearcepterton.h" +#define DEBUG_SMEARTESTER + //******************************************************************** /// @brief Class to perform smearceptance MC Studies on a custom measurement Smearceptance_Tester::Smearceptance_Tester(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { //******************************************************************** // Measurement Details std::vector<std::string> splitName = GeneralUtils::ParseToStr(name, "_"); size_t firstUS = name.find_first_of("_"); std::string smearceptorName = name.substr(firstUS + 1); fName = name.substr(0, firstUS); eventVariables = NULL; // Define our energy range for flux calcs EnuMin = 0.; EnuMax = 100.; // Arbritrarily high energy limit // Set default fitter flags fIsDiag = true; fIsShape = false; fIsRawEvents = false; // This function will sort out the input files automatically and parse all the // inputs,flags,etc. // There may be complex cases where you have to do this by hand, but usually // this will do. Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); eventVariables = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1); this->SetupDefaultHist(); fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist); covar = StatUtils::GetInvert(fFullCovar); this->fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); LOG(SAM) << "Smearceptance Flux Scaling Factor = " << fScaleFactor << std::endl; if (fScaleFactor <= 0.0) { ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; sleep(20); } // Setup our TTrees this->AddEventVariablesToTree(); smearceptor = &Smearcepterton::Get().GetSmearcepter(smearceptorName); Int_t RecNBins = 20, TrueNBins = 20; double RecBinL = 0, TrueBinL = 0, RecBinH = 10, TrueBinH = 10; if (Config::Get().GetConfigNode("smear.reconstructed.binning")) { std::vector<std::string> args = GeneralUtils::ParseToStr( Config::Get().ConfS("smear.reconstructed.binning"), ","); RecNBins = GeneralUtils::StrToInt(args[0]); RecBinL = GeneralUtils::StrToDbl(args[1]); RecBinH = GeneralUtils::StrToDbl(args[2]); TrueNBins = RecNBins; TrueBinL = RecBinL; TrueBinH = RecBinH; } if (Config::Get().GetConfigNode("smear.true.binning")) { std::vector<std::string> args = GeneralUtils::ParseToStr( Config::Get().ConfS("smear.true.binning"), ","); TrueNBins = GeneralUtils::StrToInt(args[0]); TrueBinL = GeneralUtils::StrToDbl(args[1]); TrueBinH = GeneralUtils::StrToDbl(args[2]); } SVDTruncation = 0; if (Config::Get().GetConfigNode("smear.true.binning")) { SVDTruncation = Config::Get().ConfI("smear.SVD.truncation"); QLOG(SAM, "Applying SVD truncation of: " << SVDTruncation) } QLOG(SAM, "Using binning True: " << TrueNBins << ", [" << TrueBinL << " -- " << TrueBinH << "], Rec: " << RecNBins << ", [" << RecBinL << " -- " << RecBinH << "]"); ETrueDistrib = new TH1D("ELep_rate", ";True E_{#nu};Count", TrueNBins, TrueBinL, TrueBinH); ERecDistrib = new TH1D("ELepRec_rate", ";Rec E_{#nu};Count", RecNBins, RecBinL, RecBinH); ETrueDistrib->Sumw2(); ERecDistrib->Sumw2(); RecoSmear = - new TH2D("ELepHadVis_Recon", ";Recon. E_{#nu};True E_{#nu}", RecNBins, + new TH2D("ELepHadVis_Recon", ";True E_{#nu};Recon. E_{#nu}", RecNBins, RecBinL, RecBinH, TrueNBins, TrueBinL, TrueBinH); + RecoSmear->Sumw2(); } void Smearceptance_Tester::AddEventVariablesToTree() { // Setup the TTree to save everything if (!eventVariables) { FitPar::Config().out->cd(); eventVariables = new TTree((this->fName + "_VARS").c_str(), (this->fName + "_VARS").c_str()); } LOG(SAM) << "Adding Event Variables" << std::endl; eventVariables->Branch("Omega_true", &Omega_true, "Omega_true/F"); eventVariables->Branch("Q2_true", &Q2_true, "Q2_true/F"); eventVariables->Branch("Mode_true", &Mode_true, "Mode_true/I"); eventVariables->Branch("EISLep_true", &EISLep_true, "EISLep_true/F"); eventVariables->Branch("HMFS_mu_true", &HMFS_mu_true); eventVariables->Branch("HMFS_pip_true", &HMFS_pip_true); eventVariables->Branch("HMFS_pim_true", &HMFS_pim_true); eventVariables->Branch("HMFS_cpi_true", &HMFS_cpi_true); eventVariables->Branch("HMFS_p_true", &HMFS_p_true); eventVariables->Branch("KEFSHad_cpip_true", &KEFSHad_cpip_true, "KEFSHad_cpip_true/F"); eventVariables->Branch("KEFSHad_cpim_true", &KEFSHad_cpim_true, "KEFSHad_cpim_true/F"); eventVariables->Branch("KEFSHad_cpi_true", &KEFSHad_cpi_true, "KEFSHad_cpi_true/F"); eventVariables->Branch("TEFSHad_pi0_true", &TEFSHad_pi0_true, "TEFSHad_pi0_true/F"); eventVariables->Branch("KEFSHad_p_true", &KEFSHad_p_true, "KEFSHad_p_true/F"); eventVariables->Branch("KEFSHad_n_true", &KEFSHad_n_true, "KEFSHad_n_true/F"); eventVariables->Branch("EFSHad_true", &EFSHad_true, "EFSHad_true/F"); eventVariables->Branch("EFSChargedEMHad_true", &EFSChargedEMHad_true, "EFSChargedEMHad_true/F"); eventVariables->Branch("EFSLep_true", &EFSLep_true, "EFSLep_true/F"); eventVariables->Branch("EFSgamma_true", &EFSgamma_true, "EFSgamma_true/F"); eventVariables->Branch("PDGISLep_true", &PDGISLep_true, "PDGISLep_true/I"); eventVariables->Branch("PDGFSLep_true", &PDGFSLep_true, "PDGFSLep_true/I"); eventVariables->Branch("Nprotons_true", &Nprotons_true, "Nprotons_true/I"); eventVariables->Branch("Nneutrons_true", &Nneutrons_true, "Nneutrons_true/I"); eventVariables->Branch("Ncpiplus_true", &Ncpiplus_true, "Ncpiplus_true/I"); eventVariables->Branch("Ncpiminus_true", &Ncpiminus_true, "Ncpiminus_true/I"); eventVariables->Branch("Ncpi_true", &Ncpi_true, "Ncpi_true/I"); eventVariables->Branch("Npi0_true", &Npi0_true, "Npi0_true/I"); eventVariables->Branch("HMFS_mu_rec", &HMFS_mu_rec); eventVariables->Branch("HMFS_pip_rec", &HMFS_pip_rec); eventVariables->Branch("HMFS_pim_rec", &HMFS_pim_rec); eventVariables->Branch("HMFS_cpi_rec", &HMFS_cpi_rec); eventVariables->Branch("HMFS_p_rec", &HMFS_p_rec); eventVariables->Branch("KEFSHad_cpip_rec", &KEFSHad_cpip_rec, "KEFSHad_cpip_rec/F"); eventVariables->Branch("KEFSHad_cpim_rec", &KEFSHad_cpim_rec, "KEFSHad_cpim_rec/F"); eventVariables->Branch("KEFSHad_cpi_rec", &KEFSHad_cpi_rec, "KEFSHad_cpi_rec/F"); eventVariables->Branch("TEFSHad_pi0_rec", &TEFSHad_pi0_rec, "TEFSHad_pi0_rec/F"); eventVariables->Branch("KEFSHad_p_rec", &KEFSHad_p_rec, "KEFSHad_p_rec/F"); eventVariables->Branch("KEFSHad_n_rec", &KEFSHad_n_rec, "KEFSHad_n_rec/F"); eventVariables->Branch("EFSHad_rec", &EFSHad_rec, "EFSHad_rec/F"); eventVariables->Branch("EFSLep_rec", &EFSLep_rec, "EFSLep_rec/F"); eventVariables->Branch("EFSVis_cpip", &EFSVis_cpip, "EFSVis_cpip/F"); eventVariables->Branch("EFSVis_cpim", &EFSVis_cpim, "EFSVis_cpim/F"); eventVariables->Branch("EFSVis_cpi", &EFSVis_cpi, "EFSVis_cpi/F"); eventVariables->Branch("EFSVis_pi0", &EFSVis_pi0, "EFSVis_pi0/F"); eventVariables->Branch("EFSVis_p", &EFSVis_p, "EFSVis_p/F"); eventVariables->Branch("EFSVis_n", &EFSVis_n, "EFSVis_n/F"); eventVariables->Branch("EFSVis_gamma", &EFSVis_gamma, "EFSVis_gamma/F"); eventVariables->Branch("EFSVis_other", &EFSVis_other, "EFSVis_other/F"); eventVariables->Branch("EFSVis", &EFSVis, "EFSVis/F"); eventVariables->Branch("FSCLep_seen", &FSCLep_seen, "FSCLep_seen/I"); eventVariables->Branch("Nprotons_seen", &Nprotons_seen, "Nprotons_seen/I"); eventVariables->Branch("Nneutrons_seen", &Nneutrons_seen, "Nneutrons_seen/I"); eventVariables->Branch("Ncpip_seen", &Ncpip_seen, "Ncpip_seen/I"); eventVariables->Branch("Ncpim_seen", &Ncpim_seen, "Ncpim_seen/I"); eventVariables->Branch("Ncpi_seen", &Ncpi_seen, "Ncpi_seen/I"); eventVariables->Branch("Npi0_seen", &Npi0_seen, "Npi0_seen/I"); eventVariables->Branch("Nothers_seen", &Nothers_seen, "Nothers_seen/I"); eventVariables->Branch("EISLep_QE_rec", &EISLep_QE_rec, "EISLep_QE_rec/F"); eventVariables->Branch("EISLep_LepHad_rec", &EISLep_LepHad_rec, "EISLep_LepHad_rec/F"); eventVariables->Branch("EISLep_LepHadVis_rec", &EISLep_LepHadVis_rec, "EISLep_LepHadVis_rec/F"); eventVariables->Branch("Nprotons_contributed", &Nprotons_contributed, "Nprotons_contributed/I"); eventVariables->Branch("Nneutrons_contributed", &Nneutrons_contributed, "Nneutrons_contributed/I"); eventVariables->Branch("Ncpip_contributed", &Ncpip_contributed, "Ncpip_contributed/I"); eventVariables->Branch("Ncpim_contributed", &Ncpim_contributed, "Ncpim_contributed/I"); eventVariables->Branch("Ncpi_contributed", &Ncpi_contributed, "Ncpi_contributed/I"); eventVariables->Branch("Npi0_contributed", &Npi0_contributed, "Npi0_contributed/I"); eventVariables->Branch("Ngamma_contributed", &Ngamma_contributed, "Ngamma_contributed/I"); eventVariables->Branch("Nothers_contibuted", &Nothers_contibuted, "Nothers_contibuted/I"); eventVariables->Branch("Weight", &Weight, "Weight/F"); eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F"); eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F"); eventVariables->Branch("FluxWeight", &FluxWeight, "FluxWeight/F"); eventVariables->Branch("EffWeight", &EffWeight, "EffWeight/F"); eventVariables->Branch("xsecScaling", &xsecScaling, "xsecScaling/F"); eventVariables->Branch("flagCCINC_true", &flagCCINC_true, "flagCCINC_true/O"); eventVariables->Branch("flagCC0Pi_true", &flagCC0Pi_true, "flagCC0Pi_true/O"); eventVariables->Branch("flagCCINC_rec", &flagCCINC_rec, "flagCCINC_rec/O"); eventVariables->Branch("flagCC0Pi_rec", &flagCC0Pi_rec, "flagCC0Pi_rec/O"); } template <size_t N> int CountNPdgsSeen(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += std::count(ri.RecObjClass.begin(), ri.RecObjClass.end(), pdgs[pdg_it]); } return sum; } template <size_t N> int CountNNotPdgsSeen(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += (std::count(ri.RecObjClass.begin(), ri.RecObjClass.end(), pdgs[pdg_it]) ? 0 : 1); } return sum; } template <size_t N> int CountNPdgsContributed(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += std::count(ri.TrueContribPDGs.begin(), ri.TrueContribPDGs.end(), pdgs[pdg_it]); } return sum; } template <size_t N> int CountNNotPdgsContributed(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += (std::count(ri.TrueContribPDGs.begin(), ri.TrueContribPDGs.end(), pdgs[pdg_it]) ? 0 : 1); } return sum; } TLorentzVector GetHMFSRecParticles(RecoInfo ri, int pdg) { TLorentzVector mom(0, 0, 0, 0); for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if ((ri.RecObjClass[p_it] == pdg) && (mom.Mag() < ri.RecObjMom[p_it].Mag())) { mom.SetXYZM(ri.RecObjMom[p_it].X(), ri.RecObjMom[p_it].Y(), ri.RecObjMom[p_it].Z(), PhysConst::GetMass(ri.RecObjClass[p_it]) * 1.0E3); } } return mom; } template <size_t N> double SumKE_RecoInfo(RecoInfo ri, int const (&pdgs)[N], double mass) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.RecObjClass[p_it])) { // If we don't care about this // particle type. continue; } sum += sqrt(ri.RecObjMom[p_it].Mag2() + mass * mass) - mass; } return sum; } template <size_t N> double SumTE_RecoInfo(RecoInfo ri, int const (&pdgs)[N], double mass) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.RecObjClass[p_it])) { // If we don't care about this // particle type. continue; } sum += sqrt(ri.RecObjMom[p_it].Mag2() + mass * mass); } return sum; } template <size_t N> double SumVisE_RecoInfo(RecoInfo ri, int const (&pdgs)[N]) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecVisibleEnergy.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.TrueContribPDGs[p_it])) { // If we don't care about this // particle type. continue; } sum += ri.RecVisibleEnergy[p_it]; } return sum; } template <size_t N> double SumVisE_RecoInfo_NotPdgs(RecoInfo ri, int const (&pdgs)[N]) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecVisibleEnergy.size(); ++p_it) { if (std::count(pdgs, pdgs + N, ri.TrueContribPDGs[p_it])) { // If we know about this // particle type. continue; } sum += ri.RecVisibleEnergy[p_it]; } return sum; } //******************************************************************** void Smearceptance_Tester::FillEventVariables(FitEvent *event) { //******************************************************************** static int const cpipPDG[] = {211}; static int const cpimPDG[] = {-211}; static int const pi0PDG[] = {111}; static int const ProtonPDG[] = {2212}; static int const NeutronPDG[] = {2112}; static int const GammaPDG[] = {22}; static int const CLeptonPDGs[] = {11, 13, 15}; - static int const ExplicitPDGs[] = {211, -211, 11, 2212, 2112, 22, - 11, 13, 15, 12, 14, 16}; + static int const ExplicitPDGs[] = {211, -211, 111, 2212, 2112, 22, + 11, 13, 15, 12, 14, 16}; RecoInfo *ri = smearceptor->Smearcept(event); HMFS_mu_true = TLorentzVector(0, 0, 0, 0); HMFS_mu_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsMu = event->GetHMFSMuon(); if (fsMu) { HMFS_mu_true = fsMu->P4(); HMFS_mu_rec = GetHMFSRecParticles(*ri, 13); } HMFS_pip_true = TLorentzVector(0, 0, 0, 0); HMFS_pip_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsPip = event->GetHMFSPiPlus(); if (fsPip) { HMFS_pip_true = fsPip->P4(); HMFS_pip_rec = GetHMFSRecParticles(*ri, 211); } HMFS_pim_true = TLorentzVector(0, 0, 0, 0); HMFS_pim_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsPim = event->GetHMFSPiMinus(); if (fsPim) { HMFS_pim_true = fsPim->P4(); HMFS_pim_rec = GetHMFSRecParticles(*ri, -211); } HMFS_cpi_true = TLorentzVector(0, 0, 0, 0); HMFS_cpi_rec = TLorentzVector(0, 0, 0, 0); if (fsPip || fsPim) { if (!fsPip) { HMFS_cpi_true = HMFS_pim_true; HMFS_cpi_rec = HMFS_pim_rec; } else if (!fsPim) { HMFS_cpi_true = HMFS_pip_true; HMFS_cpi_rec = HMFS_pip_rec; } else { HMFS_cpi_true = (fsPip->p2() > fsPim->p2()) ? HMFS_pip_true : HMFS_pim_true; HMFS_cpi_rec = (fsPip->p2() > fsPim->p2()) ? HMFS_pip_rec : HMFS_pim_rec; } } HMFS_p_true = TLorentzVector(0, 0, 0, 0); HMFS_p_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsP = event->GetHMFSProton(); if (fsP) { HMFS_p_true = fsP->P4(); HMFS_p_rec = GetHMFSRecParticles(*ri, 2212); } TLorentzVector FourMomentumTransfer = (event->GetHMISAnyLeptons()->P4() - event->GetHMFSAnyLeptons()->P4()); Omega_true = FourMomentumTransfer.E(); Q2_true = -1 * FourMomentumTransfer.Mag2(); Mode_true = event->Mode; EISLep_true = event->GetHMISAnyLeptons()->E(); KEFSHad_cpip_true = FitUtils::SumTE_PartVect(event->GetAllFSPiPlus()); KEFSHad_cpim_true = FitUtils::SumTE_PartVect(event->GetAllFSPiMinus()); KEFSHad_cpi_true = KEFSHad_cpip_true + KEFSHad_cpim_true; TEFSHad_pi0_true = FitUtils::SumTE_PartVect(event->GetAllFSPiZero()); KEFSHad_p_true = FitUtils::SumKE_PartVect(event->GetAllFSProton()); KEFSHad_n_true = FitUtils::SumKE_PartVect(event->GetAllFSNeutron()); EFSHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true + KEFSHad_n_true; EFSChargedEMHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true; EFSLep_true = event->GetHMFSAnyLeptons()->E(); EFSgamma_true = FitUtils::SumTE_PartVect(event->GetAllFSPhoton()); PDGISLep_true = event->GetHMISAnyLeptons()->PDG(); PDGFSLep_true = event->GetHMFSAnyLeptons()->PDG(); Nprotons_true = event->GetAllFSProton().size(); Nneutrons_true = event->GetAllFSNeutron().size(); Ncpiplus_true = event->GetAllFSPiPlus().size(); Ncpiminus_true = event->GetAllFSPiMinus().size(); Ncpi_true = Ncpiplus_true + Ncpiminus_true; Npi0_true = event->GetAllFSPiZero().size(); KEFSHad_cpip_rec = SumKE_RecoInfo(*ri, cpipPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpim_rec = SumKE_RecoInfo(*ri, cpimPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpi_rec = KEFSHad_cpip_rec + KEFSHad_cpim_rec; TEFSHad_pi0_rec = SumTE_RecoInfo(*ri, pi0PDG, PhysConst::mass_pi0 * PhysConst::mass_MeV); KEFSHad_p_rec = SumKE_RecoInfo(*ri, ProtonPDG, PhysConst::mass_proton * PhysConst::mass_MeV); KEFSHad_n_rec = SumKE_RecoInfo(*ri, NeutronPDG, PhysConst::mass_neutron * PhysConst::mass_MeV); EFSHad_rec = KEFSHad_cpi_rec + TEFSHad_pi0_rec + KEFSHad_p_rec + KEFSHad_n_rec; TLorentzVector FSLepMom_rec(0, 0, 0, 0); if (event->GetHMFSAnyLeptons()) { FSLepMom_rec = GetHMFSRecParticles(*ri, event->GetHMFSAnyLeptons()->PDG()); EFSLep_rec = FSLepMom_rec.E(); } else { EFSLep_rec = 0; } EFSVis_cpip = SumVisE_RecoInfo(*ri, cpipPDG); EFSVis_cpim = SumVisE_RecoInfo(*ri, cpimPDG); EFSVis_cpi = EFSVis_cpip + EFSVis_cpim; EFSVis_pi0 = SumVisE_RecoInfo(*ri, pi0PDG); EFSVis_p = SumVisE_RecoInfo(*ri, ProtonPDG); EFSVis_n = SumVisE_RecoInfo(*ri, NeutronPDG); EFSVis_gamma = SumVisE_RecoInfo(*ri, GammaPDG); EFSVis_other = SumVisE_RecoInfo_NotPdgs(*ri, ExplicitPDGs); - EFSVis = EFSVis_cpip + EFSVis_cpim + EFSVis_cpi + EFSVis_pi0 + EFSVis_p + - EFSVis_n + EFSVis_gamma; + EFSVis = EFSVis_cpi + EFSVis_pi0 + EFSVis_p + EFSVis_n + EFSVis_gamma; FSCLep_seen = CountNPdgsSeen(*ri, CLeptonPDGs); Nprotons_seen = CountNPdgsSeen(*ri, ProtonPDG); Nneutrons_seen = CountNPdgsSeen(*ri, NeutronPDG); Ncpip_seen = CountNPdgsSeen(*ri, cpipPDG); Ncpim_seen = CountNPdgsSeen(*ri, cpimPDG); Ncpi_seen = Ncpip_seen + Ncpim_seen; Npi0_seen = CountNPdgsSeen(*ri, pi0PDG); Nothers_seen = CountNNotPdgsSeen(*ri, ExplicitPDGs); if (FSCLep_seen && (FSLepMom_rec.Mag() > 1E-8)) { EISLep_QE_rec = FitUtils::EnuQErec(FSLepMom_rec.Mag() / 1000.0, FSLepMom_rec.CosTheta(), 34, PDGFSLep_true > 0) * 1000.0; } else { EISLep_QE_rec = 0; } EISLep_LepHad_rec = EFSLep_rec + EFSHad_rec; EISLep_LepHadVis_rec = EFSLep_rec + EFSHad_rec + EFSVis; Nprotons_contributed = CountNPdgsContributed(*ri, ProtonPDG); Nneutrons_contributed = CountNPdgsContributed(*ri, NeutronPDG); Ncpip_contributed = CountNPdgsContributed(*ri, cpipPDG); Ncpim_contributed = CountNPdgsContributed(*ri, cpimPDG); Ncpi_contributed = Ncpip_contributed + Ncpim_contributed; Npi0_contributed = CountNPdgsContributed(*ri, pi0PDG); Ngamma_contributed = CountNPdgsContributed(*ri, GammaPDG); Nothers_contibuted = CountNNotPdgsContributed(*ri, ExplicitPDGs); Weight = event->RWWeight * event->InputWeight; RWWeight = event->RWWeight; InputWeight = event->InputWeight; FluxWeight = GetFluxHistogram()->GetBinContent( GetFluxHistogram()->FindBin(EISLep_true)) / GetFluxHistogram()->Integral(); EffWeight = ri->Weight; xsecScaling = fScaleFactor; flagCCINC_true = PDGFSLep_true & 1; flagCC0Pi_true = (Ncpi_true + Npi0_true) == 0; flagCCINC_rec = FSCLep_seen && PDGFSLep_true & 1; flagCC0Pi_rec = ((Ncpi_seen + Npi0_seen) == 0) && flagCCINC_rec; // Fill the eventVariables Tree eventVariables->Fill(); - RecoSmear->Fill(flagCCINC_rec ? EISLep_LepHadVis_rec / 1000.0 : -1, - EISLep_true / 1000.0, Weight); + RecoSmear->Fill(EISLep_true / 1000.0, + flagCCINC_rec ? EISLep_LepHadVis_rec / 1000.0 : -1, Weight); ETrueDistrib->Fill(EISLep_true / 1000.0, flagCCINC_true ? Weight : 0); ERecDistrib->Fill(EISLep_LepHadVis_rec / 1000.0, flagCCINC_rec ? Weight : 0); return; }; //******************************************************************** void Smearceptance_Tester::Write(std::string drawOpt) { //******************************************************************** // First save the TTree eventVariables->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write(); GetInput()->GetEventHistogram()->Write(); TH2D *SmearMatrix_ev = static_cast<TH2D *>(RecoSmear->Clone("ELepHadVis_Smear_ev")); for (Int_t trueAxis_it = 1; - trueAxis_it < RecoSmear->GetYaxis()->GetNbins() + 1; ++trueAxis_it) { + trueAxis_it < RecoSmear->GetXaxis()->GetNbins() + 1; ++trueAxis_it) { double NEISLep = ETrueDistrib->GetBinContent(trueAxis_it); for (Int_t recoAxis_it = 1; - recoAxis_it < RecoSmear->GetXaxis()->GetNbins() + 1; ++recoAxis_it) { + recoAxis_it < RecoSmear->GetYaxis()->GetNbins() + 1; ++recoAxis_it) { if (NEISLep > std::numeric_limits<double>::epsilon()) { SmearMatrix_ev->SetBinContent( - recoAxis_it, trueAxis_it, - SmearMatrix_ev->GetBinContent(recoAxis_it, trueAxis_it) / NEISLep); + trueAxis_it, recoAxis_it, + SmearMatrix_ev->GetBinContent(trueAxis_it, recoAxis_it) / NEISLep); } } } ETrueDistrib->Write(); ERecDistrib->Write(); RecoSmear->Write(); SmearMatrix_ev->Write(); TH2D *ResponseMatrix_ev = SmearceptanceUtils::SVDGetInverse(SmearMatrix_ev, SVDTruncation); - ResponseMatrix_ev = SmearceptanceUtils::SwapXYTH2D(ResponseMatrix_ev); ResponseMatrix_ev->SetName("ResponseMatrix_ev"); ResponseMatrix_ev->Write(); #ifdef DEBUG_SMEARTESTER - TMatrixD SmearMatrix_ev_md = SmearceptanceUtils::GetMatrix( - SmearceptanceUtils::SwapXYTH2D(SmearMatrix_ev)); + TMatrixD SmearMatrix_ev_md = SmearceptanceUtils::GetMatrix(SmearMatrix_ev); TH1D *SmearedEvt = static_cast<TH1D *>(ERecDistrib->Clone()); SmearedEvt->SetNameTitle("SmearedEvt", ";Rec E_{#nu}; count"); SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( ETrueDistrib, SmearedEvt, SmearMatrix_ev_md, 5000, false); SmearedEvt->Write(); SmearedEvt->Scale(1, "width"); SmearedEvt->SetName("SmearedEvt_bw"); SmearedEvt->Write(); #endif TMatrixD ResponseMatrix_evt_md = SmearceptanceUtils::GetMatrix(ResponseMatrix_ev); TH1D *Unfolded_enu_obs = static_cast<TH1D *>(ETrueDistrib->Clone()); Unfolded_enu_obs->SetNameTitle("UnfoldedENu_evt", ";True E_{#nu};count"); SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( ERecDistrib, Unfolded_enu_obs, ResponseMatrix_evt_md, 5000, false); Unfolded_enu_obs->Write(); Unfolded_enu_obs->Scale(1, "width"); Unfolded_enu_obs->SetName("UnfoldedENu_evt_bw"); Unfolded_enu_obs->Write(); ETrueDistrib->Scale(1, "width"); ETrueDistrib->SetName("ELep_rate_bw"); ETrueDistrib->Write(); ERecDistrib->Scale(1, "width"); ERecDistrib->SetName("ELepRec_rate_bw"); ERecDistrib->Write(); } // ------------------------------------------------------------------- // Purely MC Plot // Following functions are just overrides to handle this // ------------------------------------------------------------------- //******************************************************************** /// Everything is classed as signal... bool Smearceptance_Tester::isSignal(FitEvent *event) { //******************************************************************** (void)event; return true; }; //******************************************************************** void Smearceptance_Tester::ScaleEvents() { //******************************************************************** // Saving everything to a TTree so no scaling required return; } //******************************************************************** void Smearceptance_Tester::ApplyNormScale(float norm) { //******************************************************************** // Saving everything to a TTree so no scaling required this->fCurrentNorm = norm; return; } //******************************************************************** void Smearceptance_Tester::FillHistograms() { //******************************************************************** // No Histograms need filling........ return; } //******************************************************************** void Smearceptance_Tester::ResetAll() { //******************************************************************** eventVariables->Reset(); return; } //******************************************************************** float Smearceptance_Tester::GetChi2() { //******************************************************************** // No Likelihood to test, purely MC return 0.0; } diff --git a/src/Smearceptance/EfficiencyApplicator.cxx b/src/Smearceptance/EfficiencyApplicator.cxx index b046cb5..55ab9b3 100644 --- a/src/Smearceptance/EfficiencyApplicator.cxx +++ b/src/Smearceptance/EfficiencyApplicator.cxx @@ -1,388 +1,388 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "EfficiencyApplicator.h" #include "TEfficiency.h" #include "TH2.h" #include "TH3.h" //#define DEBUG_EFFAPP EfficiencyApplicator::DependVar GetVarType(std::string const &axisvar) { if (axisvar == "kMomentum") { return EfficiencyApplicator::kMomentum; } else if (axisvar == "kKE") { return EfficiencyApplicator::kKE; } else if (axisvar == "kTheta") { return EfficiencyApplicator::kTheta; } else if (axisvar == "kCosTheta") { return EfficiencyApplicator::kCosTheta; } else if (axisvar == "kPhi") { return EfficiencyApplicator::kPhi; } return EfficiencyApplicator::kNoAxis; } TH1 *GetEffHist(TFile *inputFile, std::string const &HistName) { TH1 *hist = dynamic_cast<TH1 *>(inputFile->Get(HistName.c_str())); if (hist) { return hist; } TEfficiency *effHist = dynamic_cast<TEfficiency *>(inputFile->Get(HistName.c_str())); if (effHist) { TH1D *numer = dynamic_cast<TH1D *>(effHist->GetCopyPassedHisto()); TH1D *denom = dynamic_cast<TH1D *>(effHist->GetCopyTotalHisto()); if (numer && denom) { numer->Divide(denom); denom->SetDirectory(NULL); delete denom; // Gonna be a memory leak, but I'll get over it numer->SetDirectory(NULL); return numer; } ERROR(FTL, "TEfficiency internal histograms were not TH1Ds."); } THROW("Couldn't get appropriate efficiency object named " << HistName << " from input file " << inputFile->GetName()); } /// Reads particle efficiency nodes /// /// Nodes look like: /// <EfficiencyApplicator Name="D00N_ND_LAr"> /// <EfficiencyCurve PDG="211,-211" InputFile="effs.root" /// HistName="cpion_eff_mom_ctheta" NDims="2" XAxis="kMomentum" /// YAxis="kCosTheta" Interpolate="false" /> /// <!-- Can also contain ThresholdAccepter elements as below--> /// <RecoThreshold PDG="2212" RecoThresholdAbsCosTheta_Min="0" /> /// <VisThreshold PDG="2212" VisThresholdKE_MeV="10" Contrib="K" /> /// </EfficiencyApplicator> void EfficiencyApplicator::SpecifcSetup(nuiskey &nk) { rand.~TRandom3(); new (&rand) TRandom3(); std::vector<nuiskey> effDescriptors = nk.GetListOfChildNodes("EfficiencyCurve"); for (size_t t_it = 0; t_it < effDescriptors.size(); ++t_it) { std::string inputFileName = effDescriptors[t_it].GetS("InputFile"); std::string HistName = effDescriptors[t_it].GetS("HistName"); TFile inputFile(inputFileName.c_str()); if (!inputFile.IsOpen()) { THROW("Couldn't open specified input root file: " << inputFileName); } TH1 *inpHist = GetEffHist(&inputFile, HistName); if (!inpHist) { THROW("Couldn't get TH1D named: " << HistName << " from input root file: " << inputFileName); } int NDims = effDescriptors[t_it].GetI("NDims"); if (NDims < 1 || NDims > 3) { THROW("Read NDims attribute as: " << NDims << ", efficiency curve can " "currently have between 1 " "and 3 dimensions."); } EfficiencyApplicator::DependVar XVar = GetVarType(effDescriptors[t_it].GetS("XAxis")); double XAxisScale = effDescriptors[t_it].Has("XAxisScaleToInternal") ? effDescriptors[t_it].GetD("XAxisScaleToInternal") : 1; EfficiencyApplicator::DependVar YVar = NDims > 1 ? GetVarType(effDescriptors[t_it].GetS("YAxis")) : EfficiencyApplicator::kNoAxis; double YAxisScale = effDescriptors[t_it].Has("YAxisScaleToInternal") ? effDescriptors[t_it].GetD("YAxisScaleToInternal") : 1; EfficiencyApplicator::DependVar ZVar = NDims > 2 ? GetVarType(effDescriptors[t_it].GetS("ZAxis")) : EfficiencyApplicator::kNoAxis; double ZAxisScale = effDescriptors[t_it].Has("ZAxisScaleToInternal") ? effDescriptors[t_it].GetD("ZAxisScaleToInternal") : 1; bool Interpolate = effDescriptors[t_it].Has("Interpolate") && effDescriptors[t_it].GetI("Interpolate"); // bool ApplyAsWeight = effDescriptors[t_it].Has("ApplyAsWeight") && // effDescriptors[t_it].GetI("ApplyAsWeight"); std::string pdgs_s = effDescriptors[t_it].GetS("PDG"); std::vector<int> pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { if (Efficiencies.count(pdgs_i[pdg_it])) { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " already has a efficiency for PDG: " << pdgs_i[pdg_it]); } EffMap em; em.EffCurve = static_cast<TH1 *>(inpHist->Clone()); em.EffCurve->SetDirectory(NULL); em.Interpolate = Interpolate; // em.ApplyAsWeight = ApplyAsWeight; em.NDims = NDims; em.DependVars[0] = XVar; em.DependVars[1] = YVar; em.DependVars[2] = ZVar; em.AxisScales[0] = XAxisScale; em.AxisScales[1] = YAxisScale; em.AxisScales[2] = ZAxisScale; Efficiencies[pdgs_i[pdg_it]] = em; - QLOG(SAM, + QLOG(FIT, "Added reconstruction efficiency curve for PDG: " << pdgs_i[pdg_it]); } } SlaveTA.Setup(nk); } RecoInfo *EfficiencyApplicator::Smearcept(FitEvent *fe) { RecoInfo *ri = new RecoInfo(); for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { FitParticle *fp = fe->GetParticle(p_it); #ifdef DEBUG_EFFAPP std::cout << std::endl; std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() << ", " << fp->E() << " -- KE:" << fp->KE() << " Mom: " << fp->P3().Mag() << std::flush; #endif if (fp->Status() != kFinalState) { #ifdef DEBUG_EFFAPP std::cout << " -- Not final state." << std::flush; #endif continue; } if (!Efficiencies.count(fp->PDG())) { SlaveTA.SmearceptOneParticle(ri, fp #ifdef DEBUG_THRESACCEPT , p_it #endif ); continue; } EffMap &em = Efficiencies[fp->PDG()]; double kineProps[3]; for (Int_t dim_it = 0; dim_it < em.NDims; ++dim_it) { switch (em.DependVars[dim_it]) { case kMomentum: { kineProps[dim_it] = fp->P3().Mag(); break; } case kKE: { kineProps[dim_it] = fp->KE(); break; } case kTheta: { kineProps[dim_it] = fp->P3().Theta(); break; } case kCosTheta: { kineProps[dim_it] = fp->P3().CosTheta(); break; } case kPhi: { kineProps[dim_it] = fp->P3().Phi(); break; } default: { THROW("Trying to find particle value for a kNoAxis."); } } kineProps[dim_it] /= em.AxisScales[dim_it]; } double effProb = 0; switch (em.NDims) { case 1: { TH1 *hist = em.EffCurve; if (em.Interpolate && (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > kineProps[0])) { effProb = hist->Interpolate(kineProps[0]); } else { Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { ERROR(WRN, "Tried to apply effiency but XBin: " << xbin << " is outside range (/" << hist->GetXaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetXaxis()->GetBinLowEdge(1) << " -- " << hist->GetXaxis()->GetBinUpEdge( hist->GetXaxis()->GetNbins())); } effProb = hist->GetBinContent(xbin); } break; } case 2: { TH2 *hist = static_cast<TH2 *>(em.EffCurve); if (em.Interpolate && (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > kineProps[0]) && (hist->GetYaxis()->GetBinCenter(1) < kineProps[1]) && (hist->GetYaxis()->GetBinCenter(hist->GetYaxis()->GetNbins()) > kineProps[1])) { effProb = hist->Interpolate(kineProps[0], kineProps[1]); } else { Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); Int_t ybin = hist->GetYaxis()->FindFixBin(kineProps[1]); if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { ERROR(WRN, "Tried to apply effiency but XBin: " << xbin << " is outside range (/" << hist->GetXaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetXaxis()->GetBinLowEdge(1) << " -- " << hist->GetXaxis()->GetBinUpEdge( hist->GetXaxis()->GetNbins())); } if (!ybin || ((hist->GetYaxis()->GetNbins() + 1) == ybin)) { ERROR(WRN, "Tried to apply effiency but XBin: " << ybin << " is outside range (/" << hist->GetYaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetYaxis()->GetBinLowEdge(1) << " -- " << hist->GetYaxis()->GetBinUpEdge( hist->GetYaxis()->GetNbins())); } effProb = hist->GetBinContent(xbin, ybin); #ifdef DEBUG_EFFAPP std::cout << "\t\t: XProp: " << kineProps[0] << ", YProp: " << kineProps[1] << " x/y bins: " << xbin << "/" << ybin << ". Prop ? " << effProb << std::endl; #endif } break; } case 3: { TH3 *hist = static_cast<TH3 *>(em.EffCurve); if (em.Interpolate && (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > kineProps[0]) && (hist->GetYaxis()->GetBinCenter(1) < kineProps[1]) && (hist->GetYaxis()->GetBinCenter(hist->GetYaxis()->GetNbins()) > kineProps[2]) && (hist->GetZaxis()->GetBinCenter(hist->GetZaxis()->GetNbins()) > kineProps[2])) { effProb = hist->Interpolate(kineProps[0], kineProps[1], kineProps[2]); } else { Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); Int_t ybin = hist->GetYaxis()->FindFixBin(kineProps[1]); Int_t zbin = hist->GetZaxis()->FindFixBin(kineProps[2]); if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { ERROR(WRN, "Tried to apply effiency but XBin: " << xbin << " is outside range (/" << hist->GetXaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetXaxis()->GetBinLowEdge(1) << " -- " << hist->GetXaxis()->GetBinUpEdge( hist->GetXaxis()->GetNbins())); } if (!ybin || ((hist->GetYaxis()->GetNbins() + 1) == ybin)) { ERROR(WRN, "Tried to apply effiency but XBin: " << ybin << " is outside range (/" << hist->GetYaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetYaxis()->GetBinLowEdge(1) << " -- " << hist->GetYaxis()->GetBinUpEdge( hist->GetYaxis()->GetNbins())); } if (!zbin || ((hist->GetZaxis()->GetNbins() + 1) == zbin)) { ERROR(WRN, "Tried to apply effiency but ZBin: " << zbin << " is outside range (/" << hist->GetZaxis()->GetNbins() << "): Prop " << kineProps[0] << ", [" << hist->GetZaxis()->GetBinLowEdge(1) << " -- " << hist->GetZaxis()->GetBinUpEdge( hist->GetZaxis()->GetNbins())); } effProb = hist->GetBinContent(xbin, ybin, zbin); } break; } } bool accepted = (rand.Uniform() < effProb); if (accepted) { #ifdef DEBUG_EFFAPP std::cout << " -- Reconstructed with probability: " << effProb << std::flush; #endif ri->RecObjMom.push_back(fp->P3()); ri->RecObjClass.push_back(fp->PDG()); continue; } #ifdef DEBUG_EFFAPP std::cout << " -- Rejected with probability: " << effProb << std::flush; #endif SlaveTA.SmearceptOneParticle(ri, fp #ifdef DEBUG_THRESACCEPT , p_it #endif ); } #ifdef DEBUG_EFFAPP std::cout << std::endl; #endif #ifdef DEBUG_EFFAPP std::cout << "Reconstructed " << ri->RecObjMom.size() << " particles. " << std::endl; #endif return ri; } diff --git a/src/Smearceptance/EnergyShuffler.cxx b/src/Smearceptance/EnergyShuffler.cxx index 4fc0977..a4dc6b2 100644 --- a/src/Smearceptance/EnergyShuffler.cxx +++ b/src/Smearceptance/EnergyShuffler.cxx @@ -1,155 +1,157 @@ #include "EnergyShuffler.h" /// Node looks like /// <EnergyShuffler> /// <Shuffler From="2212" To="2112" Fraction="0.2" /> /// <Shuffler From="211,-211" To="" Fraction="0.5" /> /// </EnergyShuffler> void EnergyShuffler::Setup(nuiskey &nk) { std::vector<nuiskey> shuffleDescriptors = nk.GetListOfChildNodes("Shuffler"); for (size_t t_it = 0; t_it < shuffleDescriptors.size(); ++t_it) { if (!shuffleDescriptors[t_it].Has("From") || !shuffleDescriptors[t_it].Has("Fraction")) { THROW( "Shuffler element must have at least the From and Fraction " "attributes."); } std::string from_pdgs_s = shuffleDescriptors[t_it].GetS("From"); std::vector<int> from_pdgs_i = GeneralUtils::ParseToInt(from_pdgs_s, ","); if (!from_pdgs_i.size()) { THROW("Shuffler element must have at least one From PDG specified."); } std::vector<int> to_pdgs_i; if (shuffleDescriptors[t_it].Has("To")) { std::string to_pdgs_s = shuffleDescriptors[t_it].GetS("To"); to_pdgs_i = GeneralUtils::ParseToInt(to_pdgs_s, ","); } double Fraction = shuffleDescriptors[t_it].GetD("Fraction"); for (size_t f_it = 0; f_it < from_pdgs_i.size(); ++f_it) { ShuffleDescriptor sd; sd.ToPDGs = to_pdgs_i; sd.EFraction = Fraction; ShufflersDescriptors.push_back(std::make_pair(from_pdgs_i[f_it], sd)); QLOG(FIT, "\tAdded EnergyShuffler from " << from_pdgs_i[f_it] << " to " << to_pdgs_i.size() << " particle species at " << sd.EFraction << " KE fraction.") } } } void EnergyShuffler::DoTheShuffle(FitEvent *fe) { std::map<Int_t, double> TakenEnergy; std::map<Int_t, Int_t> NumParticlesToShare; // For each particle. // If in a from: take energy and add it to a sum. // Count particles of each species. for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { FitParticle *fp = fe->GetParticle(p_it); if (fp->Status() != kFinalState) { continue; } int PDG = fp->PDG(); for (size_t sh_it = 0; sh_it < ShufflersDescriptors.size(); ++sh_it) { ShuffleDescriptor &sd = ShufflersDescriptors[sh_it].second; if (std::find(sd.ToPDGs.begin(), sd.ToPDGs.end(), PDG) != sd.ToPDGs.end()) { // If this is a particle // that we're giving energy // to, take note. if (!NumParticlesToShare.count(sh_it)) { NumParticlesToShare[sh_it] = 0; } NumParticlesToShare[sh_it]++; #ifdef DEBUG_ESHUFFLER std::cout << "Found recieving particle in pool " << sh_it << "." << std::endl; #endif } if (ShufflersDescriptors[sh_it].first != PDG) { continue; } double KETaken = sd.EFraction * fp->KE(); if (!TakenEnergy.count(sh_it)) { TakenEnergy[sh_it] = 0; } TakenEnergy[sh_it] += KETaken; #ifdef DEBUG_ESHUFFLER std::cout << "Taking " << KETaken << " KE from " << fp->PDG() << " (" << fp << ") with " << fp->KE() << " (mom: " << fp->p() << ")." << std::endl; #endif - fp->RemoveKE(KETaken); + fe->RemoveKE(p_it, KETaken); + fp = fe->GetParticle(p_it); #ifdef DEBUG_ESHUFFLER std::cout << "\t->" << fp->KE() << " (mom: " << fp->p() << ") => " << sh_it << "." << std::endl; #endif } } double LostEnergy = 0; for (std::map<Int_t, double>::iterator te_it = TakenEnergy.begin(); te_it != TakenEnergy.end(); ++te_it) { double EToGive = te_it->second; // Get energy share for each 'to' particle if (NumParticlesToShare.count(te_it->first)) { // If we have any particles // to share the energy // between. #ifdef DEBUG_ESHUFFLER std::cout << "Energy from Shuffler " << te_it->first << " " << EToGive << " shared between " << NumParticlesToShare[te_it->first] << " particle." << std::endl; #endif EToGive /= double(NumParticlesToShare[te_it->first]); } else { LostEnergy += EToGive; continue; } ShuffleDescriptor &sd = ShufflersDescriptors[te_it->first].second; for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { FitParticle *fp = fe->GetParticle(p_it); if (fp->Status() != kFinalState) { continue; } int PDG = fp->PDG(); if (std::find(sd.ToPDGs.begin(), sd.ToPDGs.end(), PDG) == sd.ToPDGs.end()) { // This shuffler has no energy for this particle continue; } #ifdef DEBUG_ESHUFFLER std::cout << "Giving " << EToGive << " KE to " << fp->PDG() << " with " << fp->KE() << " (mom: " << fp->p() << ")." << std::endl; #endif - fp->GiveKE(EToGive); + fe->GiveKE(p_it, EToGive); + fp = fe->GetParticle(p_it); #ifdef DEBUG_ESHUFFLER std::cout << "\t->" << fp->KE() << " (mom: " << fp->p() << ")." << std::endl; #endif } } #ifdef DEBUG_ESHUFFLER if (LostEnergy > 0) { std::cout << "" << LostEnergy << " of KE went nowhere..." << std::endl; } #endif } diff --git a/src/Smearceptance/MetaSimpleSmearcepter.cxx b/src/Smearceptance/MetaSimpleSmearcepter.cxx index 32f1e55..eac85e9 100644 --- a/src/Smearceptance/MetaSimpleSmearcepter.cxx +++ b/src/Smearceptance/MetaSimpleSmearcepter.cxx @@ -1,73 +1,74 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "EfficiencyApplicator.h" #include "GaussianSmearer.h" #include "ThresholdAccepter.h" #include "TrackedMomentumMatrixSmearer.h" +#include "VisECoalescer.h" #include "MetaSimpleSmearcepter.h" void MetaSimpleSmearcepter::SpecifcSetup(nuiskey &nk) { std::map<std::string, SmearceptionFactory_fcn> factories; factories["ThresholdAccepter"] = &BuildSmearcepter<ThresholdAccepter>; factories["EfficiencyApplicator"] = &BuildSmearcepter<EfficiencyApplicator>; factories["GaussianSmearer"] = &BuildSmearcepter<GaussianSmearer>; factories["VisECoalescer"] = &BuildSmearcepter<VisECoalescer>; factories["TrackedMomentumMatrixSmearer"] = &BuildSmearcepter<TrackedMomentumMatrixSmearer>; std::vector<nuiskey> smearcepters = nk.GetListOfChildNodes(); for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { std::string const &smearType = smearcepters[smear_it].GetElementName(); if (smearType == "EnergyShuffler") { ES = new EnergyShuffler(); ES->Setup(smearcepters[smear_it]); continue; } if (!factories.count(smearType)) { ERROR(WRN, "No known smearer accepts elements named: \"" << smearType << "\""); continue; } Smearcepters.push_back(factories[smearType](smearcepters[smear_it])); QLOG(FIT, "MetaSimpleSmearcepter adopted child smearcepter: " << Smearcepters.back()->GetName() << " of type: " << Smearcepters.back()->GetElementName()); } NSmearcepters = Smearcepters.size(); } RecoInfo *MetaSimpleSmearcepter::Smearcept(FitEvent *fe) { if (ES) { ES->DoTheShuffle(fe); } RecoInfo *ri = NULL; for (size_t sm_it = 0; sm_it < NSmearcepters; ++sm_it) { if (!sm_it) { ri = Smearcepters[sm_it]->Smearcept(fe); } else { Smearcepters[sm_it]->SmearRecoInfo(ri); } } return ri; } diff --git a/src/Smearceptance/SmearceptanceUtils.cxx b/src/Smearceptance/SmearceptanceUtils.cxx index 6dda8c9..bd00b75 100644 --- a/src/Smearceptance/SmearceptanceUtils.cxx +++ b/src/Smearceptance/SmearceptanceUtils.cxx @@ -1,278 +1,284 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "SmearceptanceUtils.h" #include "TDecompSVD.h" #include "FitLogger.h" namespace SmearceptanceUtils { double Smear1DProp(TH2D *mapping, double TrueProp, TRandom3 *rnjesus) { bool myrand = false; if (!rnjesus) { rnjesus = new TRandom3(); myrand = true; } if (myrand) { delete rnjesus; } THROW("NIMPLEMENTED"); return 0; } TVectorD SVDInverseSolve(TVectorD *inp, TMatrixD *mapping) { TDecompSVD svd(*mapping); bool ok; TVectorD c_svd = svd.Solve(*inp, ok); if (!ok) { THROW("Failed to solve SVD matrix equation."); } return c_svd; } TVectorD SVDInverseSolve(TH1D *inp, TMatrixD *mapping) { TVectorD inp_v = GetVector(inp); return SVDInverseSolve(&inp_v, mapping); } TVectorD SVDInverseSolve(TH1D *inp, TH2D *mapping) { TMatrixD mat(mapping->GetXaxis()->GetNbins(), mapping->GetYaxis()->GetNbins()); for (Int_t xb_it = 0; xb_it < mapping->GetXaxis()->GetNbins(); ++xb_it) { for (Int_t yb_it = 0; yb_it < mapping->GetYaxis()->GetNbins(); ++yb_it) { mat[xb_it][yb_it] = mapping->GetBinContent(xb_it + 1, yb_it + 1); } } return SVDInverseSolve(inp, &mat); } TH2D *SVDGetInverse(TH2D *mapping, int NToTruncate) { TMatrixD mat = GetMatrix(mapping); if (mat.GetNcols() > mat.GetNrows()) { THROW("Trying to invert a " << mat.GetNrows() << "x" << mat.GetNcols() << " matrix."); } - TH2D *inverse = SwapXYTH2D(mapping); + TH2D *inverse = dynamic_cast<TH2D *>(mapping->Clone()); inverse->SetName("inverse"); inverse->Reset(); TDecompSVD svd(mat); svd.Decompose(); if (NToTruncate) { TVectorD Sig(svd.GetSig()); TMatrixD U(svd.GetU()); TMatrixD V(svd.GetV()); if (svd.GetV().TestBit(TMatrixD::kTransposed)) { THROW("ARGHH"); } TMatrixD V_T = V.Transpose(V); TMatrixD Sig_TruncM(U.GetNrows(), V.GetNrows()); for (Int_t i = 0; i < U.GetNrows(); ++i) { for (Int_t j = 0; j < V.GetNrows(); ++j) { Sig_TruncM[i][j] = ((i != j) || (i >= (Sig.GetNrows() - NToTruncate))) ? 0 : Sig[i]; } } TMatrixD Trunc = U * Sig_TruncM * V_T; svd.~TDecompSVD(); new (&svd) TDecompSVD(Trunc); } TMatrixD inv = svd.Invert(); if (fabs(inv[mapping->GetXaxis()->GetNbins() / 2] [mapping->GetXaxis()->GetNbins() / 2] - mat[mapping->GetXaxis()->GetNbins() / 2] [mapping->GetXaxis()->GetNbins() / 2]) < std::numeric_limits<double>::epsilon()) { THROW("Failed to SVD invert matrix."); } for (Int_t xb_it = 0; xb_it < inverse->GetXaxis()->GetNbins(); ++xb_it) { for (Int_t yb_it = 0; yb_it < inverse->GetYaxis()->GetNbins(); ++yb_it) { inverse->SetBinContent(xb_it + 1, yb_it + 1, inv[yb_it][xb_it]); } } return inverse; } void GetSVDDecomp(TH2D *mapping, TVectorD &Sig, TMatrixD &U, TMatrixD &V) { TMatrixD mat = GetMatrix(mapping); TDecompSVD svd(mat); U.ResizeTo(svd.GetU()); U = svd.GetU(); V.ResizeTo(svd.GetV()); V = svd.GetU(); Sig.ResizeTo(svd.GetSig()); Sig = svd.GetSig(); } TVectorD GetVector(TH1D *inp) { TVectorD vec(inp->GetXaxis()->GetNbins()); for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { vec[xb_it] = inp->GetBinContent(xb_it + 1); } return vec; } TVectorD GetErrorVector(TH1D *inp) { TVectorD vec(inp->GetXaxis()->GetNbins()); for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { vec[xb_it] = inp->GetBinError(xb_it + 1); } return vec; } TMatrixD GetMatrix(TH2D *inp) { TMatrixD mat(inp->GetYaxis()->GetNbins(), inp->GetXaxis()->GetNbins()); for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { for (Int_t yb_it = 0; yb_it < inp->GetYaxis()->GetNbins(); ++yb_it) { mat[yb_it][xb_it] = inp->GetBinContent(xb_it + 1, yb_it + 1); } } return mat; } TH1D *GetTH1FromVector(TVectorD const &inp, TH1D *templ) { TH1D *hist; if (templ) { hist = static_cast<TH1D *>(templ->Clone()); hist->Reset(); hist->SetName("vectHist"); } else { hist = new TH1D("vectHist", "", inp.GetNrows(), 0, inp.GetNrows()); } + hist->SetDirectory(NULL); for (Int_t xb_it = 0; xb_it < inp.GetNrows(); ++xb_it) { hist->SetBinContent(xb_it + 1, inp[xb_it]); } return hist; } TH2D *GetTH2FromMatrix(TMatrixD const &inp, TH2D *templ) { TH2D *hist; if (templ) { hist = static_cast<TH2D *>(templ->Clone()); hist->Reset(); hist->SetName("matHist"); } else { hist = new TH2D("matHist", "", inp.GetNcols(), 0, inp.GetNcols(), inp.GetNrows(), 0, inp.GetNrows()); } + hist->SetDirectory(NULL); + for (Int_t xb_it = 0; xb_it < inp.GetNcols(); ++xb_it) { for (Int_t yb_it = 0; yb_it < inp.GetNrows(); ++yb_it) { hist->SetBinContent(xb_it + 1, yb_it + 1, inp[yb_it][xb_it]); } } return hist; } TVectorD ThrowVectFromHist(TH1D *inp, TRandom3 *rnjesus, bool allowNeg) { TVectorD vec(inp->GetXaxis()->GetNbins()); for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { size_t attempt = 0; do { if (attempt > 1000) { THROW("Looks like we aren't getting anywhere with this bin: " << inp->GetBinContent(xb_it + 1) << " +- " << inp->GetBinError(xb_it + 1)); } vec[xb_it] = inp->GetBinContent(xb_it + 1) + inp->GetBinError(xb_it + 1) * rnjesus->Gaus(); attempt++; } while ((!allowNeg) && (vec[xb_it] < 0)); } return vec; } void PushTH1ThroughMatrixWithErrors(TH1D *inp, TH1D *oup, TMatrixD &response, size_t NToys, bool allowNeg) { TRandom3 rnjesus; oup->Reset(); TVectorD Mean(oup->GetXaxis()->GetNbins()); TVectorD RMS(oup->GetXaxis()->GetNbins()); std::vector<TVectorD> Toys; Toys.reserve(NToys); double NToysFact = 1.0 / double(NToys); for (size_t t_it = 0; t_it < NToys; ++t_it) { TVectorD Toy = ThrowVectFromHist(inp, &rnjesus, allowNeg); TVectorD UnfoldToy = response * Toy; for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { Mean[bi_it] += UnfoldToy[bi_it] * NToysFact; } Toys.push_back(UnfoldToy); } for (size_t t_it = 0; t_it < NToys; ++t_it) { for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { RMS[bi_it] += (Mean[bi_it] - Toys[t_it][bi_it]) * (Mean[bi_it] - Toys[t_it][bi_it]) * NToysFact; } } for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { oup->SetBinContent(bi_it + 1, Mean[bi_it]); oup->SetBinError(bi_it + 1, sqrt(RMS[bi_it])); } } -TH2D *SwapXYTH2D(TH2D *templ) { +TH2D * SwapXYTH2D(TH2D *templ) { TH2D *Swapped = new TH2D( (std::string(templ->GetName()) + "_c").c_str(), "", templ->GetYaxis()->GetNbins(), templ->GetYaxis()->GetXbins()->GetArray(), templ->GetXaxis()->GetNbins(), templ->GetXaxis()->GetXbins()->GetArray()); Swapped->Reset(); + Swapped->SetDirectory(NULL); + + std::string title = ";"; title += templ->GetYaxis()->GetTitle(); title += ";"; title += templ->GetXaxis()->GetTitle(); Swapped->SetTitle(title.c_str()); for (Int_t x_it = 0; x_it < templ->GetXaxis()->GetNbins() + 2; ++x_it) { for (Int_t y_it = 0; y_it < templ->GetYaxis()->GetNbins() + 2; ++y_it) { Swapped->SetBinContent(y_it, x_it, templ->GetBinContent(x_it, y_it)); Swapped->SetBinError(y_it, x_it, templ->GetBinError(x_it, y_it)); } } return Swapped; } } diff --git a/src/Smearceptance/Smearcepterton.cxx b/src/Smearceptance/Smearcepterton.cxx index 55fdbe7..17ff95d 100644 --- a/src/Smearceptance/Smearcepterton.cxx +++ b/src/Smearceptance/Smearcepterton.cxx @@ -1,77 +1,78 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "Smearcepterton.h" -#include "ThresholdAccepter.h" #include "EfficiencyApplicator.h" #include "GaussianSmearer.h" -#include "TrackedMomentumMatrixSmearer.h" #include "MetaSimpleSmearcepter.h" +#include "ThresholdAccepter.h" +#include "TrackedMomentumMatrixSmearer.h" +#include "VisECoalescer.h" #include <vector> Smearcepterton* Smearcepterton::_inst = NULL; Smearcepterton& Smearcepterton::Get() { if (!_inst) { _inst = new Smearcepterton(); } return *_inst; } Smearcepterton::Smearcepterton() { InitialiserSmearcepters(); } void Smearcepterton::InitialiserSmearcepters() { // hard coded list of tag name -> smearcepter factories, add here to add your // own. std::map<std::string, SmearceptionFactory_fcn> factories; factories["ThresholdAccepter"] = &BuildSmearcepter<ThresholdAccepter>; factories["EfficiencyApplicator"] = &BuildSmearcepter<EfficiencyApplicator>; factories["GaussianSmearer"] = &BuildSmearcepter<GaussianSmearer>; - factories["TrackedMomentumMatrixSmearer"] = &BuildSmearcepter<TrackedMomentumMatrixSmearer>; + factories["TrackedMomentumMatrixSmearer"] = + &BuildSmearcepter<TrackedMomentumMatrixSmearer>; factories["VisECoalescer"] = &BuildSmearcepter<VisECoalescer>; factories["MetaSimpleSmearcepter"] = &BuildSmearcepter<MetaSimpleSmearcepter>; - std::vector<nuiskey> smearcepterBlocks = Config::QueryKeys("smearcepters"); for (size_t smearB_it = 0; smearB_it < smearcepterBlocks.size(); ++smearB_it) { std::vector<nuiskey> smearcepters = smearcepterBlocks[smearB_it].GetListOfChildNodes(); for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { std::string const& smearType = smearcepters[smear_it].GetElementName(); if (!factories.count(smearType)) { ERROR(WRN, "No known smearer accepts elements named: \"" << smearType << "\""); continue; } ISmearcepter* smearer = factories[smearType](smearcepters[smear_it]); Smearcepters[smearer->GetName()] = smearer; QLOG(FIT, "Configured smearer named: " << smearer->GetName() << " of type: " << smearer->GetElementName()); } } } diff --git a/src/Smearceptance/ThresholdAccepter.cxx b/src/Smearceptance/ThresholdAccepter.cxx index 4a4dff3..adc7239 100644 --- a/src/Smearceptance/ThresholdAccepter.cxx +++ b/src/Smearceptance/ThresholdAccepter.cxx @@ -1,330 +1,330 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "ThresholdAccepter.h" namespace { ThresholdAccepter::KineVar GetKineType(nuiskey &nk) { if (nk.Has("RecoThresholdMomentum_MeV")) { return ThresholdAccepter::kMomentum; } else if (nk.Has("RecoThresholdKE_MeV")) { return ThresholdAccepter::kKE; } else if (nk.Has("RecoThresholdCosTheta_Max")) { return ThresholdAccepter::kCosTheta_Max; } else if (nk.Has("RecoThresholdCosTheta_Min")) { return ThresholdAccepter::kCosTheta_Min; } else if (nk.Has("RecoThresholdAbsCosTheta_Max")) { return ThresholdAccepter::kAbsCosTheta_Max; } else if (nk.Has("RecoThresholdAbsCosTheta_Min")) { return ThresholdAccepter::kAbsCosTheta_Min; } else { THROW("Cannot determine the threshold type for Smearcepter element."); } return ThresholdAccepter::kNoVar; } std::string GetKineTypeName(ThresholdAccepter::KineVar kv) { switch (kv) { case ThresholdAccepter::kMomentum: return "Momentum"; case ThresholdAccepter::kKE: return "KE"; case ThresholdAccepter::kCosTheta_Max: return "CosTheta_Max"; case ThresholdAccepter::kCosTheta_Min: return "CosTheta_Min"; case ThresholdAccepter::kAbsCosTheta_Max: return "AbsCosTheta_Max"; case ThresholdAccepter::kAbsCosTheta_Min: return "CosTheta_Min"; default: return "NoVar"; } } double GetKineThreshold(nuiskey &nk, ThresholdAccepter::KineVar kv) { switch (kv) { case ThresholdAccepter::kMomentum: return nk.GetD("RecoThresholdMomentum_MeV"); case ThresholdAccepter::kKE: return nk.GetD("RecoThresholdKE_MeV"); case ThresholdAccepter::kCosTheta_Max: return nk.GetD("RecoThresholdCosTheta_Max"); case ThresholdAccepter::kCosTheta_Min: return nk.GetD("RecoThresholdCosTheta_Min"); case ThresholdAccepter::kAbsCosTheta_Max: return nk.GetD("RecoThresholdAbsCosTheta_Max"); case ThresholdAccepter::kAbsCosTheta_Min: return nk.GetD("RecoThresholdAbsCosTheta_Min"); default: return 0; } } double GetKineVal(FitParticle *fp, ThresholdAccepter::Thresh &rt) { switch (rt.ThresholdType) { case ThresholdAccepter::kMomentum: return fp->P3().Mag(); case ThresholdAccepter::kKE: return fp->KE(); case ThresholdAccepter::kCosTheta_Max: return fp->P3().CosTheta(); case ThresholdAccepter::kCosTheta_Min: return fp->P3().CosTheta(); case ThresholdAccepter::kAbsCosTheta_Max: return fabs(fp->P3().CosTheta()); case ThresholdAccepter::kAbsCosTheta_Min: return fabs(fp->P3().CosTheta()); default: return 0; } } bool PassesThreshold(FitParticle *fp, ThresholdAccepter::Thresh &rt) { switch (rt.ThresholdType) { case ThresholdAccepter::kMomentum: return (fp->P3().Mag() > rt.ThresholdVal); case ThresholdAccepter::kKE: return (fp->KE() > rt.ThresholdVal); case ThresholdAccepter::kCosTheta_Max: return (fp->P3().CosTheta() < rt.ThresholdVal); case ThresholdAccepter::kCosTheta_Min: return (fp->P3().CosTheta() > rt.ThresholdVal); case ThresholdAccepter::kAbsCosTheta_Max: return (fabs(fp->P3().CosTheta()) < rt.ThresholdVal); case ThresholdAccepter::kAbsCosTheta_Min: return (fabs(fp->P3().CosTheta()) > rt.ThresholdVal); default: return 0; } } } /// Reads particle threshold nodes /// /// Nodes look like: /// <ThresholdAccepter Name="D00N_ND_LAr"> /// <RecoThreshold PDG="211,-211" RecoThresholdKE_MeV="30" /> /// <RecoThreshold PDG="211,-211" RecoThresholdCosTheta_Max="1" /> /// <RecoThreshold PDG="2212" RecoThresholdMomentum_MeV="350" /> /// <RecoThreshold PDG="2212" RecoThresholdAbsCosTheta_Min="0" /> /// <VisThreshold PDG="2212" VisThresholdKE_MeV="10" Contrib="K" /> /// <VisThreshold PDG="22" VisThresholdKE_MeV="10" Contrib="T" /> /// </ThresholdAccepter> void ThresholdAccepter::SpecifcSetup(nuiskey &nk) { std::vector<nuiskey> recoThresholdDescriptors = nk.GetListOfChildNodes("RecoThreshold"); for (size_t t_it = 0; t_it < recoThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = recoThresholdDescriptors[t_it].GetS("PDG"); std::vector<int> pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { Thresh t; t.ThresholdType = GetKineType(recoThresholdDescriptors[t_it]); t.ThresholdVal = GetKineThreshold(recoThresholdDescriptors[t_it], t.ThresholdType); ReconThresholds[pdgs_i[pdg_it]].push_back(t); - QLOG(SAM, "Added reconstruction threshold of type: " + QLOG(FIT, "Added reconstruction threshold of type: " << ReconThresholds[pdgs_i[pdg_it]].back().ThresholdVal << " " << GetKineTypeName( ReconThresholds[pdgs_i[pdg_it]].back().ThresholdType) << ", for PDG: " << pdgs_i[pdg_it]); } } std::vector<nuiskey> visThresholdDescriptors = nk.GetListOfChildNodes("VisThreshold"); for (size_t t_it = 0; t_it < visThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = visThresholdDescriptors[t_it].GetS("PDG"); std::vector<int> pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { if (VisThresholds.count(pdgs_i[pdg_it])) { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " already has a threshold for PDG: " << pdgs_i[pdg_it]); } VisThresh vt; vt.UseKE = visThresholdDescriptors[t_it].Has("Contrib") ? (visThresholdDescriptors[t_it].GetS("Contrib") == "K") : false; vt.Fraction = visThresholdDescriptors[t_it].Has("Fraction") ? visThresholdDescriptors[t_it].GetD("Fraction") : 1; if (visThresholdDescriptors[t_it].Has("VisThresholdKE_MeV")) { vt.ThresholdType = ThresholdAccepter::kKE; vt.ThresholdVal = visThresholdDescriptors[t_it].GetD("VisThresholdKE_MeV"); } else if (visThresholdDescriptors[t_it].Has( "VisThresholdMomentum_MeV")) { vt.ThresholdType = ThresholdAccepter::kMomentum; vt.ThresholdVal = visThresholdDescriptors[t_it].GetD("VisThresholdMomentum_MeV"); ; } else { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " cannot find threshold information for PDG: " << pdgs_i[pdg_it]); continue; } VisThresholds[pdgs_i[pdg_it]] = vt; - QLOG(SAM, + QLOG(FIT, "Added visibility threshold of MeV " << VisThresholds[pdgs_i[pdg_it]].ThresholdVal << " " << GetKineTypeName(VisThresholds[pdgs_i[pdg_it]].ThresholdType) << ", for PDG: " << pdgs_i[pdg_it] << ". If visible, particle deposits: " << (VisThresholds[pdgs_i[pdg_it]].UseKE ? "KE" : "TE")); } } } void ThresholdAccepter::SmearceptOneParticle(RecoInfo *ri, FitParticle *fp #ifdef DEBUG_THRESACCEPT , size_t p_it #endif ) { #ifdef DEBUG_THRESACCEPT std::cout << std::endl; std::cout << "[" << p_it << " = " << fp << "]: " << fp->PDG() << ", " << fp->Status() << ", " << fp->E() << " -- KE:" << fp->KE() << " Mom: " << fp->P3().Mag() << std::flush; #endif if (fp->Status() != kFinalState) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Not final state." << std::flush; #endif return; } if ((ReconThresholds.count(fp->PDG()) + VisThresholds.count(fp->PDG())) == 0) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Undetectable." << std::flush; #endif return; } // If no reco thresholds it should fall through to EVis bool Passes = ReconThresholds[fp->PDG()].size(); bool FailEnergyThresh = !ReconThresholds[fp->PDG()].size(); for (size_t rt_it = 0; rt_it < ReconThresholds[fp->PDG()].size(); ++rt_it) { bool Passed = PassesThreshold(fp, ReconThresholds[fp->PDG()][rt_it]); if (!Passed) { #ifdef DEBUG_THRESACCEPT std::cout << "\n\t -- Rejected. (" << GetKineTypeName( ReconThresholds[fp->PDG()][rt_it].ThresholdType) << " Threshold: " << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" << std::flush; if ((ReconThresholds[fp->PDG()][rt_it].ThresholdType == ThresholdAccepter::kMomentum) || (ReconThresholds[fp->PDG()][rt_it].ThresholdType == ThresholdAccepter::kKE)) { FailEnergyThresh = true; } #endif } else { #ifdef DEBUG_THRESACCEPT std::cout << "\n\t -- Accepted. (" << GetKineTypeName( ReconThresholds[fp->PDG()][rt_it].ThresholdType) << " Threshold: " << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" << std::flush; #endif } Passes = Passes && Passed; } if (Passes) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Reconstructed." << std::flush; #endif ri->RecObjMom.push_back(fp->P3()); ri->RecObjClass.push_back(fp->PDG()); return; } else if (!FailEnergyThresh) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Failed non-Energy threshold, no chance for EVis." << std::flush; #endif return; } if (((VisThresholds[fp->PDG()].ThresholdType == ThresholdAccepter::kKE) && (VisThresholds[fp->PDG()].ThresholdVal < fp->KE())) // Above KE-style threshold || ((VisThresholds[fp->PDG()].ThresholdType == ThresholdAccepter::kMomentum) && (VisThresholds[fp->PDG()].ThresholdVal < fp->P3().Mag())) // Above mom-style threshold ) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Contributed to VisE. (" << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif ri->RecVisibleEnergy.push_back( VisThresholds[fp->PDG()].Fraction * (VisThresholds[fp->PDG()].UseKE ? fp->KE() : fp->E())); ri->TrueContribPDGs.push_back(fp->PDG()); return; } else { #ifdef DEBUG_THRESACCEPT std::cout << " -- Rejected. " << " Vis: (" << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif } } RecoInfo *ThresholdAccepter::Smearcept(FitEvent *fe) { RecoInfo *ri = new RecoInfo(); for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { FitParticle *fp = fe->GetParticle(p_it); SmearceptOneParticle(ri, fp #ifdef DEBUG_THRESACCEPT , p_it #endif ); } #ifdef DEBUG_THRESACCEPT std::cout << std::endl; #endif return ri; } diff --git a/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx b/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx index 25f1f5f..9dda0cc 100644 --- a/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx +++ b/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx @@ -1,431 +1,411 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "TrackedMomentumMatrixSmearer.h" namespace { TrackedMomentumMatrixSmearer::DependVar GetVarType(std::string const &axisvar) { if (axisvar == "Momentum") { return TrackedMomentumMatrixSmearer::kMomentum; } else if (axisvar == "KE") { return TrackedMomentumMatrixSmearer::kKE; } else if (axisvar == "TE") { return TrackedMomentumMatrixSmearer::kTE; } return TrackedMomentumMatrixSmearer::kNoVar; } } TH1D const *TrackedMomentumMatrixSmearer::SmearMap::GetRecoSlice(double val) { if ((val < RecoSlices.front().first.first) || (val > RecoSlices.back().first.second)) { ERROR(WRN, "Kinematic property: " << val << ", not within smearable range: [" << RecoSlices.front().first.first << " -- " << RecoSlices.back().first.second << "]."); return NULL; } int L = 0, U = RecoSlices.size(); -#ifdef DEBUG_MATSMEAR - std::cout << "\nBin search for " << val - << " within: " << RecoSlices.front().first.first << " -- " - << RecoSlices.back().first.second << std::endl; -#endif + while (true) { -#ifdef DEBUG_MATSMEAR - std::cout << "\t\t U:" << U << ", L: " << L << " (/" << RecoSlices.size() - << ")" << std::endl; -#endif if (U == L) { -#ifdef DEBUG_MATSMEAR - std::cout << "Found: " << L << std::endl; -#endif return RecoSlices[L].second; } int R = (U - L); int m = L + (R / 2); -#ifdef DEBUG_MATSMEAR - std::cout << "Bin: " << m << "[ " << RecoSlices[m].first.first << " -- " - << RecoSlices[m].first.second << "] (Search: " << val << ")" - << std::endl; -#endif - if (val <= RecoSlices[m].first.first) { U = m - 1; continue; } if (val > RecoSlices[m].first.second) { L = m + 1; continue; } if ((val > RecoSlices[m].first.first) && (val <= RecoSlices[m].first.second)) { -#ifdef DEBUG_MATSMEAR - std::cout << "Found: " << m << std::endl; -#endif return RecoSlices[m].second; } THROW("Binary smearing search failed. Check logic."); } } TH1D *GetMapSlice(TH2D *mp, int SliceBin, bool AlongX) { int NBins = (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetNbins(); int NOtherBins = (AlongX ? mp->GetYaxis() : mp->GetXaxis())->GetNbins(); if (SliceBin >= NOtherBins) { THROW("Asked for slice " << SliceBin << " but the " << (AlongX ? 'Y' : 'X') << " axis only has " << NOtherBins); } if ((AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize() && ((NBins + 1) != (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetSize())) { THROW( "Attemping to take binning slice of variable binning, but NBins+1 != " "NBinEdges: " << (NBins + 1) << " != " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetSize()); } std::stringstream ss(""); ss << mp->GetName() << (AlongX ? 'Y' : 'X') << "Slice_" << SliceBin; std::stringstream st(""); st << mp->GetTitle() << ";" << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetTitle() << ";" << "Count"; TH1D *Ret; if ((AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize()) { Ret = new TH1D( ss.str().c_str(), st.str().c_str(), NBins, (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetArray()); } else { Ret = new TH1D(ss.str().c_str(), st.str().c_str(), NBins, (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmin(), (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmax()); } for (int bi_it = 0; bi_it < NBins + 2; ++bi_it) { int X = AlongX ? bi_it : SliceBin + 1; int Y = AlongX ? SliceBin + 1 : bi_it; int GBin = mp->GetBin(X, Y); Ret->SetBinContent(bi_it, mp->GetBinContent(GBin)); Ret->SetBinError(bi_it, mp->GetBinError(GBin)); } #ifdef DEBUG_MATSMEAR std::cout << "Took slice: " << SliceBin << " spanning [" << Ret->GetXaxis()->GetBinLowEdge(1) << " -- " << Ret->GetXaxis()->GetBinUpEdge(Ret->GetXaxis()->GetNbins()) << "] (Orignal span [" << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetBinLowEdge(1) << " -- " << (AlongX ? mp->GetXaxis() : mp->GetYaxis()) ->GetBinUpEdge( (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetNbins()) << "]) " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmin() << " -- " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmax() << " IsVBin: " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize() << std::endl; #endif Ret->SetDirectory(NULL); return Ret; } void TrackedMomentumMatrixSmearer::SmearMap::SetSlicesFromMap(TH2D *map, bool TruthIsY) { int NSlices = (TruthIsY ? map->GetYaxis() : map->GetXaxis())->GetNbins(); for (Int_t TrueSlice_it = 0; TrueSlice_it < NSlices; ++TrueSlice_it) { std::pair<double, double> BinEdges; BinEdges.first = (TruthIsY ? map->GetYaxis() : map->GetXaxis()) ->GetBinLowEdge(TrueSlice_it + 1); BinEdges.second = (TruthIsY ? map->GetYaxis() : map->GetXaxis()) ->GetBinUpEdge(TrueSlice_it + 1); TH1D *slice = GetMapSlice(map, TrueSlice_it, TruthIsY); RecoSlices.push_back(std::make_pair(BinEdges, slice)); } QLOG(FIT, "\tAdded " << RecoSlices.size() << " reco slices."); } /// Reads particle efficiency nodes /// /// Nodes look like: /// <TrackedMomentumMatrixSmearer Name="D00N_ND_LAr"> /// <SmearMatrix PDG="211,-211" InputFile="smear.root" /// HistName="cpion_mom_smear" Kinematics="[KE|Momentum]" /// MatrixToInternal="1E3" YIsTrue="true"/> /// </TrackedMomentumMatrixSmearer> void TrackedMomentumMatrixSmearer::SpecifcSetup(nuiskey &nk) { std::vector<nuiskey> effDescriptors = nk.GetListOfChildNodes("SmearMatrix"); for (size_t t_it = 0; t_it < effDescriptors.size(); ++t_it) { std::string inputFileName = effDescriptors[t_it].GetS("InputFile"); std::string HistName = effDescriptors[t_it].GetS("HistName"); bool YIsTrue = effDescriptors[t_it].Has("YIsTrue") ? effDescriptors[t_it].GetI("YIsTrue") : true; double UnitsScale = effDescriptors[t_it].Has("MatrixToInternal") ? effDescriptors[t_it].GetD("MatrixToInternal") : 1; TFile inputFile(inputFileName.c_str()); if (!inputFile.IsOpen()) { THROW("Couldn't open specified input root file: " << inputFileName); } TH2D *inpHist = dynamic_cast<TH2D *>(inputFile.Get(HistName.c_str())); if (!inpHist) { THROW("Couldn't get TH2D named: " << HistName << " from input root file: " << inputFileName); } TrackedMomentumMatrixSmearer::DependVar var = GetVarType(effDescriptors[t_it].GetS("Kinematics")); std::string pdgs_s = effDescriptors[t_it].GetS("PDG"); std::vector<int> pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { if (ParticleMappings.count(pdgs_i[pdg_it])) { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " already has a smearing for PDG: " << pdgs_i[pdg_it]); } SmearMap sm; sm.SetSlicesFromMap(inpHist, YIsTrue); sm.SmearVar = var; sm.UnitsScale = UnitsScale; ParticleMappings[pdgs_i[pdg_it]] = sm; - QLOG(SAM, "Added smearing map for PDG: " << pdgs_i[pdg_it]); + QLOG(FIT, "Added smearing map for PDG: " << pdgs_i[pdg_it]); } } SlaveGS.Setup(nk); } RecoInfo *TrackedMomentumMatrixSmearer::Smearcept(FitEvent *fe) { RecoInfo *ri = new RecoInfo(); for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { FitParticle *fp = fe->GetParticle(p_it); #ifdef DEBUG_MATSMEAR std::cout << std::endl; std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() << ", " << fp->E() << " -- KE:" << fp->KE() << " Mom: " << fp->P3().Mag() << std::flush; #endif if (fp->Status() != kFinalState) { #ifdef DEBUG_MATSMEAR std::cout << " -- Not final state." << std::flush; #endif continue; } if (!ParticleMappings.count(fp->PDG())) { SlaveGS.SmearceptOneParticle(ri, fp #ifdef DEBUG_GAUSSSMEAR , p_it #endif ); continue; } SmearMap &sm = ParticleMappings[fp->PDG()]; double kineProp = 0; switch (sm.SmearVar) { case kMomentum: { kineProp = fp->P3().Mag(); break; } case kKE: { kineProp = fp->KE(); break; } case kTE: { kineProp = fp->E(); break; } default: { THROW("Trying to find particle value for a kNoAxis."); } } TH1 const *recoDistrib = sm.GetRecoSlice(kineProp / sm.UnitsScale); #ifdef DEBUG_MATSMEAR std::cout << " -- Got slice spanning [" << recoDistrib->GetXaxis()->GetBinLowEdge(1) << " -- " << recoDistrib->GetXaxis()->GetBinUpEdge( recoDistrib->GetXaxis()->GetNbins()) << "]" << std::endl; #endif if (!recoDistrib) { #ifdef DEBUG_MATSMEAR std::cout << " -- outside smearable range." << std::flush; #endif continue; } if (recoDistrib->Integral() == 0) { ERROR(WRN, "True slice has no reconstructed events. Not smearing.") continue; } double Smeared = recoDistrib->GetRandom() * sm.UnitsScale; #ifdef DEBUG_MATSMEAR std::cout << "GotRandom: " << Smeared << ", MPV: " << recoDistrib->GetXaxis()->GetBinCenter( recoDistrib->GetMaximumBin()) * sm.UnitsScale << std::endl; #endif switch (sm.SmearVar) { case kMomentum: { ri->RecObjMom.push_back(fp->P3().Unit() * Smeared); #ifdef DEBUG_MATSMEAR std::cout << " -- Smeared: " << fp->p() << " -> " << Smeared << "." << std::flush; #endif break; } case kKE: { double mass = fp->P4().M(); double TE = mass + Smeared; double magP = sqrt(TE * TE - mass * mass); ri->RecObjMom.push_back(fp->P3().Unit() * magP); #ifdef DEBUG_MATSMEAR std::cout << " -- Smeared: " << fp->KE() << " (mass: " << mass << ") -> " << Smeared << ". Smear Mom: " << ri->RecObjMom.back().Mag() << "." << std::flush; #endif break; } case kTE: { double mass = fp->P4().M(); double TE = Smeared; double magP = sqrt(TE * TE - mass * mass); ri->RecObjMom.push_back(fp->P3().Unit() * magP); #ifdef DEBUG_MATSMEAR std::cout << " -- Smeared: " << fp->E() << " (mass: " << mass << ") -> " << Smeared << ". Smear Mom: " << ri->RecObjMom.back().Mag() << "." << std::flush; #endif break; } default: {} } #ifdef DEBUG_MATSMEAR std::cout << " -- momentum reconstructed as " << ri->RecObjMom.back().Mag() << "." << std::endl; #endif if (ri->RecObjMom.back().Mag() != ri->RecObjMom.back().Mag()) { ERROR(WRN, "Invalid particle built."); ri->RecObjMom.pop_back(); #include "TCanvas.h" TCanvas *Test = new TCanvas("c1", ""); static_cast<TH1 *>(recoDistrib->Clone())->Draw(); Test->SaveAs("Fail.png"); delete Test; THROW("ARGH"); } else { ri->RecObjClass.push_back(fp->PDG()); } } #ifdef DEBUG_MATSMEAR std::cout << std::endl; #endif return ri; } void TrackedMomentumMatrixSmearer::SmearRecoInfo(RecoInfo *ri) { for (size_t p_it = 0; p_it < ri->RecObjMom.size(); ++p_it) { if (!ParticleMappings.count(ri->RecObjClass[p_it])) { SlaveGS.SmearceptOneParticle(ri->RecObjMom[p_it], ri->RecObjClass[p_it]); continue; } SmearMap &sm = ParticleMappings[ri->RecObjClass[p_it]]; double kineProp = 0; switch (sm.SmearVar) { case kMomentum: { kineProp = ri->RecObjMom[p_it].Mag(); break; } case kKE: { double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; kineProp = sqrt(ri->RecObjMom[p_it].Mag2() + mass * mass) - mass; break; } case kTE: { double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; kineProp = sqrt(ri->RecObjMom[p_it].Mag2() + mass * mass); break; } default: { THROW("Trying to find particle value for a kNoAxis."); } } TH1 const *recoDistrib = sm.GetRecoSlice(kineProp / sm.UnitsScale); if (!recoDistrib) { continue; } double Smeared = recoDistrib->GetRandom() * sm.UnitsScale; switch (sm.SmearVar) { case kMomentum: { ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * Smeared; break; } case kKE: { double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; double TE = mass + Smeared; double magP = sqrt(TE * TE - mass * mass); ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * magP; break; } case kTE: { double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; double TE = Smeared; double magP = sqrt(TE * TE - mass * mass); ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * magP; break; } default: {} } } } diff --git a/src/Utils/FitLogger.cxx b/src/Utils/FitLogger.cxx index 6819b20..a5d364f 100644 --- a/src/Utils/FitLogger.cxx +++ b/src/Utils/FitLogger.cxx @@ -1,310 +1,350 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "FitLogger.h" #include <fcntl.h> #include <unistd.h> - namespace Logger { // Logger Variables -int log_verb = 4; +int log_verb = 4; bool use_colors = true; -bool showtrace = false; +bool showtrace = false; std::ostream* __LOG_outstream(&std::cout); std::ofstream __LOG_nullstream; // Error Variables int err_verb = 0; std::ostream* __ERR_outstream(&std::cerr); // Extra Variables bool external_verb = false; -bool super_rainbow_mode = true; //!< For when fitting gets boring. +bool super_rainbow_mode = true; //!< For when fitting gets boring. unsigned int super_rainbow_mode_colour = 0; -std::streambuf *default_cout = std::cout.rdbuf(); -std::streambuf *default_cerr = std::cerr.rdbuf(); +std::streambuf* default_cout = std::cout.rdbuf(); +std::streambuf* default_cerr = std::cerr.rdbuf(); std::ofstream redirect_stream("/dev/null"); int silentfd = open("/dev/null", O_WRONLY); int savedstdoutfd = dup(fileno(stdout)); int savedstderrfd = dup(fileno(stderr)); int nloggercalls = 0; int timelastlog = 0; - } - - // -------- Logging Functions --------- // - bool LOGGING(int level) { - // std::cout << "LOGGING : " << __FILENAME__ << " " << __FUNCTION__ << std::endl; - return (Logger::log_verb >= (uint)__GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)); + // std::cout << "LOGGING : " << __FILENAME__ << " " << __FUNCTION__ << + // std::endl; + return (Logger::log_verb >= + (uint)__GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)); }; int __GETLOG_LEVEL(int level, const char* filename, const char* funct) { - #ifdef __DEBUG__ int logfile = FitPar::Config().GetParI("logging." + std::string(filename)); if (logfile >= DEB and logfile <= EVT) { level = logfile; } int logfunc = FitPar::Config().GetParI("logging." + std::string(funct)); if (logfunc >= DEB and logfunc <= EVT) { level = logfunc; } #endif return level; }; -std::ostream& __OUTLOG(int level, const char* filename, const char* funct, int line) { - +std::ostream& __OUTLOG(int level, const char* filename, const char* funct, + int line) { if (Logger::log_verb < (unsigned int)level && Logger::log_verb != (unsigned int)DEB) { return (Logger::__LOG_nullstream); } else { - if (Logger::use_colors) { switch (level) { - case FIT: std::cout << BOLDGREEN; break; - case MIN: std::cout << BOLDBLUE; break; - case SAM: std::cout << MAGENTA; break; - case REC: std::cout << BLUE; break; - case SIG: std::cout << GREEN; break; - case DEB: std::cout << CYAN; break; - default: break; + case FIT: + std::cout << BOLDGREEN; + break; + case MIN: + std::cout << BOLDBLUE; + break; + case SAM: + std::cout << MAGENTA; + break; + case REC: + std::cout << BLUE; + break; + case SIG: + std::cout << GREEN; + break; + case DEB: + std::cout << CYAN; + break; + default: + break; } } switch (level) { - case FIT: std::cout << "[LOG Fitter]"; break; - case MIN: std::cout << "[LOG Minmzr]"; break; - case SAM: std::cout << "[LOG Sample]"; break; - case REC: std::cout << "[LOG Reconf]"; break; - case SIG: std::cout << "[LOG Signal]"; break; - case EVT: std::cout << "[LOG Event ]"; break; - case DEB: std::cout << "[LOG DEBUG ]"; break; - default: std::cout << "[LOG INFO ]"; break; + case FIT: + std::cout << "[LOG Fitter]"; + break; + case MIN: + std::cout << "[LOG Minmzr]"; + break; + case SAM: + std::cout << "[LOG Sample]"; + break; + case REC: + std::cout << "[LOG Reconf]"; + break; + case SIG: + std::cout << "[LOG Signal]"; + break; + case EVT: + std::cout << "[LOG Event ]"; + break; + case DEB: + std::cout << "[LOG DEBUG ]"; + break; + default: + std::cout << "[LOG INFO ]"; + break; } // Apply indent if (true) { switch (level) { - case FIT: std::cout << ": "; break; - case MIN: std::cout << ":- "; break; - case SAM: std::cout << ":-- "; break; - case REC: std::cout << ":--- "; break; - case SIG: std::cout << ":---- "; break; - case EVT: std::cout << ":----- "; break; - case DEB: std::cout << ":------ "; break; - default: std::cout << " "; break; + case FIT: + std::cout << ": "; + break; + case MIN: + std::cout << ":- "; + break; + case SAM: + std::cout << ":-- "; + break; + case REC: + std::cout << ":--- "; + break; + case SIG: + std::cout << ":---- "; + break; + case EVT: + std::cout << ":----- "; + break; + case DEB: + std::cout << ":------ "; + break; + default: + std::cout << " "; + break; } } if (Logger::use_colors) std::cout << RESET; if (Logger::showtrace) { - std::cout << " : " << filename << "::" << funct << "[l. " << line << "] : "; + std::cout << " : " << filename << "::" << funct << "[l. " << line + << "] : "; } return *(Logger::__LOG_outstream); } } -void SETVERBOSITY(int level) { - Logger::log_verb = level; -} +void SETVERBOSITY(int level) { Logger::log_verb = level; } void SETVERBOSITY(std::string verb) { - if (!verb.compare("DEB")) Logger::log_verb = -1; - else if (!verb.compare("QUIET")) Logger::log_verb = 0; - else if (!verb.compare("FIT")) Logger::log_verb = 1; - else if (!verb.compare("MIN")) Logger::log_verb = 2; - else if (!verb.compare("SAM")) Logger::log_verb = 3; - else if (!verb.compare("REC")) Logger::log_verb = 4; - else if (!verb.compare("SIG")) Logger::log_verb = 5; - else if (!verb.compare("EVT")) Logger::log_verb = 6; - else Logger::log_verb = std::atoi(verb.c_str()); + if (!verb.compare("DEB")) + Logger::log_verb = -1; + else if (!verb.compare("QUIET")) + Logger::log_verb = 0; + else if (!verb.compare("FIT")) + Logger::log_verb = 1; + else if (!verb.compare("MIN")) + Logger::log_verb = 2; + else if (!verb.compare("SAM")) + Logger::log_verb = 3; + else if (!verb.compare("REC")) + Logger::log_verb = 4; + else if (!verb.compare("SIG")) + Logger::log_verb = 5; + else if (!verb.compare("EVT")) + Logger::log_verb = 6; + else + Logger::log_verb = std::atoi(verb.c_str()); } /// Set Trace Option -void SETTRACE(bool val) { - Logger::showtrace = val; -} +void SETTRACE(bool val) { Logger::showtrace = val; } // ------ ERROR FUNCTIONS ---------- // -std::ostream& __OUTERR(int level, const char* filename, const char* funct, int line) { +std::ostream& __OUTERR(int level, const char* filename, const char* funct, + int line) { if (Logger::use_colors) std::cerr << RED; switch (level) { - case FTL: std::cerr << "[ERR FATAL ]: "; break; - case WRN: std::cerr << "[ERR WARN ]: "; break; + case FTL: + std::cerr << "[ERR FATAL ]: "; + break; + case WRN: + std::cerr << "[ERR WARN ]: "; + break; } if (Logger::use_colors) std::cerr << RESET; // Allows enable error debugging trace if (true or Logger::showtrace) { std::cout << filename << "::" << funct << "[l. " << line << "] : "; } return *(Logger::__ERR_outstream); } // ----------- External Logging ----------- // -void SETEXTERNALVERBOSITY(int level) { - Logger::external_verb = (level > 0); -} +void SETEXTERNALVERBOSITY(int level) { Logger::external_verb = (level > 0); } void StopTalking() { - // Check verbosity set correctly if (!Logger::external_verb) return; // Only redirect if we're not debugging if (Logger::log_verb == (unsigned int)DEB) return; std::cout.rdbuf(Logger::redirect_stream.rdbuf()); std::cerr.rdbuf(Logger::redirect_stream.rdbuf()); shhnuisancepythiaitokay_(); fflush(stdout); fflush(stderr); dup2(Logger::silentfd, fileno(stdout)); dup2(Logger::silentfd, fileno(stderr)); } void StartTalking() { - // Check verbosity set correctly if (!Logger::external_verb) return; std::cout.rdbuf(Logger::default_cout); std::cerr.rdbuf(Logger::default_cerr); canihaznuisancepythia_(); fflush(stdout); fflush(stderr); dup2(Logger::savedstdoutfd, fileno(stdout)); dup2(Logger::savedstderrfd, fileno(stderr)); } - - - - - - - - - - - - - - - - //****************************************** void LOG_VERB(std::string verb) { -//****************************************** - - if (!verb.compare("DEB")) Logger::log_verb = -1; - else if (!verb.compare("QUIET")) Logger::log_verb = 0; - else if (!verb.compare("FIT")) Logger::log_verb = 1; - else if (!verb.compare("MIN")) Logger::log_verb = 2; - else if (!verb.compare("SAM")) Logger::log_verb = 3; - else if (!verb.compare("REC")) Logger::log_verb = 4; - else if (!verb.compare("SIG")) Logger::log_verb = 5; - else if (!verb.compare("EVT")) Logger::log_verb = 6; + //****************************************** + + if (!verb.compare("DEB")) + Logger::log_verb = -1; + else if (!verb.compare("QUIET")) + Logger::log_verb = 0; + else if (!verb.compare("FIT")) + Logger::log_verb = 1; + else if (!verb.compare("MIN")) + Logger::log_verb = 2; + else if (!verb.compare("SAM")) + Logger::log_verb = 3; + else if (!verb.compare("REC")) + Logger::log_verb = 4; + else if (!verb.compare("SIG")) + Logger::log_verb = 5; + else if (!verb.compare("EVT")) + Logger::log_verb = 6; // else Logger::log_verb = GeneralUtils::StrToInt(verb); std::cout << "Set logging verbosity to : " << Logger::log_verb << std::endl; return; } //****************************************** void ERR_VERB(std::string verb) { -//****************************************** + //****************************************** std::cout << "Setting ERROR VERB" << std::endl; - if (!verb.compare("ERRQUIET")) Logger::err_verb = 0; - else if (!verb.compare("FTL")) Logger::err_verb = 1; - else if (!verb.compare("WRN")) Logger::err_verb = 2; + if (!verb.compare("ERRQUIET")) + Logger::err_verb = 0; + else if (!verb.compare("FTL")) + Logger::err_verb = 1; + else if (!verb.compare("WRN")) + Logger::err_verb = 2; // else Logger::err_verb = GeneralUtils::StrToInt(verb); std::cout << "Set error verbosity to : " << Logger::err_verb << std::endl; return; } //****************************************** bool LOG_LEVEL(int level) { -//****************************************** + //****************************************** - if (Logger::log_verb == (unsigned int) DEB) { + if (Logger::log_verb == (unsigned int)DEB) { return true; } - if (Logger::log_verb < (unsigned int) level) { + if (Logger::log_verb < (unsigned int)level) { return false; } return true; } -void SET_TRACE(bool val) { - Logger::showtrace = val; -} - +void SET_TRACE(bool val) { Logger::showtrace = val; } //****************************************** std::ostream& _LOG(int level, const char* filename, const char* func, int line) //****************************************** { return __OUTLOG(level, filename, func, line); } //****************************************** std::ostream& _ERR(int level, const char* filename, const char* func, int line) //****************************************** { - if (Logger::use_colors) std::cerr << RED; if (Logger::showtrace) { std::cout << filename << "::" << func << "[l. " << line << "] : "; } switch (level) { - case FTL: std::cerr << "[ERR FATAL ]: "; break; - case WRN: std::cerr << "[ERR WARN ] : "; break; + case FTL: + std::cerr << "[ERR FATAL ]: "; + break; + case WRN: + std::cerr << "[ERR WARN ] : "; + break; } if (Logger::use_colors) std::cerr << RESET; return *Logger::__ERR_outstream; } - - diff --git a/src/Utils/FitLogger.h b/src/Utils/FitLogger.h index 6817bac..d8b26e9 100644 --- a/src/Utils/FitLogger.h +++ b/src/Utils/FitLogger.h @@ -1,207 +1,218 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #ifndef FITLOGGER_HPP #define FITLOGGER_HPP /*! * \addtogroup FitBase * @{ */ +#include <fstream> #include <iosfwd> #include <iostream> -#include <fstream> #include <sstream> -#include "Initialiser.h" #include "FitParameters.h" +#include "Initialiser.h" #include "TRandom3.h" -#define RESET "\033[0m" -#define BLACK "\033[30m" /* Black */ -#define RED "\033[31m" /* Red */ -#define GREEN "\033[32m" /* Green */ -#define YELLOW "\033[33m" /* Yellow */ -#define BLUE "\033[34m" /* Blue */ -#define MAGENTA "\033[35m" /* Magenta */ -#define CYAN "\033[36m" /* Cyan */ -#define WHITE "\033[37m" /* White */ -#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ -#define BOLDRED "\033[1m\033[31m" /* Bold Red */ -#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ -#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ -#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ -#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ -#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ -#define BOLDWHITE "\033[1m\033[37m" /* Bold White */ - +#define RESET "\033[0m" +#define BLACK "\033[30m" /* Black */ +#define RED "\033[31m" /* Red */ +#define GREEN "\033[32m" /* Green */ +#define YELLOW "\033[33m" /* Yellow */ +#define BLUE "\033[34m" /* Blue */ +#define MAGENTA "\033[35m" /* Magenta */ +#define CYAN "\033[36m" /* Cyan */ +#define WHITE "\033[37m" /* White */ +#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ +#define BOLDRED "\033[1m\033[31m" /* Bold Red */ +#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ +#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ +#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ +#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ +#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ +#define BOLDWHITE "\033[1m\033[37m" /* Bold White */ namespace Logger { -extern int log_verb; //!< Current VERBOSITY -extern int err_verb; //!< Current ERROR VERBOSITY +extern int log_verb; //!< Current VERBOSITY +extern int err_verb; //!< Current ERROR VERBOSITY extern bool external_verb; -extern bool use_colors; //!< Use BASH Terminal Colors Flag -extern bool super_rainbow_mode; //!< For when fitting gets boring. +extern bool use_colors; //!< Use BASH Terminal Colors Flag +extern bool super_rainbow_mode; //!< For when fitting gets boring. extern unsigned int super_rainbow_mode_colour; -extern bool showtrace; // Quick Tracing for debugging +extern bool showtrace; // Quick Tracing for debugging extern int nloggercalls; extern int timelastlog; -extern std::streambuf *default_cout; //!< Where the STDOUT stream is currently directed -extern std::streambuf *default_cerr; //!< Where the STDERR stream is currently directed -extern std::ofstream redirect_stream; //!< Where should unwanted messages be thrown +extern std::streambuf* + default_cout; //!< Where the STDOUT stream is currently directed +extern std::streambuf* + default_cerr; //!< Where the STDERR stream is currently directed +extern std::ofstream + redirect_stream; //!< Where should unwanted messages be thrown } /// Returns full path to file currently in -#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) - +#define __FILENAME__ \ + (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // ------ LOGGER FUNCTIONS ------------ // namespace Logger { - /// NULL Output Stream - extern std::ofstream __LOG_nullstream; +/// NULL Output Stream +extern std::ofstream __LOG_nullstream; - /// Logging Stream - extern std::ostream* __LOG_outstream; +/// Logging Stream +extern std::ostream* __LOG_outstream; } /// Fitter VERBOSITY Enumerations /// These go through the different depths of the fitter. /// /// 0 QUIET - Little output. /// 1 FIT - Top Level Minimizer Status /// 2 MIN - Output from the FCN Minimizer Functions /// 3 SAM - Output from each of the samples during setup etc /// 4 REC - Output during each reconfigure. Percentage progress etc. /// 5 SIG - Output during every signal event that is found. /// 6 EVT - Output during every event. -/// -1 DEB - Will print only debugging info wherever a LOG(DEB) statement was made +/// -1 DEB - Will print only debugging info wherever a LOG(DEB) statement was +/// made enum __LOG_levels { DEB = -1, QUIET, FIT, MIN, SAM, REC, SIG, EVT }; /// Returns log level for a given file/function int __GETLOG_LEVEL(int level, const char* filename, const char* funct); /// Actually runs the logger -std::ostream& __OUTLOG(int level, const char* filename, const char* funct, int line); +std::ostream& __OUTLOG(int level, const char* filename, const char* funct, + int line); /// Global Logging Definitions -#define QLOG(level, stream) \ -{ \ -if (Logger::log_verb >= __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)){ \ - __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << stream << std::endl; \ -} \ -}; - -#define BREAK(level) \ -{ \ \ - if (Logger::log_verb >= __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)){ \ - __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << std::endl; \ - }\ -}; - +#define QLOG(level, stream) \ + { \ + if (Logger::log_verb >= \ + __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \ + __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \ + << std::endl; \ + } \ + }; + +#define BREAK(level) \ + { \ + \ if (Logger::log_verb >= \ + __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \ + __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << std::endl; \ + } \ + }; /// Return whether logging level is valid bool LOGGING(int level); /// Set Global Verbosity void SETVERBOSITY(int level); /// Set Global Verbosity from String void SETVERBOSITY(std::string verb); /// Set Trace Option void SETTRACE(bool val); // ----------- ERROR FUNCTIONS ---------- // /// Error Stream extern std::ostream* __ERR_outstream; /// Fitter ERROR VERBOSITY Enumerations /// /// 0 QUIET - No Error Output /// 1 FTL - Show errors only if fatal /// 2 WRN - Show Warning messages enum __ERR_levels { ERRQUIET = 0, FTL, WRN }; /// Actually runs the error messager -std::ostream& __OUTERR(int level, const char* filename, const char* funct, int line); +std::ostream& __OUTERR(int level, const char* filename, const char* funct, + int line); /// Error Logging Function -#define ERROR(level, stream) \ -{ \ - __OUTERR(level, __FILENAME__, __FUNCTION__, __LINE__) << stream << std::endl; \ -}; +#define ERROR(level, stream) \ + { \ + __OUTERR(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \ + << std::endl; \ + }; // ----------- ERROR HANDLING ------------- // /// Exit the program with given error message stream -#define THROW(stream) \ -{ \ - __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << stream << std::endl; \ - __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Exiting!" << std::endl; \ - std::abort(); \ -} - +#define THROW(stream) \ + { \ + __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << stream \ + << std::endl; \ + __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \ + << "Attempting to save output file." << std::endl; \ + if (FitPar::Config().out && FitPar::Config().out->IsOpen()) { \ + FitPar::Config().out->Write(); \ + FitPar::Config().out->Close(); \ + __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Done." \ + << std::endl; \ + } else { \ + __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \ + << "No output file set." << std::endl; \ + } \ + __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Exiting!" \ + << std::endl; \ + std::abort(); \ + } // ----------- External Logging ----------- // void SETEXTERNALVERBOSITY(int level); void StopTalking(); void StartTalking(); extern "C" { - void shhnuisancepythiaitokay_(void); - void canihaznuisancepythia_(void); +void shhnuisancepythiaitokay_(void); +void canihaznuisancepythia_(void); } - - - - - - - - - // ---------- LEGACY FUNCTIONS -------------- // bool LOG_LEVEL(int level); //! Set LOG VERBOSITY from a string void LOG_VERB(std::string verb); inline void LOG_VERB(int verb) { Logger::log_verb = verb; }; void SET_TRACE(bool val); //! Set ERROR VERBOSITY from a string void ERR_VERB(std::string verb); inline void ERR_VERB(int verb) { Logger::err_verb = verb; }; - -/// Logging Function. Use as a string stream. e.g. LOG(SAM) << "This sample is dope." << std::endl; -std::ostream& _LOG(int level, const char* filename, const char* funct, int line); +/// Logging Function. Use as a string stream. e.g. LOG(SAM) << "This sample is +/// dope." << std::endl; +std::ostream& _LOG(int level, const char* filename, const char* funct, + int line); #define LOG(level) _LOG(level, __FILENAME__, __FUNCTION__, __LINE__) - -//! Error Function. Use as a string stream. e.g. ERR(FTL) << "The fit is completely buggered." << std::endl; -std::ostream& _ERR(int level, const char* filename, const char* funct, int line); +//! Error Function. Use as a string stream. e.g. ERR(FTL) << "The fit is +//! completely buggered." << std::endl; +std::ostream& _ERR(int level, const char* filename, const char* funct, + int line); #define ERR(level) _ERR(level, __FILENAME__, __FUNCTION__, __LINE__) - /*! @} */ #endif - diff --git a/src/Utils/GeneralUtils.cxx b/src/Utils/GeneralUtils.cxx index c99e8a8..e0b10b7 100644 --- a/src/Utils/GeneralUtils.cxx +++ b/src/Utils/GeneralUtils.cxx @@ -1,196 +1,195 @@ // Copyright 2016 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "GeneralUtils.h" std::string GeneralUtils::BoolToStr(bool val) { std::ostringstream ss; ss << val; return ss.str(); } std::string GeneralUtils::IntToStr(int val) { std::ostringstream ss; ss << val; return ss.str(); }; std::string GeneralUtils::DblToStr(double val) { std::ostringstream ss; ss << val; return ss.str(); }; -std::vector<std::string> GeneralUtils::LoadCharToVectStr(int argc, char* argv[]){ +std::vector<std::string> GeneralUtils::LoadCharToVectStr(int argc, + char* argv[]) { std::vector<std::string> vect; - for (int i = 1; i < argc; i++){ - vect.push_back( std::string(argv[i]) ); + for (int i = 1; i < argc; i++) { + vect.push_back(std::string(argv[i])); } return vect; } -std::vector<std::string> GeneralUtils::ParseToStr(std::string str, const char* del) { - +std::vector<std::string> GeneralUtils::ParseToStr(std::string str, + const char* del) { std::istringstream stream(str); std::string temp_string; std::vector<std::string> vals; while (std::getline(stream >> std::ws, temp_string, *del)) { if (temp_string.empty()) continue; vals.push_back(temp_string); } return vals; } std::vector<double> GeneralUtils::ParseToDbl(std::string str, const char* del) { - std::istringstream stream(str); std::string temp_string; std::vector<double> vals; while (std::getline(stream >> std::ws, temp_string, *del)) { if (temp_string.empty()) continue; std::istringstream stream(temp_string); double entry; stream >> entry; vals.push_back(entry); - } return vals; } std::vector<int> GeneralUtils::ParseToInt(std::string str, const char* del) { - std::istringstream stream(str); std::string temp_string; std::vector<int> vals; while (std::getline(stream >> std::ws, temp_string, *del)) { if (temp_string.empty()) continue; std::istringstream stream(temp_string); int entry; stream >> entry; vals.push_back(entry); - } return vals; } double GeneralUtils::StrToDbl(std::string str) { - std::istringstream stream(str); double val; stream >> val; return val; } int GeneralUtils::StrToInt(std::string str) { - std::istringstream stream(str); int val; stream >> val; return val; } bool GeneralUtils::StrToBool(std::string str) { - // convert result to lower case for (uint i = 0; i < str.size(); i++) str[i] = std::tolower(str[i]); // Test for true/false - if (!str.compare("false")) return false; - else if (!str.compare("true") ) return true; + if (!str.compare("false")) + return false; + else if (!str.compare("true")) + return true; if (str.empty()) return false; // Push into bool std::istringstream stream(str); bool val; stream >> val; return val; } -std::vector<std::string> GeneralUtils::ParseFileToStr(std::string str, const char* del) { - +std::vector<std::string> GeneralUtils::ParseFileToStr(std::string str, + const char* del) { std::vector<std::string> linevect; std::string line; std::ifstream read; read.open(str.c_str()); if (!read.is_open()) { - THROW("Cannot open file " << str << " in ParseFileToStr"); + ERROR(FTL, "Cannot open file " << str << " in ParseFileToStr"); + throw; } - while ( std::getline(read >> std::ws, line, *del) ) { + while (std::getline(read >> std::ws, line, *del)) { linevect.push_back(line); } read.close(); return linevect; } std::string GeneralUtils::GetTopLevelDir() { - static bool first = true; static std::string topLevelVarVal; if (first) { - char * const var = getenv("NUISANCE"); + char* const var = getenv("NUISANCE"); if (!var) { - THROW("Cannot find top level directory! Set the NUISANCE environmental variable"); + ERROR(FTL, + "Cannot find top level directory! Set the NUISANCE environmental " + "variable"); + throw; } topLevelVarVal = std::string(var); first = false; } return topLevelVarVal; } - -std::string GeneralUtils::ReplaceAll(std::string const &inp, std::string const &from, - std::string const &to) { +std::string GeneralUtils::ReplaceAll(std::string const& inp, + std::string const& from, + std::string const& to) { std::stringstream ss(""); size_t nextOccurence = 0; size_t prevOccurence = 0; bool AtEnd = false; while (!AtEnd) { nextOccurence = inp.find(from, prevOccurence); if (nextOccurence == std::string::npos) { if (prevOccurence == inp.length()) { break; } AtEnd = true; } if ((nextOccurence != prevOccurence) || (nextOccurence == 0)) { ss << inp.substr(prevOccurence, (nextOccurence - prevOccurence)); if (!AtEnd) { ss << to; } } prevOccurence = nextOccurence + from.size(); } return ss.str(); }