Belle II Software release-09-00-11
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
12#include <TLatex.h>
13
14using namespace std;
15using namespace Belle2;
16
17//-----------------------------------------------------------------
18// Register module
19//-----------------------------------------------------------------
20REG_MODULE(DQMHistAnalysisCDCEpics);
21
24{
25 addParam("HistDirectory", m_name_dir, "CDC Dir of DQM Histogram", std::string("CDC"));
26 addParam("RefDirectory", m_name_refdir, "Reference histogram dir", std::string("ref/CDC/default"));
27 addParam("PvPrefix", m_name_pvpfx, "PV Prefix and Name", std::string("CDC:"));
28 addParam("RefFilePhi", m_fname_refphi, "Reference histogram file name", std::string("CDCDQM_PhiRef.root"));
29 addParam("HistLayerADC", m_hname_ladc, "Layer ADC Histogram Name", std::string("hADCLayer"));
30 addParam("HistBoardADC", m_hname_badc, "Board ADC Histogram Name", std::string("hADCBoard"));
31 addParam("HistBoardTDC", m_hname_btdc, "Board TDC Histogram Name", std::string("hTDC"));
32 addParam("HistPhiIndex", m_hname_idxphi, "Phi Index Histogram Name", std::string("hPhiIndex"));
33 addParam("HistPhiEff", m_hname_effphi, "Phi Eff Histogram Name", std::string("hPhiEff"));
34 addParam("HistHitsPhi", m_hname_hitsphi, "Phi Hits Histogram Name", std::string("hPhiNCDC"));
35 addParam("MinEvt", m_minevt, "Min events for intra-run point", 1000);
36 addParam("HistTrackingWireEff", m_histoTrackingWireEff, "Wire Eff Histogram Name", std::string("hTrackingWireEff"));
37 addParam("DoTH2PolyTrackingWireEff", m_doTH2PolyTrackingWireEff,
38 "If true, creates TH2Poly instead of TH2F for TrackingWireEff Histos", m_doTH2PolyTrackingWireEff);
39 addParam("FirstEffBoundary", m_firstEffBoundary, "The first boundary of the efficiency range", m_firstEffBoundary);
40 addParam("SecondEffBoundary", m_secondEffBoundary, "The second boundary of the efficiency range", m_secondEffBoundary);
41 for (int i = 0; i < 300; i++) {
42 m_hists_bADC[i] = nullptr;
43 m_hists_bTDC[i] = nullptr;
44 //layer
45 if (i < 56)m_hists_lADC[i] = nullptr;
46 }
47
48 B2DEBUG(20, "DQMHistAnalysisCDCEpics: Constructor done.");
49}
50
52{
53}
54
56{
57
58 gROOT->cd();
59 c_histmd_ladc = new TCanvas("CDC/c_histmd_ladc", "c_histmd_ladc", 500, 400);
60 m_histmd_ladc = new TH1F("CDC/histmd_ladc", "m_histmd_ladc", 56, 0, 56);
61 m_histmd_ladc->SetTitle("ADC Medians vs Layers (SL-lines); CDC Layer index; ADC medians");
62
63 c_hist_adc = new TCanvas("CDC/c_hist_adc", "c_hist_adc", 500, 400);
64 m_hist_adc = new TH1F("CDC/hist_adc", "m_hist_adc", 300, 0, 300);
65 m_hist_adc->SetTitle("ADC Medians; CDC board index; ADC medians");
66
67 c_hist_tdc = new TCanvas("CDC/c_hist_tdc", "c_hist_tdc", 500, 400);
68 m_hist_tdc = new TH1F("CDC/hist_tdc", "m_hist_tdc", 300, 0, 300);
69 m_hist_tdc->SetTitle("TDC Medians; CDC board index; TDC medians");
70
71 //array of various phi histograms
72 for (int ic = 0; ic < 8; ic++) {
73 c_hist_skimphi[ic] = new TCanvas(Form("CDC/c_hist_skimphi_c%d", ic), Form("hist_skimphi_c%d", ic), 500, 400);
74 }
75
76 c_hist_crphi = new TCanvas("CDC/c_hist_crphi", "c_hist_crphi", 500, 400);
77 c_hist_hitsphi = new TCanvas("CDC/c_hist_hitsphi", "c_hist_hitsphi", 500, 400);
78
79 //CR alarm reference
80 if (m_fname_refphi != "") {
81 m_fileRefPhi = TFile::Open(m_fname_refphi.data(), "READ");
82 if (m_fileRefPhi && m_fileRefPhi->IsOpen()) {
83 B2INFO("DQMHistAnalysisCDCEpics: reference (" << m_fname_refphi << ") found OK");
84 m_histref_phiindex = (TH2F*)m_fileRefPhi->Get((m_name_refdir + "/hPhiIndex").data());
85 if (!m_histref_phiindex)B2INFO("\t .. but (histogram) not found");
86 else B2INFO("\t ..and (cdcdqm_phiref) also exist");
87 }
88 }
89
90 m_lines.clear();
91 m_lines.reserve(kNumLayers);
92 for (unsigned il = 0; il < kNumLayers; ++il) {
93 int bin = il + 1;
94 auto* line = new TLine(bin, 0, bin, 1.0);
95 line->SetLineStyle(2);
96 if (bin >= 8 && bin < 14)line->SetLineColor(kRed); // U-type
97 else if (bin >= 20 && bin < 26)line->SetLineColor(kGreen); // V-type
98 else if (bin >= 32 && bin < 38)line->SetLineColor(kRed); // U-type
99 else if (bin >= 44 && bin < 50)line->SetLineColor(kGreen); // v-type
100 else line->SetLineColor(kGray); // A-type
101 m_lines.push_back(line);
102 }
103
104 c_hist_effphi = new TCanvas("CDC/c_hist_effphi", "c_hist_effphi", 500, 400);
105 m_hist_effphi = new TH1D("CDC/hist_effphi", "m_hist_effphi", 360, -180.0, 180.0);
106
107 c_hist_attach_eff[0] = new TCanvas("CDC/c_hist_attached_wires", "c_hist_attached_wires", 403, 400);
108 c_hist_attach_eff[1] = new TCanvas("CDC/c_hist_expected_wires", "c_hist_expected_wires", 403, 400);
109 c_hist_attach_eff[2] = new TCanvas("CDC/c_hist_attach_eff", "c_hist_attach_eff", 403, 400);
110 c_hist_attach_eff[3] = new TCanvas("CDC/c_hist_attach_eff_1d", "c_hist_attach_eff_1d", 403, 400);
112 m_hist_attach_eff_Poly[0] = createEffiTH2Poly("CDC/hist_attachedWires",
113 "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin");
114 m_hist_attach_eff_Poly[0]->GetYaxis()->SetTitleOffset(1.4);
115 m_hist_attach_eff_Poly[0]->SetDirectory(gDirectory);
116 m_hist_attach_eff_Poly[1] = (TH2Poly*)m_hist_attach_eff_Poly[0]->Clone();
117 m_hist_attach_eff_Poly[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
118 m_hist_attach_eff_Poly[1]->SetDirectory(gDirectory);
119 m_hist_attach_eff_Poly[2] = (TH2Poly*)m_hist_attach_eff_Poly[0]->Clone();
120 m_hist_attach_eff_Poly[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
121 m_hist_attach_eff_Poly[2]->SetDirectory(gDirectory);
122 } else {
124 int nSLayers = cdcgeo.getNumberOfSenseLayers();
125 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
126 m_hist_attach_eff[0] = new TH2F("CDC/hist_attachedWires", "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin",
127 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02,
128 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02);
129 m_hist_attach_eff[0]->GetYaxis()->SetTitleOffset(1.4);
130 m_hist_attach_eff[1] = (TH2F*)m_hist_attach_eff[0]->Clone();
131 m_hist_attach_eff[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
132 m_hist_attach_eff[2] = (TH2F*)m_hist_attach_eff[0]->Clone();
133 m_hist_attach_eff[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
134 }
135 m_hist_wire_attach_eff_1d = new TH1F("CDC/hist_wire_attach_eff_1d", "hist_wire_attach_eff_1d;Wire Efficiency;Wire / bin",
136 208, -0.02, 1.02);
137 m_hist_wire_attach_eff_1d->GetYaxis()->SetTitleOffset(1.4);
138
140 addDeltaPar(m_name_dir, m_hname_ladc, HistDelta::c_Entries, m_minevt, 1);
141
143 addDeltaPar(m_name_dir, m_hname_badc, HistDelta::c_Entries, m_minevt, 1);
144
146 addDeltaPar(m_name_dir, m_hname_btdc, HistDelta::c_Entries, m_minevt, 1);
147
149 addDeltaPar(m_name_dir, m_hname_idxphi, HistDelta::c_Entries, m_minevt, 1);
150
152 addDeltaPar(m_name_dir, m_hname_effphi, HistDelta::c_Entries, m_minevt, 1);
153
155 addDeltaPar(m_name_dir, m_hname_hitsphi, HistDelta::c_Entries, m_minevt, 1);
156
158 addDeltaPar(m_name_dir, m_histoTrackingWireEff, HistDelta::c_Events, m_minevt, 1);
159
160 //creating box for normal adc and tdc windows, the real position is updated at begin run
161 m_line_ladc = new TLine(0, m_minadc, 300, m_minadc);
162 m_line_ladc->SetLineColor(kRed);
163 m_line_ladc->SetLineWidth(2);
164
165 m_line_hadc = new TLine(0, m_maxadc, 300, m_maxadc);
166 m_line_hadc->SetLineColor(kRed);
167 m_line_hadc->SetLineWidth(2);
168
169 m_line_ltdc = new TLine(0, m_mintdc, 300, m_mintdc);
170 m_line_ltdc->SetLineColor(kRed);
171 m_line_ltdc->SetLineWidth(2);
172
173 m_line_htdc = new TLine(0, m_maxtdc, 300, m_maxtdc);
174 m_line_htdc->SetLineColor(kRed);
175 m_line_htdc->SetLineWidth(2);
176
177 registerEpicsPV(m_name_pvpfx + "cdcboards_wadc", "adcboards");
178 registerEpicsPV(m_name_pvpfx + "cdcboards_wtdc", "tdcboards");
179
180 registerEpicsPV(m_name_pvpfx + "adc_median_window", "adcmedianwindow");
181 registerEpicsPV(m_name_pvpfx + "tdc_median_window", "tdcmedianwindow");
182
183 registerEpicsPV(m_name_pvpfx + "phi_compare_window", "phicomparewindow");
184
186
187 B2DEBUG(20, "DQMHistAnalysisCDCEpics: initialized.");
188}
189
191{
192 double unused = 0;
193 requestLimitsFromEpicsPVs("adcmedianwindow", unused, m_minadc, m_maxadc, unused);
194 requestLimitsFromEpicsPVs("tdcmedianwindow", unused, m_mintdc, m_maxtdc, unused);
195 requestLimitsFromEpicsPVs("phicomparewindow", m_phialarm, m_phiwarn, unused, unused);
196
197 //in case if something is wrong in config file
198 if (std::isnan(m_minadc)) m_minadc = 60.0;
199 if (std::isnan(m_maxadc)) m_maxadc = 130.0;
200 if (std::isnan(m_mintdc)) m_mintdc = 4600.0;
201 if (std::isnan(m_maxtdc)) m_maxtdc = 5000.0;
202
203 if (std::isnan(m_phiwarn)) m_phiwarn = 0.05; //>%5 is warning
204 if (std::isnan(m_phialarm)) m_phialarm = 0.15; //>%15 is warning
205
206 // Update Line position from Epics limits
207 m_line_ladc->SetY1(m_minadc);
208 m_line_ladc->SetY2(m_minadc);
209 m_line_hadc->SetY1(m_maxadc);
210 m_line_hadc->SetY2(m_maxadc);
211 m_line_ltdc->SetY1(m_mintdc);
212 m_line_ltdc->SetY2(m_mintdc);
213 m_line_htdc->SetY1(m_maxtdc);
214 m_line_htdc->SetY2(m_maxtdc);
215
216 B2DEBUG(20, "DQMHistAnalysisCDCEpics: beginRun run called");
217}
218
220{
221 //1. get adc median vs layer numbers
222 auto m_delta_ladc = (TH2F*)getDelta(m_name_dir, m_hname_ladc, 0, true);
223 if (m_delta_ladc) {
224 m_histmd_ladc->Reset();
225 for (unsigned il = 0; il < kNumLayers; ++il) {
226 if (m_hists_lADC[il]) delete m_hists_lADC[il];
227 m_hists_lADC[il] = m_delta_ladc->ProjectionY(Form("histmd_adc_layer%d", il + 1), il + 1, il + 1, "");
228 m_hists_lADC[il]->SetTitle(Form("histmd_adc_layer%d", il));
229 float md_ladc = getHistMedian(m_hists_lADC[il]);
230 m_histmd_ladc->SetBinContent(il + 1, md_ladc);
231 }
232 // Draw canvas
233 c_histmd_ladc->Clear();
234 c_histmd_ladc->cd();
235 getHistStyle(m_histmd_ladc, "layeradc", 0);
236 double y_max = m_histmd_ladc->GetMaximum();
237 m_histmd_ladc->SetFillColor(kYellow);
238 m_histmd_ladc->SetMinimum(0);
239 m_histmd_ladc->SetMaximum(y_max * 1.20);
240 m_histmd_ladc->Draw("hist");
241 for (auto* line : m_lines) {
242 line->SetY2(y_max * 1.20);
243 line->Draw("same");
244 }
245 c_histmd_ladc->Update();
247 }
248
249 //2. get adc medians vs board ID
250 auto m_delta_adc = (TH2F*)getDelta(m_name_dir, m_hname_badc, 0, true); //true=only if updated
251 if (m_delta_adc) {
252 m_hist_adc->Reset();
253 int cadcgood = 0;
254 int cadcbad = 0;
255 double sumadcgood = 0;
256 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
257 if (ic == 0) continue; //299 boards only
258 if (m_hists_bADC[ic]) delete m_hists_bADC[ic];
259 m_hists_bADC[ic] = m_delta_adc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
260 m_hists_bADC[ic]->SetTitle(Form("histmd_adc_board%d", ic));
261 float md_adc = getHistMedian(m_hists_bADC[ic]);
262 m_hist_adc->SetBinContent(ic + 1, md_adc);
263 if (md_adc >= m_minadc && md_adc <= m_maxadc) {
264 sumadcgood = sumadcgood + md_adc;
265 cadcgood++;
266 } else cadcbad++;
267 }
268 double adcfrac = cadcgood / 2.99; // (100.0/299) in %
269 setEpicsPV("adcboards", adcfrac);
270 // Draw canvas
271 c_hist_adc->Clear();
272 c_hist_adc->cd();
273 if (cadcgood > 0)sumadcgood = sumadcgood * 1.0 / cadcgood;
274 getHistStyle(m_hist_adc, "adc", sumadcgood);
275 m_hist_adc->SetTitle(Form("ADC Medians: Bad board count = %d (%0.01f%%)", cadcbad - 1, 100.0 - adcfrac));
276 m_hist_adc->Draw("");
277 m_line_ladc->Draw("same");
278 m_line_hadc->Draw("same");
279 c_hist_adc->Update();
281 }
282
283 //3. get tdc medians vs board ID
284 auto m_delta_tdc = (TH2F*)getDelta(m_name_dir, m_hname_btdc, 0, true);
285 if (m_delta_tdc) {
286 m_hist_tdc->Reset();
287 int ctdcgood = 0;
288 int ctdcbad = 0;
289 double sumtdcgood = 0;
290 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
291 if (ic == 0) continue; //299 boards only
292 if (m_hists_bTDC[ic]) delete m_hists_bTDC[ic];
293 m_hists_bTDC[ic] = m_delta_tdc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
294 m_hists_bTDC[ic]->SetTitle(Form("histmd_tdc_board%d", ic));
295 float md_tdc = getHistMedian(m_hists_bTDC[ic]);
296 m_hist_tdc->SetBinContent(ic + 1, md_tdc);
297 if (md_tdc >= m_mintdc && md_tdc <= m_maxtdc) {
298 ctdcgood++;
299 sumtdcgood = sumtdcgood + md_tdc;
300 } else ctdcbad++;
301 }
302 double tdcfrac = ctdcgood / 2.99;
303 setEpicsPV("tdcboards", tdcfrac);
304 c_hist_tdc->Clear();
305 c_hist_tdc->cd();
306 if (ctdcgood > 0)sumtdcgood = sumtdcgood * 1.0 / ctdcgood;
307 getHistStyle(m_hist_tdc, "tdc", sumtdcgood);
308 m_hist_tdc->SetTitle(Form("TDC Medians: Bad board count = %d (%0.01f%%)", ctdcbad - 1, 100.0 - tdcfrac));
309 m_hist_tdc->Draw("");
310 m_line_ltdc->Draw("same");
311 m_line_htdc->Draw("same");
312 c_hist_tdc->Update();
314 }
315
316 //get phi plots for various options
317 auto m_delta_skimphi = (TH2F*)getDelta(m_name_dir, m_hname_idxphi, 0, true); //true=only if updated
318 if (m_delta_skimphi) {
319 TString sip[2] = {"OffIP", "IP"};
320 TString sname[4] = {"all", "bhabha", "hadron", "mumutrk"};
321 for (int j = 0; j < 2; j++) { //ip selections
322 for (int i = 0; i < 4; i++) { //skim selections
323 int k = 4 * j + i; //0 to 7
324 TString hname = TString::Format("histphi_%s_%sevt", sip[j].Data(), sname[i].Data());
325 m_hist_skimphi[k] = m_delta_skimphi->ProjectionX(hname, k + 1, k + 1, "");
326 m_hist_skimphi[k]->SetTitle(TString::Format("cdc-track #phi (%s, %s-events);#phi;entries", sip[j].Data(), sname[i].Data()));
327 if (k < 4)m_hist_skimphi[k]->SetFillColor(kGray);
328 else m_hist_skimphi[k]->SetFillColor(kCyan);
329 c_hist_skimphi[k]->Clear();
330 c_hist_skimphi[k]->cd();
331 gPad->SetGridx(1);
332 gPad->SetGridy(1);
333 m_hist_skimphi[k]->Draw("hist");
334 }
335 }
336 }
337
338 //for CR shifter IP + all hadrons including alarm system
339 if (m_delta_skimphi) {
340 c_hist_crphi->Clear();
341 bool isFew = false, isAlarm = false, isWarn = false;
342 m_hist_crphi = m_delta_skimphi->ProjectionX("histphi_ip_hadrons", 7, 7, "");
343 m_hist_crphi->SetTitle("cdc-track #phi (IP + hadrons);cdc-track #phi;norm entries");
344 if (m_hist_crphi) {
345 double maxnow = m_hist_crphi->Integral();
346 if (maxnow > 0)m_hist_crphi->Scale(1.0 / maxnow);
347 if (maxnow < 10000) {
348 isFew = true;
349 } else {
350 if (m_histref_phiindex) {
351 m_hist_refphi = m_histref_phiindex->ProjectionX("histphi_ip_hadronsref", 7, 7, "");
352 double nbinref = m_hist_refphi->GetNbinsX();
353 double nbinnow = m_hist_crphi->GetNbinsX();
354 if (nbinref == nbinnow) { //same bins
355 double maxref = m_hist_refphi->Integral();
356 if (maxref > 0) {
357 m_hist_refphi->Scale(1.0 / maxref);
358 double maxphidiff = 0;
359 double maxphidiff_angle = 0;
360 for (int iphi = 0; iphi < nbinnow; iphi++) {
361 double icnow = m_hist_crphi->GetBinContent(iphi + 1);
362 double icref = m_hist_refphi->GetBinContent(iphi + 1);
363 double phidiff = fabs(icnow - icref);
364 if (phidiff > m_phiwarn)isWarn = true;
365 if (phidiff > m_phialarm)isAlarm = true;
366 if (phidiff > maxphidiff) {
367 maxphidiff = phidiff;
368 maxphidiff_angle = m_hist_crphi->GetBinLowEdge(iphi + 1) + m_hist_crphi->GetBinWidth(iphi + 1);
369 }
370 }
371 m_hist_crphi->SetTitle(Form("%s (diff = %0.03f at %0.1f)", m_hist_crphi->GetTitle(), maxphidiff, maxphidiff_angle));
372 }
373 }
374 }
375 }
376 }
377 c_hist_crphi->cd();
378 gPad->SetGridx(1);
379 gPad->SetGridy(1);
380 if (!m_histref_phiindex)m_hist_crphi->SetTitle(Form("%s (no ref file)", m_hist_crphi->GetTitle()));
381 m_hist_crphi->Draw("hist");
383 else if (isAlarm)colorizeCanvas(c_hist_crphi, c_StatusError);
386 c_hist_crphi->Update();
388 }
389
390 //get tracking efficiency
391 auto m_delta_effphi = (TH2F*)getDelta(m_name_dir, m_hname_effphi, 0, true); //true=only if updated
392 if (m_delta_effphi) {
393 c_hist_effphi->Clear();
394 double eff = -1;
395 const int all_phibins = m_delta_effphi->GetNbinsX();
396 const int all_hitbins = m_delta_effphi->GetNbinsY();
397 const int thr_hitbin = m_delta_effphi->GetYaxis()->FindBin(20);//min hits bin
398 for (int iphi = 0; iphi < all_phibins; iphi++) {
399 TH1D* temp = (TH1D*)m_delta_effphi->ProjectionY(Form("hhits_bin_%d", iphi + 1), iphi + 1, iphi + 1, "");
400 Double_t num = temp->Integral(thr_hitbin, all_hitbins);
401 Double_t den = temp->Integral();
402 if (den > 0)eff = num * 100.0 / den;
403 m_hist_effphi->SetBinContent(iphi + 1, eff);
404 m_hist_effphi->SetBinError(iphi + 1, 0);
405 delete temp;
406 }
407 m_hist_effphi->GetYaxis()->SetRangeUser(80.0, 110.0); //per efficiency
408 m_hist_effphi->SetTitle("CDC track efficiency(cdchits>20/all); cdc-track #phi; tracking efficiency");
409 c_hist_effphi->cd();
410 gPad->SetGridx();
411 gPad->SetGridy();
412 m_hist_effphi->SetFillColor(kCyan);
413 m_hist_effphi->Draw("hist");
414 c_hist_effphi->Update();
416 }
417
418 //get cdc hits vs phi
419 auto m_delta_hitphi = (TH2F*)getDelta(m_name_dir, m_hname_hitsphi, 0, true); //true=only if updated
420 if (m_delta_hitphi) {
421 c_hist_hitsphi->Clear();
422 m_delta_hitphi->SetTitle("CDC track #phi vs cdchits; cdc-track #phi; nCDCHits");
423 c_hist_hitsphi->cd();
424 m_delta_hitphi->Draw("COLZ");
425 c_hist_hitsphi->Update();
427 }
428
429 // get wire efficiency
430 double meanWireAttachProb = 0;
431 double fracWiresWithLowAttachProb = 0;
432 double fracWiresWithHighAttachProb = 0;
433 gStyle->SetNumberContours(100);
434 auto m_delta_efflay = (TH2F*)getDelta(m_name_dir, m_histoTrackingWireEff, 0, true); //true=only if updated
435 if (m_delta_efflay) {
436 for (int ij = 0; ij < 4; ij++) c_hist_attach_eff[ij]->Clear();
438 int nEffiValues = 0;
439 for (int ij = 1; ij <= m_delta_efflay->GetNbinsX(); ij++) {
440 int halfYbin = m_delta_efflay->GetNbinsY() / 2;
441 for (int jk = 0; jk < halfYbin; jk++) {
442 if (m_delta_efflay->GetBinContent(ij, jk + 1) == 0) continue;
443 double binEffi = m_delta_efflay->GetBinContent(ij, jk + halfYbin + 1) / m_delta_efflay->GetBinContent(ij, jk + 1);
444 m_hist_wire_attach_eff_1d->Fill(binEffi);
445 meanWireAttachProb += binEffi;
446 nEffiValues++;
447 }
448 }
449 if (nEffiValues) meanWireAttachProb /= nEffiValues;
452 else
454 TLatex latex;
455 latex.SetTextSize(0.025);
456 for (int ij = 0; ij < 3; ij++) {
457 c_hist_attach_eff[ij]->cd();
459 m_hist_attach_eff_Poly[ij]->SetStats(0);
460 m_hist_attach_eff_Poly[ij]->Draw("COLZ");
461 } else {
462 m_hist_attach_eff[ij]->SetStats(0);
463 m_hist_attach_eff[ij]->Draw("COLZ");
464 int isl = 0;
465 TEllipse* el[9];
466 for (int ilay = 0; ilay < 56; ilay++) {
467 int rmdr = int(abs(ilay - 2) % 6);
468 if ((rmdr == 0 && ilay > 2) || ilay == 55) {
469 isl++;
470 el[isl] = new TEllipse(0, 0, m_lbinEdges[ilay], m_lbinEdges[ilay]);
471 el[isl]->SetLineColor(kRed);
472 el[isl]->SetLineWidth(2);
473 el[isl]->SetFillStyle(0);
474 el[isl]->Draw("same");
475 }
476 }
477 }
478 if (ij == 2)
479 latex.DrawLatexNDC(0.12, 0.87, TString::Format("mean = %.3f%%", meanWireAttachProb * 100.0));
480 }
481 c_hist_attach_eff[3]->cd();
482 if (nEffiValues) {
483 int firstBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_firstEffBoundary) - 1;
484 fracWiresWithLowAttachProb = m_hist_wire_attach_eff_1d->Integral(1, firstBoundaryBin) / nEffiValues;
485 int secondBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_secondEffBoundary) - 1;
486 fracWiresWithHighAttachProb = m_hist_wire_attach_eff_1d->Integral(secondBoundaryBin + 1,
487 m_hist_wire_attach_eff_1d->GetNbinsX()) / nEffiValues;
488 m_hist_wire_attach_eff_1d->SetStats(0);
490 latex.DrawLatexNDC(0.15, 0.87, TString::Format("%06.3f%% wire : eff < %.2f",
491 fracWiresWithLowAttachProb * 100,
493 latex.DrawLatexNDC(0.15, 0.84, TString::Format("%06.3f%% wire : %.2f < eff < %.2f",
494 (1. - fracWiresWithHighAttachProb - fracWiresWithLowAttachProb) * 100,
496 latex.DrawLatexNDC(0.15, 0.81, TString::Format("%06.3f%% wire : %.2f < eff",
497 fracWiresWithHighAttachProb * 100,
499 }
500 for (int ij = 0; ij < 4; ij++) {
501 c_hist_attach_eff[ij]->Update();
503 }
504 }
505
506 m_monObj->setVariable("meanWireAttachProb", meanWireAttachProb);
507 m_monObj->setVariable("fracWiresWithLowAttachProb", fracWiresWithLowAttachProb);
508 m_monObj->setVariable("fracWiresWithHighAttachProb", fracWiresWithHighAttachProb);
509
510 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end event");
511}
512
513//------------------------------------
515{
516 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end run");
517}
518
519
520//------------------------------------
522{
523 for (auto* line : m_lines) delete line;
524 m_lines.clear();
525 B2DEBUG(20, "DQMHistAnalysisCDCEpics: terminate called");
526}
527
528
529//------------------------------------
531{
532 TH1D* hist = (TH1D*)h->Clone();
533 hist->SetBinContent(1, 0.0); // Exclude 0-th bin
534 float median = 0.0;
535 if (hist->GetMean() != 0) {
536 // Avoid an error if only TCD/ADC=0 entries
537 double quantiles[1] = {0.0}; // One element to store median
538 double probSums[1] = {0.5}; // Median definition
539 hist->GetQuantiles(1, quantiles, probSums);
540 median = quantiles[0];
541 }
542 delete hist;
543 return median;
544}
545
546
547void DQMHistAnalysisCDCEpicsModule::fillEffiTH2(TH2F* hist, TH2F* attached, TH2F* expected, TH2F* efficiency)
548{
550 int nSLayers = cdcgeo.getNumberOfSenseLayers();
551
552 // Array to hold bin edges, with nSLayers + 1 edges needed for nSLayers bins
553 std::vector<double> binEdges(nSLayers + 1);
554 // Calculate r bin edges
555 double firstR = cdcgeo.senseWireR(0);
556 double secondR = cdcgeo.senseWireR(1);
557 binEdges[0] = firstR - (secondR - firstR) / 2;
558 m_lbinEdges[0] = firstR;
559 for (int lay = 1; lay < nSLayers; lay++) {
560 double prevR = cdcgeo.senseWireR(lay - 1);
561 double currentR = cdcgeo.senseWireR(lay);
562 binEdges[lay] = (prevR + currentR) / 2;
563 m_lbinEdges[lay] = currentR;
564 }
565 double lastR = cdcgeo.senseWireR(nSLayers - 1);
566 double secondLastR = cdcgeo.senseWireR(nSLayers - 2);
567 binEdges[nSLayers] = lastR + (lastR - secondLastR) / 2;
568 // convenient histogram to get layer number
569 TH1F layerHist("layerHist", "Layer Histogram", nSLayers, binEdges.data());
570
571 for (int binx = 1; binx <= efficiency->GetNbinsX(); binx++) {
572 for (int biny = 1; biny <= efficiency->GetNbinsY(); biny++) {
573 double bincenterx = efficiency->GetXaxis()->GetBinCenter(binx);
574 double bincentery = efficiency->GetYaxis()->GetBinCenter(biny);
575 double r = TMath::Sqrt(bincenterx * bincenterx + bincentery * bincentery);
576 double phi = TMath::ATan2(bincentery, bincenterx);
577 if (phi < 0) phi += 2 * TMath::Pi();
578
579 int layerBin = layerHist.FindBin(r); // Get the bin corresponding to r
580 if (layerBin < 1 || layerBin > nSLayers) continue;
581 int layerExpected = layerBin - 1;
582
583 int nWires = cdcgeo.nWiresInLayer(layerExpected);
584 double offset = cdcgeo.offset(layerExpected);
585 int wireExpected = phi * nWires / (2 * TMath::Pi()) - offset + 0.5;
586 if (wireExpected < 0) wireExpected += nWires;
587 if (wireExpected >= nWires) wireExpected -= nWires;
588
589 int expBin = hist->GetYaxis()->FindBin(layerExpected);
590 int obsBin = expBin + nSLayers;
591 expected->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, expBin));
592 attached->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, obsBin));
593 }
594 }
595 efficiency->Divide(attached, expected);
596}
597
598TH2Poly* DQMHistAnalysisCDCEpicsModule::createEffiTH2Poly(const TString& name, const TString& title)
599{
601 int nSLayers = cdcgeo.getNumberOfSenseLayers();
602 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
603 TH2Poly* hist = new TH2Poly(name, title, -maxLayerR * 1.02, maxLayerR * 1.02, -maxLayerR * 1.02, maxLayerR * 1.02);
604 for (int lay = 0; lay < nSLayers; lay++) {
605 int nWires = cdcgeo.nWiresInLayer(lay);
606 double offset = cdcgeo.offset(lay);
607 double layerR = cdcgeo.senseWireR(lay);
608 double r_inner = 0;
609 double r_outer = 0;
610 if (lay == 0) {
611 r_inner = layerR - (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
612 r_outer = layerR + (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
613 } else if (lay == nSLayers - 1) {
614 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
615 r_outer = layerR + (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
616 } else {
617 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
618 r_outer = layerR + (cdcgeo.senseWireR(lay + 1) - cdcgeo.senseWireR(lay)) / 2;
619 }
620 for (int wire = 0; wire < nWires; wire++) {
621 double phi_inner = (wire - 0.5 + offset) * 2 * TMath::Pi() / nWires;
622 double phi_outer = (wire + 0.5 + offset) * 2 * TMath::Pi() / nWires;
623 // Calculate the four corners of the bin
624 double x0 = r_inner * TMath::Cos(phi_inner);
625 double y0 = r_inner * TMath::Sin(phi_inner);
626 double x1 = r_outer * TMath::Cos(phi_inner);
627 double y1 = r_outer * TMath::Sin(phi_inner);
628 double x2 = r_outer * TMath::Cos(phi_outer);
629 double y2 = r_outer * TMath::Sin(phi_outer);
630 double x3 = r_inner * TMath::Cos(phi_outer);
631 double y3 = r_inner * TMath::Sin(phi_outer);
632 double xx[] = {x0, x1, x2, x3};
633 double yy[] = {y0, y1, y2, y3};
634 hist->AddBin(4, xx, yy);
635 }
636 }
637 return hist;
638}
639
640void DQMHistAnalysisCDCEpicsModule::fillEffiTH2Poly(TH2F* hist, TH2Poly* attached, TH2Poly* expected, TH2Poly* efficiency)
641{
642 attached->Reset("ICES");
643 expected->Reset("ICES");
645 int nSLayers = cdcgeo.getNumberOfSenseLayers();
646 for (int lay = 0; lay < nSLayers; lay++) {
647 int nWires = cdcgeo.nWiresInLayer(lay);
648 double layerR = cdcgeo.senseWireR(lay);
649 double offset = cdcgeo.offset(lay);
650 int expBin = hist->GetYaxis()->FindBin(lay);
651 int obsBin = expBin + nSLayers;
652 // fill the bins for this layer
653 for (int wire = 0; wire < nWires; wire++) {
654 double phi = (wire + offset) * 2 * TMath::Pi() / nWires;
655 double fillX = layerR * TMath::Cos(phi);
656 double fillY = layerR * TMath::Sin(phi);
657 attached->Fill(fillX, fillY, hist->GetBinContent(wire + 1, obsBin));
658 expected->Fill(fillX, fillY, hist->GetBinContent(wire + 1, expBin));
659 }
660 }
661 efficiency->Divide(attached, expected);
662}
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 * c_hist_adc
canvas for adc board median
TCanvas * c_hist_skimphi[8]
canvas for various phi distribution
void initialize() override final
Initialize the Module.
double m_minadc
min adc median thershold accepted
TCanvas * c_histmd_ladc
canvas for adc layer median
double m_secondEffBoundary
The second boundary of the efficiency range.
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_hname_idxphi
Phi Inedx histogram names.
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)
TH2Poly * createEffiTH2Poly(const TString &name, const TString &title)
Convenient function to create a TH2Poly based on CDC geometry.
std::string m_hname_hitsphi
Phi Hits histogram names.
double m_phiwarn
warn thershold for phi differences
std::string m_histoTrackingWireEff
Wire Eff histogram names.
TFile * m_fileRefPhi
reference histogram file point
TLine * m_line_htdc
line for higher TDC window
double m_phialarm
alarm thershold for phi differences
double m_maxadc
max adc median thershold accepted
std::string m_hname_effphi
Phi Eff histogram names.
double m_maxtdc
max tdc median thershold accepted
double m_lbinEdges[kNumLayers+1]
vector for radius edge 56
void getHistStyle(TH1F *&htemp, std::string label, double max) const
get histogram styles
MonitoringObject * m_monObj
monitoring object
TCanvas * c_hist_crphi
canvas for control shifter phi
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
TCanvas * c_hist_tdc
canvas for tdc board median
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.
TCanvas * c_hist_hitsphi
expert canvas for hits vs phi
TCanvas * c_hist_attach_eff[4]
canvas for layer efficiency
double m_firstEffBoundary
The first boundary of the efficiency range.
std::string m_name_refdir
reference histogram dir
void endRun() override final
End-of-run action.
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.
TH1D * m_hists_bTDC[kNumBoards]
TDC histograms with track associated hits for each board (0-299)
float getHistMedian(TH1D *h) const
Get median of given histogram.
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.
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.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
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 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)
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: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.