Belle II Software development
DQMHistAnalysisCDCEpics.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#include <dqm/analysis/modules/DQMHistAnalysisCDCEpics.h>
10
11using namespace std;
12using namespace Belle2;
13
14//-----------------------------------------------------------------
15// Register module
16//-----------------------------------------------------------------
17REG_MODULE(DQMHistAnalysisCDCEpics);
18
21{
22 addParam("HistDirectory", m_histoDir, "CDC Dir of DQM Histogram", std::string("CDC"));
23 addParam("HistADC", m_histoADC, "ADC Histogram Name", std::string("hADC"));
24 addParam("HistTDC", m_histoTDC, "TDC Histogram Name", std::string("hTDC"));
25 addParam("HistPhiIndex", m_histoPhiIndex, "Phi Index Histogram Name", std::string("hPhiIndex"));
26 addParam("HistPhiEff", m_histoPhiEff, "Phi Eff Histogram Name", std::string("hPhiEff"));
27 addParam("PvPrefix", m_pvPrefix, "PV Prefix and Name", std::string("CDC:"));
28 addParam("RefFilePhi", m_refNamePhi, "Reference histogram file name", std::string("CDCDQM_PhiRef.root"));
29 addParam("RefDirectory", m_refDir, "Reference histogram dir", std::string("ref/CDC/default"));
30 addParam("MinEvt", m_minevt, "Min events for intra-run point", 20000);
31 for (int i = 0; i < 300; i++) {
32 m_hADCs[i] = nullptr;
33 m_hTDCs[i] = nullptr;
34 }
35 B2DEBUG(20, "DQMHistAnalysisCDCEpics: Constructor done.");
36}
37
39{
40
41}
42
44{
45 gROOT->cd();
46 c_hist_adc = new TCanvas("CDC/c_hist_adc", "c_hist_adc", 500, 400);
47 m_hist_adc = new TH1F("CDC/hist_adc", "m_hist_adc", 300, 0, 300);
48 m_hist_adc->SetTitle("ADC Medians; CDC board index; ADC medians");
49
50 c_hist_tdc = new TCanvas("CDC/c_hist_tdc", "c_hist_tdc", 500, 400);
51 m_hist_tdc = new TH1F("CDC/hist_tdc", "m_hist_tdc", 300, 0, 300);
52 m_hist_tdc->SetTitle("TDC Medians; CDC board index; TDC medians");
53
54 //array of various phi histograms
55 c_hist_skimphi = new TCanvas("CDC/c_hist_skimphi", "c_hist_skimphi", 1600, 800);
56
57 c_hist_crphi = new TCanvas("CDC/c_hist_crphi", "c_hist_crphi", 500, 400);
58
59 //CR alram reference
60 if (m_refNamePhi != "") {
61 m_fileRefPhi = TFile::Open(m_refNamePhi.data(), "READ");
62 if (m_fileRefPhi && m_fileRefPhi->IsOpen()) {
63 B2INFO("DQMHistAnalysisCDCEpics: reference (" << m_refNamePhi << ") found OK");
64 m_histref_phiindex = (TH2F*)m_fileRefPhi->Get((m_refDir + "/hPhiIndex").data());
65 if (!m_histref_phiindex)B2INFO("\t .. but (histogram) not found");
66 else B2INFO("\t ..and (cdcdqm_phiref) also exist");
67 }
68 }
69
70 c_hist_effphi = new TCanvas("CDC/c_hist_effphi", "c_hist_effphi", 500, 400);
71 m_hist_effphi = new TH1D("CDC/hist_effphi", "m_hist_effphi", 360, -180.0, 180.0);
72
74 addDeltaPar(m_histoDir, m_histoADC, HistDelta::c_Entries, m_minevt, 1);
75
77 addDeltaPar(m_histoDir, m_histoTDC, HistDelta::c_Entries, m_minevt, 1);
78
80 addDeltaPar(m_histoDir, m_histoPhiIndex, HistDelta::c_Entries, m_minevt, 1);
81
83 addDeltaPar(m_histoDir, m_histoPhiEff, HistDelta::c_Entries, m_minevt, 1);
84
85 registerEpicsPV(m_pvPrefix + "cdcboards_wadc", "adcboards");
86 registerEpicsPV(m_pvPrefix + "cdcboards_wtdc", "tdcboards");
87
88 registerEpicsPV(m_pvPrefix + "adc_median_window", "adcmedianwindow");
89 registerEpicsPV(m_pvPrefix + "tdc_median_window", "tdcmedianwindow");
90
91 registerEpicsPV(m_pvPrefix + "phi_compare_window", "phicomparewindow");
92
93 B2DEBUG(20, "DQMHistAnalysisCDCEpics: initialized.");
94}
95
97{
98 double unused = 0;
99 requestLimitsFromEpicsPVs("adcmedianwindow", unused, m_minadc, m_maxadc, unused);
100 requestLimitsFromEpicsPVs("tdcmedianwindow", unused, m_mintdc, m_maxtdc, unused);
101 requestLimitsFromEpicsPVs("phicomparewindow", m_phialarm, m_phiwarn, unused, unused);
102
103 //in case if something is wrong in config file
104 if (std::isnan(m_minadc)) m_minadc = 60.0;
105 if (std::isnan(m_maxadc)) m_maxadc = 130.0;
106 if (std::isnan(m_mintdc)) m_mintdc = 4600.0;
107 if (std::isnan(m_maxtdc)) m_maxtdc = 5000.0;
108
109 if (std::isnan(m_phiwarn)) m_phiwarn = 0.05; //>%5 is warning
110 if (std::isnan(m_phialarm)) m_phialarm = 0.15; //>%15 is warning
111
112 //creating box for normal adc and tdc windows
113 m_line_ladc = new TLine(0, m_minadc, 300, m_minadc);
114 m_line_ladc->SetLineColor(kRed);
115 m_line_ladc->SetLineWidth(2);
116
117 m_line_hadc = new TLine(0, m_maxadc, 300, m_maxadc);
118 m_line_hadc->SetLineColor(kRed);
119 m_line_hadc->SetLineWidth(2);
120
121 m_line_ltdc = new TLine(0, m_mintdc, 300, m_mintdc);
122 m_line_ltdc->SetLineColor(kRed);
123 m_line_ltdc->SetLineWidth(2);
124
125 m_line_htdc = new TLine(0, m_maxtdc, 300, m_maxtdc);
126 m_line_htdc->SetLineColor(kRed);
127 m_line_htdc->SetLineWidth(2);
128
129 B2DEBUG(20, "DQMHistAnalysisCDCEpics: beginRun run called");
130}
131
133{
134 //get intra-run histogram from CDC DQM module
135 auto m_delta_adc = (TH2F*)getDelta(m_histoDir, m_histoADC, 0, true); //true=only if updated
136 if (m_delta_adc) {
137 m_hist_adc->Reset();
138 int cadcgood = 0;
139 int cadcbad = 0;
140 double sumadcgood = 0;
141 for (int ic = 0; ic < 300; ++ic) {
142 if (ic == 0) continue; //299 boards only
143 if (m_hADCs[ic]) delete m_hADCs[ic];
144 m_hADCs[ic] = m_delta_adc->ProjectionY(Form("hADC%d", ic + 1), ic + 1, ic + 1, "");
145 m_hADCs[ic]->SetTitle(Form("hADC%d", ic));
146 float md_adc = getHistMedian(m_hADCs[ic]);
147 m_hist_adc->SetBinContent(ic + 1, md_adc);
148 if (md_adc >= m_minadc && md_adc <= m_maxadc) {
149 sumadcgood = sumadcgood + md_adc;
150 cadcgood++;
151 } else cadcbad++;
152 }
153 double adcfrac = cadcgood / 2.99; // (100.0/299) in %
154 setEpicsPV("adcboards", adcfrac);
155 // Draw canvas
156 c_hist_adc->Clear();
157 c_hist_adc->cd();
158 if (cadcgood > 0)sumadcgood = sumadcgood * 1.0 / cadcgood;
159 getHistStyle(m_hist_adc, "adc", sumadcgood);
160 m_hist_adc->SetTitle(Form("ADC Medians: Bad board count = %d (%0.01f%%)", cadcbad - 1, 100.0 - adcfrac));
161 m_hist_adc->Draw("");
162 m_line_ladc->Draw("same");
163 m_line_hadc->Draw("same");
164 c_hist_adc->Update();
166 }
167
168 auto m_delta_tdc = (TH2F*)getDelta(m_histoDir, m_histoTDC, 0, true);
169 if (m_delta_tdc) {
170 m_hist_tdc->Reset();
171 int ctdcgood = 0;
172 int ctdcbad = 0;
173 double sumtdcgood = 0;
174 for (int ic = 0; ic < 300; ++ic) {
175 if (ic == 0) continue; //299 boards only
176 if (m_hTDCs[ic]) delete m_hTDCs[ic];
177 m_hTDCs[ic] = m_delta_tdc->ProjectionY(Form("hTDC%d", ic + 1), ic + 1, ic + 1, "");
178 m_hTDCs[ic]->SetTitle(Form("hTDC%d", ic));
179 float md_tdc = getHistMedian(m_hTDCs[ic]);
180 m_hist_tdc->SetBinContent(ic + 1, md_tdc);
181 if (md_tdc >= m_mintdc && md_tdc <= m_maxtdc) {
182 ctdcgood++;
183 sumtdcgood = sumtdcgood + md_tdc;
184 } else ctdcbad++;
185
186 }
187 double tdcfrac = ctdcgood / 2.99;
188 setEpicsPV("tdcboards", tdcfrac);
189 c_hist_tdc->Clear();
190 c_hist_tdc->cd();
191 if (ctdcgood > 0)sumtdcgood = sumtdcgood * 1.0 / ctdcgood;
192 getHistStyle(m_hist_tdc, "tdc", sumtdcgood);
193 m_hist_tdc->SetTitle(Form("TDC Medians: Bad board count = %d (%0.01f%%)", ctdcbad - 1, 100.0 - tdcfrac));
194 m_hist_tdc->Draw("");
195 m_line_ltdc->Draw("same");
196 m_line_htdc->Draw("same");
197 c_hist_tdc->Update();
199 }
200
201 //get phi plots for various options
202 auto m_delta_skimphi = (TH2F*)getDelta(m_histoDir, m_histoPhiIndex, 0, true); //true=only if updated
203 c_hist_skimphi->Clear();
204 c_hist_skimphi->Divide(4, 2);
205 if (m_delta_skimphi) {
206 TString sip[2] = {"OffIP", "IP"};
207 TString sname[4] = {"all", "bhabha", "hadron", "mumutrk"};
208 for (int j = 0; j < 2; j++) { //ip selections
209 for (int i = 0; i < 4; i++) { //skim selections
210 int k = 4 * j + i; //0 to 7
211 TString hname = TString::Format("histphi_%s_%sevt", sip[j].Data(), sname[i].Data());
212 m_hist_skimphi[k] = m_delta_skimphi->ProjectionX(hname, k + 1, k + 1, "");
213 m_hist_skimphi[k]->SetTitle(TString::Format("cdc-track #phi (%s, %s-events);#phi;entries", sip[j].Data(), sname[i].Data()));
214 if (k < 4)m_hist_skimphi[k]->SetFillColor(kGray);
215 else m_hist_skimphi[k]->SetFillColor(kCyan);
216 c_hist_skimphi->cd(k + 1);
217 gPad->SetGridx(1);
218 gPad->SetGridy(1);
219 m_hist_skimphi[k]->Draw("hist");
220 }
221 }
222 }
223
224 //for CR shifter IP + all hadrons including alarm system
225 if (m_delta_skimphi) {
226 c_hist_crphi->Clear();
227 bool isFew = false, isAlarm = false, isWarn = false;
228 m_hist_crphi = m_delta_skimphi->ProjectionX("histphi_ip_hadrons", 7, 7, "");
229 m_hist_crphi->SetTitle("cdc-track #phi (IP + hadrons);cdc-track #phi;norm entries");
230 if (m_hist_crphi) {
231 double maxnow = m_hist_crphi->Integral();
232 m_hist_crphi->Scale(1.0 / maxnow);
233 if (maxnow < 10000) isFew = true;
234 else {
235 if (m_histref_phiindex) {
236 m_hist_refphi = m_histref_phiindex->ProjectionX("histphi_ip_hadronsref", 7, 7, "");
237 double nbinref = m_hist_refphi->GetNbinsX();
238 double nbinnow = m_hist_crphi->GetNbinsX();
239 if (nbinref == nbinnow) { //same bins
240 double maxref = m_hist_refphi->Integral();
241 m_hist_refphi->Scale(1.0 / maxref);
242 double maxphidiff = 0;
243 double maxphidiff_angle = 0;
244 for (int iphi = 0; iphi < nbinnow; iphi++) {
245 double icnow = m_hist_crphi->GetBinContent(iphi + 1);
246 double icref = m_hist_refphi->GetBinContent(iphi + 1);
247 double phidiff = fabs(icnow - icref);
248 if (phidiff > m_phiwarn)isWarn = true;
249 if (phidiff > m_phialarm)isAlarm = true;
250 if (phidiff > maxphidiff) {
251 maxphidiff = phidiff;
252 maxphidiff_angle = m_hist_crphi->GetBinLowEdge(iphi + 1) + m_hist_crphi->GetBinWidth(iphi + 1);
253 }
254 }
255 m_hist_crphi->SetTitle(Form("%s (diff = %0.03f at %0.1f)", m_hist_crphi->GetTitle(), maxphidiff, maxphidiff_angle));
256 }
257 }
258 }
259 }
260 c_hist_crphi->cd();
261 gPad->SetGridx(1);
262 gPad->SetGridy(1);
263 if (!m_histref_phiindex)m_hist_crphi->SetTitle(Form("%s (no ref file)", m_hist_crphi->GetTitle()));
264 m_hist_crphi->Draw("hist");
266 else if (isAlarm)colorizeCanvas(c_hist_crphi, c_StatusError);
269 c_hist_crphi->Update();
271 }
272
273 //get tracking efficiency
274 auto m_delta_effphi = (TH2F*)getDelta(m_histoDir, m_histoPhiEff, 0, true); //true=only if updated
275 c_hist_effphi->Clear();
276 if (m_delta_effphi) {
277 double eff = -1;
278 const int all_phibins = m_delta_effphi->GetNbinsX();
279 const int all_hitbins = m_delta_effphi->GetNbinsY();
280 const int thr_hitbin = m_delta_effphi->GetYaxis()->FindBin(20);//min hits bin
281 for (int iphi = 0; iphi < all_phibins; iphi++) {
282 TH1D* temp = (TH1D*)m_delta_effphi->ProjectionY(Form("hhits_bin_%d", iphi + 1), iphi + 1, iphi + 1, "");
283 Double_t num = temp->Integral(thr_hitbin, all_hitbins);
284 Double_t den = temp->Integral();
285 if (den > 0)eff = num * 100.0 / den;
286 m_hist_effphi->SetBinContent(iphi + 1, eff);
287 m_hist_effphi->SetBinError(iphi + 1, 0);
288 }
289 m_hist_effphi->GetYaxis()->SetRangeUser(80.0, 110.0); //per efficiency
290 m_hist_effphi->SetTitle("Tracking efficiency via cdchits (>20/all); cdc-track #phi; efficiency");
291 c_hist_effphi->cd();
292 gPad->SetGridx();
293 gPad->SetGridy();
294 m_hist_effphi->SetFillColor(kCyan);
295 m_hist_effphi->Draw("hist");
296 c_hist_effphi->Update();
298 }
299
300 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end event");
301}
302
303//------------------------------------
305{
306 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end run");
307}
308
309//------------------------------------
311{
312 TH1D* hist = (TH1D*)h->Clone();
313 hist->SetBinContent(1, 0.0); // Exclude 0-th bin
314 float median = 0.0;
315 if (hist->GetMean() != 0) {
316 // Avoid an error if only TCD/ADC=0 entries
317 double quantiles[1] = {0.0}; // One element to store median
318 double probSums[1] = {0.5}; // Median definition
319 hist->GetQuantiles(1, quantiles, probSums);
320 median = quantiles[0];
321 }
322 delete hist;
323 return median;
324}
325
326//------------------------------------
328{
329 B2DEBUG(20, "DQMHistAnalysisCDCEpics: terminate called");
330}
TCanvas * c_hist_adc
canvas for adc board median
std::string m_refDir
reference histogram dir of CDC DQMs
void initialize() override final
Initialize the Module.
double m_minadc
min adc median thershold accepted
TLine * m_line_hadc
line for higher ADC window
int m_minevt
min events for single intra-run point
TCanvas * c_hist_effphi
canvas for tracking efficiency
std::string m_histoADC
ADC histogram names of CDC DQMs.
std::string m_histoDir
histogram dir of CDC DQMs
std::string m_histoTDC
TDC histogram names of CDC DQMs.
double m_phiwarn
warn thershold for phi differences
std::string m_refNamePhi
reference histogram of phi
TFile * m_fileRefPhi
reference histogram file point
TLine * m_line_htdc
line for higher TDC window
double m_phialarm
alram thershold for phi differences
double m_maxadc
max adc median thershold accepted
TH1D * m_hTDCs[300]
TDC histograms with track associated hits for each board (0-299)
double m_maxtdc
max tdc median thershold accepted
void getHistStyle(TH1F *&htemp, std::string label, double max) const
get histogram styles
TCanvas * c_hist_crphi
canvas for control shifter phi
void terminate() override final
Termination action.
void event() override final
intra-run actions (EPICC PVs).
std::string m_histoPhiEff
Phi Eff histogram names of CDC DQMs.
TCanvas * c_hist_tdc
canvas for tdc board median
TH1D * m_hADCs[300]
ADC histograms with track associated hits for each board (0-299)
TCanvas * c_hist_skimphi
canvas for various phi distribution
void endRun() override final
End-of-run action.
std::string m_histoPhiIndex
Phi Inedx histogram names of CDC DQMs.
TLine * m_line_ltdc
line for lower TDC window
TLine * m_line_ladc
line for lower ADC window
void beginRun() override final
Called when entering a new run.
float getHistMedian(TH1D *h) const
Get median of given histogram.
double m_mintdc
min tdc median thershold accepted
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.
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
void colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
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.
@ c_StatusTooFew
Not enough entries/event to judge.
@ c_StatusError
Analysis result: Severe issue found.
@ c_StatusWarning
Analysis result: Warning, there may be minor issues.
@ c_StatusGood
Analysis result: Good.
int registerEpicsPV(std::string pvname, std::string keyname="")
EPICS related Functions.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
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.
STL namespace.