Belle II Software release-09-00-00
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}
108
110{
111 B2INFO("DQMHistAnalysisInputRootFile: event called.");
112 TH1::AddDirectory(false);
113
114 sleep(m_interval);
115
117 m_run_idx++;
118 if (m_run_idx == m_runList.size()) {
119 m_eventMetaDataPtr.create();
120 m_eventMetaDataPtr->setEndOfData();
121 return;
122 }
123 m_count = 0;
124 if (m_file != nullptr) {
125 m_file->Close();
126 delete m_file;
127 }
128 m_file = new TFile(m_fileList[m_run_idx].c_str());
129 }
130
131 // Clear only after EndOfRun check, otherwise we wont have any histograms for MiraBelle
132 // which expects analysis run in endRun function
134
135 if (m_nullHistoMode) {
136 m_eventMetaDataPtr.create();
137 m_eventMetaDataPtr->setExperiment(m_expno);
139 m_eventMetaDataPtr->setEvent(m_count);
140 m_eventMetaDataPtr->setTime(0);
141 //setExpNr(m_expno); // redundant access from MetaData
142 //setRunNr(m_runno); // redundant access from MetaData
144 //ExtractRunType();
146 //ExtractEvent();
147
148 B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
149 m_count++;
150 return;
151 }
152
153 std::vector<TH1*> hs;
154 unsigned long long int ts = 0;
155 m_file->cd();
156 TIter next(m_file->GetListOfKeys());
157 TKey* key = NULL;
158 while ((key = (TKey*)next())) {
159 TClass* cl = gROOT->GetClass(key->GetClassName());
160 if (ts == 0) ts = key->GetDatime().Convert();
161 if (!cl->InheritsFrom("TDirectory")) continue;
162 TDirectory* d = (TDirectory*)key->ReadObj();
163 std::string dirname = d->GetName();
164
165 d->cd();
166 TIter nextd(d->GetListOfKeys());
167
168 TKey* dkey;
169 while ((dkey = (TKey*)nextd())) {
170 TClass* dcl = gROOT->GetClass(dkey->GetClassName());
171 if (!dcl->InheritsFrom("TH1")) continue;
172 TH1* h = (TH1*)dkey->ReadObj();
173 if (h->InheritsFrom("TH2")) h->SetOption("col");
174 else h->SetOption("hist");
175 Double_t scale = 1.0 * m_count / m_eventsList[m_run_idx];
176 h->Scale(scale);
177 std::string hname = h->GetName();
178
179 bool hpass = false;
180 if (m_histograms.size() == 0) {
181 hpass = true;
182 } else {
183 for (auto& hpattern : m_histograms) {
184 if (hnamePatternMatch(hpattern, dirname + "/" + hname)) {
185 hpass = true;
186 break;
187 }
188 }
189 }
190 if (!hpass) continue;
191
192 if (hname.find("/") == std::string::npos) h->SetName((dirname + "/" + hname).c_str());
193 hs.push_back(h);
194 }
195 m_file->cd();
196 }
197
198 // if no histograms are found in the sub-directories
199 // search the top folder
200 if (hs.size() == 0) {
201 TIter nexth(m_file->GetListOfKeys());
202 TKey* keyh = NULL;
203 while ((keyh = (TKey*)nexth())) {
204 TClass* cl = gROOT->GetClass(keyh->GetClassName());
205 TH1* h;
206 if (!cl->InheritsFrom("TH1")) continue;
207 h = (TH1*)keyh->ReadObj();
208
209 bool hpass = false;
210 if (m_histograms.size() == 0) {
211 hpass = true;
212 } else {
213 for (auto& hpattern : m_histograms) {
214 if (hnamePatternMatch(hpattern, h->GetName())) {
215 hpass = true;
216 break;
217 }
218 }
219 }
220 if (!hpass) continue;
221
222 hs.push_back(h);
223 Double_t scale = 1.0 * m_count / m_eventsList[m_run_idx];
224 h->Scale(scale);
225 }
226 }
227
228 auto runno = m_runList[m_run_idx];
229 if (m_c_info != NULL) m_c_info->SetTitle(("OFFLINE: Exp " + std::to_string(m_expno) + ", Run " + std::to_string(
230 runno) + ", RunType " + m_runType + ", Last Changed NEVER, Last Updated NEVER, Last DQM event NEVER").c_str());
231
232 m_count++;
233 m_eventMetaDataPtr.create();
234 m_eventMetaDataPtr->setExperiment(m_expno);
236 m_eventMetaDataPtr->setEvent(m_count);
237 m_eventMetaDataPtr->setTime(ts * 1e9);
238
240 m_h_expno->SetTitle(std::to_string(m_expno).c_str());
241 hs.push_back(m_h_expno);
242 m_h_runno->SetTitle(std::to_string(runno).c_str());
243 hs.push_back(m_h_runno);
244 m_h_rtype->SetTitle(m_runType.c_str());
245 hs.push_back(m_h_rtype);
246 }
247 //setExpNr(m_expno); // redundant access from MetaData
248 //setRunNr(m_runno); // redundant access from MetaData
249 if (m_runType == "") ExtractRunType(hs);
250 if (m_fillEvent <= 0) ExtractEvent(hs);
251
252 // this code must be run after "event processed" has been extracted
253 for (size_t i = 0; i < hs.size(); i++) {
254 TH1* h = hs[i];
255 addHist("", h->GetName(), h);
256 B2DEBUG(1, "Found : " << h->GetName() << " : " << h->GetEntries());
257 }
258
259 B2INFO("DQMHistAnalysisInputRootFile: event finished. count: " << m_count);
260}
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.
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.