Belle II Software  release-05-02-19
VariablesToHistogramModule.cc
1 /**************************************************************************
2 * BASF2 (Belle Analysis Framework 2) *
3 * Copyright(C) 2013 - Belle II Collaboration *
4 * *
5 * Author: The Belle II Collaboration *
6 * Contributors: Thomas Keck *
7 * *
8 * This software is provided "as is" without any warranty. *
9 **************************************************************************/
10 
11 #include <analysis/modules/VariablesToHistogram/VariablesToHistogramModule.h>
12 
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>
20 
21 #include <memory>
22 
23 using namespace std;
24 using namespace Belle2;
25 
26 // Register module in the framework
27 REG_MODULE(VariablesToHistogram)
28 
29 
31  Module()
32 {
33  //Set module properties
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);
36 
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)",
41  std::string(""));
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.",
44  emptylist);
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.",
47  emptylist_2d);
48 
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);
52 
53  m_file = nullptr;
54 }
55 
56 void VariablesToHistogramModule::initialize()
57 {
58  if (not m_particleList.empty())
59  StoreObjPtr<ParticleList>().isRequired(m_particleList);
60 
61  // Check if we can acces the given file
62  m_file = RootFileCreationManager::getInstance().getFile(m_fileName);
63  if (!m_file) return;
64  // Make sure we don't disturb the global directory for other modules, friggin side effects everywhere
65  TDirectory::TContext directoryGuard(m_file.get());
66  if (not m_directory.empty()) {
67  m_directory = makeROOTCompatible(m_directory);
68  m_file->mkdir(m_directory.c_str());
69  m_file->cd(m_directory.c_str());
70  }
71 
72  for (const auto& varTuple : m_variables) {
73  std::string varStr;
74  int varNbins = 0;
75  float low = 0;
76  float high = 0;
77  std::tie(varStr, varNbins, low, high) = varTuple;
78  std::string compatibleName = makeROOTCompatible(varStr);
79 
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));
84 
85  //also collection function pointers
86  const Variable::Manager::Var* var = Variable::Manager::Instance().getVariable(varStr);
87  if (!var) {
88  B2ERROR("Variable '" << varStr << "' is not available in Variable::Manager!");
89  } else {
90  m_functions.push_back(var->function);
91  }
92  }
93 
94  for (const auto& varTuple : m_variables_2d) {
95  std::string varStr1;
96  int varNbins1 = 0;
97  float low1 = 0;
98  float high1 = 0;
99  std::string varStr2;
100  int varNbins2 = 0;
101  float low2 = 0;
102  float high2 = 0;
103  std::tie(varStr1, varNbins1, low1, high1, varStr2, varNbins2, low2, high2) = varTuple;
104  std::string compatibleName1 = makeROOTCompatible(varStr1);
105  std::string compatibleName2 = makeROOTCompatible(varStr2);
106 
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));
112 
113  //also collection function pointers
114  const Variable::Manager::Var* var1 = Variable::Manager::Instance().getVariable(varStr1);
115  if (!var1) {
116  B2ERROR("Variable '" << varStr1 << "' is not available in Variable::Manager!");
117  } else {
118  m_functions_2d_1.push_back(var1->function);
119  }
120 
121  //also collection function pointers
122  const Variable::Manager::Var* var2 = Variable::Manager::Instance().getVariable(varStr2);
123  if (!var2) {
124  B2ERROR("Variable '" << varStr2 << "' is not available in Variable::Manager!");
125  } else {
126  m_functions_2d_2.push_back(var2->function);
127  }
128  }
129 
130 }
131 
132 void VariablesToHistogramModule::event()
133 {
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);
139 
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]);
144  }
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]);
149  }
150 
151  } else {
152  StoreObjPtr<ParticleList> particlelist(m_particleList);
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]);
159  }
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]);
164  }
165  }
166  }
167 }
168 
169 void VariablesToHistogramModule::terminate()
170 {
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());
175  }
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);
180  }
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);
184  }
185 
186  const bool writeError = m_file->TestBit(TFile::kWriteError);
187  m_file.reset();
188  if (writeError) {
189  B2FATAL("A write error occured while saving '" << m_fileName << "', please check if enough disk space is available.");
190  }
191  }
192 }
Belle2::Variable::Manager::Var
A variable returning a floating-point value for a given Particle.
Definition: Manager.h:137
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Variable::Manager::Var::function
FunctionPtr function
Pointer to function.
Definition: Manager.h:138
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::makeROOTCompatible
std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
Definition: MakeROOTCompatible.cc:74
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::Particle
Class to store reconstructed particles.
Definition: Particle.h:77
Belle2::VariablesToHistogramModule
Module to calculate variables specified by the user for a given ParticleList and save them into an Hi...
Definition: VariablesToHistogramModule.h:44