Belle II Software development
RbTuple.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/core/HistoModule.h>
10#include <framework/pcore/RbTuple.h>
11#include <framework/pcore/ProcHandler.h>
12
13#include <framework/logging/Logger.h>
14
15#include <TFileMerger.h>
16#include <TFile.h>
17
18#include <unistd.h>
19#include <dirent.h>
20#include <cerrno>
21
22using namespace std;
23using namespace Belle2;
24
26
27// Constructor and Destructor
28RbTupleManager::RbTupleManager() = default;
29
30RbTupleManager::~RbTupleManager() = default;
31
32RbTupleManager::RbTupleManager(int nproc, const char* file, const char* workdir):
33 m_nproc(nproc), m_filename(file), m_workdir(workdir)
34{
35}
36
37// Access to Singleton
39{
40 if (!s_instance) {
42 }
43 return *s_instance;
44}
45
46// Global initialization
47void RbTupleManager::init(int nprocess, const char* filename, const char* workdir)
48{
49 m_filename = filename;
50 m_nproc = nprocess;
51 m_workdir = workdir;
52
53 if (ProcHandler::EvtProcID() == -1 && m_nproc > 0) {
54
55 // should be called only from main
56 // Open current directory
57 std::string dir = m_workdir;
58 DIR* dp;
59 struct dirent* dirp;
60 if ((dp = opendir(dir.c_str())) == nullptr) {
61 B2ERROR("Error on opening the directory."
62 << LogVar("directory", dir));
63 return;
64 }
65
66 // Scan the directory and delete temporary files
67 std::string compfile = m_filename + ".";
68 while ((dirp = readdir(dp)) != nullptr) {
69 std::string curfile = std::string(dirp->d_name);
70 if (curfile.compare(0, compfile.size(), compfile) == 0) {
71 // unlink(curfile.c_str());
72 unlink((m_workdir + "/" + curfile).c_str());
73 }
74 }
75 closedir(dp);
76 B2INFO("RbTupleManager: old temporary histogram files deleted.");
77 }
78}
79
80// Function to register histogram definitions
82{
83 m_histdefs.push_back(mod);
84}
85
86// Function called from event processes
87int RbTupleManager::begin(int procid)
88{
89 if (m_nproc > 0) {
90 std::string fileNamePlusId = m_workdir + "/" +
91 m_filename + '.' + std::to_string(procid);
92 m_root = new TFile(fileNamePlusId.c_str(), "update");
93 // printf("RbTupleManager: histo file opened for process %d (pid=%d)\n",
94 // procid, getpid());
95 B2INFO("RbTupleManager: histogram file opened."
96 << LogVar("process", procid)
97 << LogVar("pid", getpid()));
98 } else {
99 m_root = new TFile(m_filename.c_str(), "recreate");
100 // printf("RbTupleManager: initialized for single-process\n");
101 B2INFO("RbTupleManager: initialized for single process.");
102 }
103 if (m_root == nullptr) return -1;
104 // printf ( "RbTupleManager::TFile opened\n" );
105
106 for (auto& mod : m_histdefs) {
107 auto* hmod = (HistoModule*) mod;
108 hmod->defineHisto();
109 }
110
111 // printf ( "RbTupleManager::Histograms defined in proc %d\n", procid );
112
113 return 0;
114}
115
117{
118 if (m_root != nullptr) {
119 m_root->Write();
120 m_root->Close();
121 delete m_root;
122 m_root = nullptr;
123 }
124 return 0;
125}
126
128{
129 if (m_root != nullptr) {
130 m_root->Write();
131 }
132 return 0;
133}
134
135// Functions called from main process
136int RbTupleManager::hadd(bool deleteflag)
137{
138 // No need to call this function when nprocess=0
139 if (m_nproc == 0) {
140 // if ( m_root != NULL ) terminate();
141 return 0;
142 }
143
144 B2INFO("RbTupleManager: hadd started.");
145
146 // Set up merger with output file
147 TFileMerger merger(false, false);
148 if (!merger.OutputFile(m_filename.c_str())) {
149 B2ERROR("RbTupleManager: error on opening the output file."
150 << LogVar("file name", m_filename));
151 return -1;
152 }
153
154 // Open current directory
155 // std::string dir = ".";
156 std::string dir = m_workdir;
157 DIR* dp;
158 struct dirent* dirp;
159 if ((dp = opendir(dir.c_str())) == nullptr) {
160 B2ERROR("RbTubleManager: error on opening the directory."
161 << LogVar("directory", dir));
162 return errno;
163 }
164
165 std::vector<std::string> filenames;
166 // Scan the directory and register all histogram files
167 // std::string compfile = dir + "/" + m_filename + ".";
168 std::string compfile = m_filename + ".";
169 B2INFO(LogVar("compfile", compfile));
170 while ((dirp = readdir(dp)) != nullptr) {
171 std::string curfile = std::string(dirp->d_name);
172 // printf("Checking %s with compfile%s\n", curfile.c_str(), compfile.c_str());
173 if (curfile.compare(0, compfile.size(), compfile) == 0) {
174 printf("RbTupleManager:: adding file =%s\n", curfile.c_str());
175 merger.AddFile((m_workdir + "/" + curfile).c_str());
176 filenames.push_back(m_workdir + "/" + curfile);
177 }
178 }
179 closedir(dp);
180
181 // Do Merge
182 if (!merger.Merge()) {
183 // printf ( "RbTupleManager:: error to merge files\n" );
184 B2ERROR("RbTupleManager: error on merging files.");
185 return -1;
186 }
187
188 if (deleteflag) {
189 // Delete temporary files
190 vector<string>::iterator it;
191 for (it = filenames.begin(); it != filenames.end(); ++it) {
192 string& hfile = *it;
193 unlink(hfile.c_str());
194 }
195 }
196
197 B2INFO("RbTupleManager: histogram files are added.");
198
199 return 0;
200}
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
Base class for Modules.
Definition: Module.h:72
static int EvtProcID()
Return ID of the current process.
Definition: ProcHandler.cc:248
Class to manage histograms defined in registered modules.
Definition: RbTuple.h:29
TFile * m_root
Histogram output file.
Definition: RbTuple.h:78
static RbTupleManager & Instance()
Access to singleton.
Definition: RbTuple.cc:38
int hadd(bool deleteflag=true)
Functions to add up all histogram files.
Definition: RbTuple.cc:136
std::string m_workdir
Name of working directory.
Definition: RbTuple.h:77
int terminate()
Function called by HistoManager module at the end.
Definition: RbTuple.cc:116
std::string m_filename
Name of histogram output file.
Definition: RbTuple.h:76
int dump()
Function to dump histograms/tuples to the file.
Definition: RbTuple.cc:127
void init(int nprocess, const char *filename, const char *workdir=".")
Global initialization.
Definition: RbTuple.cc:47
int begin(int pid)
Function called by HistoManager module for the first event.
Definition: RbTuple.cc:87
int m_nproc
Number of parallel processes.
Definition: RbTuple.h:75
void register_module(Module *)
Functions called by analysis modules in mother process.
Definition: RbTuple.cc:81
std::vector< Module * > m_histdefs
registered HistoModules.
Definition: RbTuple.h:74
static RbTupleManager * s_instance
singleton instance.
Definition: RbTuple.h:72
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.
STL namespace.