Belle II Software development
DQMHistAnalysisInput2.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 : DQMHistAnalysisInput2.cc
10// Description :
11//-
12
13
14#include <dqm/analysis/modules/DQMHistAnalysisInput2.h>
15
16#include <TROOT.h>
17#include <TKey.h>
18
19#include <ctime>
20
21using namespace Belle2;
22
23//-----------------------------------------------------------------
24// Register the Module
25//-----------------------------------------------------------------
26REG_MODULE(DQMHistAnalysisInput2);
27
28//-----------------------------------------------------------------
29// Implementation
30//-----------------------------------------------------------------
31
34{
35 //Parameter definition
36 addParam("HistMemoryPath", m_mempath, "Path to Input Hist memory");
37 addParam("StatFileName", m_statname, "Filename for status export", std::string(""));
38 addParam("RefreshInterval", m_interval, "Refresh interval of histograms", 10);
39 addParam("EnableRunInfo", m_enable_run_info, "Enable Run Info", false);
40 B2DEBUG(1, "DQMHistAnalysisInput2: Constructor done.");
41}
42
44{
46 m_c_info = new TCanvas("DQMInfo/c_info", "");
47 m_c_info->SetTitle("");
48 }
49 m_eventMetaDataPtr.registerInDataStore();
50 B2DEBUG(1, "DQMHistAnalysisInput2: initialized.");
51}
52
54{
55 B2DEBUG(1, "DQMHistAnalysisInput2: beginRun called.");
58
59 m_last_beginrun = time(0);
61 m_lasttime -= std::chrono::seconds(1); // just change
62}
63
64void DQMHistAnalysisInput2Module::addToHistList(std::vector<TH1*>& inputHistList, std::string dirname, TKey* key)
65{
66 auto h = (TH1*)key->ReadObj();
67 if (h == nullptr) return; // would be strange, but better check
68 std::string hname = h->GetName();
69
70 if (hname.find("/") == std::string::npos) {
71 if (dirname != "") {
72 hname = dirname + "/" + hname;
73 h->SetName(hname.c_str());
74 } else {
75 // histo in root dir without prefix -> do not keep!
76 delete h;
77 return;
78 }
79 }
80
81 // Remove ":" from folder name, workaround!
82 // Is this really needed?
83 if (hname.find(":") != std::string::npos) {
84 B2ERROR("histogram or folder name with : is problematic");
85 }
86 TString a = h->GetName();
87 a.ReplaceAll(":", "");
88 h->SetName(a);
89 B2DEBUG(1, "DQMHistAnalysisInput2: get histo " << a.Data());
90
91 // Histograms in the inputHistList list will be taken care of later (delete)
92 inputHistList.push_back(h);
93}
94
96{
97 m_last_event = time(0);
99
100 TH1::AddDirectory(false);
102
103// we create a metadata and set the latest exp/run
104// if do not, execution will be terminate if file is not updated/zombie
105// if we only put dummy exp/run, we trigger begin/endRun ...
106 m_eventMetaDataPtr.create();
107 m_eventMetaDataPtr->setExperiment(m_expno);
109 m_eventMetaDataPtr->setEvent(m_count);
110
111 const std::filesystem::file_time_type ftime = std::filesystem::last_write_time(m_mempath);
112
113 if (m_lasttime == ftime) {
114 B2INFO("File not updated! -> Sleep");
115 sleep(m_interval);
116 setReturnValue(false);
117 return;
118 }
119 m_last_file_update = time(0);
120 m_lasttime = ftime;
121
122 char mbstr[100];
123 time_t now = time(0);
124 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
125 B2INFO("[" << mbstr << "] before Load File");
126
127 std::unique_ptr<TFile> pFile = std::unique_ptr<TFile> (new TFile(m_mempath.c_str(), "READ"));
128 if (pFile->IsZombie()) {
129 B2WARNING("DQMHistAnalysisInput2: " << m_mempath + " is Zombie -> Sleep");
130 sleep(m_interval);
131 setReturnValue(false);
132 return;
133 }
134
135 now = time(0);
136 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
137 B2INFO("[" << mbstr << "] after LoadFile");
138
139 const TDatime& mt = pFile->GetModificationDate();
140 TDatime mmt(mt.Convert());
141 std::string expno("UNKNOWN"), runno("UNKNOWN"), rtype("UNKNOWN");
142
143 now = time(0);
144 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
145 B2INFO("[" << mbstr << "] before input loop");
146
147 // check if histograms were updated since last DQM event (based on number of processed events)
148 if (m_nevent != getEventProcessed()) {
149 m_lastChange = std::string(mbstr);
150 }
151 // update number of processed events
153
155 std::vector<TH1*> inputHistList;
156
157 // first check sub-directories
158 pFile->cd();
159 TIter next(pFile->GetListOfKeys());
160 while (auto key = (TKey*)next()) {
161 TClass* cl = gROOT->GetClass(key->GetClassName());
162 if (cl->InheritsFrom("TDirectory")) {
163 TDirectory* d = (TDirectory*)key->ReadObj();
164 std::string dirname = d->GetName();
165
166 d->cd();
167 TIter nextd(d->GetListOfKeys());
168
169 while (auto dkey = (TKey*)nextd()) {
170 if (gROOT->GetClass(dkey->GetClassName())->InheritsFrom("TH1")) {
171 addToHistList(inputHistList, dirname, dkey);
172 }
173 }
174 pFile->cd();
175 } else if (cl->InheritsFrom("TH1")) {
176 addToHistList(inputHistList, "", key);
177 }
178 }
179
180 for (auto& h : inputHistList) {
181 if (std::string(h->GetName()) == std::string("DQMInfo/expno")) expno = h->GetTitle();
182 if (std::string(h->GetName()) == std::string("DQMInfo/runno")) runno = h->GetTitle();
183 if (std::string(h->GetName()) == std::string("DQMInfo/rtype")) rtype = h->GetTitle();
184 }
185
186 now = time(0);
187 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
188 B2INFO("[" << mbstr << "] before Close File");
189
190 // we are done with reading, so close it
191 pFile->Close();
192
193 now = time(0);
194 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
195 B2INFO("[" << mbstr << "] before delete File");
196 pFile = nullptr;
197
198 now = time(0);
199 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
200 B2INFO("[" << mbstr << "] after input loop");
201
202 if (expno == std::string("UNKNOWN") || runno == std::string("UNKNOWN")) {
203 B2WARNING("DQMHistAnalysisInput2: " << m_mempath + ": Exp " + expno + ", Run " + runno + ", RunType " + rtype + ", Last Updated " +
204 mmt.AsString());
205 setReturnValue(false);
206 for (auto& h : inputHistList) delete h;
207 return;
208 } else {
209 if (m_c_info != NULL) m_c_info->SetTitle((m_mempath + ": Exp " + expno + ", Run " + runno + ", RunType " + rtype + ", Last Changed "
210 + m_lastChange + ", Last Updated "
211 + mmt.AsString() + ", Last DQM event " + std::string(mbstr)).c_str());
212 m_expno = std::stoi(expno);
213 m_runno = std::stoi(runno);
214 }
215 B2INFO("DQMHistAnalysisInput2: " << m_mempath + ": Exp " + expno + ", Run " + runno + ", RunType " + rtype + ", Last Updated " +
216 mmt.AsString());
217
218
219 m_count++;
220 // Override with updated values
221 m_eventMetaDataPtr->setExperiment(m_expno);
223 m_eventMetaDataPtr->setEvent(m_count);
224 m_eventMetaDataPtr->setTime(mt.Convert());
225
226 //setExpNr(m_expno); // redundant access from MetaData
227 //setRunNr(m_runno); // redundant access from MetaData
228 // ExtractRunType();// Run Type is processed above already, just take it
229 setRunType(rtype);
230 ExtractNEvent(inputHistList);
231
232 if (m_lastRun != m_runno or m_lastExp != m_expno) {
233 // Run change detected
236 // we cannot do that in beginRun(), otherwise all histos are cleare before first event
239 }
240
241 // this code must be run after "event processed" has been extracted
242 bool anyupdate = false; // flag if any histogram updated at all
243 for (auto& h : inputHistList) {
244 anyupdate |= addHist("", h->GetName(), h);
245 B2DEBUG(1, "Found : " << h->GetName() << " : " << h->GetEntries());
246 }
247
248 if (anyupdate) {
249 m_last_content_update = time(0);
250 } else {
251 // if there is no update, sleep a moment
252 sleep(m_interval);
253 }
254
255 // if no histogram was updated, we could stop processing
256 setReturnValue(anyupdate);
257}
258
260{
261 B2DEBUG(1, "DQMHistAnalysisInput2: endRun called");
262}
263
265{
266 B2DEBUG(1, "DQMHistAnalysisInput2: terminate called");
267 if (m_c_info) delete m_c_info;
268 clearlist(); // necessary in the Input Module! Otherwise ROOT may clean before we do
269}
270
272{
273 if (m_statname == "") return;
274 FILE* fh = fopen(m_statname.c_str(), "wt+");
275 if (fh) {
276 char mbstr[100];
277 time_t now = time(0);
278 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&now));
279 fprintf(fh, "%s,%s,%s,", m_statname.c_str(), m_mempath.c_str(), mbstr);
280 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&m_last_event));
281 fprintf(fh, "%s,", mbstr);
282 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&m_last_beginrun));
283 fprintf(fh, "%s,", mbstr);
284 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&m_last_file_update));
285 fprintf(fh, "%s,", mbstr);
286 strftime(mbstr, sizeof(mbstr), "%F %T", localtime(&m_last_content_update));
287 fprintf(fh, "%s\n", mbstr);
288
289 fclose(fh);
290 }
291}
std::string m_lastChange
last change date/time of shm input file
void initialize() override final
Initialize the module.
std::string m_statname
The file name of the analysis for stats.
std::filesystem::file_time_type m_lasttime
Last time input file changes.
bool m_enable_run_info
Whether to enable the run info to be displayed.
void terminate() override final
This method is called at the end of the event processing.
time_t m_last_event
last time event loop entered
void event() override final
This method is called for each event.
std::string m_mempath
The name of the shared memory for the histograms.
time_t m_last_file_update
last time input file update detected
time_t m_last_content_update
last time input file content has changed
void endRun() override final
This method is called if the current run ends.
int m_interval
The name of the memory file (HLT or ExpressReco).
void beginRun() override final
Called when entering a new run.
void addToHistList(std::vector< TH1 * > &inputHistList, std::string dirname, TKey *key)
Read histogram from key and add to list vector.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
The metadata for each event.
TCanvas * m_c_info
The canvas hold the basic DQM info.
int m_nevent
DAQ number of processed events.
time_t m_last_beginrun
last time begin run entered
void write_state(void)
Write stats of analysis.
The base class for the histogram analysis module.
void clearlist(void)
Clear all static global lists.
void ExtractNEvent(std::vector< TH1 * > &hs)
Extract event processed from daq histogram, called from input 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.
static bool addHist(const std::string &dirname, const std::string &histname, TH1 *h)
Add histogram.
void clearCanvases(void)
Clear content of all Canvases.
static int getEventProcessed(void)
Get the number of processed events.
static void initHistListBeforeEvent(void)
Reset the list of histograms.
void resetDeltaList(void)
Reset Delta.
void setReturnValue(int value)
Sets the return value for this module as integer.
Definition: Module.cc:220
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
Abstract base class for different kinds of events.