Belle II Software  release-08-00-10
DQMHistAnalysis.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 : DQMHistAnalysisModule.cc
10 // Description : Baseclass for DQM histogram analysis module
11 //-
12 
13 #include <dqm/core/DQMHistAnalysis.h>
14 #include <boost/algorithm/string.hpp>
15 #include <TROOT.h>
16 #include <TClass.h>
17 
18 using namespace std;
19 using namespace Belle2;
20 
21 //-----------------------------------------------------------------
22 // Register the Module
23 //-----------------------------------------------------------------
24 REG_MODULE(DQMHistAnalysis);
25 
26 //-----------------------------------------------------------------
27 // Implementation
28 //-----------------------------------------------------------------
29 
30 DQMHistAnalysisModule::HistList DQMHistAnalysisModule::s_histList;
31 DQMHistAnalysisModule::MonObjList DQMHistAnalysisModule::s_monObjList;
32 DQMHistAnalysisModule::DeltaList DQMHistAnalysisModule::s_deltaList;
33 DQMHistAnalysisModule::CanvasUpdatedList DQMHistAnalysisModule::s_canvasUpdatedList;
34 
35 bool DQMHistAnalysisModule::m_useEpics = false; // default to false, to enable EPICS, add special EPICS Module class into chain
36 bool DQMHistAnalysisModule::m_epicsReadOnly =
37  false; // special for second "online" use (reading limits). default to false, to enable EPICS, add special EPICS Module parameter
38 std::string DQMHistAnalysisModule::m_PVPrefix = "TEST:"; // default to "TEST:", for production, set in EPICS enabler to e.g. "DQM:"
39 
40 DQMHistAnalysisModule::DQMHistAnalysisModule() : Module()
41 {
42  //Set module properties
43  setDescription("Histogram Analysis module base class");
44 }
45 
46 bool DQMHistAnalysisModule::addHist(const std::string& dirname, const std::string& histname, TH1* h)
47 {
48  std::string fullname;
49  if (dirname.size() > 0) {
50  fullname = dirname + "/" + histname;
51  } else {
52  fullname = histname;
53  }
54 
55  if (s_histList[fullname].update(h)) {
56  // only if histogram changed, check if delta histogram update needed
57  auto it = s_deltaList.find(fullname);
58  if (it != s_deltaList.end()) {
59  B2DEBUG(20, "Found Delta" << fullname);
60  it->second->update(h); // update
61  }
62  return true; // histogram changed
63  }
64 
65  return false; // histogram didnt change
66 }
67 
68 void DQMHistAnalysisModule::addDeltaPar(const std::string& dirname, const std::string& histname, HistDelta::EDeltaType t, int p,
69  unsigned int a)
70 {
71  std::string fullname;
72  if (dirname.size() > 0) {
73  fullname = dirname + "/" + histname;
74  } else {
75  fullname = histname;
76  }
77  s_deltaList[fullname] = new HistDelta(t, p, a);
78 }
79 
80 bool DQMHistAnalysisModule::hasDeltaPar(const std::string& dirname, const std::string& histname)
81 {
82  std::string fullname;
83  if (dirname.size() > 0) {
84  fullname = dirname + "/" + histname;
85  } else {
86  fullname = histname;
87  }
88  return s_deltaList.find(fullname) != s_deltaList.end(); // contains() if we switch to C++20
89 }
90 
91 TH1* DQMHistAnalysisModule::getDelta(const std::string& dirname, const std::string& histname, int n, bool onlyIfUpdated)
92 {
93  std::string fullname;
94  if (dirname.size() > 0) {
95  fullname = dirname + "/" + histname;
96  } else {
97  fullname = histname;
98  }
99  return getDelta(fullname, n, onlyIfUpdated);
100 }
101 
102 TH1* DQMHistAnalysisModule::getDelta(const std::string& fullname, int n, bool onlyIfUpdated)
103 {
104  auto it = s_deltaList.find(fullname);
105  if (it != s_deltaList.end()) {
106  return it->second->getDelta(n, onlyIfUpdated);
107  }
108  B2WARNING("Delta hist " << fullname << " not found");
109  return nullptr;
110 }
111 
113 {
114  if (s_monObjList.find(objName) != s_monObjList.end()) {
115  if (s_monObjList[objName]) {
116  return s_monObjList[objName];
117  } else {
118  B2WARNING("MonitoringObject " << objName << " listed as being in memfile but points to nowhere. New Object will be made.");
119  s_monObjList.erase(objName);
120  }
121  }
122 
123  MonitoringObject* obj = new MonitoringObject(objName);
124  s_monObjList.insert(MonObjList::value_type(objName, obj));
125  return obj;
126 }
127 
128 TCanvas* DQMHistAnalysisModule::findCanvas(TString canvas_name)
129 {
130  TIter nextkey(gROOT->GetListOfCanvases());
131  TObject* obj{};
132 
133  while ((obj = dynamic_cast<TObject*>(nextkey()))) {
134  if (obj->IsA()->InheritsFrom("TCanvas")) {
135  if (obj->GetName() == canvas_name)
136  return dynamic_cast<TCanvas*>(obj);
137  }
138  }
139  return nullptr;
140 }
141 
142 TH1* DQMHistAnalysisModule::findHist(const std::string& histname, bool was_updated)
143 {
144  if (s_histList.find(histname) != s_histList.end()) {
145  if (was_updated && !s_histList[histname].isUpdated()) return nullptr;
146  if (s_histList[histname].getHist()) {
147  return s_histList[histname].getHist();
148  } else {
149  B2ERROR("Histogram " << histname << " in histogram list but nullptr.");
150  }
151  }
152  B2INFO("Histogram " << histname << " not in list.");
153  return nullptr;
154 }
155 
156 TH1* DQMHistAnalysisModule::findHist(const std::string& dirname, const std::string& histname, bool updated)
157 {
158  if (dirname.size() > 0) {
159  return findHist(dirname + "/" + histname, updated);
160  }
161  return findHist(histname, updated);
162 }
163 
164 TH1* DQMHistAnalysisModule::findHistInCanvas(const std::string& histo_name)
165 {
166  // parse the dir+histo name and create the corresponding canvas name
167  auto s = StringSplit(histo_name, '/');
168  if (s.size() != 2) {
169  B2ERROR("findHistInCanvas: histoname not valid (missing dir?), should be 'dirname/histname': " << histo_name);
170  return nullptr;
171  }
172  auto dirname = s.at(0);
173  auto hname = s.at(1);
174  std::string canvas_name = dirname + "/c_" + hname;
175 
176  auto cobj = findCanvas(canvas_name);
177  if (cobj == nullptr) return nullptr;
178 
179  TIter nextkey(((TCanvas*)cobj)->GetListOfPrimitives());
180  TObject* obj{};
181  while ((obj = dynamic_cast<TObject*>(nextkey()))) {
182  if (obj->IsA()->InheritsFrom("TH1")) {
183  if (obj->GetName() == histo_name)
184  return dynamic_cast<TH1*>(obj);
185  }
186  }
187  return nullptr;
188 }
189 
190 TH1* DQMHistAnalysisModule::findHistInFile(TFile* file, const std::string& histname)
191 {
192  // find histogram by name in file, histname CAN contain directory!
193  // will return nullptr if file is zeroptr, not found or not correct type
194  if (file && file->IsOpen()) {
195  auto obj = file->Get(histname.data());
196  if (obj != nullptr) {
197  // check class type
198  if (obj->IsA()->InheritsFrom("TH1")) {
199  B2DEBUG(20, "Histogram " << histname << " found in file");
200  return dynamic_cast<TH1*>(obj);
201  } else {
202  B2INFO("Found Object " << histname << " in file is not a histogram");
203  }
204  } else {
205  B2INFO("Histogram " << histname << " not found in file");
206  }
207  }
208  return nullptr;
209 }
210 
212 {
213  if (s_monObjList.find(objName) != s_monObjList.end()) {
214  if (s_monObjList[objName]) {
215  //Want to search elsewhere if null-pointer saved in map
216  return s_monObjList[objName];
217  } else {
218  B2ERROR("MonitoringObject " << objName << " listed as being in memfile but points to nowhere.");
219  }
220  }
221  B2INFO("MonitoringObject " << objName << " not in memfile.");
222  return NULL;
223 }
224 
226 {
227  double probs[2] = {0.16, 1 - 0.16};
228  double quant[2] = {0, 0};
229  h->GetQuantiles(2, quant, probs);
230  const double sigma68 = (-quant[0] + quant[1]) / 2;
231  return sigma68;
232 }
233 
234 std::vector <std::string> DQMHistAnalysisModule::StringSplit(const std::string& in, const char delim)
235 {
236  std::vector <std::string> out;
237  boost::split(out, in, [delim](char c) {return c == delim;});
238  return out;
239 }
240 
242 {
243  for (auto& h : s_histList) {
244  // attention, we need the reference, otherwise we work on a copy
245  h.second.resetBeforeEvent();
246  }
247  for (auto d : s_deltaList) {
248  d.second->setNotUpdated();
249  }
250 
251  s_canvasUpdatedList.clear();
252 }
253 
255 {
256  s_histList.clear();
257 }
258 
259 void DQMHistAnalysisModule::UpdateCanvas(std::string name, bool updated)
260 {
261  s_canvasUpdatedList[name] = updated;
262 }
263 
264 void DQMHistAnalysisModule::UpdateCanvas(TCanvas* c, bool updated)
265 {
266  if (c) UpdateCanvas(c->GetName(), updated);
267 }
268 
269 void DQMHistAnalysisModule::ExtractRunType(std::vector <TH1*>& hs)
270 {
271  s_runType = "";
272  for (size_t i = 0; i < hs.size(); i++) {
273  if (hs[i]->GetName() == std::string("DQMInfo/rtype")) {
274  s_runType = hs[i]->GetTitle();
275  return;
276  }
277  }
278  B2ERROR("ExtractRunType: Histogram \"DQMInfo/rtype\" missing");
279 }
280 
281 void DQMHistAnalysisModule::ExtractEvent(std::vector <TH1*>& hs)
282 {
283  s_eventProcessed = 0;
284  for (size_t i = 0; i < hs.size(); i++) {
285  if (hs[i]->GetName() == std::string("DAQ/Nevent")) {
286  s_eventProcessed = hs[i]->GetEntries();
287  return;
288  }
289  }
290  B2ERROR("ExtractEvent: Histogram \"DAQ/Nevent\" missing");
291 }
292 
293 
294 int DQMHistAnalysisModule::registerEpicsPV(std::string pvname, std::string keyname, bool update_pvs)
295 {
296  if (!m_useEpics) return -1;
297 #ifdef _BELLE2_EPICS
298  if (m_epicsNameToChID[pvname] != nullptr) {
299  B2ERROR("Epics PV " << pvname << " already registered!");
300  return -1;
301  }
302  if (keyname != "" && m_epicsNameToChID[keyname] != nullptr) {
303  B2ERROR("Epics PV with key " << keyname << " already registered!");
304  return -1;
305  }
306 
307  m_epicsChID.emplace_back();
308  auto ptr = &m_epicsChID.back();
309  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
310  // the subscribed name includes the prefix, the map below does *not*
311  SEVCHK(ca_create_channel((m_PVPrefix + pvname).data(), NULL, NULL, 10, ptr), "ca_create_channel failure");
312 
313  if (update_pvs) SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
314 
315  m_epicsNameToChID[pvname] = *ptr;
316  if (keyname != "") m_epicsNameToChID[keyname] = *ptr;
317  return m_epicsChID.size() - 1; // return index to last added item
318 #else
319  return -1;
320 #endif
321 }
322 
323 void DQMHistAnalysisModule::setEpicsPV(std::string keyname, double value)
324 {
325  if (!m_useEpics || m_epicsReadOnly) return;
326 #ifdef _BELLE2_EPICS
327  if (m_epicsNameToChID[keyname] == nullptr) {
328  B2ERROR("Epics PV " << keyname << " not registered!");
329  return;
330  }
331  SEVCHK(ca_put(DBR_DOUBLE, m_epicsNameToChID[keyname], (void*)&value), "ca_set failure");
332 #endif
333 }
334 
335 void DQMHistAnalysisModule::setEpicsPV(std::string keyname, int value)
336 {
337  if (!m_useEpics || m_epicsReadOnly) return;
338 #ifdef _BELLE2_EPICS
339  if (m_epicsNameToChID[keyname] == nullptr) {
340  B2ERROR("Epics PV " << keyname << " not registered!");
341  return;
342  }
343  SEVCHK(ca_put(DBR_SHORT, m_epicsNameToChID[keyname], (void*)&value), "ca_set failure");
344 #endif
345 }
346 
347 void DQMHistAnalysisModule::setEpicsStringPV(std::string keyname, std::string value)
348 {
349  if (!m_useEpics || m_epicsReadOnly) return;
350 #ifdef _BELLE2_EPICS
351  if (m_epicsNameToChID[keyname] == nullptr) {
352  B2ERROR("Epics PV " << keyname << " not registered!");
353  return;
354  }
355  if (value.length() > 40) {
356  B2ERROR("Epics string PV " << keyname << " too long (>40 characters)!");
357  return;
358  }
359  char text[40];
360  strcpy(text, value.c_str());
361  SEVCHK(ca_put(DBR_STRING, m_epicsNameToChID[keyname], text), "ca_set failure");
362 #endif
363 }
364 
365 void DQMHistAnalysisModule::setEpicsPV(int index, double value)
366 {
367  if (!m_useEpics || m_epicsReadOnly) return;
368 #ifdef _BELLE2_EPICS
369  if (index < 0 || index >= (int)m_epicsChID.size()) {
370  B2ERROR("Epics PV with " << index << " not registered!");
371  return;
372  }
373  SEVCHK(ca_put(DBR_DOUBLE, m_epicsChID[index], (void*)&value), "ca_set failure");
374 #endif
375 }
376 
377 void DQMHistAnalysisModule::setEpicsPV(int index, int value)
378 {
379  if (!m_useEpics || m_epicsReadOnly) return;
380 #ifdef _BELLE2_EPICS
381  if (index < 0 || index >= (int)m_epicsChID.size()) {
382  B2ERROR("Epics PV with " << index << " not registered!");
383  return;
384  }
385  SEVCHK(ca_put(DBR_SHORT, m_epicsChID[index], (void*)&value), "ca_set failure");
386 #endif
387 }
388 
389 void DQMHistAnalysisModule::setEpicsStringPV(int index, std::string value)
390 {
391  if (!m_useEpics || m_epicsReadOnly) return;
392 #ifdef _BELLE2_EPICS
393  if (index < 0 || index >= (int)m_epicsChID.size()) {
394  B2ERROR("Epics PV with " << index << " not registered!");
395  return;
396  }
397  char text[40];
398  strcpy(text, value.c_str());
399  SEVCHK(ca_put(DBR_STRING, m_epicsChID[index], text), "ca_set failure");
400 #endif
401 }
402 
403 double DQMHistAnalysisModule::getEpicsPV(std::string keyname)
404 {
405  double value{NAN};
406  if (!m_useEpics) return value;
407 #ifdef _BELLE2_EPICS
408  if (m_epicsNameToChID[keyname] == nullptr) {
409  B2ERROR("Epics PV " << keyname << " not registered!");
410  return value;
411  }
412  // From EPICS doc. When ca_get or ca_array_get are invoked the returned channel value cant be assumed to be stable
413  // in the application supplied buffer until after ECA_NORMAL is returned from ca_pend_io. If a connection is lost
414  // outstanding get requests are not automatically reissued following reconnect.
415  auto r = ca_get(DBR_DOUBLE, m_epicsNameToChID[keyname], (void*)&value);
416  if (r == ECA_NORMAL) r = ca_pend_io(5.0); // this is needed!
417  if (r == ECA_NORMAL) {
418  return value;
419  } else {
420  SEVCHK(r, "ca_get or ca_pend_io failure");
421  }
422 #endif
423  return NAN;
424 }
425 
427 {
428  double value{NAN};
429  if (!m_useEpics) return value;
430 #ifdef _BELLE2_EPICS
431  if (index < 0 || index >= (int)m_epicsChID.size()) {
432  B2ERROR("Epics PV with " << index << " not registered!");
433  return value;
434  }
435  // From EPICS doc. When ca_get or ca_array_get are invoked the returned channel value cant be assumed to be stable
436  // in the application supplied buffer until after ECA_NORMAL is returned from ca_pend_io. If a connection is lost
437  // outstanding get requests are not automatically reissued following reconnect.
438  auto r = ca_get(DBR_DOUBLE, m_epicsChID[index], (void*)&value);
439  if (r == ECA_NORMAL) r = ca_pend_io(5.0); // this is needed!
440  if (r == ECA_NORMAL) {
441  return value;
442  } else {
443  SEVCHK(r, "ca_get or ca_pend_io failure");
444  }
445 #endif
446  return NAN;
447 }
448 
449 std::string DQMHistAnalysisModule::getEpicsStringPV(std::string keyname, bool& status)
450 {
451  status = false;
452  char value[40] = "";
453  if (!m_useEpics) return std::string(value);
454 #ifdef _BELLE2_EPICS
455  if (m_epicsNameToChID[keyname] == nullptr) {
456  B2ERROR("Epics PV " << keyname << " not registered!");
457  return std::string(value);
458  }
459  // From EPICS doc. When ca_get or ca_array_get are invoked the returned channel value cant be assumed to be stable
460  // in the application supplied buffer until after ECA_NORMAL is returned from ca_pend_io. If a connection is lost
461  // outstanding get requests are not automatically reissued following reconnect.
462  auto r = ca_get(DBR_STRING, m_epicsNameToChID[keyname], value);
463  if (r == ECA_NORMAL) r = ca_pend_io(5.0); // this is needed!
464  if (r == ECA_NORMAL) {
465  status = true;
466  return std::string(value);
467  } else {
468  SEVCHK(r, "ca_get or ca_pend_io failure");
469  }
470 #endif
471  return std::string(value);
472 }
473 
474 std::string DQMHistAnalysisModule::getEpicsStringPV(int index, bool& status)
475 {
476  status = false;
477  char value[40] = "";
478  if (!m_useEpics) return std::string(value);
479 #ifdef _BELLE2_EPICS
480  if (index < 0 || index >= (int)m_epicsChID.size()) {
481  B2ERROR("Epics PV with " << index << " not registered!");
482  return std::string(value);
483  }
484  // From EPICS doc. When ca_get or ca_array_get are invoked the returned channel value cant be assumed to be stable
485  // in the application supplied buffer until after ECA_NORMAL is returned from ca_pend_io. If a connection is lost
486  // outstanding get requests are not automatically reissued following reconnect.
487  auto r = ca_get(DBR_DOUBLE, m_epicsChID[index], value);
488  if (r == ECA_NORMAL) r = ca_pend_io(5.0); // this is needed!
489  if (r == ECA_NORMAL) {
490  status = true;
491  return std::string(value);
492  } else {
493  SEVCHK(r, "ca_get or ca_pend_io failure");
494  }
495 #endif
496  return std::string(value);
497 }
498 
499 chid DQMHistAnalysisModule::getEpicsPVChID(std::string keyname)
500 {
501 #ifdef _BELLE2_EPICS
502  if (m_useEpics) {
503  if (m_epicsNameToChID[keyname] != nullptr) {
504  return m_epicsNameToChID[keyname];
505  } else {
506  B2ERROR("Epics PV " << keyname << " not registered!");
507  }
508  }
509 #endif
510  return nullptr;
511 }
512 
514 {
515 #ifdef _BELLE2_EPICS
516  if (m_useEpics) {
517  if (index >= 0 && index < (int)m_epicsChID.size()) {
518  return m_epicsChID[index];
519  } else {
520  B2ERROR("Epics PV with " << index << " not registered!");
521  }
522  }
523 #endif
524  return nullptr;
525 }
526 
528 {
529  if (!m_useEpics) return;
530 #ifdef _BELLE2_EPICS
531  if (wait > 0.) SEVCHK(ca_pend_io(wait), "ca_pend_io failure");
532 #endif
533 }
534 
536 {
537  // this should be called in terminate function of analysis modules
538 #ifdef _BELLE2_EPICS
539  if (getUseEpics()) {
540  for (auto& it : m_epicsChID) SEVCHK(ca_clear_channel(it), "ca_clear_channel failure");
541  updateEpicsPVs(5.0);
542  // Make sure we clean up both afterwards!
543  m_epicsChID.clear();
544  m_epicsNameToChID.clear();
545  }
546 #endif
547 }
548 
549 bool DQMHistAnalysisModule::requestLimitsFromEpicsPVs(std::string name, double& lowerAlarm, double& lowerWarn, double& upperWarn,
550  double& upperAlarm)
551 {
552  return requestLimitsFromEpicsPVs(getEpicsPVChID(name), lowerAlarm, lowerWarn, upperWarn, upperAlarm);
553 }
554 
555 bool DQMHistAnalysisModule::requestLimitsFromEpicsPVs(int index, double& lowerAlarm, double& lowerWarn, double& upperWarn,
556  double& upperAlarm)
557 {
558  return requestLimitsFromEpicsPVs(getEpicsPVChID(index), lowerAlarm, lowerWarn, upperWarn, upperAlarm);
559 }
560 
561 bool DQMHistAnalysisModule::requestLimitsFromEpicsPVs(chid pv, double& lowerAlarm, double& lowerWarn, double& upperWarn,
562  double& upperAlarm)
563 {
564  // get warn and error limit only if pv exists
565  // overwrite only if limit is defined (not NaN)
566  // user should initilize with NaN before calling, unless
567  // some "default" values should be set otherwise
568  if (pv != nullptr) {
569  struct dbr_ctrl_double tPvData;
570  // From EPICS doc. When ca_get or ca_array_get are invoked the returned channel value cant be assumed to be stable
571  // in the application supplied buffer until after ECA_NORMAL is returned from ca_pend_io. If a connection is lost
572  // outstanding get requests are not automatically reissued following reconnect.
573  auto r = ca_get(DBR_CTRL_DOUBLE, pv, &tPvData);
574  if (r == ECA_NORMAL) r = ca_pend_io(5.0); // this is needed!
575  if (r == ECA_NORMAL) {
576  if (!std::isnan(tPvData.lower_alarm_limit)) {
577  lowerAlarm = tPvData.lower_alarm_limit;
578  }
579  if (!std::isnan(tPvData.lower_warning_limit)) {
580  lowerWarn = tPvData.lower_warning_limit;
581  }
582  if (!std::isnan(tPvData.upper_warning_limit)) {
583  upperWarn = tPvData.upper_warning_limit;
584  }
585  if (!std::isnan(tPvData.upper_alarm_limit)) {
586  upperAlarm = tPvData.upper_alarm_limit;
587  }
588  return true;
589  } else {
590  SEVCHK(r, "ca_get or ca_pend_io failure");
591  }
592  }
593  return false;
594 }
static MonObjList s_monObjList
The list of MonitoringObjects.
TCanvas * findCanvas(TString cname)
Find canvas by name.
bool hasDeltaPar(const std::string &dirname, const std::string &histname)
Check if Delta histogram parameters exist for histogram.
std::map< std::string, HistObject > HistList
The type of list of histograms.
void updateEpicsPVs(float timeout)
Update all EPICS PV (flush to network)
int registerEpicsPV(std::string pvname, std::string keyname="", bool update_pvs=true)
EPICS related Functions.
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
static TH1 * findHistInFile(TFile *file, const std::string &histname)
Find histogram in specific TFile (e.g.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
static MonitoringObject * findMonitoringObject(const std::string &objName)
Find MonitoringObject.
double getSigma68(TH1 *h) const
Helper function to compute half of the central interval covering 68% of a distribution.
double getEpicsPV(std::string keyname)
Read value from a EPICS PV.
static int s_eventProcessed
Number of Events processed to fill histograms.
std::map< std::string, bool > CanvasUpdatedList
The type of list of canvas updated status.
std::string getEpicsStringPV(std::string keyname, bool &status)
Read value from a EPICS PV.
static HistList s_histList
The list of Histograms.
static std::string s_runType
The Run type.
static void clearHistList(void)
Clears the list of histograms.
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
std::vector< std::string > StringSplit(const std::string &s, const char delim)
Helper function for string token split.
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
std::map< std::string, MonitoringObject * > MonObjList
The type of list of MonitoringObjects.
static DeltaList s_deltaList
The list of Delta Histograms and settings.
static bool m_epicsReadOnly
Flag if to use EPICS in ReadOnly mode (for reading limits) do not set by yourself,...
static bool addHist(const std::string &dirname, const std::string &histname, TH1 *h)
Add histogram.
bool getUseEpics(void)
Getter for EPICS usage.
void ExtractRunType(std::vector< TH1 * > &hs)
Extract Run Type from histogram title, called from input module.
static std::string m_PVPrefix
The Prefix for EPICS PVs.
TH1 * findHistInCanvas(const std::string &hname)
Find histogram in corresponding canvas.
void cleanupEpicsPVs(void)
Unsubscribe from EPICS PVs on terminate.
static bool m_useEpics
Flag if to use EPICS do not set by yourself, use EpicsEnable module to set.
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 UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
static MonitoringObject * getMonitoringObject(const std::string &histname)
Get MonitoringObject with given name (new object is created if non-existing)
std::map< std::string, HistDelta * > DeltaList
The type of list of delta settings and histograms.
chid getEpicsPVChID(std::string keyname)
Get EPICS PV Channel Id.
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
void setEpicsStringPV(std::string keyname, std::string value)
Write string to a EPICS PV.
static CanvasUpdatedList s_canvasUpdatedList
The list of canvas updated status.
Class to keep track of delta histograms.
Definition: HistDelta.h:23
EDeltaType
enum definition for delta algo Disabled: nothing Entries: use nr histogram entries Underflow: use ent...
Definition: HistDelta.h:32
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
MonitoringObject is a basic object to hold data for the run-dependency monitoring Run summary TCanvas...
#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.