Belle II Software  release-08-01-10
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 
24 using namespace std;
25 using namespace Belle2;
26 
27 RbTupleManager* RbTupleManager::s_instance = nullptr;
28 
29 // Constructor and Destructor
30 RbTupleManager::RbTupleManager() = default;
31 
32 RbTupleManager::~RbTupleManager() = default;
33 
34 RbTupleManager::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
49 void 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
89 int 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
138 int 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.