Belle II Software  release-05-02-19
RbTuple.cc
1 //+
2 // File : rbtuple.cc
3 // Description : Collect histograms from multiple processes
4 //
5 // Author : Ryosuke Itoh, IPNS, KEK
6 // Date : 21 - Apr - 2009
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 to open directory" << dir);
64  return;
65  }
66 
67  // Scan the directory and delete temporary files
68  std::string compfile = m_filename + ".";
69  while ((dirp = readdir(dp)) != nullptr) {
70  std::string curfile = std::string(dirp->d_name);
71  if (curfile.compare(0, compfile.size(), compfile) == 0) {
72  // unlink(curfile.c_str());
73  unlink((m_workdir + "/" + curfile).c_str());
74  }
75  }
76  closedir(dp);
77  cout << "HistoManager : old temporary histogram files deleted" << endl;
78  }
79 }
80 
81 // Function to register histogram definitions
83 {
84  m_histdefs.push_back(mod);
85 }
86 
87 // Function called from event processes
88 int RbTupleManager::begin(int procid)
89 {
90  if (m_nproc > 0) {
91  std::string fileNamePlusId = m_workdir + "/" +
92  m_filename + '.' + std::to_string(procid);
93  m_root = new TFile(fileNamePlusId.c_str(), "update");
94  // printf("RbTupleManager: histo file opened for process %d (pid=%d)\n",
95  // procid, getpid());
96  B2INFO("RbTupleManager : histo file opened for process " << procid << "(" << getpid() << ")");
97  } else {
98  m_root = new TFile(m_filename.c_str(), "recreate");
99  // printf("RbTupleManager: initialized for single-process\n");
100  B2INFO("RbTupleManager : initialized for single process");
101  }
102  if (m_root == nullptr) return -1;
103  // printf ( "RbTupleManager::TFile opened\n" );
104 
105  for (auto& mod : m_histdefs) {
106  auto* hmod = (HistoModule*) mod;
107  hmod->defineHisto();
108  }
109 
110  // printf ( "RbTupleManager::Histograms defined in proc %d\n", procid );
111 
112  return 0;
113 }
114 
116 {
117  if (m_root != nullptr) {
118  m_root->Write();
119  m_root->Close();
120  delete m_root;
121  m_root = nullptr;
122  }
123  return 0;
124 }
125 
127 {
128  if (m_root != nullptr) {
129  m_root->Write();
130  }
131  return 0;
132 }
133 
134 // Functions called from main process
135 int RbTupleManager::hadd(bool deleteflag)
136 {
137  // No need to call this function when nprocess=0
138  if (m_nproc == 0) {
139  // if ( m_root != NULL ) terminate();
140  return 0;
141  }
142 
143  printf("RbTupleManager::hadd started\n");
144 
145  // Set up merger with output file
146  TFileMerger merger(false, false);
147  if (!merger.OutputFile(m_filename.c_str())) {
148  B2ERROR("RbTupleManager:: error to open output file " << m_filename);
149  return -1;
150  }
151 
152  // Open current directory
153  // std::string dir = ".";
154  std::string dir = m_workdir;
155  DIR* dp;
156  struct dirent* dirp;
157  if ((dp = opendir(dir.c_str())) == nullptr) {
158  B2ERROR("Error to open directory" << dir);
159  return errno;
160  }
161 
162  std::vector<std::string> filenames;
163  // Scan the directory and register all histogram files
164  // std::string compfile = dir + "/" + m_filename + ".";
165  std::string compfile = m_filename + ".";
166  printf("compfile = %s\n", compfile.c_str());
167  while ((dirp = readdir(dp)) != nullptr) {
168  std::string curfile = std::string(dirp->d_name);
169  // printf("Checking %s with compfile%s\n", curfile.c_str(), compfile.c_str());
170  if (curfile.compare(0, compfile.size(), compfile) == 0) {
171  printf("RbTupleManager:: adding file =%s\n", curfile.c_str());
172  merger.AddFile((m_workdir + "/" + curfile).c_str());
173  filenames.push_back(m_workdir + "/" + curfile);
174  }
175  }
176  closedir(dp);
177 
178  // Do Merge
179  if (!merger.Merge()) {
180  // printf ( "RbTupleManager:: error to merge files\n" );
181  B2ERROR("RbTupleManager:: error to merge files");
182  return -1;
183  }
184 
185  if (deleteflag) {
186  // Delete temporary files
187  vector<string>::iterator it;
188  for (it = filenames.begin(); it != filenames.end(); ++it) {
189  string& hfile = *it;
190  unlink(hfile.c_str());
191  }
192  }
193 
194  printf("RbTupleManager: histogram files are added\n");
195  // B2INFO ( "RbTupleManager : histogram files are added" );
196 
197  return 0;
198 }
Belle2::RbTupleManager::init
void init(int nprocess, const char *filename, const char *workdir=".")
Global initialization.
Definition: RbTuple.cc:49
Belle2::RbTupleManager::s_instance
static RbTupleManager * s_instance
singleton instance.
Definition: RbTuple.h:73
Belle2::RbTupleManager::register_module
void register_module(Module *)
Functions called by analysis modules in mother process.
Definition: RbTuple.cc:82
Belle2::RbTupleManager::dump
int dump()
Function to dump histograms/tuples to the file.
Definition: RbTuple.cc:126
Belle2::RbTupleManager::begin
int begin(int pid)
Function called by HistoManager module for the first event.
Definition: RbTuple.cc:88
Belle2::RbTupleManager
Class to manage histograms defined in registered modules.
Definition: RbTuple.h:30
Belle2::RbTupleManager::m_nproc
int m_nproc
Number of parallel processes.
Definition: RbTuple.h:76
Belle2::RbTupleManager::m_histdefs
std::vector< Module * > m_histdefs
registered HistoModules.
Definition: RbTuple.h:75
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RbTupleManager::m_root
TFile * m_root
Histogram output file.
Definition: RbTuple.h:79
Belle2::RbTupleManager::Instance
static RbTupleManager & Instance()
Access to singleton.
Definition: RbTuple.cc:40
Belle2::ProcHandler::EvtProcID
static int EvtProcID()
Return ID of the current process.
Definition: ProcHandler.cc:243
Belle2::RbTupleManager::hadd
int hadd(bool deleteflag=true)
Functions to add up all histogram files.
Definition: RbTuple.cc:135
Belle2::RbTupleManager::m_filename
std::string m_filename
Name of histogram output file.
Definition: RbTuple.h:77
Belle2::RbTupleManager::terminate
int terminate()
Function called by HistoManager module at the end.
Definition: RbTuple.cc:115
Belle2::RbTupleManager::m_workdir
std::string m_workdir
Name of working directory.
Definition: RbTuple.h:78
Belle2::HistoModule
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29