Belle II Software  release-08-00-10
DQMHistAnalysisPXDDAQ.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 : DQMHistAnalysisPXDDAQ.cc
10 // Description : Analysis of PXD DAQ and Issues
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisPXDDAQ.h>
15 #include <TROOT.h>
16 
17 using namespace std;
18 using namespace Belle2;
19 
20 //-----------------------------------------------------------------
21 // Register the Module
22 //-----------------------------------------------------------------
23 REG_MODULE(DQMHistAnalysisPXDDAQ);
24 
25 //-----------------------------------------------------------------
26 // Implementation
27 //-----------------------------------------------------------------
28 
29 DQMHistAnalysisPXDDAQModule::DQMHistAnalysisPXDDAQModule()
31 {
32  // This module CAN NOT be run in parallel!
33  setDescription("DQM Analysis for PXD DAQ Statistics and Issues");
34 
35  // Parameter definition
36  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDDAQ"));
37  addParam("minEntries", m_minEntries, "minimum number of new entries for last time slot", 10000);
38  B2DEBUG(1, "DQMHistAnalysisPXDDAQ: Constructor done.");
39 
40 }
41 
43 {
44 }
45 
47 {
48  B2DEBUG(1, "DQMHistAnalysisPXDDAQ: initialized.");
49 
51 
52  gROOT->cd(); // this seems to be important, or strange things happen
53 
54  m_cDAQError = new TCanvas((m_histogramDirectoryName + "/c_DAQError").data());
55  m_cMissingDHC = new TCanvas((m_histogramDirectoryName + "/c_MissingDHC").data());
56  m_cMissingDHE = new TCanvas((m_histogramDirectoryName + "/c_MissingDHE").data());
57  m_cMissingDHP = new TCanvas((m_histogramDirectoryName + "/c_MissingDHP").data());
58  m_cStatistic = new TCanvas((m_histogramDirectoryName + "/c_Statistic").data());
59  m_cStatisticUpd = new TCanvas((m_histogramDirectoryName + "/c_StatisticUpd").data());
61  HistDelta::c_Underflow, m_minEntries, 1); // register delta
62 
68 
69  m_hMissingDHC = new TH2F("hPXDMissingDHC", "PXD Missing DHC", 16, 0, 16, 2, 0, 2);
70  m_hMissingDHE = new TH2F("hPXDMissingDHE", "PXD Missing DHE", 64, 0, 64, 2, 0, 2);
71 
72  registerEpicsPV("PXD:DAQ:HLTRej", "HLTReject");
73  registerEpicsPV("PXD:DAQ:Trunc", "Trunc");
74  registerEpicsPV("PXD:DAQ:HER_Trunc", "HER_Trunc");
75  registerEpicsPV("PXD:DAQ:LER_Trunc", "LER_Trunc");
76  registerEpicsPV("PXD:DAQ:CM63", "CM63");
77  registerEpicsPV("PXD:DAQ:HER_CM63", "HER_CM63");
78  registerEpicsPV("PXD:DAQ:LER_CM63", "LER_CM63");
79  registerEpicsPV("PXD:DAQ:HER_CM63_1ms", "HER_CM63_1ms");
80  registerEpicsPV("PXD:DAQ:LER_CM63_1ms", "LER_CM63_1ms");
81  registerEpicsPV("PXD:DAQ:HER_Trunc_1ms", "HER_Trunc_1ms");
82  registerEpicsPV("PXD:DAQ:LER_Trunc_1ms", "LER_Trunc_1ms");
83  registerEpicsPV("PXD:DAQ:MissFrame", "MissFrame");
84  registerEpicsPV("PXD:DAQ:Timeout", "Timeout");
85  registerEpicsPV("PXD:DAQ:LinkDown", "LinkDown");
86  registerEpicsPV("PXD:DAQ:Mismatch", "Mismatch");
87  registerEpicsPV("PXD:DAQ:HER_Miss", "HER_Miss");
88  registerEpicsPV("PXD:DAQ:LER_Miss", "LER_Miss");
89  registerEpicsPV("PXD:DAQ:HER_Miss_1ms", "HER_Miss_1ms");
90  registerEpicsPV("PXD:DAQ:LER_Miss_1ms", "LER_Miss_1ms");
91  registerEpicsPV("PXD:DAQ:unused", "unused");
92 }
93 
95 {
96  B2DEBUG(1, "DQMHistAnalysisPXDDAQ: beginRun called.");
97 
98  m_cMissingDHP->Clear();
99  m_cStatisticUpd->Clear();
100 }
101 
103 {
104 // double data = 0.0;
105  if (m_cMissingDHP == nullptr || m_cMissingDHE == nullptr || m_cMissingDHC == nullptr
106  || m_cStatistic == nullptr) return; // we could assume this
107 
108  m_cDAQError->Clear();
109  m_cMissingDHP->Clear();
110  m_cMissingDHE->Clear();
111  m_cMissingDHC->Clear();
112  m_cStatistic->Clear();
113 
114  {
115  std::string name = "PXDDAQError";
116 
117  if (m_hDAQError) { delete m_hDAQError; m_hDAQError = nullptr;}
118 
119  TH1* hh1 = findHist(name);
120  if (hh1 == NULL) {
121  hh1 = findHist(m_histogramDirectoryName, name);
122  }
123  m_cDAQError->cd();
124  if (hh1) {
125  m_hDAQError = (TH1D*)hh1->DrawClone("text");
126  m_hDAQError->SetName("hPXDDAQError");
127  m_hDAQError->SetTitle("PXD Fraction of DAQ Errors");
128  if (m_hDAQError->GetBinContent(0)) {
129  m_hDAQError->Scale(1.0 / m_hDAQError->GetBinContent(0));
130  }
131  m_hDAQError->Draw("text,hist");
132  }
133  }
134  {
135  // DHC histogram
136  std::string name = "PXDDAQDHCError";
137 
138  TH1* hh1 = findHist(name);
139  if (hh1 == NULL) {
140  hh1 = findHist(m_histogramDirectoryName, name);
141  }
142  m_cMissingDHC->cd();
143  if (hh1) {
144  auto events = hh1->GetBinContent(hh1->GetBin(-1, -1));
145  // first, we have to relate the per-DHC overflow (DHC object count) to the overall overflow (event count)
146  // second, we have to relate the "fake data" DHC bin to the per-DHC overflow (DHC object count)
147  m_hMissingDHC->Reset();
148  for (int i = 0; i < 16; i++) {
149  auto dhecount = hh1->GetBinContent(hh1->GetBin(i, -1));
150  if (events > 0) m_hMissingDHC->Fill((double)i, 0.0, 1.0 - dhecount / events);
151  // c_FAKE_NO_DATA_TRIG = 1ull << 29,
152  if (dhecount > 0) m_hMissingDHC->Fill((double)i, 1.0, hh1->GetBinContent(hh1->GetBin(i, 29) / dhecount));
153  }
154  m_hMissingDHC->Draw("text");
155  }
156  }
157 
158  {
159  // DHE histogram
160  std::string name = "PXDDAQDHEError";
161 
162  TH1* hh1 = findHist(name);
163  if (hh1 == NULL) {
164  hh1 = findHist(m_histogramDirectoryName, name);
165  }
166  m_cMissingDHE->cd();
167  if (hh1) {
168  auto events = hh1->GetBinContent(hh1->GetBin(-1, -1));
169  // first, we have to relate the per-DHE overflow (DHE object count) to the overall overflow (event count)
170  // second, we have to relate the "fake data" DHE bin to the per-DHE overflow (DHE object count)
171  m_hMissingDHE->Reset();
172  for (int i = 0; i < 64; i++) {
173  auto dhecount = hh1->GetBinContent(hh1->GetBin(i, -1));
174  if (events > 0) m_hMissingDHE->Fill((double)i, 0.0, 1.0 - dhecount / events);
175  // c_FAKE_NO_DATA_TRIG = 1ull << 29,
176  if (dhecount > 0) m_hMissingDHE->Fill((double)i, 1.0, hh1->GetBinContent(hh1->GetBin(i, 29) / dhecount));
177  }
178  m_hMissingDHE->Draw("text");
179  }
180  }
181 
182  {
183  // DHP histogram
184  if (m_hMissingDHP) { delete m_hMissingDHP; m_hMissingDHP = nullptr;}
185 
186  std::string name = "PXDDAQDHPDataMissing";
187 
188  TH1* hh1 = findHist(name);
189  if (hh1 == NULL) {
190  hh1 = findHist(m_histogramDirectoryName, name);
191  }
192  m_cMissingDHP->cd();
193  if (hh1) {
194  m_hMissingDHP = (TH1F*)hh1->DrawClone("text");
195  if (m_hMissingDHP->GetBinContent(0)) {
196  m_hMissingDHP->Scale(1.0 / m_hMissingDHP->GetBinContent(0));
197  m_hMissingDHP->Draw("text");
198  }
199  }
200  // double data = m_hMissingDHP->Max???;
201  //
202  // m_monObj->setVariable("missingDHPFraction", data);
203  //
204  m_cMissingDHP->Modified();
205  m_cMissingDHP->Update();
206  }
207 
208  std::string name = "PXDDAQStat";
209 
210  auto* statsum = findHist(m_histogramDirectoryName, name, true);
211  if (statsum) {
212  // Stat histogram
213  if (m_hStatistic) { delete m_hStatistic; m_hStatistic = nullptr;}
214  m_cStatistic->cd();
215  m_hStatistic = (TH1D*)statsum->DrawClone("text");
216  if (m_hStatistic->GetBinContent(0)) {
217  m_hStatistic->Scale(1.0 / m_hStatistic->GetBinContent(0));
218  m_hStatistic->Draw("text");
219  }
220  m_cStatistic->Modified();
221  m_cStatistic->Update();
222  }
223 
224  // now the important part, check fraction of "errors" and export
225  double data_HLTRej = 0.0;
226  double data_Trunc = 0.0;
227  double data_HER_Trunc = 0.0;
228  double data_LER_Trunc = 0.0;
229  double data_CM63 = 0.0;
230  double data_HER_CM63 = 0.0;
231  double data_LER_CM63 = 0.0;
232  double data_HER_CM63_1ms = 0.0;
233  double data_LER_CM63_1ms = 0.0;
234  double data_HER_Trunc_1ms = 0.0;
235  double data_LER_Trunc_1ms = 0.0;
236  double data_MissFrame = 0.0;
237  double data_Timeout = 0.0;
238  double data_LinkDown = 0.0;
239  double data_Mismatch = 0.0;
240  double data_HER_Miss = 0.0;
241  double data_LER_Miss = 0.0;
242  double data_HER_Miss_1ms = 0.0;
243  double data_LER_Miss_1ms = 0.0;
244  double data_unused = 0.0;
245 
246  bool update_epics = false;
247 
248  auto* delta = getDelta(m_histogramDirectoryName, name); // only updated by default
249  if (delta) {
250  gROOT->cd();
251  m_cStatisticUpd->Clear();
252  m_cStatisticUpd->cd();// necessary!
253  delta->Draw("hist");
254  // now check that we have enough stats for useful export
255  double scale = delta->GetBinContent(0);// underflow is event counter
256  if (scale >= m_minEntries) {
257  if (scale != 0.0) scale = 1.0 / scale; // just avoid divide by zero, should never happen
258  data_HLTRej = delta->GetBinContent(1 + 0) * scale;
259  data_Trunc = delta->GetBinContent(1 + 1) * scale;
260  data_HER_Trunc = delta->GetBinContent(1 + 2) * scale;
261  data_LER_Trunc = delta->GetBinContent(1 + 3) * scale;
262  data_CM63 = delta->GetBinContent(1 + 4) * scale;
263  data_HER_CM63 = delta->GetBinContent(1 + 5) * scale;
264  data_LER_CM63 = delta->GetBinContent(1 + 6) * scale;
265  data_HER_CM63_1ms = delta->GetBinContent(1 + 7) * scale;
266  data_LER_CM63_1ms = delta->GetBinContent(1 + 8) * scale;
267  data_HER_Trunc_1ms = delta->GetBinContent(1 + 9) * scale;
268  data_LER_Trunc_1ms = delta->GetBinContent(1 + 10) * scale;
269  data_MissFrame = delta->GetBinContent(1 + 11) * scale;
270  data_Timeout = delta->GetBinContent(1 + 12) * scale;
271  data_LinkDown = delta->GetBinContent(1 + 13) * scale;
272  data_Mismatch = delta->GetBinContent(1 + 14) * scale;
273  data_HER_Miss = delta->GetBinContent(1 + 15) * scale;
274  data_LER_Miss = delta->GetBinContent(1 + 16) * scale;
275  data_HER_Miss_1ms = delta->GetBinContent(1 + 17) * scale;
276  data_LER_Miss_1ms = delta->GetBinContent(1 + 18) * scale;
277  data_unused = delta->GetBinContent(1 + 19) * scale;
278  update_epics = true;
279  }
280  m_cStatisticUpd->Modified();
281  m_cStatisticUpd->Update();
282  }
283 
284  if (update_epics) {
285  m_monObj->setVariable("HLTReject", data_HLTRej);
286  m_monObj->setVariable("Trunc", data_Trunc);
287  m_monObj->setVariable("HER_Trunc", data_HER_Trunc);
288  m_monObj->setVariable("LER_Trunc", data_LER_Trunc);
289  m_monObj->setVariable("CM63", data_CM63);
290  m_monObj->setVariable("HER_CM63", data_HER_CM63);
291  m_monObj->setVariable("LER_CM63", data_LER_CM63);
292  m_monObj->setVariable("HER_CM63_1ms", data_HER_CM63_1ms);
293  m_monObj->setVariable("LER_CM63_1ms", data_LER_CM63_1ms);
294  m_monObj->setVariable("HER_Trunc_1ms", data_HER_Trunc_1ms);
295  m_monObj->setVariable("LER_Trunc_1ms", data_LER_Trunc_1ms);
296  m_monObj->setVariable("MissFrame", data_MissFrame);
297  m_monObj->setVariable("Timeout", data_Timeout);
298  m_monObj->setVariable("LinkDown", data_LinkDown);
299  m_monObj->setVariable("Mismatch", data_Mismatch);
300  m_monObj->setVariable("HER_Miss", data_HER_Miss);
301  m_monObj->setVariable("LER_Miss", data_LER_Miss);
302  m_monObj->setVariable("HER_Miss_1ms", data_HER_Miss_1ms);
303  m_monObj->setVariable("LER_Miss_1ms", data_LER_Miss_1ms);
304 
305  setEpicsPV("HLTReject", data_HLTRej);
306  setEpicsPV("Trunc", data_Trunc);
307  setEpicsPV("HER_Trunc", data_HER_Trunc);
308  setEpicsPV("LER_Trunc", data_LER_Trunc);
309  setEpicsPV("CM63", data_CM63);
310  setEpicsPV("HER_CM63", data_HER_CM63);
311  setEpicsPV("LER_CM63", data_LER_CM63);
312  setEpicsPV("HER_CM63_1ms", data_HER_CM63_1ms);
313  setEpicsPV("LER_CM63_1ms", data_LER_CM63_1ms);
314  setEpicsPV("HER_Trunc_1ms", data_HER_Trunc_1ms);
315  setEpicsPV("LER_Trunc_1ms", data_LER_Trunc_1ms);
316  setEpicsPV("MissFrame", data_MissFrame);
317  setEpicsPV("Timeout", data_Timeout);
318  setEpicsPV("LinkDown", data_LinkDown);
319  setEpicsPV("Mismatch", data_Mismatch);
320  setEpicsPV("HER_Miss", data_HER_Miss);
321  setEpicsPV("LER_Miss", data_LER_Miss);
322  setEpicsPV("HER_Miss_1ms", data_HER_Miss_1ms);
323  setEpicsPV("LER_Miss_1ms", data_LER_Miss_1ms);
324  setEpicsPV("unused", data_unused);
325  }
326 }
The base class for the histogram analysis module.
bool hasDeltaPar(const std::string &dirname, const std::string &histname)
Check if Delta histogram parameters exist for histogram.
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 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
static MonitoringObject * getMonitoringObject(const std::string &histname)
Get MonitoringObject with given name (new object is created if non-existing)
int m_minEntries
Update entry intervall.
void initialize(void) override final
Initializer.
TH1D * m_hStatistic
Histogram covering stat.
MonitoringObject * m_monObj
Monitoring Object.
std::string m_histogramDirectoryName
name of histogram directory
TH2F * m_hMissingDHC
Histogram covering all DHC modules.
TH1 * m_hDAQError
Histogram covering all error types.
TH1F * m_hMissingDHP
Histogram covering all modules*DHP.
TH2F * m_hMissingDHE
Histogram covering all DHE modules.
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called for each event.
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setVariable(const std::string &var, float val, float upErr=-1., float dwErr=-1)
set value to float variable (new variable is made if not yet existing)
void addCanvas(TCanvas *canv)
Add Canvas to monitoring object.
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:560
#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.