Belle II Software development
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
17using namespace std;
18using namespace Belle2;
19
20//-----------------------------------------------------------------
21// Register the Module
22//-----------------------------------------------------------------
23REG_MODULE(DQMHistAnalysisPXDDAQ);
24
25//-----------------------------------------------------------------
26// Implementation
27//-----------------------------------------------------------------
28
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 B2DEBUG(1, "DQMHistAnalysisPXDDAQ: initialized.");
45
47
48 gROOT->cd(); // this seems to be important, or strange things happen
49
50 m_cDAQError = new TCanvas((m_histogramDirectoryName + "/c_DAQError").data());
51 m_cMissingDHC = new TCanvas((m_histogramDirectoryName + "/c_MissingDHC").data());
52 m_cMissingDHE = new TCanvas((m_histogramDirectoryName + "/c_MissingDHE").data());
53 m_cMissingDHP = new TCanvas((m_histogramDirectoryName + "/c_MissingDHP").data());
54 m_cStatistic = new TCanvas((m_histogramDirectoryName + "/c_Statistic").data());
55 m_cStatisticUpd = new TCanvas((m_histogramDirectoryName + "/c_StatisticUpd").data());
57 HistDelta::c_Underflow, m_minEntries, 1); // register delta
58
59 m_monObj->addCanvas(m_cDAQError);
60 m_monObj->addCanvas(m_cMissingDHC);
61 m_monObj->addCanvas(m_cMissingDHE);
62 m_monObj->addCanvas(m_cMissingDHP);
63 m_monObj->addCanvas(m_cStatistic);
64
65 m_hMissingDHC = new TH2F("hPXDMissingDHC", "PXD Missing DHC", 16, 0, 16, 2, 0, 2);
66 m_hMissingDHE = new TH2F("hPXDMissingDHE", "PXD Missing DHE", 64, 0, 64, 2, 0, 2);
67
68 registerEpicsPV("PXD:DAQ:HLTRej", "HLTReject");
69 registerEpicsPV("PXD:DAQ:Trunc", "Trunc");
70 registerEpicsPV("PXD:DAQ:HER_Trunc", "HER_Trunc");
71 registerEpicsPV("PXD:DAQ:LER_Trunc", "LER_Trunc");
72 registerEpicsPV("PXD:DAQ:CM63", "CM63");
73 registerEpicsPV("PXD:DAQ:HER_CM63", "HER_CM63");
74 registerEpicsPV("PXD:DAQ:LER_CM63", "LER_CM63");
75 registerEpicsPV("PXD:DAQ:HER_CM63_1ms", "HER_CM63_1ms");
76 registerEpicsPV("PXD:DAQ:LER_CM63_1ms", "LER_CM63_1ms");
77 registerEpicsPV("PXD:DAQ:HER_Trunc_1ms", "HER_Trunc_1ms");
78 registerEpicsPV("PXD:DAQ:LER_Trunc_1ms", "LER_Trunc_1ms");
79 registerEpicsPV("PXD:DAQ:MissFrame", "MissFrame");
80 registerEpicsPV("PXD:DAQ:Timeout", "Timeout");
81 registerEpicsPV("PXD:DAQ:LinkDown", "LinkDown");
82 registerEpicsPV("PXD:DAQ:Mismatch", "Mismatch");
83 registerEpicsPV("PXD:DAQ:HER_Miss", "HER_Miss");
84 registerEpicsPV("PXD:DAQ:LER_Miss", "LER_Miss");
85 registerEpicsPV("PXD:DAQ:HER_Miss_1ms", "HER_Miss_1ms");
86 registerEpicsPV("PXD:DAQ:LER_Miss_1ms", "LER_Miss_1ms");
87 registerEpicsPV("PXD:DAQ:unused", "unused");
88}
89
91{
92 B2DEBUG(1, "DQMHistAnalysisPXDDAQ: beginRun called.");
93
94 m_cMissingDHP->Clear();
95 m_cMissingDHE->Clear();
96 m_cMissingDHC->Clear();
97 m_cStatistic->Clear();
98 m_cStatisticUpd->Clear();
99
100 m_hMissingDHE->Reset();
101 m_hMissingDHC->Reset();
102 if (m_hMissingDHP) m_hMissingDHP->Reset();
103 if (m_hDAQError) m_hDAQError->Reset();
104 if (m_hStatistic) m_hStatistic->Reset();
105}
106
108{
109 if (m_cMissingDHP == nullptr || m_cMissingDHE == nullptr || m_cMissingDHC == nullptr
110 || m_cStatistic == nullptr) return; // we could assume this
111
112 {
113 // Overall PXD DAQ Error
114 if (auto hh1 = findHist(m_histogramDirectoryName, "PXDDAQError", true); hh1 != nullptr) {
115 m_cDAQError->Clear();
116 m_cDAQError->cd();
117 if (m_hDAQError) delete m_hDAQError;
118 m_hDAQError = static_cast<TH1D*>(hh1->DrawClone("text"));// or just Clone here and Draw below?
119 m_hDAQError->SetName("hPXDDAQError");
120 m_hDAQError->SetTitle("PXD Fraction of DAQ Errors");
121 if (m_hDAQError->GetBinContent(0)) {
122 m_hDAQError->Scale(1.0 / m_hDAQError->GetBinContent(0));
123 }
124 m_hDAQError->Draw("text,hist");
126 }
127 }
128 {
129 // DHC histogram
130 if (auto hh1 = findHist(m_histogramDirectoryName, "PXDDAQDHCError", true); hh1 != nullptr) {
131 auto events = hh1->GetBinContent(hh1->GetBin(-1, -1));
132 m_cMissingDHC->Clear();
133 m_cMissingDHC->cd();
134 // first, we have to relate the per-DHC overflow (DHC object count) to the overall overflow (event count)
135 // second, we have to relate the "fake data" DHC bin to the per-DHC overflow (DHC object count)
136 m_hMissingDHC->Reset();
137 for (int i = 0; i < 16; i++) {
138 auto dhecount = hh1->GetBinContent(hh1->GetBin(i, -1));
139 if (events > 0) m_hMissingDHC->Fill((double)i, 0.0, 1.0 - dhecount / events);
140 // c_FAKE_NO_DATA_TRIG = 1ull << 29,
141 if (dhecount > 0) m_hMissingDHC->Fill((double)i, 1.0, hh1->GetBinContent(hh1->GetBin(i, 29) / dhecount));
142 }
143 m_hMissingDHC->Draw("text");
145 }
146 }
147
148 {
149 // DHE histogram
150 if (auto hh1 = findHist(m_histogramDirectoryName, "PXDDAQDHEError", true); hh1 != nullptr) {
151 auto events = hh1->GetBinContent(hh1->GetBin(-1, -1));
152 // first, we have to relate the per-DHE overflow (DHE object count) to the overall overflow (event count)
153 // second, we have to relate the "fake data" DHE bin to the per-DHE overflow (DHE object count)
154 m_cMissingDHE->Clear();
155 m_cMissingDHE->cd();
156 m_hMissingDHE->Reset();
157 for (int i = 0; i < 64; i++) {
158 auto dhecount = hh1->GetBinContent(hh1->GetBin(i, -1));
159 if (events > 0) m_hMissingDHE->Fill((double)i, 0.0, 1.0 - dhecount / events);
160 // c_FAKE_NO_DATA_TRIG = 1ull << 29,
161 if (dhecount > 0) m_hMissingDHE->Fill((double)i, 1.0, hh1->GetBinContent(hh1->GetBin(i, 29) / dhecount));
162 }
163 m_hMissingDHE->Draw("text");
165 }
166 }
167
168 {
169 // DHP histogram
170 if (auto hh1 = findHist(m_histogramDirectoryName, "PXDDAQDHPDataMissing", true); hh1 != nullptr) {
171 m_cMissingDHP->Clear();
172 m_cMissingDHP->cd();
173 if (m_hMissingDHP) delete m_hMissingDHP;
174 m_hMissingDHP = static_cast<TH1F*>(hh1->DrawClone("text"));
175 if (m_hMissingDHP->GetBinContent(0)) {
176 m_hMissingDHP->Scale(1.0 / m_hMissingDHP->GetBinContent(0));
177 m_hMissingDHP->Draw("text");
178 }
179 m_cMissingDHP->Modified();
180 m_cMissingDHP->Update();
182 }
183 // double data = m_hMissingDHP->Max???;
184 //
185 // m_monObj->setVariable("missingDHPFraction", data);
186 //
187 }
188
189 std::string name = "PXDDAQStat";
190
191 if (auto* statsum = findHist(m_histogramDirectoryName, name, true); statsum != nullptr) {
192 // Stat histogram
193 m_cStatistic->Clear();
194 m_cStatistic->cd();
195 if (m_hStatistic) delete m_hStatistic;
196 m_hStatistic = static_cast<TH1D*>(statsum->DrawClone("text"));
197 if (m_hStatistic->GetBinContent(0)) {
198 m_hStatistic->Scale(1.0 / m_hStatistic->GetBinContent(0));
199 m_hStatistic->Draw("text");
200 }
201 m_cStatistic->Modified();
202 m_cStatistic->Update();
204 }
205
206 // now the important part, check fraction of "errors" and export
207 double data_HLTRej = 0.0;
208 double data_Trunc = 0.0;
209 double data_HER_Trunc = 0.0;
210 double data_LER_Trunc = 0.0;
211 double data_CM63 = 0.0;
212 double data_HER_CM63 = 0.0;
213 double data_LER_CM63 = 0.0;
214 double data_HER_CM63_1ms = 0.0;
215 double data_LER_CM63_1ms = 0.0;
216 double data_HER_Trunc_1ms = 0.0;
217 double data_LER_Trunc_1ms = 0.0;
218 double data_MissFrame = 0.0;
219 double data_Timeout = 0.0;
220 double data_LinkDown = 0.0;
221 double data_Mismatch = 0.0;
222 double data_HER_Miss = 0.0;
223 double data_LER_Miss = 0.0;
224 double data_HER_Miss_1ms = 0.0;
225 double data_LER_Miss_1ms = 0.0;
226 double data_unused = 0.0;
227
228 bool update_epics = false;
229
230 auto* delta = getDelta(m_histogramDirectoryName, name); // only updated by default
231 if (delta) {
232 gROOT->cd();
233 m_cStatisticUpd->Clear();
234 m_cStatisticUpd->cd();// necessary!
235 delta->Draw("hist");
236 // now check that we have enough stats for useful export
237 double scale = delta->GetBinContent(0);// underflow is event counter
238 if (scale >= m_minEntries) {
239 if (scale != 0.0) scale = 1.0 / scale; // just avoid divide by zero, should never happen
240 data_HLTRej = delta->GetBinContent(1 + 0) * scale;
241 data_Trunc = delta->GetBinContent(1 + 1) * scale;
242 data_HER_Trunc = delta->GetBinContent(1 + 2) * scale;
243 data_LER_Trunc = delta->GetBinContent(1 + 3) * scale;
244 data_CM63 = delta->GetBinContent(1 + 4) * scale;
245 data_HER_CM63 = delta->GetBinContent(1 + 5) * scale;
246 data_LER_CM63 = delta->GetBinContent(1 + 6) * scale;
247 data_HER_CM63_1ms = delta->GetBinContent(1 + 7) * scale;
248 data_LER_CM63_1ms = delta->GetBinContent(1 + 8) * scale;
249 data_HER_Trunc_1ms = delta->GetBinContent(1 + 9) * scale;
250 data_LER_Trunc_1ms = delta->GetBinContent(1 + 10) * scale;
251 data_MissFrame = delta->GetBinContent(1 + 11) * scale;
252 data_Timeout = delta->GetBinContent(1 + 12) * scale;
253 data_LinkDown = delta->GetBinContent(1 + 13) * scale;
254 data_Mismatch = delta->GetBinContent(1 + 14) * scale;
255 data_HER_Miss = delta->GetBinContent(1 + 15) * scale;
256 data_LER_Miss = delta->GetBinContent(1 + 16) * scale;
257 data_HER_Miss_1ms = delta->GetBinContent(1 + 17) * scale;
258 data_LER_Miss_1ms = delta->GetBinContent(1 + 18) * scale;
259 data_unused = delta->GetBinContent(1 + 19) * scale;
260 update_epics = true;
261 }
262 m_cStatisticUpd->Modified();
263 m_cStatisticUpd->Update();
264 }
265
266 if (update_epics) {
267 m_monObj->setVariable("HLTReject", data_HLTRej);
268 m_monObj->setVariable("Trunc", data_Trunc);
269 m_monObj->setVariable("HER_Trunc", data_HER_Trunc);
270 m_monObj->setVariable("LER_Trunc", data_LER_Trunc);
271 m_monObj->setVariable("CM63", data_CM63);
272 m_monObj->setVariable("HER_CM63", data_HER_CM63);
273 m_monObj->setVariable("LER_CM63", data_LER_CM63);
274 m_monObj->setVariable("HER_CM63_1ms", data_HER_CM63_1ms);
275 m_monObj->setVariable("LER_CM63_1ms", data_LER_CM63_1ms);
276 m_monObj->setVariable("HER_Trunc_1ms", data_HER_Trunc_1ms);
277 m_monObj->setVariable("LER_Trunc_1ms", data_LER_Trunc_1ms);
278 m_monObj->setVariable("MissFrame", data_MissFrame);
279 m_monObj->setVariable("Timeout", data_Timeout);
280 m_monObj->setVariable("LinkDown", data_LinkDown);
281 m_monObj->setVariable("Mismatch", data_Mismatch);
282 m_monObj->setVariable("HER_Miss", data_HER_Miss);
283 m_monObj->setVariable("LER_Miss", data_LER_Miss);
284 m_monObj->setVariable("HER_Miss_1ms", data_HER_Miss_1ms);
285 m_monObj->setVariable("LER_Miss_1ms", data_LER_Miss_1ms);
286
287 setEpicsPV("HLTReject", data_HLTRej);
288 setEpicsPV("Trunc", data_Trunc);
289 setEpicsPV("HER_Trunc", data_HER_Trunc);
290 setEpicsPV("LER_Trunc", data_LER_Trunc);
291 setEpicsPV("CM63", data_CM63);
292 setEpicsPV("HER_CM63", data_HER_CM63);
293 setEpicsPV("LER_CM63", data_LER_CM63);
294 setEpicsPV("HER_CM63_1ms", data_HER_CM63_1ms);
295 setEpicsPV("LER_CM63_1ms", data_LER_CM63_1ms);
296 setEpicsPV("HER_Trunc_1ms", data_HER_Trunc_1ms);
297 setEpicsPV("LER_Trunc_1ms", data_LER_Trunc_1ms);
298 setEpicsPV("MissFrame", data_MissFrame);
299 setEpicsPV("Timeout", data_Timeout);
300 setEpicsPV("LinkDown", data_LinkDown);
301 setEpicsPV("Mismatch", data_Mismatch);
302 setEpicsPV("HER_Miss", data_HER_Miss);
303 setEpicsPV("LER_Miss", data_LER_Miss);
304 setEpicsPV("HER_Miss_1ms", data_HER_Miss_1ms);
305 setEpicsPV("LER_Miss_1ms", data_LER_Miss_1ms);
306 setEpicsPV("unused", data_unused);
307 }
308}
309
311{
312 B2DEBUG(1, "DQMHistAnalysisPXDDAQ: terminate called.");
313 // delete dynamical variables
314 if (m_cDAQError) delete m_cDAQError;
315 if (m_cMissingDHC) delete m_cMissingDHC;
316 if (m_cMissingDHE) delete m_cMissingDHE;
317 if (m_cMissingDHP) delete m_cMissingDHP;
318 if (m_cStatistic) delete m_cStatistic;
320
321 if (m_hMissingDHC) delete m_hMissingDHC;
322 if (m_hMissingDHE) delete m_hMissingDHE;
323 if (m_hDAQError) delete m_hDAQError;
324 if (m_hMissingDHP) delete m_hMissingDHP;
325 if (m_hStatistic) delete m_hStatistic;
326}
static bool hasDeltaPar(const std::string &dirname, const std::string &histname)
Check if Delta histogram parameters exist for histogram.
int registerEpicsPV(const std::string &pvname, const std::string &keyname="")
EPICS related Functions.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
static void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
DQMHistAnalysisModule()
Constructor / Destructor.
TH1 * getDelta(const std::string &dirname, const std::string &histname="", int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
static TH1 * findHist(const std::string &dirname, const std::string &histname="", bool onlyIfUpdated=false)
Find histogram.
void terminate(void) override final
Terminator.
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 addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.