Belle II Software  release-06-00-14
DQMHistAnalysisInput.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 : DQMHistAnalysisInput.cc
10 // Description :
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisInput.h>
15 
16 #include <daq/slc/base/StringUtil.h>
17 #include <ctime>
18 
19 #include <TROOT.h>
20 #include <TKey.h>
21 
22 using namespace Belle2;
23 
24 //-----------------------------------------------------------------
25 // Register the Module
26 //-----------------------------------------------------------------
27 REG_MODULE(DQMHistAnalysisInput)
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
35 {
36  //Parameter definition
37  addParam("HistMemoryPath", m_mempath, "Path to Input Hist memory", std::string(""));
38  addParam("HistMemorySize", m_memsize, "Size of Input Hist memory", 10000000);
39  addParam("HistMemoryName", m_memname, "Name of Input Hist memory", std::string(""));
40  addParam("ShmId", m_shm_id, "ID of shared memory", 0);
41  addParam("SemId", m_sem_id, "ID of semaphore", 0);
42  addParam("RefreshInterval", m_interval, "Refresh interval of histograms", 10);
43  addParam("AutoCanvas", m_autocanvas, "Automatic creation of canvas", true);
44  addParam("AutoCanvasFolders", m_acfolders, "List of histograms to automatically create canvases, empty for all",
45  std::vector<std::string>());
46  addParam("ExcludeFolders", m_exclfolders, "List of folders to exclude from create canvases, empty for none, \"all\" for all",
47  std::vector<std::string>());
48  addParam("RemoveEmpty", m_remove_empty, "Remove empty histograms", false);
49  addParam("EnableRunInfo", m_enable_run_info, "Enable Run Info", false);
50  B2DEBUG(1, "DQMHistAnalysisInput: Constructor done.");
51 }
52 
53 
54 DQMHistAnalysisInputModule::~DQMHistAnalysisInputModule() { }
55 
57 {
58  if (m_memory != nullptr) delete m_memory;
59  if (m_mempath != "")
60  m_memory = new DqmMemFile(m_mempath.c_str());
61  else
64  m_c_info = new TCanvas("DQMInfo/c_info", "");
65  m_c_info->SetTitle("");
66  } else {
67  m_c_info = NULL;
68  }
69  m_eventMetaDataPtr.registerInDataStore();
70  B2INFO("DQMHistAnalysisInput: initialized.");
71 }
72 
73 
75 {
76  B2INFO("DQMHistAnalysisInput: beginRun called.");
77 }
78 
80 {
81  sleep(m_interval);
82  std::vector<TH1*> hs;
83  char mbstr[100];
84 
85  time_t now = time(0);
86  strftime(mbstr, sizeof(mbstr), "%c", localtime(&now));
87  B2INFO("[" << mbstr << "] before LoadMemFile");
88 
89  TMemFile* file = m_memory->LoadMemFile();
90 
91  now = time(0);
92  strftime(mbstr, sizeof(mbstr), "%c", localtime(&now));
93  B2INFO("[" << mbstr << "] after LoadMemFile");
94 
95  const TDatime& mt = file->GetModificationDate();
96  TDatime mmt(mt.Convert());
97  std::string expno("UNKNOWN"), runno("UNKNOWN"), rtype("UNKNOWN");
98 
99  file->cd();
100  TIter next(file->GetListOfKeys());
101  TKey* key = NULL;
102 
103  now = time(0);
104  strftime(mbstr, sizeof(mbstr), "%c", localtime(&now));
105  B2INFO("[" << mbstr << "] before input loop");
106 
107  while ((key = (TKey*)next())) {
108  TH1* h = (TH1*)key->ReadObj();
109  if (h == NULL) continue; // would be strange, but better check
110  if (m_remove_empty && h->GetEntries() == 0) continue;
111  // Remove ":" from folder name, workaround!
112  TString a = h->GetName();
113  a.ReplaceAll(":", "");
114  h->SetName(a);
115  B2DEBUG(1, "DQMHistAnalysisInput: get histo " << a.Data());
116 
117  if (StringUtil::split(a.Data(), '/').size() <= 1) continue;
118 
119  std::string dir_name = StringUtil::split(a.Data(), '/')[0];
120 
121  hs.push_back(h);
122  if (std::string(h->GetName()) == std::string("DQMInfo/expno")) expno = h->GetTitle();
123  if (std::string(h->GetName()) == std::string("DQMInfo/runno")) runno = h->GetTitle();
124  if (std::string(h->GetName()) == std::string("DQMInfo/rtype")) rtype = h->GetTitle();
125  if (m_autocanvas) {
126  StringList s = StringUtil::split(a.Data(), '/');
127 
128  bool give_canvas = false;
129  if (m_exclfolders.size() == 0) { //If none specified, canvases for all histograms
130  give_canvas = true;
131  } else {
132  bool in_excl_folder = false;
133  if (m_exclfolders.size() == 1 && m_exclfolders[0] == "all") {
134  in_excl_folder = true;
135  } else {
136  for (auto& excl_folder : m_exclfolders) {
137  if (excl_folder == s[0]) {
138  in_excl_folder = true;
139  break;
140  }
141  }
142  }
143 
144  if (in_excl_folder) {
145  for (auto& wanted_folder : m_acfolders) {
146  B2DEBUG(1, "==" << wanted_folder << "==" << s[0] << "==");
147  if (wanted_folder == std::string(h->GetName())) {
148  give_canvas = true;
149  break;
150  }
151  }
152  } else {
153  give_canvas = true;
154  }
155  }
156 
157  if (give_canvas) {
158  B2DEBUG(1, "Auto Hist->Canvas for " << a);
159  a.ReplaceAll("/", "_");
160  std::string name = a.Data();
161  if (m_cs.find(name) == m_cs.end()) {
162  if (s.size() > 1) {
163  std::string dirname = s[0];
164  std::string hname = s[1];
165  if ((dirname + "/" + hname) == "softwaretrigger/skim") hname = "skim_hlt";
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  } else {
169  std::string hname = a.Data();
170  TCanvas* c = new TCanvas(("c_" + hname).c_str(), ("c_" + hname).c_str());
171  m_cs.insert(std::pair<std::string, TCanvas*>(name, c));
172  }
173  }
174  TCanvas* c = m_cs[name];
175  B2DEBUG(1, "DQMHistAnalysisInput: new canvas " << c->GetName());
176  c->cd();
177  if (h->GetDimension() == 1) {
178  if (h->GetMinimum() > 0) h->SetMinimum(0);
179  h->Draw("hist");
180  } else if (h->GetDimension() == 2) {
181  h->Draw("colz");
182  }
183  c->Update();
184  }
185  }
186  }
187 
188  now = time(0);
189  strftime(mbstr, sizeof(mbstr), "%c", localtime(&now));
190  B2INFO("[" << mbstr << "] after input loop");
191 
192  if (expno == std::string("UNKNOWN") || runno == std::string("UNKNOWN")) {
193  if (m_c_info != NULL) m_c_info->SetTitle((m_memname + ": Last Updated " + mmt.AsString()).c_str());
194  } else {
195  if (m_c_info != NULL) m_c_info->SetTitle((m_memname + ": Exp " + expno + ", Run " + runno + ", RunType " + rtype + ", Last Updated "
196  + mmt.AsString()).c_str());
197  m_expno = std::stoi(expno);
198  m_runno = std::stoi(runno);
199  }
200  B2INFO("DQMHistAnalysisInput: " << m_memname + ": Exp " + expno + ", Run " + runno + ", RunType " + rtype + ", Last Updated " +
201  mmt.AsString());
202 
203  resetHist();
204  for (size_t i = 0; i < hs.size(); i++) {
205  TH1* h = hs[i];
206  addHist("", h->GetName(), h);
207  B2DEBUG(1, "Found : " << h->GetName() << " : " << h->GetEntries());
208  std::string vname = h->GetName();
209  setFloatValue(vname + ".entries", h->GetEntries());
210  if (h->GetDimension() == 1) {
211  setFloatValue(vname + ".rms", h->GetRMS());
212  setFloatValue(vname + ".rmserr", h->GetRMSError());
213  setFloatValue(vname + ".mean", h->GetMean());
214  setFloatValue(vname + ".meanerr", h->GetMeanError());
215  } else if (h->GetDimension() == 2) {
216  setFloatValue(vname + ".xrms", h->GetRMS(1));
217  setFloatValue(vname + ".xrmserr", h->GetRMSError(1));
218  setFloatValue(vname + ".xmean", h->GetMean(1));
219  setFloatValue(vname + ".xmeanerr", h->GetMeanError(1));
220  setFloatValue(vname + ".yrms", h->GetRMS(2));
221  setFloatValue(vname + ".yrmserr", h->GetRMSError(2));
222  setFloatValue(vname + ".ymean", h->GetMean(2));
223  setFloatValue(vname + ".ymeanerr", h->GetMeanError(2));
224  }
225  }
226 
227  m_count++;
228  m_eventMetaDataPtr.create();
229  m_eventMetaDataPtr->setExperiment(m_expno);
230  m_eventMetaDataPtr->setRun(m_runno);
231  m_eventMetaDataPtr->setEvent(m_count);
232  m_eventMetaDataPtr->setTime(mt.Convert());
233 }
234 
236 {
237  B2INFO("DQMHistAnalysisInput : endRun called");
238 
239  TIter nextckey(gROOT->GetListOfCanvases());
240  TObject* cobj = NULL;
241 
242  while ((cobj = dynamic_cast<TObject*>(nextckey()))) {
243  if (cobj->IsA()->InheritsFrom("TCanvas")) {
244  (dynamic_cast<TCanvas*>(cobj))->Clear();
245  }
246  }
247 }
248 
249 
251 {
252  B2INFO("terminate called");
253 }
254 
Class definition for the output module of Sequential ROOT I/O.
std::string m_memname
The name of the memory file (HLT or ExpressReco).
bool m_remove_empty
Whether to remove empty histograms.
virtual void initialize() override
Module functions to be called from main process.
bool m_autocanvas
Whether automatically generate canvases for histograms.
virtual void event() override
This method is the core of the module.
bool m_enable_run_info
Whether to enable the run info to be displayed.
int m_shm_id
The shmid for the shared memory.
virtual void endRun() override
This method is called if the current run ends.
virtual void terminate() override
This method is called at the end of the event processing.
std::string m_mempath
The name of the shared memory for the histograms.
virtual void beginRun() override
Module functions to be called from event process.
DqmMemFile * m_memory
Memory file to hold histograms.
std::map< std::string, TCanvas * > m_cs
The list of canvases for output.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
The metadata for each event.
TCanvas * m_c_info
The canvas hold the basic DQM info.
std::vector< std::string > m_acfolders
The list of folders for which automatically generate canvases.
std::vector< std::string > m_exclfolders
The list of folders which are excluded from automatically generate canvases.
int m_sem_id
The semid for the shared memory.
The base class for the histogram analysis module.
static void addHist(const std::string &dirname, const std::string &histname, TH1 *h)
Add histogram.
static void resetHist()
Clear and reset the list of histograms.
static void setFloatValue(const std::string &parname, float vfloat)
Set the float value of the parameter.
#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.