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#include <cdc/geometry/CDCGeometryPar.h>
11
12using namespace std;
13using namespace Belle2;
14
15//-----------------------------------------------------------------
16// Register module
17//-----------------------------------------------------------------
18REG_MODULE(DQMHistAnalysisCDCEpics);
19
22{
23 addParam("HistDirectory", m_name_dir, "CDC Dir of DQM Histogram", std::string("CDC"));
24 addParam("RefDirectory", m_name_refdir, "Reference histogram dir", std::string("ref/CDC/default"));
25 addParam("PvPrefix", m_name_pvpfx, "PV Prefix and Name", std::string("CDC:"));
26 addParam("RefFilePhi", m_fname_refphi, "Reference histogram file name", std::string("CDCDQM_PhiRef.root"));
27 addParam("HistLayerADC", m_hname_ladc, "Layer ADC Histogram Name", std::string("hADCLayer"));
28 addParam("HistBoardADC", m_hname_badc, "Board ADC Histogram Name", std::string("hADCBoard"));
29 addParam("HistBoardTDC", m_hname_btdc, "Board TDC Histogram Name", std::string("hTDC"));
30 addParam("HistPhiIndex", m_hname_idxphi, "Phi Index Histogram Name", std::string("hPhiIndex"));
31 addParam("HistPhiEff", m_hname_effphi, "Phi Eff Histogram Name", std::string("hPhiEff"));
32 addParam("HistHitsPhi", m_hname_hitsphi, "Phi Hits Histogram Name", std::string("hPhiNCDC"));
33 addParam("MinPhiDiffFrac", m_minphibinsfrac, "Minimum bin percentage for phi diff comparison", 0.05);
34 addParam("MinEvt", m_minevt, "Min events for intra-run point", 1000);
35 addParam("HistTrackingWireEff", m_histoTrackingWireEff, "Wire Eff Histogram Name", std::string("hTrackingWireEff"));
36 addParam("DoTH2PolyTrackingWireEff", m_doTH2PolyTrackingWireEff,
37 "If true, creates TH2Poly instead of TH2F for TrackingWireEff Histos", m_doTH2PolyTrackingWireEff);
38 addParam("FirstEffBoundary", m_firstEffBoundary, "The first boundary of the efficiency range", m_firstEffBoundary);
39 addParam("SecondEffBoundary", m_secondEffBoundary, "The second boundary of the efficiency range", m_secondEffBoundary);
40 for (int i = 0; i < 300; i++) {
41 m_hists_bADC[i] = nullptr;
42 m_hists_bTDC[i] = nullptr;
43 //layer
44 if (i < 56)m_hists_lADC[i] = nullptr;
45 }
46
47 B2DEBUG(20, "DQMHistAnalysisCDCEpics: Constructor done.");
48}
49
51{
52
53 gROOT->cd();
54 m_canv_md_ladc = new TCanvas("CDC/c_histmd_ladc", "c_histmd_ladc", 500, 400);
55 m_histmd_ladc = new TH1F("CDC/histmd_ladc", "m_histmd_ladc", 56, 0, 56);
56 m_histmd_ladc->SetTitle("ADC Medians vs Layers (SL-lines); CDC Layer index; ADC medians");
57
58 m_canv_adc = new TCanvas("CDC/c_hist_adc", "c_hist_adc", 500, 400);
59 m_hist_adc = new TH1F("CDC/hist_adc", "m_hist_adc", 300, 0, 300);
60 m_hist_adc->SetTitle("ADC Medians; CDC board index; ADC medians");
61
62 m_canv_tdc = new TCanvas("CDC/c_hist_tdc", "c_hist_tdc", 500, 400);
63 m_hist_tdc = new TH1F("CDC/hist_tdc", "m_hist_tdc", 300, 0, 300);
64 m_hist_tdc->SetTitle("TDC Medians; CDC board index; TDC medians");
65
66 //array of various phi histograms
67 for (int ic = 0; ic < 8; ic++) {
68 m_canv_skimphi[ic] = new TCanvas(Form("CDC/c_hist_skimphi_c%d", ic), Form("hist_skimphi_c%d", ic), 500, 400);
69 }
70
71 m_canv_crphi = new TCanvas("CDC/c_hist_crphi", "c_hist_crphi", 500, 400);
72 m_canv_hitsphi = new TCanvas("CDC/c_hist_hitsphi", "c_hist_hitsphi", 500, 400);
73
74 //CR alarm reference
75 if (m_fname_refphi != "") {
76 m_fileRefPhi = TFile::Open(m_fname_refphi.data(), "READ");
77 if (m_fileRefPhi && m_fileRefPhi->IsOpen()) {
78 B2INFO("DQMHistAnalysisCDCEpics: reference (" << m_fname_refphi << ") found OK");
79 m_histref_phiindex = static_cast<TH2F*>(m_fileRefPhi->Get((m_name_refdir + "/hPhiIndex").data()));
80 if (!m_histref_phiindex)B2INFO("\t .. but (histogram) not found");
81 else B2INFO("\t ..and (cdcdqm_phiref) also exist");
82 }
83 }
84
85 m_lines.clear();
86 m_lines.reserve(kNumLayers);
87 for (unsigned il = 0; il < kNumLayers; ++il) {
88 int bin = il + 1;
89 auto* line = new TLine(bin, 0, bin, 1.0);
90 line->SetLineStyle(2);
91 if (bin >= 8 && bin < 14)line->SetLineColor(kRed); // U-type
92 else if (bin >= 20 && bin < 26)line->SetLineColor(kGreen); // V-type
93 else if (bin >= 32 && bin < 38)line->SetLineColor(kRed); // U-type
94 else if (bin >= 44 && bin < 50)line->SetLineColor(kGreen); // v-type
95 else line->SetLineColor(kGray); // A-type
96 m_lines.push_back(line);
97 }
98
99 m_canv_effphi = new TCanvas("CDC/c_hist_effphi", "c_hist_effphi", 500, 400);
100 m_hist_effphi = new TH1D("CDC/hist_effphi", "m_hist_effphi", 180, -180.0, 180.0);
101
102 m_canv_attach_eff[0] = new TCanvas("CDC/c_hist_attached_wires", "c_hist_attached_wires", 403, 400);
103 m_canv_attach_eff[1] = new TCanvas("CDC/c_hist_expected_wires", "c_hist_expected_wires", 403, 400);
104 m_canv_attach_eff[2] = new TCanvas("CDC/c_hist_attach_eff", "c_hist_attach_eff", 403, 400);
105 m_canv_attach_eff[3] = new TCanvas("CDC/c_hist_attach_eff_1d", "c_hist_attach_eff_1d", 403, 400);
107 m_hist_attach_eff_Poly[0] = createEffiTH2Poly("CDC/hist_attachedWires",
108 "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin");
109 m_hist_attach_eff_Poly[0]->GetYaxis()->SetTitleOffset(1.4);
110 m_hist_attach_eff_Poly[0]->SetDirectory(gDirectory);
111 m_hist_attach_eff_Poly[1] = static_cast<TH2Poly*>(m_hist_attach_eff_Poly[0]->Clone());
112 m_hist_attach_eff_Poly[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
113 m_hist_attach_eff_Poly[1]->SetDirectory(gDirectory);
114 m_hist_attach_eff_Poly[2] = static_cast<TH2Poly*>(m_hist_attach_eff_Poly[0]->Clone());
115 m_hist_attach_eff_Poly[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
116 m_hist_attach_eff_Poly[2]->SetDirectory(gDirectory);
117 } else {
119 int nSLayers = cdcgeo.getNumberOfSenseLayers();
120 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
121 m_hist_attach_eff[0] = new TH2F("CDC/hist_attachedWires", "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin",
122 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02,
123 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02);
124 m_hist_attach_eff[0]->GetYaxis()->SetTitleOffset(1.4);
125 m_hist_attach_eff[1] = static_cast<TH2F*>(m_hist_attach_eff[0]->Clone());
126 m_hist_attach_eff[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
127 m_hist_attach_eff[2] = static_cast<TH2F*>(m_hist_attach_eff[0]->Clone());
128 m_hist_attach_eff[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
129 }
130 m_hist_wire_attach_eff_1d = new TH1F("CDC/hist_wire_attach_eff_1d", "hist_wire_attach_eff_1d;Wire Efficiency;Wire / bin",
131 208, -0.02, 1.02);
132 m_hist_wire_attach_eff_1d->GetYaxis()->SetTitleOffset(1.4);
133
135 addDeltaPar(m_name_dir, m_hname_ladc, HistDelta::c_Entries, m_minevt, 1);
136
138 addDeltaPar(m_name_dir, m_hname_badc, HistDelta::c_Entries, m_minevt, 1);
139
141 addDeltaPar(m_name_dir, m_hname_btdc, HistDelta::c_Entries, m_minevt, 1);
142
144 addDeltaPar(m_name_dir, m_hname_idxphi, HistDelta::c_Entries, m_minevt, 1);
145
147 addDeltaPar(m_name_dir, m_hname_effphi, HistDelta::c_Entries, m_minevt, 1);
148
150 addDeltaPar(m_name_dir, m_hname_hitsphi, HistDelta::c_Entries, m_minevt, 1);
151
153 addDeltaPar(m_name_dir, m_histoTrackingWireEff, HistDelta::c_Events, m_minevt, 1);
154
155
156 m_line_ladc_sl01 = new TLine(0, m_minadc_sl01, 47, m_minadc_sl01);
157 m_line_ladc_sl01->SetLineColor(kBlue);
158 m_line_ladc_sl01->SetLineWidth(2);
159
160 m_line_hadc_sl01 = new TLine(0, m_maxadc_sl01, 47, m_maxadc_sl01);
161 m_line_hadc_sl01->SetLineColor(kBlue);
162 m_line_hadc_sl01->SetLineWidth(2);
163
164 m_line_ltdc_sl01 = new TLine(0, m_mintdc_sl01, 47, m_mintdc_sl01);
165 m_line_ltdc_sl01->SetLineColor(kBlue);
166 m_line_ltdc_sl01->SetLineWidth(2);
167
168 m_line_htdc_sl01 = new TLine(0, m_maxtdc_sl01, 47, m_maxtdc_sl01);
169 m_line_htdc_sl01->SetLineColor(kBlue);
170 m_line_htdc_sl01->SetLineWidth(2);
171
172 m_line_ladc_sl28 = new TLine(48, m_minadc_sl28, 300, m_minadc_sl28);
173 m_line_ladc_sl28->SetLineColor(kRed);
174 m_line_ladc_sl28->SetLineWidth(2);
175
176 m_line_hadc_sl28 = new TLine(48, m_maxadc_sl28, 300, m_maxadc_sl28);
177 m_line_hadc_sl28->SetLineColor(kRed);
178 m_line_hadc_sl28->SetLineWidth(2);
179
180 m_line_ltdc_sl28 = new TLine(48, m_mintdc_sl28, 300, m_mintdc_sl28);
181 m_line_ltdc_sl28->SetLineColor(kRed);
182 m_line_ltdc_sl28->SetLineWidth(2);
183
184 m_line_htdc_sl28 = new TLine(48, m_maxtdc_sl28, 300, m_maxtdc_sl28);
185 m_line_htdc_sl28->SetLineColor(kRed);
186 m_line_htdc_sl28->SetLineWidth(2);
187
188 registerEpicsPV(m_name_pvpfx + "cdcboards_wadc", "adcboards");
189 registerEpicsPV(m_name_pvpfx + "cdcboards_wtdc", "tdcboards");
190
191 registerEpicsPV(m_name_pvpfx + "adc_median_window_sl01", "adcmedianwindow_sl01");
192 registerEpicsPV(m_name_pvpfx + "tdc_median_window_sl01", "tdcmedianwindow_sl01");
193 registerEpicsPV(m_name_pvpfx + "adc_median_window_sl28", "adcmedianwindow_sl28");
194 registerEpicsPV(m_name_pvpfx + "tdc_median_window_sl28", "tdcmedianwindow_sl28");
195
196 registerEpicsPV(m_name_pvpfx + "phi_compare_window", "phicomparewindow");
197
199
200 B2DEBUG(20, "DQMHistAnalysisCDCEpics: initialized.");
201}
202
204{
205 double unused = 0;
206 requestLimitsFromEpicsPVs("adcmedianwindow_sl01", unused, m_minadc_sl01, m_maxadc_sl01, unused);
207 requestLimitsFromEpicsPVs("tdcmedianwindow_sl01", unused, m_mintdc_sl01, m_maxtdc_sl01, unused);
208 requestLimitsFromEpicsPVs("adcmedianwindow_sl28", unused, m_minadc_sl28, m_maxadc_sl28, unused);
209 requestLimitsFromEpicsPVs("tdcmedianwindow_sl28", unused, m_mintdc_sl28, m_maxtdc_sl28, unused);
210 requestLimitsFromEpicsPVs("phicomparewindow", m_phialarm, m_phiwarn, unused, unused);
211
212 //in case if something is wrong in config file (for S0-1 and S2-8)
213 //SL 0 and 1 is with different HV thershold
214
215 if (std::isnan(m_minadc_sl01)) m_minadc_sl01 = 20.0;
216 if (std::isnan(m_maxadc_sl01)) m_maxadc_sl01 = 40.0;
217 if (std::isnan(m_mintdc_sl01)) m_mintdc_sl01 = 4700.0;
218 if (std::isnan(m_maxtdc_sl01)) m_maxtdc_sl01 = 5200.0;
219
220 if (std::isnan(m_minadc_sl28)) m_minadc_sl28 = 60.0;
221 if (std::isnan(m_maxadc_sl28)) m_maxadc_sl28 = 130.0;
222 if (std::isnan(m_mintdc_sl28)) m_mintdc_sl28 = 4500.0;
223 if (std::isnan(m_maxtdc_sl28)) m_maxtdc_sl28 = 5000.0;
224
225 if (std::isnan(m_phiwarn)) m_phiwarn = 0.05;
226 if (std::isnan(m_phialarm)) m_phialarm = 0.15;
227
236
245
246 B2DEBUG(20, "DQMHistAnalysisCDCEpics: beginRun run called");
247}
248
250{
251 //1. get adc median vs layer numbers
252 auto m_delta_ladc = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_ladc, 0, true));
253 if (m_delta_ladc) {
254 m_histmd_ladc->Reset();
255 for (unsigned il = 0; il < kNumLayers; ++il) {
256 if (m_hists_lADC[il]) delete m_hists_lADC[il];
257 m_hists_lADC[il] = m_delta_ladc->ProjectionY(Form("histmd_adc_layer%d", il + 1), il + 1, il + 1, "");
258 m_hists_lADC[il]->SetTitle(Form("histmd_adc_layer%d", il));
259 float md_ladc = getHistMedian(m_hists_lADC[il]);
260 if (!std::isfinite(md_ladc) || md_ladc < 0) md_ladc = 0;
261 m_histmd_ladc->SetBinContent(il + 1, md_ladc);
262 }
263 // Draw canvas
264 m_canv_md_ladc->Clear();
265 m_canv_md_ladc->cd();
266 double y_max = 0;
267 for (int ib = 1; ib <= m_histmd_ladc->GetNbinsX(); ib++) {
268 double val = m_histmd_ladc->GetBinContent(ib);
269 if (std::isfinite(val) && val > y_max) y_max = val;
270 }
271 if (y_max <= 0) y_max = 1;
272 m_histmd_ladc->SetMaximum(y_max * 1.20);
273 m_histmd_ladc->SetFillColor(kYellow);
274 m_histmd_ladc->SetMinimum(0);
275 m_histmd_ladc->Draw("hist");
276 for (auto* line : m_lines) {
277 line->SetY1(0);
278 line->SetY2(y_max);
279 line->Draw("same");
280 }
281 m_canv_md_ladc->Update();
283 }
284
285 //2. get adc medians vs board ID
286 auto m_delta_adc = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_badc, 0, true)); //true=only if updated
287 if (m_delta_adc) {
288 m_hist_adc->Reset();
289 int cadcgood = 0;
290 int cadcbad = 0;
291 double sumadcgood = 0;
292 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
293 if (ic == 0) continue; //299 boards only
294 if (m_hists_bADC[ic]) delete m_hists_bADC[ic];
295 m_hists_bADC[ic] = m_delta_adc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
296 m_hists_bADC[ic]->SetTitle(Form("histmd_adc_board%d", ic));
297 float md_adc = getHistMedian(m_hists_bADC[ic]);
298 m_hist_adc->SetBinContent(ic + 1, md_adc);
299 float minadc = (ic < 48) ? m_minadc_sl01 : m_minadc_sl28;
300 float maxadc = (ic < 48) ? m_maxadc_sl01 : m_maxadc_sl28;
301 if (md_adc >= minadc && md_adc <= maxadc) {
302 sumadcgood = sumadcgood + md_adc;
303 cadcgood++;
304 } else cadcbad++;
305 }
306 double adcfrac = cadcgood / 2.99; // (100.0/299) in %
307 setEpicsPV("adcboards", adcfrac);
308 // Draw canvas
309 m_canv_adc->Clear();
310 m_canv_adc->cd();
311 if (cadcgood > 0)sumadcgood = sumadcgood * 1.0 / cadcgood;
312 getHistStyle(m_hist_adc, "adc", sumadcgood);
313 m_hist_adc->SetTitle(Form("ADC Medians: Bad board count = %d (%0.01f%%)", cadcbad - 1, 100.0 - adcfrac));
314 m_hist_adc->Draw("");
315 m_line_ladc_sl01->Draw("same");
316 m_line_hadc_sl01->Draw("same");
317 m_line_ladc_sl28->Draw("same");
318 m_line_hadc_sl28->Draw("same");
319 m_canv_adc->Update();
321 }
322
323 //3. get tdc medians vs board ID
324 auto m_delta_tdc = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_btdc, 0, true));
325 if (m_delta_tdc) {
326 m_hist_tdc->Reset();
327 int ctdcgood = 0;
328 int ctdcbad = 0;
329 double sumtdcgood = 0;
330 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
331 if (ic == 0) continue; //299 boards only
332 if (m_hists_bTDC[ic]) delete m_hists_bTDC[ic];
333 m_hists_bTDC[ic] = m_delta_tdc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
334 m_hists_bTDC[ic]->SetTitle(Form("histmd_tdc_board%d", ic));
335 float md_tdc = getHistMedian(m_hists_bTDC[ic]);
336 m_hist_tdc->SetBinContent(ic + 1, md_tdc);
337 float mintdc = (ic <= 48) ? m_mintdc_sl01 : m_mintdc_sl28;
338 float maxtdc = (ic <= 48) ? m_maxtdc_sl01 : m_maxtdc_sl28;
339 if (md_tdc >= mintdc && md_tdc <= maxtdc) {
340 ctdcgood++;
341 sumtdcgood = sumtdcgood + md_tdc;
342 } else ctdcbad++;
343 }
344 double tdcfrac = ctdcgood / 2.99;
345 setEpicsPV("tdcboards", tdcfrac);
346 m_canv_tdc->Clear();
347 m_canv_tdc->cd();
348 if (ctdcgood > 0)sumtdcgood = sumtdcgood * 1.0 / ctdcgood;
349 getHistStyle(m_hist_tdc, "tdc", sumtdcgood);
350 m_hist_tdc->SetTitle(Form("TDC Medians: Bad board count = %d (%0.01f%%)", ctdcbad - 1, 100.0 - tdcfrac));
351 m_hist_tdc->Draw("");
352 m_line_ltdc_sl01->Draw("same");
353 m_line_htdc_sl01->Draw("same");
354 m_line_ltdc_sl28->Draw("same");
355 m_line_htdc_sl28->Draw("same");
356 m_canv_tdc->Update();
358 }
359
360 //get phi plots for various options
361 auto m_delta_skimphi = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_idxphi, 0, true)); //true=only if updated
362 if (m_delta_skimphi) {
363 TString sip[2] = {"OffIP", "IP"};
364 TString sname[4] = {"all", "bhabha", "hadron", "mumutrk"};
365 for (int j = 0; j < 2; j++) { //ip selections
366 for (int i = 0; i < 4; i++) { //skim selections
367 int k = 4 * j + i; //0 to 7
368 TString hname = TString::Format("histphi_%s_%sevt", sip[j].Data(), sname[i].Data());
369 m_hist_skimphi[k] = m_delta_skimphi->ProjectionX(hname, k + 1, k + 1, "");
370 m_hist_skimphi[k]->SetTitle(TString::Format("cdc-track #phi (%s, %s-events);#phi;entries", sip[j].Data(), sname[i].Data()));
371 if (k < 4)m_hist_skimphi[k]->SetFillColor(kGray);
372 else m_hist_skimphi[k]->SetFillColor(kCyan);
373 m_canv_skimphi[k]->Clear();
374 m_canv_skimphi[k]->cd();
375 gPad->SetGridx(1);
376 gPad->SetGridy(1);
377 m_hist_skimphi[k]->Draw("hist");
378 }
379 }
380 }
381
382 //for CR shifter IP + all hadrons including alarm system
383 if (m_delta_skimphi) {
384 m_canv_crphi->Clear();
385 bool isFew = false, isAlarm = false, isWarn = false;
386 m_hist_crphi = m_delta_skimphi->ProjectionX("histphi_ip_hadrons", 7, 7, "");
387 if (m_hist_crphi) {
388 m_hist_crphi->SetTitle("cdc-track #phi (IP + hadrons);cdc-track #phi;norm entries");
389 double maxnow = m_hist_crphi->Integral();
390 if (maxnow > 0)m_hist_crphi->Scale(1.0 / maxnow);
391 if (maxnow < 10000) {
392 isFew = true;
393 } else {
394 if (m_histref_phiindex) {
395 m_hist_refphi = m_histref_phiindex->ProjectionX("histphi_ip_hadronsref", 7, 7, "");
396 double nbinref = m_hist_refphi->GetNbinsX();
397 double nbinnow = m_hist_crphi->GetNbinsX();
398 if (nbinref == nbinnow) { //same bins
399 double maxref = m_hist_refphi->Integral();
400 if (maxref > 0) {
401 m_hist_refphi->Scale(1.0 / maxref);
402 int warnCount = 0;
403 int alarmCount = 0;
404 for (int iphi = 0; iphi < nbinnow; iphi++) {
405 double icnow = m_hist_crphi->GetBinContent(iphi + 1);
406 double icref = m_hist_refphi->GetBinContent(iphi + 1);
407 double phidiff = 0;
408 if (icref > 0) phidiff = fabs(icnow - icref) / icref;
409 if (phidiff > m_phiwarn) warnCount++;
410 if (phidiff > m_phialarm) alarmCount++;
411 }
412 // difference threshold
413 int minBins = m_minphibinsfrac * nbinnow;
414 if (warnCount >= minBins) isWarn = true;
415 if (alarmCount >= minBins) isAlarm = true;
416 double warnFrac = 100.0 * warnCount / nbinnow;
417 double alarmFrac = 100.0 * alarmCount / nbinnow;
418 m_hist_crphi->SetTitle(
419 Form("%s [warn bins %.1f%%, alarm bins %.1f%% | crit: %.1f%% bins]",
420 m_hist_crphi->GetTitle(),
421 warnFrac,
422 alarmFrac,
423 100.0 * m_minphibinsfrac)
424 );
425 }
426 }
427 }
428 }
429 }
430 m_canv_crphi->cd();
431 gPad->SetGridx(1);
432 gPad->SetGridy(1);
433 if (!m_histref_phiindex)m_hist_crphi->SetTitle(Form("%s (no ref file)", m_hist_crphi->GetTitle()));
434 m_hist_crphi->Draw("hist");
436 else if (isAlarm)colorizeCanvas(m_canv_crphi, c_StatusError);
439 m_canv_crphi->Update();
441 }
442
443 //get tracking efficiency
444 auto m_delta_effphi = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_effphi, 0, true)); //true=only if updated
445 if (m_delta_effphi) {
446 m_canv_effphi->Clear();
447 double eff = -1;
448 const int all_phibins = m_delta_effphi->GetNbinsX();
449 const int all_hitbins = m_delta_effphi->GetNbinsY();
450 const int thr_hitbin = m_delta_effphi->GetYaxis()->FindBin(20);//min hits bin
451 for (int iphi = 0; iphi < all_phibins; iphi++) {
452 TH1D* temp = static_cast<TH1D*>(m_delta_effphi->ProjectionY(Form("hhits_bin_%d", iphi + 1), iphi + 1, iphi + 1, ""));
453 Double_t num = temp->Integral(thr_hitbin, all_hitbins);
454 Double_t den = temp->Integral();
455 if (den > 0)eff = num * 100.0 / den;
456 m_hist_effphi->SetBinContent(iphi + 1, eff);
457 m_hist_effphi->SetBinError(iphi + 1, 0);
458 delete temp;
459 }
460 m_hist_effphi->GetYaxis()->SetRangeUser(80.0, 110.0); //per efficiency
461 m_hist_effphi->SetTitle("CDC track efficiency(cdchits>20/all); cdc-track #phi; tracking efficiency");
462 m_canv_effphi->cd();
463 gPad->SetGridx();
464 gPad->SetGridy();
465 m_hist_effphi->SetFillColor(kCyan);
466 m_hist_effphi->Draw("hist");
467 m_canv_effphi->Update();
469 }
470
471 //get cdc hits vs phi
472 auto m_delta_hitphi = static_cast<TH2F*>(getDelta(m_name_dir, m_hname_hitsphi, 0, true)); //true=only if updated
473 if (m_delta_hitphi) {
474 m_canv_hitsphi->Clear();
475 m_delta_hitphi->SetTitle("CDC track #phi vs cdchits; cdc-track #phi; nCDCHits");
476 m_canv_hitsphi->cd();
477 gPad->SetLogz();
478 m_delta_hitphi->Draw("COLZ");
479 m_canv_hitsphi->Update();
481 }
482
483 // get wire efficiency
484 double meanWireAttachProb = 0;
485 double fracWiresWithLowAttachProb = 0;
486 double fracWiresWithHighAttachProb = 0;
487 gStyle->SetNumberContours(100);
488 auto m_delta_efflay = static_cast<TH2F*>(getDelta(m_name_dir, m_histoTrackingWireEff, 0, true)); //true=only if updated
489 if (m_delta_efflay) {
490 for (int ij = 0; ij < 4; ij++) m_canv_attach_eff[ij]->Clear();
492 int nEffiValues = 0;
493 for (int ij = 1; ij <= m_delta_efflay->GetNbinsX(); ij++) {
494 int halfYbin = m_delta_efflay->GetNbinsY() / 2;
495 for (int jk = 0; jk < halfYbin; jk++) {
496 if (m_delta_efflay->GetBinContent(ij, jk + 1) == 0) continue;
497 double binEffi = m_delta_efflay->GetBinContent(ij, jk + halfYbin + 1) / m_delta_efflay->GetBinContent(ij, jk + 1);
498 m_hist_wire_attach_eff_1d->Fill(binEffi);
499 meanWireAttachProb += binEffi;
500 nEffiValues++;
501 }
502 }
503 if (nEffiValues) meanWireAttachProb /= nEffiValues;
506 else
508 TLatex latex;
509 latex.SetTextSize(0.025);
510 for (int ij = 0; ij < 3; ij++) {
511 m_canv_attach_eff[ij]->cd();
513 m_hist_attach_eff_Poly[ij]->SetStats(0);
514 m_hist_attach_eff_Poly[ij]->Draw("COLZ");
515 } else {
516 m_hist_attach_eff[ij]->SetStats(0);
517 m_hist_attach_eff[ij]->Draw("COLZ");
518 int isl = 0;
519 TEllipse* el[9];
520 for (int ilay = 0; ilay < 56; ilay++) {
521 int rmdr = int(abs(ilay - 2) % 6);
522 if ((rmdr == 0 && ilay > 2) || ilay == 55) {
523 isl++;
524 el[isl] = new TEllipse(0, 0, m_lbinEdges[ilay], m_lbinEdges[ilay]);
525 el[isl]->SetLineColor(kRed);
526 el[isl]->SetLineWidth(2);
527 el[isl]->SetFillStyle(0);
528 el[isl]->Draw("same");
529 }
530 }
531 }
532 if (ij == 2)
533 latex.DrawLatexNDC(0.12, 0.87, TString::Format("mean = %.3f%%", meanWireAttachProb * 100.0));
534 }
535 m_canv_attach_eff[3]->cd();
536 if (nEffiValues) {
537 int firstBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_firstEffBoundary) - 1;
538 fracWiresWithLowAttachProb = m_hist_wire_attach_eff_1d->Integral(1, firstBoundaryBin) / nEffiValues;
539 int secondBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_secondEffBoundary) - 1;
540 fracWiresWithHighAttachProb = m_hist_wire_attach_eff_1d->Integral(secondBoundaryBin + 1,
541 m_hist_wire_attach_eff_1d->GetNbinsX()) / nEffiValues;
542 m_hist_wire_attach_eff_1d->SetStats(0);
544 latex.DrawLatexNDC(0.15, 0.87, TString::Format("%06.3f%% wire : eff < %.2f",
545 fracWiresWithLowAttachProb * 100,
547 latex.DrawLatexNDC(0.15, 0.84, TString::Format("%06.3f%% wire : %.2f < eff < %.2f",
548 (1. - fracWiresWithHighAttachProb - fracWiresWithLowAttachProb) * 100,
550 latex.DrawLatexNDC(0.15, 0.81, TString::Format("%06.3f%% wire : %.2f < eff",
551 fracWiresWithHighAttachProb * 100,
553 }
554 for (int ij = 0; ij < 4; ij++) {
555 m_canv_attach_eff[ij]->Update();
557 }
558 }
559
560 m_monObj->setVariable("meanWireAttachProb", meanWireAttachProb);
561 m_monObj->setVariable("fracWiresWithLowAttachProb", fracWiresWithLowAttachProb);
562 m_monObj->setVariable("fracWiresWithHighAttachProb", fracWiresWithHighAttachProb);
563
564 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end event");
565}
566
567//------------------------------------
569{
570 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end run");
571}
572
573
574//------------------------------------
576{
577 for (auto* line : m_lines) delete line;
578 m_lines.clear();
579 B2DEBUG(20, "DQMHistAnalysisCDCEpics: terminate called");
580}
581
582
583//------------------------------------
585{
586
587 if (!h) return 0.0;
588 TH1* hist = static_cast<TH1*>(h->Clone());
589 hist->SetBinContent(1, 0.0); // Exclude 0-th bin
590 float median = 0.0;
591 if (hist->Integral(1, hist->GetNbinsX()) > 0) {
592 double quantiles[1];
593 double probSums[1] = {0.5};
594 hist->GetQuantiles(1, quantiles, probSums);
595 if (std::isfinite(quantiles[0]))median = quantiles[0];
596 }
597 delete hist;
598 return median;
599}
600
601
602void DQMHistAnalysisCDCEpicsModule::fillEffiTH2(TH2F* hist, TH2F* attached, TH2F* expected, TH2F* efficiency)
603{
605 int nSLayers = cdcgeo.getNumberOfSenseLayers();
606
607 // Array to hold bin edges, with nSLayers + 1 edges needed for nSLayers bins
608 std::vector<double> binEdges(nSLayers + 1);
609 // Calculate r bin edges
610 double firstR = cdcgeo.senseWireR(0);
611 double secondR = cdcgeo.senseWireR(1);
612 binEdges[0] = firstR - (secondR - firstR) / 2;
613 m_lbinEdges[0] = firstR;
614 for (int lay = 1; lay < nSLayers; lay++) {
615 double prevR = cdcgeo.senseWireR(lay - 1);
616 double currentR = cdcgeo.senseWireR(lay);
617 binEdges[lay] = (prevR + currentR) / 2;
618 m_lbinEdges[lay] = currentR;
619 }
620 double lastR = cdcgeo.senseWireR(nSLayers - 1);
621 double secondLastR = cdcgeo.senseWireR(nSLayers - 2);
622 binEdges[nSLayers] = lastR + (lastR - secondLastR) / 2;
623 // convenient histogram to get layer number
624 TH1F layerHist("layerHist", "Layer Histogram", nSLayers, binEdges.data());
625
626 for (int binx = 1; binx <= efficiency->GetNbinsX(); binx++) {
627 for (int biny = 1; biny <= efficiency->GetNbinsY(); biny++) {
628 double bincenterx = efficiency->GetXaxis()->GetBinCenter(binx);
629 double bincentery = efficiency->GetYaxis()->GetBinCenter(biny);
630 double r = TMath::Sqrt(bincenterx * bincenterx + bincentery * bincentery);
631 double phi = TMath::ATan2(bincentery, bincenterx);
632 if (phi < 0) phi += 2 * TMath::Pi();
633
634 int layerBin = layerHist.FindBin(r); // Get the bin corresponding to r
635 if (layerBin < 1 || layerBin > nSLayers) continue;
636 int layerExpected = layerBin - 1;
637
638 int nWires = cdcgeo.nWiresInLayer(layerExpected);
639 double offset = cdcgeo.offset(layerExpected);
640 int wireExpected = phi * nWires / (2 * TMath::Pi()) - offset + 0.5;
641 if (wireExpected < 0) wireExpected += nWires;
642 if (wireExpected >= nWires) wireExpected -= nWires;
643
644 int expBin = hist->GetYaxis()->FindBin(layerExpected);
645 int obsBin = expBin + nSLayers;
646 expected->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, expBin));
647 attached->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, obsBin));
648 }
649 }
650 efficiency->Divide(attached, expected);
651}
652
653TH2Poly* DQMHistAnalysisCDCEpicsModule::createEffiTH2Poly(const TString& name, const TString& title)
654{
656 int nSLayers = cdcgeo.getNumberOfSenseLayers();
657 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
658 TH2Poly* hist = new TH2Poly(name, title, -maxLayerR * 1.02, maxLayerR * 1.02, -maxLayerR * 1.02, maxLayerR * 1.02);
659 for (int lay = 0; lay < nSLayers; lay++) {
660 int nWires = cdcgeo.nWiresInLayer(lay);
661 double offset = cdcgeo.offset(lay);
662 double layerR = cdcgeo.senseWireR(lay);
663 double r_inner = 0;
664 double r_outer = 0;
665 if (lay == 0) {
666 r_inner = layerR - (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
667 r_outer = layerR + (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
668 } else if (lay == nSLayers - 1) {
669 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
670 r_outer = layerR + (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
671 } else {
672 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
673 r_outer = layerR + (cdcgeo.senseWireR(lay + 1) - cdcgeo.senseWireR(lay)) / 2;
674 }
675 for (int wire = 0; wire < nWires; wire++) {
676 double phi_inner = (wire - 0.5 + offset) * 2 * TMath::Pi() / nWires;
677 double phi_outer = (wire + 0.5 + offset) * 2 * TMath::Pi() / nWires;
678 // Calculate the four corners of the bin
679 double x0 = r_inner * TMath::Cos(phi_inner);
680 double y0 = r_inner * TMath::Sin(phi_inner);
681 double x1 = r_outer * TMath::Cos(phi_inner);
682 double y1 = r_outer * TMath::Sin(phi_inner);
683 double x2 = r_outer * TMath::Cos(phi_outer);
684 double y2 = r_outer * TMath::Sin(phi_outer);
685 double x3 = r_inner * TMath::Cos(phi_outer);
686 double y3 = r_inner * TMath::Sin(phi_outer);
687 double xx[] = {x0, x1, x2, x3};
688 double yy[] = {y0, y1, y2, y3};
689 hist->AddBin(4, xx, yy);
690 }
691 }
692 return hist;
693}
694
695void DQMHistAnalysisCDCEpicsModule::fillEffiTH2Poly(TH2F* hist, TH2Poly* attached, TH2Poly* expected, TH2Poly* efficiency)
696{
697 attached->Reset("ICES");
698 expected->Reset("ICES");
700 int nSLayers = cdcgeo.getNumberOfSenseLayers();
701 for (int lay = 0; lay < nSLayers; lay++) {
702 int nWires = cdcgeo.nWiresInLayer(lay);
703 double layerR = cdcgeo.senseWireR(lay);
704 double offset = cdcgeo.offset(lay);
705 int expBin = hist->GetYaxis()->FindBin(lay);
706 int obsBin = expBin + nSLayers;
707 // fill the bins for this layer
708 for (int wire = 0; wire < nWires; wire++) {
709 double phi = (wire + offset) * 2 * TMath::Pi() / nWires;
710 double fillX = layerR * TMath::Cos(phi);
711 double fillY = layerR * TMath::Sin(phi);
712 attached->Fill(fillX, fillY, hist->GetBinContent(wire + 1, obsBin));
713 expected->Fill(fillX, fillY, hist->GetBinContent(wire + 1, expBin));
714 }
715 }
716 efficiency->Divide(attached, expected);
717}
The Class for CDC Geometry Parameters.
double offset(int layerID) const
Return wire offset in phi direction at endplate.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
ushort getNumberOfSenseLayers() const
Get the number of sense layers.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
TCanvas * m_canv_effphi
canvas for tracking efficiency
TLine * m_line_ltdc_sl28
line for lower TDC window for SL2-8
double m_maxtdc_sl28
max tdc median threshold accepted for SL2-8
void initialize() override final
Initialize the Module.
double m_secondEffBoundary
The second boundary of the efficiency range.
int m_minevt
min events for single intra-run point
std::string m_hname_idxphi
Phi Inedx histogram names.
static void fillEffiTH2Poly(TH2F *hist, TH2Poly *attached, TH2Poly *expected, TH2Poly *efficiency)
Populate the efficiency histograms.
TH1D * m_hists_bADC[kNumBoards]
ADC histograms with track associated hits for each board (0-299)
double m_mintdc_sl01
min tdc median threshold accepted for SL0-1
static TH2Poly * createEffiTH2Poly(const TString &name, const TString &title)
Convenient function to create a TH2Poly based on CDC geometry.
double m_maxadc_sl28
max adc median threshold accepted for SL2-8
std::string m_hname_hitsphi
Phi Hits histogram names.
double m_phiwarn
5% warn thershold for phi differences
TLine * m_line_ladc_sl01
line for lower ADC window for SL0-1
static float getHistMedian(TH1 *h)
Get median of given histogram.
static void getHistStyle(TH1F *&htemp, const std::string &label, double max)
get histogram styles
std::string m_histoTrackingWireEff
Wire Eff histogram names.
TFile * m_fileRefPhi
reference histogram file point
TCanvas * m_canv_md_ladc
canvas for adc layer median
double m_mintdc_sl28
min tdc median threshold accepted for SL2-8
double m_phialarm
15% alarm thershold for phi differences
TLine * m_line_ltdc_sl01
line for lower TDC window for SL0-1
std::string m_hname_effphi
Phi Eff histogram names.
TCanvas * m_canv_tdc
canvas for tdc board median
double m_maxadc_sl01
max adc median threshold accepted for SL0-1
TLine * m_line_hadc_sl01
line for higher ADC window for SL0-1
double m_lbinEdges[kNumLayers+1]
vector for radius edge 56
MonitoringObject * m_monObj
monitoring object
double m_minadc_sl28
min adc median threshold accepted for SL2-8
TLine * m_line_htdc_sl01
line for higher TDC window for SL0-1
std::string m_fname_refphi
reference file of phi histogram
void terminate() override final
Termination action.
void event() override final
intra-run actions (EPICC PVs).
std::vector< TLine * > m_lines
number of CDC layer lines
std::string m_hname_ladc
Layer ADC histogram names.
TH1D * m_hists_lADC[kNumLayers]
ADC histograms with track associated hits for each board (0-299)
bool m_doTH2PolyTrackingWireEff
If true, creates TH2Poly instead of TH2F for TrackingWireEff Histos.
double m_minphibinsfrac
min phi diff fraction for alarms
double m_firstEffBoundary
The first boundary of the efficiency range.
double m_maxtdc_sl01
max tdc median threshold accepted for SL0-1
std::string m_name_refdir
reference histogram dir
void endRun() override final
End-of-run action.
TCanvas * m_canv_hitsphi
expert canvas for hits vs phi
void beginRun() override final
Called when entering a new run.
TLine * m_line_htdc_sl28
line for higher TDC window for SL2-8
TH1D * m_hists_bTDC[kNumBoards]
TDC histograms with track associated hits for each board (0-299)
double m_minadc_sl01
min adc median threshold accepted for SL0-1
TLine * m_line_hadc_sl28
line for higher ADC window for SL2-8
TCanvas * m_canv_crphi
canvas for control shifter phi
TCanvas * m_canv_skimphi[8]
canvas for various phi distribution
TCanvas * m_canv_adc
canvas for adc board median
TCanvas * m_canv_attach_eff[4]
canvas for layer efficiency
TLine * m_line_ladc_sl28
line for lower ADC window for SL2-8
std::string m_hname_btdc
Board TDC histogram names.
std::string m_hname_badc
Board ADC histogram names.
void fillEffiTH2(TH2F *hist, TH2F *attached, TH2F *expected, TH2F *efficiency)
Populate the efficiency histograms.
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 colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
static void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
DQMHistAnalysisModule()
Constructor / Destructor.
@ 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.
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
constexpr unsigned kNumLayers
const CDC numbers for layers, boards and super layers
constexpr unsigned kNumBoards
Total number of CDC Boards.
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.