Belle II Software development
DQMHistAnalysisECL.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//THIS MODULE
10#include <dqm/analysis/modules/DQMHistAnalysisECL.h>
11
12//ROOT
13#include <TROOT.h>
14#include <TStyle.h>
15#include <TColor.h>
16
17//std
18#include <sstream>
19
20//boost
21#include "boost/format.hpp"
22
23using namespace Belle2;
24
25REG_MODULE(DQMHistAnalysisECL);
26
29{
30 B2DEBUG(20, "DQMHistAnalysisECL: Constructor done.");
31
32 m_WaveformOption = {"psd", "logic", "rand", "dphy", "other"};
34 "Provide a large number of ECL DQM analysis histograms:\n"
35 " 1. Normalize some low-level DQM histograms by the event count.\n"
36 " 2. Display time offsets for each ECL crate.\n"
37 " 3. Display the number of failed fits in each ECL module.");
38 addParam("HitMapThresholds", m_HitMapThresholds, "Thresholds to display hit map, MeV", std::vector<double> {0, 5, 10, 20, 50});
39 addParam("WaveformOption", m_WaveformOption, "Option (all,psd,logic,rand,dphy) to display waveform flow",
41 addParam("CrateTimeOffsetsMax", m_CrateTimeOffsetsMax, "Maximum boundary for crate time offsets", 20.);
42 addParam("LogicTestMax", m_LogicTestMax, " Maximum of fails for logic test", 50);
43 addParam("pvPrefix", m_pvPrefix, "Prefix to use for PVs registered by this module",
44 std::string("ECL:"));
45}
46
47
49{
50 gROOT->cd();
51 B2DEBUG(20, "DQMHistAnalysisECL: initialized.");
52
53 //new canvases for existing histograms
54 c_quality_analysis = new TCanvas("ECL/c_quality_analysis");
55 c_quality_other_analysis = new TCanvas("ECL/c_quality_other_analysis");
56 c_bad_quality_analysis = new TCanvas("ECL/c_bad_quality_analysis");
57 c_trigtag1_analysis = new TCanvas("ECL/c_trigtag1_analysis");
58 c_trigtag2_analysis = new TCanvas("ECL/c_trigtag2_analysis");
59 c_adc_hits_analysis = new TCanvas("ECL/c_adc_hits_analysis");
60 c_ampfail_quality_analysis = new TCanvas("ECL/c_ampfail_quality_analysis");
61 c_timefail_quality_analysis = new TCanvas("ECL/c_timefail_quality_analysis");
62 c_quality_fit_data_analysis = new TCanvas("ECL/c_quality_fit_data_analysis");
63
64 for (const auto& id : m_HitMapThresholds) {
65 std::string canvas_name = str(boost::format("ECL/c_cid_Thr%1%MeV_analysis") % id);
66 TCanvas* canvas = new TCanvas(canvas_name.c_str());
67 c_cid_analysis.push_back(canvas);
68 }
69
70 for (const auto& id : m_WaveformOption) {
71 if (id != "other") {
72 std::string canvas_name = str(boost::format("ECL/c_wf_cid_%1%_analysis") % id);
73 TCanvas* canvas = new TCanvas(canvas_name.c_str());
74 c_wf_analysis.push_back(canvas);
75 }
76 }
77
78 //Boundaries for 'trigtag2_trigid' histogram
79 m_lower_boundary_trigtag2 = new TLine(1, 0, 53, 0);
80 m_lower_boundary_trigtag2->SetLineWidth(3);
81 m_lower_boundary_trigtag2->SetLineColor(kBlue);
82
83 m_upper_boundary_trigtag2 = new TLine(1, 1, 53, 1);
84 m_upper_boundary_trigtag2->SetLineWidth(3);
85 m_upper_boundary_trigtag2->SetLineColor(kBlue);
86 //Boundaries for 'crate_time_offset' plot
87 m_lower_boundary_time_offsets = new TLine(0, -20, 52, -20);
88 m_lower_boundary_time_offsets->SetLineWidth(3);
89 m_lower_boundary_time_offsets->SetLineColor(kBlue);
90
91 m_upper_boundary_time_offsets = new TLine(0, 20, 52, 20);
92 m_upper_boundary_time_offsets->SetLineWidth(3);
93 m_upper_boundary_time_offsets->SetLineColor(kBlue);
94
95 //Summary crate_time_offsets plot
96 c_crate_time_offsets = new TCanvas("ECL/c_crate_time_offsets", "", 840, 840);
97 h_crate_time_offsets = new TGraphErrors();
98 h_crate_time_offsets->SetName("t_off");
99 h_crate_time_offsets->SetTitle("Crate time offset (E > 1 GeV); Crate ID (same as ECLCollector ID); Time offset [ns]");
100 h_crate_time_offsets->SetMarkerColor(kBlue);
101 h_crate_time_offsets->SetMarkerStyle(20);
102
103 //New DQM summary for logic test in CR shifter panel
104 c_logic_summary = new TCanvas("ECL/c_logic_summary");
105 h_logic_summary = new TH2F("logic_summary", "FPGA <-> C++ fitter inconsistencies count", 52, 1, 53, 12, 1, 13);
106 h_logic_summary->SetTitle("FPGA <-> C++ fitter inconsistencies count; ECLCollector ID (same as Crate ID); Shaper ID inside the crate");
107 h_logic_summary->SetCanExtend(TH1::kAllAxes);
108 h_logic_summary->SetStats(0);
109 for (unsigned short i = 0; i < 52; i++) h_logic_summary->GetXaxis()->SetBinLabel(i + 1, std::to_string(i + 1).c_str());
110 for (unsigned short i = 0; i < 12; i++) h_logic_summary->GetYaxis()->SetBinLabel(i + 1, std::to_string(i + 1).c_str());
111 h_logic_summary->LabelsOption("v");
112 h_logic_summary->SetTickLength(0, "xy");
113
114
115 //EPICS PVs for 'crate_time_offset' plot
116 for (unsigned short i = 0; i < 52; i++) {
117 auto pv_name = (boost::format("time_offset:crate%02d") % (i + 1)).str();
118 registerEpicsPV(m_pvPrefix + pv_name, pv_name);
119 }
120 for (auto wf_option : m_WaveformOption) {
121 auto pv_name = (boost::format("wf_frac:%s:min") % wf_option).str();
122 registerEpicsPV(m_pvPrefix + pv_name, pv_name);
123 }
124
126}
127
129{
130 B2DEBUG(20, "DQMHistAnalysisECL: beginRun called.");
131}
132
133void DQMHistAnalysisECLModule::normalize(TCanvas* c, const std::string& h_name, const Double_t& weight)
134{
135 c->Clear();
136 c->cd();
137 TH1* h = findHist(h_name);
138 if (h != NULL) {
139 for (unsigned short i = 0; i < h->GetNbinsX(); i++) {
140 Double_t entries = h->GetBinContent(i + 1);
141 Double_t error = h->GetBinError(i + 1);
142 if (weight) {
143 h->SetBinContent(i + 1, entries / weight);
144 h->SetBinError(i + 1, error / weight);
145 }
146 }
147 h->Draw("HIST");
148 }
149 c->Draw();
150 c->Modified();
151 c->Update();
152}
153
155{
156 B2DEBUG(20, "DQMHistAnalysisECL: event called");
157
158 //gStyle requirements
159 gStyle->SetPalette(1);
160
161 //1D histos
162 //quality
163 c_quality_analysis->Clear();
164 c_quality_analysis->cd();
165 c_quality_analysis->SetLogy();
166 TH1* h_quality = findHist("ECL/quality");
167 if (h_quality != NULL) {
168 h_quality->SetFillColor(kPink - 4);
169 h_quality->SetDrawOption("hist");
170 h_quality->SetMinimum(0.1);
171 h_quality->Draw("hist");
172 }
173 c_quality_analysis->Draw();
174 c_quality_analysis->Modified();
175 c_quality_analysis->Update();
176
177 //quality_other
180 c_quality_other_analysis->SetLogy();
181 TH1* h_quality_other = findHist("ECL/quality_other");
182 if (h_quality_other != NULL) {
183 h_quality_other->SetMinimum(0.1);
184 h_quality_other->SetFillColor(kPink - 4);
185 h_quality_other->Draw("hist");
186 }
188 c_quality_other_analysis->Modified();
189 c_quality_other_analysis->Update();
190
191 //bad_quality ,cid_Thr%1%MeV, wf_cid_%1%, wf_sh_%1%, wf_cr_%1%
192 TH1* h_evtot = findHist("ECL/event");
193 if (h_evtot != NULL) {
194 Double_t events = h_evtot->GetBinContent(1);
195 normalize(c_bad_quality_analysis, "ECL/bad_quality", events);
196 for (std::size_t i = 0; i < m_HitMapThresholds.size(); ++i)
198 str(boost::format("ECL/cid_Thr%1%MeV") % m_HitMapThresholds[i]), events);
199 }
200 for (std::size_t i = 0; i < m_WaveformOption.size(); ++i) {
201 auto val = m_WaveformOption[i];
202 if (val != "psd" && val != "other") {
203 TH1* h_evtot_norm = findHist(str(boost::format("ECL/event_%1%") % val));
204 if (h_evtot_norm != NULL) {
205 Double_t events = h_evtot_norm->GetBinContent(1);
207 str(boost::format("ECL/wf_cid_%1%") % val), events);
208 }
209 } else if (val == "psd") {
210 c_wf_analysis[i]->Clear();
211 c_wf_analysis[i]->cd();
212 TH1* h_psd = findHist(str(boost::format("ECL/wf_cid_%1%") % val));
213 TH1* h_psd_norm = findHist(str(boost::format("ECL/%1%_cid") % val));
214 if (h_psd != NULL && h_psd_norm != NULL) {
215 h_psd->Divide(h_psd, h_psd_norm);
216 h_psd->Draw("HIST");
217 }
218 c_wf_analysis[i]->Draw();
219 c_wf_analysis[i]->Modified();
220 c_wf_analysis[i]->Update();
221 }
222 } //m_WaveformOption
223
224 //trigtag1
225 c_trigtag1_analysis->Clear();
227 c_trigtag1_analysis->Pad()->SetFrameFillColor(10);
228 c_trigtag1_analysis->Pad()->SetFillColor(c_ColorDefault);
229 c_trigtag1_analysis->SetLogy();
230 TH1* h_trigtag1 = findHist("ECL/trigtag1");
231 if (h_trigtag1 != NULL) {
232 h_trigtag1->SetMinimum(0.1);
233 h_trigtag1->Draw("hist");
234 if (h_trigtag1->GetBinContent(2)) c_trigtag1_analysis->Pad()->SetFillColor(c_ColorError);
235 }
236 c_trigtag1_analysis->Draw();
237 c_trigtag1_analysis->Modified();
238 c_trigtag1_analysis->Update();
239
240 //adc_hits
241 c_adc_hits_analysis->Clear();
243 c_adc_hits_analysis->SetLogy();
244 TH1* h_adc_hits = findHist("ECL/adc_hits");
245 if (h_adc_hits != NULL) {
246 h_adc_hits->SetMinimum(0.1);
247 h_adc_hits->Draw("hist");
248 }
249 c_adc_hits_analysis->Draw();
250 c_adc_hits_analysis->Modified();
251 c_adc_hits_analysis->Update();
252
253 //ampfail_quality
256 c_ampfail_quality_analysis->Pad()->SetFrameFillColor(10);
257 c_ampfail_quality_analysis->Pad()->SetFillColor(c_ColorDefault);
259 TH1* h_ampfail_quality = findHist("ECL/ampfail_quality");
260 if (h_ampfail_quality != NULL) {
261 h_ampfail_quality->SetMinimum(0.1);
262 h_ampfail_quality->Draw("hist");
263 for (unsigned short i = 1; i < 5; i++) {
264 if (h_ampfail_quality->GetBinContent(i + 1)) {
265 c_ampfail_quality_analysis->Pad()->SetFillColor(c_ColorError);
266 break;
267 }
268 }
269 }
271 c_ampfail_quality_analysis->Modified();
273
274 //timefail_quality
277 c_timefail_quality_analysis->Pad()->SetFrameFillColor(10);
278 c_timefail_quality_analysis->Pad()->SetFillColor(c_ColorDefault);
280 TH1* h_timefail_quality = findHist("ECL/timefail_quality");
281 if (h_timefail_quality != NULL) {
282 h_timefail_quality->SetMinimum(0.1);
283 h_timefail_quality->Draw("hist");
284 for (unsigned short i = 1; i < 5; i++) {
285 if (h_timefail_quality->GetBinContent(i + 1)) {
286 c_timefail_quality_analysis->Pad()->SetFillColor(c_ColorError);
287 break;
288 }
289 }
290 }
292 c_timefail_quality_analysis->Modified();
294
295 //2D histos
296 //trigtag2_trigid
297 c_trigtag2_analysis->Clear();
299 c_trigtag2_analysis->Pad()->SetFrameFillColor(10);
300 c_trigtag2_analysis->Pad()->SetFillColor(c_ColorDefault);
301 TH1* h_trigtag2_trigid = findHist("ECL/trigtag2_trigid");
302 if (h_trigtag2_trigid != NULL) {
303 h_trigtag2_trigid->Draw("colz");
304 for (unsigned short i = 0; i < 52; i++) {
305 if (h_trigtag2_trigid->GetBinContent(h_trigtag2_trigid->GetBin(i + 1, 3))) {
306 c_trigtag2_analysis->Pad()->SetFillColor(c_ColorError);
307 break;
308 }
309 }
310 }
313
314 c_trigtag2_analysis->Draw();
315 c_trigtag2_analysis->Modified();
316 c_trigtag2_analysis->Update();
317
318 //quality_fit_data
321 c_quality_fit_data_analysis->Pad()->SetFrameFillColor(10);
322 c_quality_fit_data_analysis->Pad()->SetFillColor(c_ColorDefault);
323 TH1* h_quality_fit_data = findHist("ECL/quality_fit_data");
324 if (h_quality_fit_data != NULL) {
325 h_quality_fit_data->Draw("hist");
326 for (unsigned short i = 0; i < 4; i++) {
327 for (unsigned short j = 0; j < 4; j++) {
328 if (h_quality_fit_data->GetBinContent(h_quality_fit_data->GetBin(i + 1, j + 1)) > 0) {
329 c_quality_fit_data_analysis->Pad()->SetFillColor(c_ColorError);
330 break;
331 }
332 }
333 }
334 }
336 c_quality_fit_data_analysis->Modified();
338
339 //_time_crate_%1%_Thr1GeV
340 bool crates_bad_timing = false;
341
342 m_low.clear();
343 h_crate_time_offsets->Set(0);
344
345 for (unsigned short i = 0; i < 52; i++) {
346 m_crate_time_offsets[i] = std::numeric_limits<double>::quiet_NaN();
347
348 std::string h_title = "ECL/time_crate_" + std::to_string(i + 1) + "_Thr1GeV";
350 if (h_time_crate_Thr1GeV != NULL) {
352 h_crate_time_offsets->SetPoint(i, i + 0.5, h_time_crate_Thr1GeV->GetMean());
353 h_crate_time_offsets->SetPointError(i, 0.1, h_time_crate_Thr1GeV->GetMeanError());
354
355 if (h_time_crate_Thr1GeV->Integral() > 100) {
356 double yval = (h_time_crate_Thr1GeV->GetMean() > 0) ?
357 h_time_crate_Thr1GeV->GetMean() - 2 * h_time_crate_Thr1GeV->GetMeanError() :
358 h_time_crate_Thr1GeV->GetMean() + 2 * h_time_crate_Thr1GeV->GetMeanError();
359 if (fabs(yval) > m_CrateTimeOffsetsMax) crates_bad_timing = true;
360 } else {
361 m_low.push_back(i + 1);
362 }
363 }
364 auto pv_name = (boost::format("time_offset:crate%02d") % (i + 1)).str();
365 setEpicsPV(pv_name, m_crate_time_offsets[i]);
366 }
367
368 c_crate_time_offsets->Clear();
369 c_crate_time_offsets->SetGrid();
371
372 c_crate_time_offsets->Pad()->SetFrameFillColor(10);
373 c_crate_time_offsets->Pad()->SetFillColor(c_ColorDefault);
374
375 h_crate_time_offsets->SetMinimum(-50);
376 h_crate_time_offsets->SetMaximum(50);
377 h_crate_time_offsets->GetXaxis()->Set(52, 0, 52);
378 for (unsigned short i = 0; i < 52; i++) h_crate_time_offsets->GetXaxis()->SetBinLabel(i + 1, std::to_string(i + 1).c_str());
379 h_crate_time_offsets->GetXaxis()->LabelsOption("v");
380
381 h_crate_time_offsets->GetHistogram()->Draw();
382 h_crate_time_offsets->Draw("P");
383
384 if (!m_low.empty()) {
385 auto tg = new TLatex(5, 40, "Low statistics");
386 tg->SetTextSize(.06);
387 tg->SetTextAlign(12);
388 tg->Draw();
389 c_crate_time_offsets->Pad()->SetFillColor(c_ColorTooFew);
390 if (m_low.size() < 52) {
391 std::ostringstream sstream;
392 std::copy(m_low.begin(), m_low.end() - 1, std::ostream_iterator<short>(sstream, ","));
393 sstream << m_low.back();
394 std::string str = "Crates: " + sstream.str();
395 auto tg1 = new TLatex(5, 30, str.c_str());
396 tg1->SetTextSize(.03);
397 tg1->SetTextAlign(12);
398 tg1->Draw();
399 } else {
400 auto tg1 = new TLatex(5, 30, "All crates");
401 tg1->SetTextSize(.06);
402 tg1->SetTextAlign(12);
403 tg1->Draw();
404 }
405 }
406
409
410 if (crates_bad_timing) c_crate_time_offsets->Pad()->SetFillColor(c_ColorError);
411
412 c_crate_time_offsets->Draw();
413 c_crate_time_offsets->Modified();
414 c_crate_time_offsets->Update();
415
416 //DQM summary logic
417 h_logic_summary->Reset();
418
419 TH1* h_fail_crateid = findHist("ECL/fail_crateid");
420 TH1* h_fail_shaperid = findHist("ECL/fail_shaperid");
421 if (h_fail_crateid != NULL && h_fail_shaperid != NULL) {
422 for (unsigned short i = 0; i < 52; i++) {
423 if (h_fail_crateid->GetBinContent(i + 1)) {
424 for (unsigned short j = i * 12; j < i * 12 + 12; j++) {
425 if (h_fail_shaperid->GetBinContent(j + 1)) {
426 unsigned short shaper = (j + 1) - 12 * i;
427 h_logic_summary->SetBinContent(h_logic_summary->FindBin(i + 1, shaper), h_fail_shaperid->GetBinContent(j + 1));
428 }
429 }
430 }
431 }
432 c_logic_summary->Clear();
433 c_logic_summary->SetGrid();
434 c_logic_summary->cd();
435
436 c_logic_summary->Pad()->SetFrameFillColor(10);
437 c_logic_summary->Pad()->SetFillColor(c_ColorGood);
438
439 if (h_logic_summary->GetMaximum() > 0
440 && h_logic_summary->GetMaximum() < m_LogicTestMax) c_logic_summary->Pad()->SetFillColor(c_ColorWarning);
441 if (h_logic_summary->GetMaximum() >= m_LogicTestMax) c_logic_summary->Pad()->SetFillColor(c_ColorError);
442 h_logic_summary->Draw("textcol");
443 c_logic_summary->Draw();
444 c_logic_summary->Modified();
445 c_logic_summary->Update();
446 }
447
448 //Set EPICS PVs
449 if (h_evtot == NULL) return;
450
451 Double_t events = h_evtot->GetBinContent(1);
452 for (auto wf_option : m_WaveformOption) {
453 m_wf_fraction[wf_option] = std::numeric_limits<double>::quiet_NaN();
454 // Get minimal value for each type of saved waveforms
455 if (events > 100000) {
456 TH1* hist = findHist(str(boost::format("ECL/wf_cid_%1%") % wf_option));
457 m_wf_fraction[wf_option] = hist->GetBinContent(hist->GetMinimumBin());
458 }
459 auto pv_name = (boost::format("wf_frac:%s:min") % wf_option).str();
460 setEpicsPV(pv_name, m_wf_fraction[wf_option]);
461 }
462}
463
465{
466 B2DEBUG(20, "DQMHistAnalysisECL: endRun called");
467 for (unsigned short i = 0; i < 52; i++) {
468 auto var_name = (boost::format("time_offset_crate%02d") % (i + 1)).str();
469 m_monObj->setVariable(var_name, m_crate_time_offsets[i]);
470 }
471 for (auto wf_option : m_WaveformOption) {
472 auto var_name = (boost::format("wf_frac_%s_min") % wf_option).str();
473 m_monObj->setVariable(var_name, m_wf_fraction[wf_option]);
474 }
475 for (auto threshold : m_HitMapThresholds) {
476 auto var_name_avg = (boost::format("average_number_of_ECL_digits_at_%1%_MeV") % threshold).str();
477 auto var_name_std = (boost::format("standard_deviation_of_ECL_digits_at_%1%_MeV") % threshold).str();
478 auto h_ECL_ncev = findHist(str(boost::format("ECL/ncev_Thr%1%MeV") % threshold));
479 if (h_ECL_ncev) {
480 m_monObj->setVariable(var_name_avg, h_ECL_ncev->GetMean());
481 m_monObj->setVariable(var_name_std, h_ECL_ncev->GetStdDev());
482 }
483 }
484}
485
std::vector< double > m_HitMapThresholds
Parameters for hit map histograms.
void normalize(TCanvas *, const std::string &, const Double_t &)
Normalize histograms.
void initialize() override final
Initialize the module.
TCanvas * c_bad_quality_analysis
TCanvas for bad_quality .
std::vector< TCanvas * > c_wf_analysis
Vector of TCanvases for waveforms .
TLine * m_lower_boundary_trigtag2
TLine to show lower boundary for 'trigtag2_trigid' histogram.
int m_LogicTestMax
Maximum of fails for logic test.
TCanvas * c_crate_time_offsets
TCanvas for time offsets.
TH1 * h_time_crate_Thr1GeV
Histogram showing signal times from ECL crates (Thr.
DQMHistAnalysisECLModule()
< derived from DQMHistAnalysisModule class.
TCanvas * c_quality_fit_data_analysis
TCanvas for quality_fit_data .
TCanvas * c_ampfail_quality_analysis
TCanvas for ampfail_quality .
std::string m_pvPrefix
Prefix to use for PVs registered by this module.
MonitoringObject * m_monObj
MiraBelle monitoring object.
void terminate() override final
Terminate.
double m_crate_time_offsets[52]
Values of crate time offsets.
TLine * m_upper_boundary_time_offsets
TLine to show upper boundary for 'crate_time_offsets' graph.
void event() override final
Event processor.
std::map< std::string, double > m_wf_fraction
Minimum fraction of saved waveforms for each waveform type.
TLine * m_upper_boundary_trigtag2
TLine to show upper boundary for 'trigtag2_trigid' histogram.
std::vector< short > m_low
Vector for crates IDs w/ low statistics.
std::vector< std::string > m_WaveformOption
Options for waveform histograms.
TCanvas * c_quality_analysis
TCanvas for quality .
TH2F * h_logic_summary
Histogram for ECL logic summary.
void endRun() override final
Call when a run ends.
TCanvas * c_adc_hits_analysis
TCanvas for adc_hits .
TCanvas * c_logic_summary
TCanvas for ECL logic summary.
void beginRun() override final
Call when a run begins.
TGraphErrors * h_crate_time_offsets
Graph for time offsets.
TLine * m_lower_boundary_time_offsets
TLine to show lower boundary for 'crate_time_offsets' graph.
TCanvas * c_quality_other_analysis
TCanvas for quality_other .
std::vector< TCanvas * > c_cid_analysis
Vector of TCanvases for hit map .
TCanvas * c_trigtag1_analysis
TCanvas for trigtag1 .
double m_CrateTimeOffsetsMax
Maximum boundary for crate time offsets.
TCanvas * c_trigtag2_analysis
TCanvas for trigtag2 .
TCanvas * c_timefail_quality_analysis
TCanvas for timefail_quality .
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 TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
@ c_ColorWarning
Analysis result: Warning, there may be minor issues.
@ c_ColorError
Analysis result: Severe issue found.
@ c_ColorTooFew
Not enough entries/event to judge.
@ c_ColorGood
Analysis result: Good.
@ c_ColorDefault
default for non-coloring
DQMHistAnalysisModule()
Constructor / Destructor.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
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.