11 #include <analysis/modules/VariablesToHistogram/VariablesToHistogramModule.h>
13 #include <analysis/dataobjects/ParticleList.h>
14 #include <analysis/VariableManager/Manager.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/pcore/ProcHandler.h>
17 #include <framework/utilities/MakeROOTCompatible.h>
18 #include <framework/core/ModuleParam.templateDetails.h>
19 #include <framework/utilities/RootFileCreationManager.h>
34 setDescription(
"Calculate variables specified by the user for a given ParticleList and save them into one or two dimensional histograms.");
35 setPropertyFlags(c_ParallelProcessingCertified | c_TerminateInAllProcesses);
37 std::vector<std::tuple<std::string, int, float, float>> emptylist;
38 std::vector<std::tuple<std::string, int, float, float, std::string, int, float, float>> emptylist_2d;
39 addParam(
"particleList", m_particleList,
40 "Name of particle list with reconstructed particles. If no list is provided the variables are saved once per event (only possible for event-type variables)",
42 addParam(
"variables", m_variables,
43 "List of variables to save. Variables are taken from Variable::Manager, and are identical to those available to e.g. ParticleSelector.",
45 addParam(
"variables_2d", m_variables_2d,
46 "List of variable pairs to save. Variables are taken from Variable::Manager, and are identical to those available to e.g. ParticleSelector.",
49 addParam(
"fileName", m_fileName,
"Name of ROOT file for output.",
string(
"VariablesToHistogram.root"));
50 addParam(
"directory", m_directory,
"Directory for all histograms **inside** the file to allow for histograms from multiple "
51 "particlelists in the same file without conflicts", m_directory);
56 void VariablesToHistogramModule::initialize()
58 if (not m_particleList.empty())
62 m_file = RootFileCreationManager::getInstance().getFile(m_fileName);
65 TDirectory::TContext directoryGuard(m_file.get());
66 if (not m_directory.empty()) {
68 m_file->mkdir(m_directory.c_str());
69 m_file->cd(m_directory.c_str());
72 for (
const auto& varTuple : m_variables) {
77 std::tie(varStr, varNbins, low, high) = varTuple;
80 auto ptr = std::make_unique<StoreObjPtr<RootMergeable<TH1D>>>(
"", DataStore::c_Persistent);
81 ptr->registerInDataStore(m_fileName + m_directory + varStr, DataStore::c_DontWriteOut);
82 ptr->construct(compatibleName.c_str(), compatibleName.c_str(), varNbins, low, high);
83 m_hists.emplace_back(std::move(ptr));
88 B2ERROR(
"Variable '" << varStr <<
"' is not available in Variable::Manager!");
90 m_functions.push_back(var->function);
94 for (
const auto& varTuple : m_variables_2d) {
103 std::tie(varStr1, varNbins1, low1, high1, varStr2, varNbins2, low2, high2) = varTuple;
107 auto ptr2d = std::make_unique<StoreObjPtr<RootMergeable<TH2D>>>(
"", DataStore::c_Persistent);
108 ptr2d->registerInDataStore(m_fileName + m_directory + varStr1 + varStr2, DataStore::c_DontWriteOut);
109 ptr2d->construct((compatibleName1 + compatibleName2).c_str(), (compatibleName1 + compatibleName2).c_str(),
110 varNbins1, low1, high1, varNbins2, low2, high2);
111 m_2d_hists.emplace_back(std::move(ptr2d));
116 B2ERROR(
"Variable '" << varStr1 <<
"' is not available in Variable::Manager!");
118 m_functions_2d_1.push_back(var1->function);
124 B2ERROR(
"Variable '" << varStr2 <<
"' is not available in Variable::Manager!");
126 m_functions_2d_2.push_back(var2->
function);
132 void VariablesToHistogramModule::event()
134 unsigned int nVars = m_variables.size();
135 unsigned int nVars_2d = m_variables_2d.size();
136 std::vector<float> vars(nVars);
137 std::vector<float> vars_2d_1(nVars_2d);
138 std::vector<float> vars_2d_2(nVars_2d);
140 if (m_particleList.empty()) {
141 for (
unsigned int iVar = 0; iVar < nVars; iVar++) {
142 vars[iVar] = m_functions[iVar](
nullptr);
143 (*m_hists[iVar])->get().Fill(vars[iVar]);
145 for (
unsigned int iVar = 0; iVar < nVars_2d; iVar++) {
146 vars_2d_1[iVar] = m_functions_2d_1[iVar](
nullptr);
147 vars_2d_2[iVar] = m_functions_2d_2[iVar](
nullptr);
148 (*m_2d_hists[iVar])->get().Fill(vars_2d_1[iVar], vars_2d_2[iVar]);
153 unsigned int nPart = particlelist->getListSize();
154 for (
unsigned int iPart = 0; iPart < nPart; iPart++) {
155 const Particle* particle = particlelist->getParticle(iPart);
156 for (
unsigned int iVar = 0; iVar < nVars; iVar++) {
157 vars[iVar] = m_functions[iVar](particle);
158 (*m_hists[iVar])->get().Fill(vars[iVar]);
160 for (
unsigned int iVar = 0; iVar < nVars_2d; iVar++) {
161 vars_2d_1[iVar] = m_functions_2d_1[iVar](particle);
162 vars_2d_2[iVar] = m_functions_2d_2[iVar](particle);
163 (*m_2d_hists[iVar])->get().Fill(vars_2d_1[iVar], vars_2d_2[iVar]);
169 void VariablesToHistogramModule::terminate()
171 if (!ProcHandler::parallelProcessingUsed() or ProcHandler::isOutputProcess()) {
172 TDirectory::TContext directoryGuard(m_file.get());
173 if (not m_directory.empty()) {
174 m_file->cd(m_directory.c_str());
176 B2INFO(
"Writing Histograms to " << gDirectory->GetPath());
177 unsigned int nVars = m_variables.size();
178 for (
unsigned int iVar = 0; iVar < nVars; iVar++) {
179 (*m_hists[iVar])->write(gDirectory);
181 unsigned int nVars_2d = m_variables_2d.size();
182 for (
unsigned int iVar = 0; iVar < nVars_2d; iVar++) {
183 (*m_2d_hists[iVar])->write(gDirectory);
186 const bool writeError = m_file->TestBit(TFile::kWriteError);
189 B2FATAL(
"A write error occured while saving '" << m_fileName <<
"', please check if enough disk space is available.");