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 <sys/types.h>
19#include <unistd.h>
20#include <dirent.h>
21#include <cerrno>
22#include <iostream>
23
24using namespace std;
25using namespace Belle2;
26
28
29// Constructor and Destructor
30RbTupleManager::RbTupleManager() = default;
31
32RbTupleManager::~RbTupleManager() = default;
33
34RbTupleManager::RbTupleManager(int nproc, const char* file, const char* workdir):
35 m_nproc(nproc), m_filename(file), m_workdir(workdir)
36{
37}
38
39// Access to Singleton
41{
42 if (!s_instance) {
44 }
45 return *s_instance;
46}
47
48// Global initialization
49void RbTupleManager::init(int nprocess, const char* filename, const char* workdir)
50{
51 m_filename = filename;
52 m_nproc = nprocess;
53 m_workdir = workdir;
54
55 if (ProcHandler::EvtProcID() == -1 && m_nproc > 0) {
56
57 // should be called only from main
58 // Open current directory
59 std::string dir = m_workdir;
60 DIR* dp;
61 struct dirent* dirp;
62 if ((dp = opendir(dir.c_str())) == nullptr) {
63 B2ERROR("Error on opening the directory."
64 << LogVar("directory", dir));
65 return;
66 }
67
68 // Scan the directory and delete temporary files
69 std::string compfile = m_filename + ".";
70 while ((dirp = readdir(dp)) != nullptr) {
71 std::string curfile = std::string(dirp->d_name);
72 if (curfile.compare(0, compfile.size(), compfile) == 0) {
73 // unlink(curfile.c_str());
74 unlink((m_workdir + "/" + curfile).c_str());
75 }
76 }
77 closedir(dp);
78 B2INFO("RbTupleManager: old temporary histogram files deleted.");
79 }
80}
81
82// Function to register histogram definitions
84{
85 m_histdefs.push_back(mod);
86}
87
88// Function called from event processes
89int RbTupleManager::begin(int procid)
90{
91 if (m_nproc > 0) {
92 std::string fileNamePlusId = m_workdir + "/" +
93 m_filename + '.' + std::to_string(procid);
94 m_root = new TFile(fileNamePlusId.c_str(), "update");
95 // printf("RbTupleManager: histo file opened for process %d (pid=%d)\n",
96 // procid, getpid());
97 B2INFO("RbTupleManager: histogram file opened."
98 << LogVar("process", procid)
99 << LogVar("pid", getpid()));
100 } else {
101 m_root = new TFile(m_filename.c_str(), "recreate");
102 // printf("RbTupleManager: initialized for single-process\n");
103 B2INFO("RbTupleManager: initialized for single process.");
104 }
105 if (m_root == nullptr) return -1;
106 // printf ( "RbTupleManager::TFile opened\n" );
107
108 for (auto& mod : m_histdefs) {
109 auto* hmod = (HistoModule*) mod;
110 hmod->defineHisto();
111 }
112
113 // printf ( "RbTupleManager::Histograms defined in proc %d\n", procid );
114
115 return 0;
116}
117
119{
120 if (m_root != nullptr) {
121 m_root->Write();
122 m_root->Close();
123 delete m_root;
124 m_root = nullptr;
125 }
126 return 0;
127}
128
130{
131 if (m_root != nullptr) {
132 m_root->Write();
133 }
134 return 0;
135}
136
137// Functions called from main process
138int RbTupleManager::hadd(bool deleteflag)
139{
140 // No need to call this function when nprocess=0
141 if (m_nproc == 0) {
142 // if ( m_root != NULL ) terminate();
143 return 0;
144 }
145
146 B2INFO("RbTupleManager: hadd started.");
147
148 // Set up merger with output file
149 TFileMerger merger(false, false);
150 if (!merger.OutputFile(m_filename.c_str())) {
151 B2ERROR("RbTupleManager: error on opening the output file."
152 << LogVar("file name", m_filename));
153 return -1;
154 }
155
156 // Open current directory
157 // std::string dir = ".";
158 std::string dir = m_workdir;
159 DIR* dp;
160 struct dirent* dirp;
161 if ((dp = opendir(dir.c_str())) == nullptr) {
162 B2ERROR("RbTubleManager: error on opening the directory."
163 << LogVar("directory", dir));
164 return errno;
165 }
166
167 std::vector<std::string> filenames;
168 // Scan the directory and register all histogram files
169 // std::string compfile = dir + "/" + m_filename + ".";
170 std::string compfile = m_filename + ".";
171 B2INFO(LogVar("compfile", compfile));
172 while ((dirp = readdir(dp)) != nullptr) {
173 std::string curfile = std::string(dirp->d_name);
174 // printf("Checking %s with compfile%s\n", curfile.c_str(), compfile.c_str());
175 if (curfile.compare(0, compfile.size(), compfile) == 0) {
176 printf("RbTupleManager:: adding file =%s\n", curfile.c_str());
177 merger.AddFile((m_workdir + "/" + curfile).c_str());
178 filenames.push_back(m_workdir + "/" + curfile);
179 }
180 }
181 closedir(dp);
182
183 // Do Merge
184 if (!merger.Merge()) {
185 // printf ( "RbTupleManager:: error to merge files\n" );
186 B2ERROR("RbTupleManager: error on merging files.");
187 return -1;
188 }
189
190 if (deleteflag) {
191 // Delete temporary files
192 vector<string>::iterator it;
193 for (it = filenames.begin(); it != filenames.end(); ++it) {
194 string& hfile = *it;
195 unlink(hfile.c_str());
196 }
197 }
198
199 B2INFO("RbTupleManager: histogram files are added.");
200
201 return 0;
202}
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:40
int hadd(bool deleteflag=true)
Functions to add up all histogram files.
Definition: RbTuple.cc:138
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:118
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:129
void init(int nprocess, const char *filename, const char *workdir=".")
Global initialization.
Definition: RbTuple.cc:49
int begin(int pid)
Function called by HistoManager module for the first event.
Definition: RbTuple.cc:89
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:83
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.