diff --git a/src/samples/MCTools/NuisToCAFTruth.cxx b/src/samples/MCTools/NuisToCAFTruth.cxx
index 5ba6935..2377685 100644
--- a/src/samples/MCTools/NuisToCAFTruth.cxx
+++ b/src/samples/MCTools/NuisToCAFTruth.cxx
@@ -1,253 +1,253 @@
// Copyright 2018 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 .
*******************************************************************************/
//********************************************************************
#include "samples/SimpleMCStudy.hxx"
#include "utility/EventTopologyUtility.hxx"
#include "utility/FullEventUtility.hxx"
#include "utility/KinematicUtility.hxx"
#include "utility/PDGCodeUtility.hxx"
#include "utility/ROOTUtility.hxx"
#include "persistency/ROOTOutput.hxx"
using namespace nuis::event;
using namespace nuis::utility;
class NuisToCAFTruth : public SimpleMCStudy {
TreeFile outputTree;
// int mode;
int isFD;
int isFHC;
int isCC;
int nuPDG;
int nuPDGunosc;
int LepPDG;
double NuMomX;
double NuMomY;
double NuMomZ;
double Ev;
double LepMomX;
double LepMomY;
double LepMomZ;
double LepE;
double LepNuAngle;
double Q2;
double W;
double X;
double Y;
int nP;
int nN;
int nipip;
int nipim;
int nipi0;
int nikp;
int nikm;
int nik0;
int niem;
int niother;
int nNucleus;
int nUNKNOWN;
double eP;
double eN;
double ePip;
double ePim;
double ePi0;
double eOther;
double xsecWeight;
bool isOscSwap;
public:
NuisToCAFTruth() { ReadGlobalConfigDefaults(); }
void Initialize(fhicl::ParameterSet const &instance_sample_configuration) {
- outputTree = AddNewTTreeToFile(nuis::persistency::GetOutputFile().get(),
- "cafTruthTree");
-
isFD = instance_sample_configuration.get("is_fd", false);
isFHC = instance_sample_configuration.get("is_numode", true);
isOscSwap = instance_sample_configuration.get("is_nueswap", false);
// Perform any per-sample configuration in the base class
SimpleMCStudy::Initialize(instance_sample_configuration);
+ outputTree = AddNewTTreeToFile(nuis::persistency::GetOutputFile().get(),
+ "cafTruthTree", write_directory);
+
// outputTree->Branch("mode", &mode, "mode/I");
outputTree->Branch("isFD", &isFD, "isFD/I");
outputTree->Branch("isFHC", &isFHC, "isFHC/I");
outputTree->Branch("isCC", &isCC, "isCC/I");
outputTree->Branch("nuPDG", &nuPDG, "nuPDG/I");
outputTree->Branch("nuPDGunosc", &nuPDGunosc, "nuPDGunosc/I");
outputTree->Branch("LepPDG", &LepPDG, "LepPDG/I");
outputTree->Branch("NuMomX", &NuMomX, "NuMomX/D");
outputTree->Branch("NuMomY", &NuMomY, "NuMomY/D");
outputTree->Branch("NuMomZ", &NuMomZ, "NuMomZ/D");
outputTree->Branch("Ev", &Ev, "Ev/D");
outputTree->Branch("LepMomX", &LepMomX, "LepMomX/D");
outputTree->Branch("LepMomY", &LepMomY, "LepMomY/D");
outputTree->Branch("LepMomZ", &LepMomZ, "LepMomZ/D");
outputTree->Branch("LepE", &LepE, "LepE/D");
outputTree->Branch("LepNuAngle", &LepNuAngle, "LepNuAngle/D");
outputTree->Branch("Q2", &Q2, "Q2/D");
outputTree->Branch("W", &W, "W/D");
outputTree->Branch("X", &X, "X/D");
outputTree->Branch("Y", &Y, "Y/D");
outputTree->Branch("nP", &nP, "nP/I");
outputTree->Branch("nN", &nN, "nN/I");
outputTree->Branch("nipip", &nipip, "nipip/I");
outputTree->Branch("nipim", &nipim, "nipim/I");
outputTree->Branch("nipi0", &nipi0, "nipi0/I");
outputTree->Branch("nikp", &nikp, "nikp/I");
outputTree->Branch("nikm", &nikm, "nikm/I");
outputTree->Branch("nik0", &nik0, "nik0/I");
outputTree->Branch("niem", &niem, "niem/I");
outputTree->Branch("niother", &niother, "niother/I");
outputTree->Branch("nNucleus", &nNucleus, "nNucleus/I");
outputTree->Branch("nUNKNOWN", &nUNKNOWN, "nUNKNOWN/I");
outputTree->Branch("eP", &eP, "eP/D");
outputTree->Branch("eN", &eN, "eN/D");
outputTree->Branch("ePip", &ePip, "ePip/D");
outputTree->Branch("ePim", &ePim, "ePim/D");
outputTree->Branch("ePi0", &ePi0, "ePi0/D");
outputTree->Branch("eOther", &eOther, "eOther/D");
outputTree->Branch("xsecWeight", &xsecWeight, "xsecWeight/D");
//! Here you do whatever you want to do on a per-event basis.
//! This method will be run for every event given by the input handler,
//! the weight allows differential xsecs to be plotted easily and also
//! contains any requested reweightable parameter variations.
ProcessEventFunction = [&](nuis::event::FullEvent const &ev,
double weight) -> void {
xsecWeight = weight;
nP = 0;
nN = 0;
nipip = 0;
nipim = 0;
nipi0 = 0;
nikp = 0;
nikm = 0;
nik0 = 0;
niem = 0;
niother = 0;
nNucleus = 0;
nUNKNOWN = 0;
eP = 0;
eN = 0;
ePip = 0;
ePim = 0;
ePi0 = 0;
eOther = 0;
Particle ISLep = GetHMISNeutralLepton(ev);
Particle FSLep = GetHMFSLepton(ev);
isCC = IsChargedLepton(FSLep.pdg);
nuPDG = ISLep.pdg;
nuPDGunosc = isOscSwap
? (ISLep.pdg < 0 ? pdgcodes::kNuMuBar : pdgcodes::kNuMu)
: ISLep.pdg;
LepPDG = FSLep.pdg;
NuMomX = ISLep.P4.X();
NuMomY = ISLep.P4.Y();
NuMomZ = ISLep.P4.Z();
Ev = ISLep.P4.E();
LepMomX = FSLep.P4.X();
LepMomY = FSLep.P4.Y();
LepMomZ = FSLep.P4.Z();
LepE = FSLep.P4.E();
LepNuAngle = FSLep.Dir().Dot(ISLep.Dir());
TLorentzVector FourMomTransfer = GetEnergyMomentumTransfer(ev);
Q2 = -FourMomTransfer.Mag2();
W = sqrt(-Q2 +
2 * pdgmasses::kNucleonAverageMass_MeV * FourMomTransfer.E() +
pdgmasses::kNucleonAverageMass_MeV *
pdgmasses::kNucleonAverageMass_MeV);
X = Q2 / (2 * pdgmasses::kNucleonAverageMass_MeV * FourMomTransfer.E());
Y = 1 - LepE / Ev;
for (Particle const &p : GetNuclearLeavingParticles(ev)) {
if (p == FSLep) {
continue;
}
if (IsProton(p.pdg)) {
nP++;
eP += p.KE();
} else if (IsNeutron(p.pdg)) {
nN++;
eN += p.KE();
} else if (IsPositivePion(p.pdg)) {
nipip++;
ePip += p.KE();
} else if (IsNegativePion(p.pdg)) {
nipim++;
ePim += p.KE();
} else if (IsNeutralPion(p.pdg)) {
nipi0++;
ePi0 += p.KE();
} else if (IsPositiveKaon(p.pdg)) {
nikp++;
eOther += p.KE();
} else if (IsNegativeKaon(p.pdg)) {
nikm++;
eOther += p.KE();
} else if (IsNeutralKaon(p.pdg)) {
nik0++;
eOther += p.KE();
} else if (IsGamma(p.pdg)) {
niem++;
eOther += p.KE();
} else if (IsNuclearPDG(p.pdg)) {
nNucleus++;
} else {
niother++;
eOther += p.KE();
}
}
outputTree->Fill();
};
}
std::string Name() { return "NuisToCAFTruth"; }
void Write() {}
};
//! These declarations allow your class to be loaded dynamically by NUISANCE
DECLARE_PLUGIN(IEventProcessor, NuisToCAFTruth);
diff --git a/src/utility/ROOTUtility.hxx b/src/utility/ROOTUtility.hxx
index 60551e8..75b0d47 100644
--- a/src/utility/ROOTUtility.hxx
+++ b/src/utility/ROOTUtility.hxx
@@ -1,155 +1,164 @@
// Copyright 2018 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NUISANCE. If not, see .
*******************************************************************************/
#ifndef UTILITY_ROOTUTILITY_HXX_SEEN
#define UTILITY_ROOTUTILITY_HXX_SEEN
#include "exception/exception.hxx"
#include "TFile.h"
#include "TTree.h"
#include
#include
#include
#include
namespace nuis {
namespace utility {
NEW_NUIS_EXCEPT(failed_to_open_TFile);
NEW_NUIS_EXCEPT(failed_to_get_TTree);
inline void CloseTFile(TFile *f = nullptr) {
if (f) {
std::cout << "[INFO]: Shutting TFile: " << f->GetName() << ", " << f
<< std::endl;
f->Close();
}
delete f;
}
using TFile_ptr = std::unique_ptr;
inline TFile_ptr make_unique_TFile(TFile *f) {
return TFile_ptr(f, &CloseTFile);
}
inline TFile_ptr CheckOpenTFile(std::string const &fname,
char const *opts = "") {
TDirectory *ogDir = gDirectory;
TFile *inpF = new TFile(fname.c_str(), opts);
if (!inpF || !inpF->IsOpen()) {
throw failed_to_open_TFile()
<< "[ERROR]: Couldn't open input file: " << std::quoted(fname);
}
if (ogDir) {
ogDir->cd();
}
return make_unique_TFile(inpF);
}
struct TreeFile {
TFile_ptr file;
TTree *tree;
bool file_owned;
TreeFile()
: file(make_unique_TFile(nullptr)), tree(nullptr), file_owned(false) {}
TreeFile(TreeFile const &other) = delete;
TreeFile &operator=(TreeFile &&other) {
file = std::move(other.file);
tree = other.tree;
file_owned = other.file_owned;
other.file = nullptr;
other.tree = nullptr;
other.file_owned = false;
return *this;
}
TreeFile(TreeFile &&other)
: file(std::move(other.file)), tree(other.tree),
file_owned(other.file_owned) {
other.file = nullptr;
other.tree = nullptr;
other.file_owned = false;
}
TTree *operator->() { return tree; }
~TreeFile() {
if (!file_owned) {
file.release();
}
}
};
inline TreeFile CheckGetTTree(TFile *file, std::string const &tname) {
TreeFile tf;
tf.file = make_unique_TFile(file);
tf.tree = dynamic_cast(tf.file->Get(tname.c_str()));
tf.file_owned = false;
if (!tf.tree) {
throw failed_to_get_TTree()
<< "[ERROR]: Failed to get TTree named: " << std::quoted(tname)
<< " from TFile: " << std::quoted(file->GetName());
}
std::cout << "[INFO]: Opened TFile: " << file->GetName() << ", " << file
<< std::endl;
return tf;
}
inline TreeFile CheckGetTTree(std::string const &fname,
std::string const &tname, char const *opts = "") {
TreeFile tf = CheckGetTTree(CheckOpenTFile(fname, opts).release(), tname);
tf.file_owned = true;
return tf;
}
inline TreeFile MakeNewTTree(std::string const &fname, std::string const &tname,
char const *opts = "") {
TreeFile tf;
tf.file = CheckOpenTFile(fname, opts);
tf.tree = new TTree(tname.c_str(), "");
tf.tree->SetDirectory(tf.file.get());
tf.file_owned = true;
return tf;
}
-inline TreeFile AddNewTTreeToFile(TFile *f, std::string const &tname) {
+inline TreeFile AddNewTTreeToFile(TFile *f, std::string const &tname,
+ std::string const &dirname = "") {
TreeFile tf;
// This is pretty dumb...
tf.file = make_unique_TFile(f);
tf.tree = new TTree(tname.c_str(), "");
- tf.tree->SetDirectory(tf.file.get());
+ if (dirname.size()) {
+ TDirectory *dir = tf.file->GetDirectory(dirname.c_str());
+ if (!dir) {
+ dir = tf.file->mkdir(dirname.c_str());
+ }
+ tf.tree->SetDirectory(dir);
+ } else {
+ tf.tree->SetDirectory(tf.file.get());
+ }
tf.file_owned = false;
return tf;
}
inline std::string SanitizeROOTObjectName(std::string name) { return name; }
} // namespace utility
} // namespace nuis
#endif