Belle II Software  release-06-01-15
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 
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  }
209 
210  m_count++;
211  m_eventMetaDataPtr.create();
212  m_eventMetaDataPtr->setExperiment(m_expno);
213  m_eventMetaDataPtr->setRun(m_runno);
214  m_eventMetaDataPtr->setEvent(m_count);
215  m_eventMetaDataPtr->setTime(mt.Convert());
216 }
217 
219 {
220  B2INFO("DQMHistAnalysisInput : endRun called");
221 
222  TIter nextckey(gROOT->GetListOfCanvases());
223  TObject* cobj = NULL;
224 
225  while ((cobj = dynamic_cast<TObject*>(nextckey()))) {
226  if (cobj->IsA()->InheritsFrom("TCanvas")) {
227  (dynamic_cast<TCanvas*>(cobj))->Clear();
228  }
229  }
230 }
231 
232 
234 {
235  B2INFO("terminate called");
236 }
237 
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
Initializer.
bool m_autocanvas
Whether automatically generate canvases for histograms.
virtual void event() override
This method is called for each event.
virtual ~DQMHistAnalysisInputModule()
Destructor.
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
Called when entering a new run.
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.
#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.