Belle II Software  release-06-02-00
DQMHistAnalysisRunNr.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 : DQMHistAnalysisRunNr.cc
10 // Description : DQM Analysis for RunNr Check
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisRunNr.h>
15 #include <TROOT.h>
16 #include <TPaveText.h>
17 
18 using namespace std;
19 using namespace Belle2;
20 
21 //-----------------------------------------------------------------
22 // Register the Module
23 //-----------------------------------------------------------------
24 REG_MODULE(DQMHistAnalysisRunNr)
25 
26 //-----------------------------------------------------------------
27 // Implementation
28 //-----------------------------------------------------------------
29 
32 {
33  // This module CAN NOT be run in parallel!
34 
35  //Parameter definition
36  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("DAQ"));
37  addParam("PVPrefix", m_pvPrefix, "PV Prefix", std::string("DQM:DAQ:RunNr:"));
38  addParam("useEpics", m_useEpics, "Whether to update EPICS PVs.", false);
39 
40  B2DEBUG(99, "DQMHistAnalysisRunNr: Constructor done.");
41 }
42 
43 DQMHistAnalysisRunNrModule::~DQMHistAnalysisRunNrModule()
44 {
45 #ifdef _BELLE2_EPICS
46  if (m_useEpics) {
47  if (ca_current_context()) ca_context_destroy();
48  }
49 #endif
50 }
51 
52 void DQMHistAnalysisRunNrModule::initialize()
53 {
54  m_monObj = getMonitoringObject("daq");
55 
56  gROOT->cd(); // this seems to be important, or strange things happen
57 
58  m_cRunNr = new TCanvas((m_histogramDirectoryName + "/c_RunNr").data());
59 
60  // m_monObj->addCanvas(m_cRunNr);// useful?
61 
62 #ifdef _BELLE2_EPICS
63  if (m_useEpics) {
64  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
65  mychid.resize(2);
66  SEVCHK(ca_create_channel((m_pvPrefix + "Alarm").data(), NULL, NULL, 10, &mychid[0]), "ca_create_channel failure");
67  SEVCHK(ca_create_channel((m_pvPrefix + "RunNr").data(), NULL, NULL, 10, &mychid[1]), "ca_create_channel failure");
68 
69  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
70  }
71 #endif
72  B2DEBUG(99, "DQMHistAnalysisRunNr: initialized.");
73 }
74 
75 void DQMHistAnalysisRunNrModule::beginRun()
76 {
77  B2DEBUG(99, "DQMHistAnalysisRunNr: beginRun called.");
78 
79  m_cRunNr->Clear();
80 
81  // make sure we reset at run start to retrigger the alarm
82 #ifdef _BELLE2_EPICS
83  if (m_useEpics) {
84  double mean = 0.0; // must be double, mean of histogram -> runnr
85  int status = 0; // must be int, epics alarm status 0 = no data, 2 = o.k., 4 = not o.k.
86  // if status & runnr valid
87  SEVCHK(ca_put(DBR_INT, mychid[0], (void*)&status), "ca_set failure");
88  SEVCHK(ca_put(DBR_DOUBLE, mychid[1], (void*)&mean), "ca_set failure");
89  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
90  }
91 #endif
92 }
93 
94 void DQMHistAnalysisRunNrModule::event()
95 {
96  if (!m_cRunNr) return;
97  double mean = 0.0; // must be double, mean of histogram -> runnr
98  int status = 0; // must be int, epics alarm status 0 = no data, 2 = o.k., 4 = not o.k.
99 
100  m_cRunNr->cd();
101  m_cRunNr->Clear();
102 
103  auto leg = new TPaveText(0.6, 0.6, 0.95, 0.95, "NDC");
104  leg->SetFillColor(kWhite);
105 
106  auto name = "hRunnr";
107  TH1* hh1 = findHist(name);
108  if (hh1 == NULL) {
109  hh1 = findHist(m_histogramDirectoryName, name);
110  }
111  if (hh1) {
112  hh1->SetStats(kFALSE); // get rid of annoying box, we have our own
113  hh1->Draw("hist");
114  mean = hh1->GetMean();
115  if (hh1->GetEntries() > 0) {
116  leg->AddText("Contains Run: Entries");
117  // loop over bins and check if more than one is used
118  int nfilled = 0;
119  for (int i = 0; i <= hh1->GetXaxis()->GetNbins() + 1; i++) {
120  // resizeable histogram, thus there should never be under or overflow. still we loop over them
121  if (hh1->GetBinContent(i) > 0) {
122  nfilled++;
123  TString tmp;
124  tmp.Form("%ld: %ld", (long int)hh1->GetXaxis()->GetBinCenter(i), (long int)hh1->GetBinContent(i));
125  leg->AddText(tmp);
126  }
127  }
128  if (nfilled > 1) {
129  status = 4;
130  } else if (nfilled == 1) {
131  status = 2;
132  }// else nfilled=0, status stays 0
133  }
134  }
135 
136  if (status == 0) {
137  // no data (empty) or no histogram
138  m_cRunNr->Pad()->SetFillColor(kGray);// Magenta or Gray
139  leg->AddText("No data yet");
140  } else if (status == 2) {
141  // only one run
142  m_cRunNr->Pad()->SetFillColor(kGreen);// Green
143  } else { /*if ( status==4 )*/
144  // anything else is bad
145  m_cRunNr->Pad()->SetFillColor(kRed);// Red
146  }
147 
148  leg->Draw();
149 
150  m_cRunNr->Modified();
151  m_cRunNr->Update();
152 
153 
154 #ifdef _BELLE2_EPICS
155  if (m_useEpics) {
156  // if status & runnr valid
157  SEVCHK(ca_put(DBR_INT, mychid[0], (void*)&status), "ca_set failure");
158  SEVCHK(ca_put(DBR_DOUBLE, mychid[1], (void*)&mean), "ca_set failure");
159  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
160  }
161 #endif
162 }
163 
164 void DQMHistAnalysisRunNrModule::terminate()
165 {
166  B2DEBUG(99, "DQMHistAnalysisRunNr: terminate called");
167  // should delete canvas here, maybe hist, too? Who owns it?
168 #ifdef _BELLE2_EPICS
169  if (m_useEpics) {
170  for (auto m : mychid) SEVCHK(ca_clear_channel(m), "ca_clear_channel failure");
171  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
172  }
173 #endif
174 }
175 
The base class for the histogram analysis module.
DQM Histogram Analysis for PXD Common Modes.
#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.