Belle II Software development
DQMHistAnalysisInputRootFile.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// File : DQMHistAnalysisInputRootFile.cc
10// Description : Module for offline testing of histogram analysis code.
11// Root file containing DQM histograms can be used as input.
12//-
13
14
15#include <dqm/analysis/modules/DQMHistAnalysisInputRootFile.h>
16
17#include <TROOT.h>
18#include <TKey.h>
19
20#include <boost/regex.hpp>
21#include <boost/algorithm/string/replace.hpp>
22#include <iostream>
23
24using namespace Belle2;
25
26//-----------------------------------------------------------------
27// Register the Module
28//-----------------------------------------------------------------
29REG_MODULE(DQMHistAnalysisInputRootFile);
30
31//-----------------------------------------------------------------
32// Implementation
33//-----------------------------------------------------------------
34
37{
38 //Parameter definition
39 addParam("FileList", m_fileList, "List of input files", std::vector<std::string> {"input_histo.root"});
40 addParam("SelectHistograms", m_histograms, "List of histogram name patterns, empty for all. Support wildcard matching (* and ?).",
41 std::vector<std::string>());
42 addParam("Experiment", m_expno, "Experiment Nr", 7u);
43 addParam("RunList", m_runList, "Run Number List", std::vector<unsigned int> {1u});
44 addParam("EventsList", m_eventsList, "Number of events for each run", std::vector<unsigned int> {10u});
45 addParam("RunType", m_runType, "Run Type override", std::string(""));
46 addParam("EventFilled", m_fillEvent, "Event override", 0);
47 addParam("EventInterval", m_interval, "Time between events (seconds)", 20u);
48 addParam("NullHistogramMode", m_nullHistoMode, "Test mode for null histograms", false);
49 addParam("EnableRunInfo", m_enable_run_info, "Enable Run Info", false);
50 addParam("AddRunControlHist", m_add_runcontrol_hist, "Add Hists from Run Control", false);
51 B2DEBUG(1, "DQMHistAnalysisInputRootFile: Constructor done.");
52}
53
55{
56 if (m_file != nullptr) delete m_file;
57 if (m_fileList.size() == 0) B2ERROR("File list is empty.");
58 if (m_runList.size() == 0) B2ERROR("Run list is empty.");
59 if (m_eventsList.size() == 0) B2ERROR("Events list is empty.");
60 if (m_runList.size() != m_eventsList.size()) B2ERROR("Run list does not have the same size as events list.");
61 if (m_runList.size() != m_fileList.size()) B2ERROR("Run list does not have the same size as file list.");
62 m_run_idx = 0;
63 m_file = new TFile(m_fileList[m_run_idx].c_str());
64 m_eventMetaDataPtr.registerInDataStore();
65
67 m_c_info = new TCanvas("DQMInfo/c_info", "");
68 m_c_info->SetTitle("");
69 }
71 m_h_expno = new TH1F("DQMInfo/expno", "", 1, 0, 1);
72 m_h_runno = new TH1F("DQMInfo/runno", "", 1, 0, 1);
73 m_h_rtype = new TH1F("DQMInfo/rtype", "", 1, 0, 1);
74 }
75
76 B2INFO("DQMHistAnalysisInputRootFile: initialized.");
77}
78
79bool DQMHistAnalysisInputRootFileModule::hnamePatternMatch(std::string pattern, std::string text)
80{
81 boost::replace_all(pattern, "\\", "\\\\");
82 boost::replace_all(pattern, "^", "\\^");
83 boost::replace_all(pattern, ".", "\\.");
84 boost::replace_all(pattern, "$", "\\$");
85 boost::replace_all(pattern, "|", "\\|");
86 boost::replace_all(pattern, "(", "\\(");
87 boost::replace_all(pattern, ")", "\\)");
88 boost::replace_all(pattern, "[", "\\[");
89 boost::replace_all(pattern, "]", "\\]");
90 boost::replace_all(pattern, "*", "\\*");
91 boost::replace_all(pattern, "+", "\\+");
92 boost::replace_all(pattern, "?", "\\?");
93 boost::replace_all(pattern, "/", "\\/");
94
95 boost::replace_all(pattern, "\\?", ".");
96 boost::replace_all(pattern, "\\*", ".*");
97
98 boost::regex bpattern(pattern);
99
100 return regex_match(text, bpattern);
101}
102
104{
105 B2INFO("DQMHistAnalysisInputRootFile: beginRun called. Run: " << m_runList[m_run_idx]);
107 clearRefList();
108}
109
111{
112 B2INFO("DQMHistAnalysisInputRootFile: event called.");
113 TH1::AddDirectory(false);
114
115 sleep(m_interval);
116
118 m_run_idx++;
119 if (m_run_idx == m_runList.size()) {
120 m_eventMetaDataPtr.create();
121 m_eventMetaDataPtr->setEndOfData();
122 return;
123 }
124 m_count = 0;
125 if (m_file != nullptr) {
126 m_file->Close();
127 delete m_file;
128 }
129 m_file = new TFile(m_fileList[m_run_idx].c_str());
130 }
131
132 // Clear only after EndOfRun check, otherwise we won't have any histograms for MiraBelle
133 // which expects analysis run in endRun function
135
136 if (m_nullHistoMode) {
137 m_eventMetaDataPtr.create();
138 m_eventMetaDataPtr->setExperiment(m_expno);
140 m_eventMetaDataPtr->setEvent(m_count);
141 m_eventMetaDataPtr->setTime(0);
142 //setExpNr(m_expno); // redundant access from MetaData
143 //setRunNr(m_runno); // redundant access from MetaData
145 //ExtractRunType();
147 //ExtractEvent();
148
149 B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
150 m_count++;
151 return;
152 }
153
154 std::vector<TH1*> hs;
155 unsigned long long int ts = 0;
156 m_file->cd();
157 TIter next(m_file->GetListOfKeys());
158 TKey* key = NULL;
159 while ((key = (TKey*)next())) {
160 TClass* cl = gROOT->GetClass(key->GetClassName());
161 if (ts == 0) ts = key->GetDatime().Convert();
162 if (!cl->InheritsFrom("TDirectory")) continue;
163 TDirectory* d = (TDirectory*)key->ReadObj();
164 std::string dirname = d->GetName();
165
166 d->cd();
167 TIter nextd(d->GetListOfKeys());
168
169 TKey* dkey;
170 while ((dkey = (TKey*)nextd())) {
171 TClass* dcl = gROOT->GetClass(dkey->GetClassName());
172 if (!dcl->InheritsFrom("TH1")) continue;
173 TH1* h = (TH1*)dkey->ReadObj();
174 if (h->InheritsFrom("TH2")) h->SetOption("col");
175 else h->SetOption("hist");
176 Double_t scale = 1.0 * m_count / m_eventsList[m_run_idx];
177 h->Scale(scale);
178 std::string hname = h->GetName();
179
180 bool hpass = false;
181 if (m_histograms.size() == 0) {
182 hpass = true;
183 } else {
184 for (auto& hpattern : m_histograms) {
185 if (hnamePatternMatch(hpattern, dirname + "/" + hname)) {
186 hpass = true;
187 break;
188 }
189 }
190 }
191 if (!hpass) continue;
192
193 if (hname.find("/") == std::string::npos) h->SetName((dirname + "/" + hname).c_str());
194 hs.push_back(h);
195 }
196 m_file->cd();
197 }
198
199 // if no histograms are found in the sub-directories
200 // search the top folder
201 if (hs.size() == 0) {
202 TIter nexth(m_file->GetListOfKeys());
203 TKey* keyh = NULL;
204 while ((keyh = (TKey*)nexth())) {
205 TClass* cl = gROOT->GetClass(keyh->GetClassName());
206 TH1* h;
207 if (!cl->InheritsFrom("TH1")) continue;
208 h = (TH1*)keyh->ReadObj();
209
210 bool hpass = false;
211 if (m_histograms.size() == 0) {
212 hpass = true;
213 } else {
214 for (auto& hpattern : m_histograms) {
215 if (hnamePatternMatch(hpattern, h->GetName())) {
216 hpass = true;
217 break;
218 }
219 }
220 }
221 if (!hpass) continue;
222
223 hs.push_back(h);
224 Double_t scale = 1.0 * m_count / m_eventsList[m_run_idx];
225 h->Scale(scale);
226 }
227 }
228
229 auto runno = m_runList[m_run_idx];
230 if (m_c_info != NULL) m_c_info->SetTitle(("OFFLINE: Exp " + std::to_string(m_expno) + ", Run " + std::to_string(
231 runno) + ", RunType " + m_runType + ", Last Changed NEVER, Last Updated NEVER, Last DQM event NEVER").c_str());
232
233 m_count++;
234 m_eventMetaDataPtr.create();
235 m_eventMetaDataPtr->setExperiment(m_expno);
237 m_eventMetaDataPtr->setEvent(m_count);
238 m_eventMetaDataPtr->setTime(ts * 1e9);
239
241 m_h_expno->SetTitle(std::to_string(m_expno).c_str());
242 hs.push_back(m_h_expno);
243 m_h_runno->SetTitle(std::to_string(runno).c_str());
244 hs.push_back(m_h_runno);
245 m_h_rtype->SetTitle(m_runType.c_str());
246 hs.push_back(m_h_rtype);
247 }
248 //setExpNr(m_expno); // redundant access from MetaData
249 //setRunNr(m_runno); // redundant access from MetaData
250 if (m_runType == "") ExtractRunType(hs);
251 if (m_fillEvent <= 0) ExtractEvent(hs);
252
253 // this code must be run after "event processed" has been extracted
254 for (size_t i = 0; i < hs.size(); i++) {
255 TH1* h = hs[i];
256 addHist("", h->GetName(), h);
257 B2DEBUG(1, "Found : " << h->GetName() << " : " << h->GetEntries());
258 }
259
260 B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
261}
TH1F * m_h_runno
emulated histogram from runcontrol, runno
void initialize() override final
Initialize the module.
std::vector< unsigned int > m_eventsList
List of total number of events for each run.
std::vector< std::string > m_fileList
The list of names of the input root file.
bool m_nullHistoMode
Test mode for null histograms.
bool m_add_runcontrol_hist
Whether to add the run control histograms.
bool m_enable_run_info
Whether to enable the run info to be displayed.
std::vector< std::string > m_histograms
List of histogram name patterns to process.
TH1F * m_h_expno
emulated histogram from runcontrol, expno
bool hnamePatternMatch(std::string pattern, std::string text)
Pattern match for histogram name.
TH1F * m_h_rtype
emulated histogram from runcontrol, runtype
TFile * m_file
The TFile object for the input file.
unsigned int m_interval
Time between two events in second.
void beginRun() override final
Called when entering a new run.
std::vector< unsigned int > m_runList
List of runs.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Global EventMetaData for run number and event number.
TCanvas * m_c_info
The canvas hold the basic DQM info.
unsigned int m_run_idx
Index in the list of runs, events and files.
The base class for the histogram analysis module.
static void clearHistList(void)
Clears the list of histograms.
static void clearRefList(void)
Clears the list of ref histograms.
void setRunType(std::string &t)
Set the Run Type.
void setEventProcessed(int e)
Set the number of processed events.
static bool addHist(const std::string &dirname, const std::string &histname, TH1 *h)
Add histogram.
void ExtractRunType(std::vector< TH1 * > &hs)
Extract Run Type from histogram title, called from input module.
static void initHistListBeforeEvent(void)
Reset the list of histograms.
void ExtractEvent(std::vector< TH1 * > &hs)
Extract event processed from daq histogram, called from input module.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.