Belle II Software  release-05-02-19
DQMHistAnalysisInputRootFile.cc
1 //+
2 // File : DQMHistAnalysisInputRootFile.cc
3 // Description : Module for offline testing of histogram analysis code.
4 // Root file containing DQM histograms can be used as input.
5 //
6 // Author : Boqun Wang
7 // Date : Jun - 2018
8 //-
9 
10 
11 #include <dqm/analysis/modules/DQMHistAnalysisInputRootFile.h>
12 
13 #include <daq/slc/base/StringUtil.h>
14 #include <TKey.h>
15 #include <TROOT.h>
16 
17 #include <boost/regex.hpp>
18 #include <boost/algorithm/string/replace.hpp>
19 #include <iostream>
20 using namespace Belle2;
21 
22 //-----------------------------------------------------------------
23 // Register the Module
24 //-----------------------------------------------------------------
25 REG_MODULE(DQMHistAnalysisInputRootFile)
26 
27 //-----------------------------------------------------------------
28 // Implementation
29 //-----------------------------------------------------------------
30 
33 {
34  //Parameter definition
35  addParam("FileList", m_file_list, "List of input files" , std::vector<std::string> {"input_histo.root"});
36  addParam("SelectHistograms", m_histograms, "List of histogram name patterns, empty for all. Support wildcard matching (* and ?).",
37  std::vector<std::string>());
38  addParam("Experiment", m_expno, "Experiment Nr" , 7u);
39  addParam("RunList", m_run_list, "Run Number List" , std::vector<unsigned int> {1u});
40  addParam("EventsList", m_events_list, "Number of events for each run" , std::vector<unsigned int> {10u});
41  addParam("EventInterval", m_interval, "Time between events (seconds)" , 20u);
42  addParam("NullHistogramMode", m_null_histo_mode, "Test mode for null histograms" , false);
43  addParam("AutoCanvas", m_autocanvas, "Automatic creation of canvas", true);
44  B2DEBUG(1, "DQMHistAnalysisInputRootFile: Constructor done.");
45 }
46 
48 {
49  if (m_file != nullptr) delete m_file;
50  if (m_file_list.size() == 0) B2ERROR("File list is empty.");
51  if (m_run_list.size() == 0) B2ERROR("Run list is empty.");
52  if (m_events_list.size() == 0) B2ERROR("Events list is empty.");
53  if (m_run_list.size() != m_events_list.size()) B2ERROR("Run list does not have the same size as events list.");
54  if (m_run_list.size() != m_file_list.size()) B2ERROR("Run list does not have the same size as file list.");
55  m_run_idx = 0;
56  m_file = new TFile(m_file_list[m_run_idx].c_str());
57  m_eventMetaDataPtr.registerInDataStore();
58  B2INFO("DQMHistAnalysisInputRootFile: initialized.");
59 }
60 
61 bool DQMHistAnalysisInputRootFileModule::hname_pattern_match(std::string pattern, std::string text)
62 {
63  boost::replace_all(pattern, "\\", "\\\\");
64  boost::replace_all(pattern, "^", "\\^");
65  boost::replace_all(pattern, ".", "\\.");
66  boost::replace_all(pattern, "$", "\\$");
67  boost::replace_all(pattern, "|", "\\|");
68  boost::replace_all(pattern, "(", "\\(");
69  boost::replace_all(pattern, ")", "\\)");
70  boost::replace_all(pattern, "[", "\\[");
71  boost::replace_all(pattern, "]", "\\]");
72  boost::replace_all(pattern, "*", "\\*");
73  boost::replace_all(pattern, "+", "\\+");
74  boost::replace_all(pattern, "?", "\\?");
75  boost::replace_all(pattern, "/", "\\/");
76 
77  boost::replace_all(pattern, "\\?", ".");
78  boost::replace_all(pattern, "\\*", ".*");
79 
80  boost::regex bpattern(pattern);
81 
82  return regex_match(text, bpattern);
83 }
84 
86 {
87  B2INFO("DQMHistAnalysisInputRootFile: beginRun called. Run: " << m_run_list[m_run_idx]);
88 }
89 
91 {
92  B2INFO("DQMHistAnalysisInputRootFile: event called.");
93  sleep(m_interval);
94 
96  m_run_idx++;
97  if (m_run_idx == m_run_list.size()) {
98  m_eventMetaDataPtr.create();
99  m_eventMetaDataPtr->setEndOfData();
100  return;
101  }
102  m_count = 0;
103  if (m_file != nullptr) {
104  m_file->Close();
105  delete m_file;
106  }
107  m_file = new TFile(m_file_list[m_run_idx].c_str());
108  }
109 
110  if (m_null_histo_mode) {
111  m_eventMetaDataPtr.create();
112  m_eventMetaDataPtr->setExperiment(m_expno);
114  m_eventMetaDataPtr->setEvent(m_count);
115  m_eventMetaDataPtr->setTime(0);
116  B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
117  m_count++;
118  return;
119  }
120 
121  std::vector<TH1*> hs;
122  unsigned long long int ts = 0;
123  m_file->cd();
124  TIter next(m_file->GetListOfKeys());
125  TKey* key = NULL;
126  while ((key = (TKey*)next())) {
127  TClass* cl = gROOT->GetClass(key->GetClassName());
128  if (ts == 0) ts = key->GetDatime().Convert();
129  if (!cl->InheritsFrom("TDirectory")) continue;
130  TDirectory* d = (TDirectory*)key->ReadObj();
131  std::string dirname = d->GetName();
132 
133  d->cd();
134  TIter nextd(d->GetListOfKeys());
135 
136  TKey* dkey;
137  while ((dkey = (TKey*)nextd())) {
138  TClass* dcl = gROOT->GetClass(dkey->GetClassName());
139  if (!dcl->InheritsFrom("TH1")) continue;
140  TH1* h = (TH1*)dkey->ReadObj();
141  if (h->InheritsFrom("TH2")) h->SetOption("col");
142  else h->SetOption("hist");
143  Double_t scale = 1.0 * m_count / m_events_list[m_run_idx];
144  h->Scale(scale);
145  std::string hname = h->GetName();
146 
147  bool hpass = false;
148  if (m_histograms.size() == 0) {
149  hpass = true;
150  } else {
151  for (auto& hpattern : m_histograms) {
152  if (hname_pattern_match(hpattern, dirname + "/" + hname)) {
153  hpass = true;
154  break;
155  }
156  }
157  }
158  if (!hpass) continue;
159 
160  if (hname.find("/") == std::string::npos) h->SetName((dirname + "/" + hname).c_str());
161  hs.push_back(h);
162 
163  if (m_autocanvas) {
164  std::string name = dirname + "_" + hname;
165  if (m_cs.find(name) == m_cs.end()) {
166  TCanvas* c = new TCanvas((dirname + "/c_" + hname).c_str(), ("c_" + hname).c_str());
167  m_cs.insert(std::pair<std::string, TCanvas*>(name, c));
168  }
169 
170  TCanvas* c = m_cs[name];
171  c->cd();
172  if (h->GetDimension() == 1) {
173  h->Draw("hist");
174  } else if (h->GetDimension() == 2) {
175  h->Draw("colz");
176  }
177  c->Update();
178  }
179  }
180  m_file->cd();
181  }
182 
183  // if no histograms are found in the sub-directories
184  // searc the top folder
185  if (hs.size() == 0) {
186  TIter nexth(m_file->GetListOfKeys());
187  TKey* keyh = NULL;
188  while ((keyh = (TKey*)nexth())) {
189  TClass* cl = gROOT->GetClass(keyh->GetClassName());
190  TH1* h;
191  if (!cl->InheritsFrom("TH1")) continue;
192  h = (TH1*)keyh->ReadObj();
193 
194  bool hpass = false;
195  if (m_histograms.size() == 0) {
196  hpass = true;
197  } else {
198  for (auto& hpattern : m_histograms) {
199  if (hname_pattern_match(hpattern, h->GetName())) {
200  hpass = true;
201  break;
202  }
203  }
204  }
205  if (!hpass) continue;
206 
207  hs.push_back(h);
208  Double_t scale = 1.0 * m_count / m_events_list[m_run_idx];
209  h->Scale(scale);
210  if (m_autocanvas) {
211  std::string name = h->GetName();
212  name.replace(name.find("/"), 1, "/c_");
213  if (m_cs.find(name) == m_cs.end()) {
214  TCanvas* c = new TCanvas(name.c_str(), name.c_str());
215  m_cs.insert(std::pair<std::string, TCanvas*>(name, c));
216  }
217  TCanvas* c = m_cs[name];
218  c->cd();
219  if (h->GetDimension() == 1) {
220  h->Draw("hist");
221  } else if (h->GetDimension() == 2) {
222  h->Draw("colz");
223  }
224  c->Update();
225  }
226  }
227  }
228 
229  resetHist();
230  for (size_t i = 0; i < hs.size(); i++) {
231  TH1* h = hs[i];
232  addHist("", h->GetName(), h);
233  B2DEBUG(1, "Found : " << h->GetName() << " : " << h->GetEntries());
234  }
235  m_eventMetaDataPtr.create();
236 
237  m_eventMetaDataPtr->setExperiment(m_expno);
239  m_eventMetaDataPtr->setEvent(m_count);
240  m_eventMetaDataPtr->setTime(ts * 1e9);
241  B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
242 
243  m_count++;
244 }
245 
247 {
248  B2INFO("DQMHistAnalysisInputRootFile : endRun called");
249 }
250 
251 
253 {
254  B2INFO("terminate called");
255 }
256 
Belle2::DQMHistAnalysisInputRootFileModule
Class to read histograms from a root file for offline testing of analysis modules.
Definition: DQMHistAnalysisInputRootFile.h:43
Belle2::DQMHistAnalysisInputRootFileModule::m_autocanvas
bool m_autocanvas
Whether to automatically generate canvases for histograms.
Definition: DQMHistAnalysisInputRootFile.h:122
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::DQMHistAnalysisInputRootFileModule::m_file_list
std::vector< std::string > m_file_list
The list of names of the input root file.
Definition: DQMHistAnalysisInputRootFile.h:87
Belle2::DQMHistAnalysisInputRootFileModule::beginRun
void beginRun() override final
Called when entering a new run.
Definition: DQMHistAnalysisInputRootFile.cc:85
Belle2::DQMHistAnalysisInputRootFileModule::m_expno
unsigned int m_expno
Exp number.
Definition: DQMHistAnalysisInputRootFile.h:102
Belle2::DQMHistAnalysisInputRootFileModule::hname_pattern_match
bool hname_pattern_match(std::string pattern, std::string text)
Pattern match for histogram name.
Definition: DQMHistAnalysisInputRootFile.cc:61
Belle2::DQMHistAnalysisInputRootFileModule::m_histograms
std::vector< std::string > m_histograms
List of histogram name patterns to process.
Definition: DQMHistAnalysisInputRootFile.h:99
Belle2::DQMHistAnalysisInputRootFileModule::m_run_idx
unsigned int m_run_idx
Index in the list of runs, events and files.
Definition: DQMHistAnalysisInputRootFile.h:117
Belle2::DQMHistAnalysisInputRootFileModule::initialize
void initialize() override final
Initialize the module.
Definition: DQMHistAnalysisInputRootFile.cc:47
Belle2::DQMHistAnalysisInputRootFileModule::endRun
void endRun() override final
End-of-run action.
Definition: DQMHistAnalysisInputRootFile.cc:246
Belle2::DQMHistAnalysisInputRootFileModule::event
void event() override final
Event processor.
Definition: DQMHistAnalysisInputRootFile.cc:90
Belle2::DQMHistAnalysisInputRootFileModule::m_events_list
std::vector< unsigned int > m_events_list
List of total number of events for each run.
Definition: DQMHistAnalysisInputRootFile.h:108
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::DQMHistAnalysisInputRootFileModule::m_cs
std::map< std::string, TCanvas * > m_cs
The map between canvas name and canvas object.
Definition: DQMHistAnalysisInputRootFile.h:96
Belle2::DQMHistAnalysisInputRootFileModule::m_run_list
std::vector< unsigned int > m_run_list
List of runs.
Definition: DQMHistAnalysisInputRootFile.h:111
Belle2::DQMHistAnalysisInputRootFileModule::m_count
unsigned int m_count
Evt number.
Definition: DQMHistAnalysisInputRootFile.h:105
Belle2::DQMHistAnalysisInputRootFileModule::m_null_histo_mode
bool m_null_histo_mode
Test mode for null histograms.
Definition: DQMHistAnalysisInputRootFile.h:120
Belle2::DQMHistAnalysisInputRootFileModule::m_eventMetaDataPtr
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Global EventMetaData for run number and event number.
Definition: DQMHistAnalysisInputRootFile.h:93
Belle2::DQMHistAnalysisModule::resetHist
static void resetHist()
Clear and reset the list of histograms.
Definition: DQMHistAnalysis.h:179
Belle2::DQMHistAnalysisInputRootFileModule::m_interval
unsigned int m_interval
Time between two events in second.
Definition: DQMHistAnalysisInputRootFile.h:114
Belle2::DQMHistAnalysisInputRootFileModule::m_file
TFile * m_file
The TFile object for the input file.
Definition: DQMHistAnalysisInputRootFile.h:90
Belle2::DQMHistAnalysisModule::addHist
static void addHist(const std::string &dirname, const std::string &histname, TH1 *h)
Add histogram.
Definition: DQMHistAnalysis.cc:46
Belle2::DQMHistAnalysisModule
The base class for the histogram analysis module.
Definition: DQMHistAnalysis.h:27
Belle2::DQMHistAnalysisInputRootFileModule::terminate
void terminate() override final
Termination action.
Definition: DQMHistAnalysisInputRootFile.cc:252