Belle II Software release-09-00-07
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 registerEpicsPV(m_name_pvpfx + "cdcboards_wadc", "adcboards");
161 registerEpicsPV(m_name_pvpfx + "cdcboards_wtdc", "tdcboards");
162
163 registerEpicsPV(m_name_pvpfx + "adc_median_window", "adcmedianwindow");
164 registerEpicsPV(m_name_pvpfx + "tdc_median_window", "tdcmedianwindow");
165
166 registerEpicsPV(m_name_pvpfx + "phi_compare_window", "phicomparewindow");
167
169
170 B2DEBUG(20, "DQMHistAnalysisCDCEpics: initialized.");
171}
172
174{
175 double unused = 0;
176 requestLimitsFromEpicsPVs("adcmedianwindow", unused, m_minadc, m_maxadc, unused);
177 requestLimitsFromEpicsPVs("tdcmedianwindow", unused, m_mintdc, m_maxtdc, unused);
178 requestLimitsFromEpicsPVs("phicomparewindow", m_phialarm, m_phiwarn, unused, unused);
179
180 //in case if something is wrong in config file
181 if (std::isnan(m_minadc)) m_minadc = 60.0;
182 if (std::isnan(m_maxadc)) m_maxadc = 130.0;
183 if (std::isnan(m_mintdc)) m_mintdc = 4600.0;
184 if (std::isnan(m_maxtdc)) m_maxtdc = 5000.0;
185
186 if (std::isnan(m_phiwarn)) m_phiwarn = 0.05; //>%5 is warning
187 if (std::isnan(m_phialarm)) m_phialarm = 0.15; //>%15 is warning
188
189 //creating box for normal adc and tdc windows
190 m_line_ladc = new TLine(0, m_minadc, 300, m_minadc);
191 m_line_ladc->SetLineColor(kRed);
192 m_line_ladc->SetLineWidth(2);
193
194 m_line_hadc = new TLine(0, m_maxadc, 300, m_maxadc);
195 m_line_hadc->SetLineColor(kRed);
196 m_line_hadc->SetLineWidth(2);
197
198 m_line_ltdc = new TLine(0, m_mintdc, 300, m_mintdc);
199 m_line_ltdc->SetLineColor(kRed);
200 m_line_ltdc->SetLineWidth(2);
201
202 m_line_htdc = new TLine(0, m_maxtdc, 300, m_maxtdc);
203 m_line_htdc->SetLineColor(kRed);
204 m_line_htdc->SetLineWidth(2);
205
206 B2DEBUG(20, "DQMHistAnalysisCDCEpics: beginRun run called");
207}
208
210{
211 //1. get adc median vs layer numbers
212 auto m_delta_ladc = (TH2F*)getDelta(m_name_dir, m_hname_ladc, 0, true);
213 if (m_delta_ladc) {
214 m_histmd_ladc->Reset();
215 for (unsigned il = 0; il < kNumLayers; ++il) {
216 if (m_hists_lADC[il]) delete m_hists_lADC[il];
217 m_hists_lADC[il] = m_delta_ladc->ProjectionY(Form("histmd_adc_layer%d", il + 1), il + 1, il + 1, "");
218 m_hists_lADC[il]->SetTitle(Form("histmd_adc_layer%d", il));
219 float md_ladc = getHistMedian(m_hists_lADC[il]);
220 m_histmd_ladc->SetBinContent(il + 1, md_ladc);
221 }
222 // Draw canvas
223 c_histmd_ladc->Clear();
224 c_histmd_ladc->cd();
225 getHistStyle(m_histmd_ladc, "layeradc", 0);
226 double y_max = m_histmd_ladc->GetMaximum();
227 m_histmd_ladc->SetFillColor(kYellow);
228 m_histmd_ladc->SetMinimum(0);
229 m_histmd_ladc->SetMaximum(y_max * 1.20);
230 m_histmd_ladc->Draw("hist");
231 for (auto* line : m_lines) {
232 line->SetY2(y_max * 1.20);
233 line->Draw("same");
234 }
235 c_histmd_ladc->Update();
237 }
238
239 //2. get adc medians vs board ID
240 auto m_delta_adc = (TH2F*)getDelta(m_name_dir, m_hname_badc, 0, true); //true=only if updated
241 if (m_delta_adc) {
242 m_hist_adc->Reset();
243 int cadcgood = 0;
244 int cadcbad = 0;
245 double sumadcgood = 0;
246 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
247 if (ic == 0) continue; //299 boards only
248 if (m_hists_bADC[ic]) delete m_hists_bADC[ic];
249 m_hists_bADC[ic] = m_delta_adc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
250 m_hists_bADC[ic]->SetTitle(Form("histmd_adc_board%d", ic));
251 float md_adc = getHistMedian(m_hists_bADC[ic]);
252 m_hist_adc->SetBinContent(ic + 1, md_adc);
253 if (md_adc >= m_minadc && md_adc <= m_maxadc) {
254 sumadcgood = sumadcgood + md_adc;
255 cadcgood++;
256 } else cadcbad++;
257 }
258 double adcfrac = cadcgood / 2.99; // (100.0/299) in %
259 setEpicsPV("adcboards", adcfrac);
260 // Draw canvas
261 c_hist_adc->Clear();
262 c_hist_adc->cd();
263 if (cadcgood > 0)sumadcgood = sumadcgood * 1.0 / cadcgood;
264 getHistStyle(m_hist_adc, "adc", sumadcgood);
265 m_hist_adc->SetTitle(Form("ADC Medians: Bad board count = %d (%0.01f%%)", cadcbad - 1, 100.0 - adcfrac));
266 m_hist_adc->Draw("");
267 m_line_ladc->Draw("same");
268 m_line_hadc->Draw("same");
269 c_hist_adc->Update();
271 }
272
273 //3. get tdc medians vs board ID
274 auto m_delta_tdc = (TH2F*)getDelta(m_name_dir, m_hname_btdc, 0, true);
275 if (m_delta_tdc) {
276 m_hist_tdc->Reset();
277 int ctdcgood = 0;
278 int ctdcbad = 0;
279 double sumtdcgood = 0;
280 for (unsigned ic = 0; ic < kNumBoards; ++ic) {
281 if (ic == 0) continue; //299 boards only
282 if (m_hists_bTDC[ic]) delete m_hists_bTDC[ic];
283 m_hists_bTDC[ic] = m_delta_tdc->ProjectionY(Form("histmd_tdc_board%d", ic + 1), ic + 1, ic + 1, "");
284 m_hists_bTDC[ic]->SetTitle(Form("histmd_tdc_board%d", ic));
285 float md_tdc = getHistMedian(m_hists_bTDC[ic]);
286 m_hist_tdc->SetBinContent(ic + 1, md_tdc);
287 if (md_tdc >= m_mintdc && md_tdc <= m_maxtdc) {
288 ctdcgood++;
289 sumtdcgood = sumtdcgood + md_tdc;
290 } else ctdcbad++;
291 }
292 double tdcfrac = ctdcgood / 2.99;
293 setEpicsPV("tdcboards", tdcfrac);
294 c_hist_tdc->Clear();
295 c_hist_tdc->cd();
296 if (ctdcgood > 0)sumtdcgood = sumtdcgood * 1.0 / ctdcgood;
297 getHistStyle(m_hist_tdc, "tdc", sumtdcgood);
298 m_hist_tdc->SetTitle(Form("TDC Medians: Bad board count = %d (%0.01f%%)", ctdcbad - 1, 100.0 - tdcfrac));
299 m_hist_tdc->Draw("");
300 m_line_ltdc->Draw("same");
301 m_line_htdc->Draw("same");
302 c_hist_tdc->Update();
304 }
305
306 //get phi plots for various options
307 auto m_delta_skimphi = (TH2F*)getDelta(m_name_dir, m_hname_idxphi, 0, true); //true=only if updated
308 if (m_delta_skimphi) {
309 TString sip[2] = {"OffIP", "IP"};
310 TString sname[4] = {"all", "bhabha", "hadron", "mumutrk"};
311 for (int j = 0; j < 2; j++) { //ip selections
312 for (int i = 0; i < 4; i++) { //skim selections
313 int k = 4 * j + i; //0 to 7
314 TString hname = TString::Format("histphi_%s_%sevt", sip[j].Data(), sname[i].Data());
315 m_hist_skimphi[k] = m_delta_skimphi->ProjectionX(hname, k + 1, k + 1, "");
316 m_hist_skimphi[k]->SetTitle(TString::Format("cdc-track #phi (%s, %s-events);#phi;entries", sip[j].Data(), sname[i].Data()));
317 if (k < 4)m_hist_skimphi[k]->SetFillColor(kGray);
318 else m_hist_skimphi[k]->SetFillColor(kCyan);
319 c_hist_skimphi[k]->Clear();
320 c_hist_skimphi[k]->cd();
321 gPad->SetGridx(1);
322 gPad->SetGridy(1);
323 m_hist_skimphi[k]->Draw("hist");
324 }
325 }
326 }
327
328 //for CR shifter IP + all hadrons including alarm system
329 if (m_delta_skimphi) {
330 c_hist_crphi->Clear();
331 bool isFew = false, isAlarm = false, isWarn = false;
332 m_hist_crphi = m_delta_skimphi->ProjectionX("histphi_ip_hadrons", 7, 7, "");
333 m_hist_crphi->SetTitle("cdc-track #phi (IP + hadrons);cdc-track #phi;norm entries");
334 if (m_hist_crphi) {
335 double maxnow = m_hist_crphi->Integral();
336 if (maxnow > 0)m_hist_crphi->Scale(1.0 / maxnow);
337 if (maxnow < 10000) {
338 isFew = true;
339 } else {
340 if (m_histref_phiindex) {
341 m_hist_refphi = m_histref_phiindex->ProjectionX("histphi_ip_hadronsref", 7, 7, "");
342 double nbinref = m_hist_refphi->GetNbinsX();
343 double nbinnow = m_hist_crphi->GetNbinsX();
344 if (nbinref == nbinnow) { //same bins
345 double maxref = m_hist_refphi->Integral();
346 if (maxref > 0) {
347 m_hist_refphi->Scale(1.0 / maxref);
348 double maxphidiff = 0;
349 double maxphidiff_angle = 0;
350 for (int iphi = 0; iphi < nbinnow; iphi++) {
351 double icnow = m_hist_crphi->GetBinContent(iphi + 1);
352 double icref = m_hist_refphi->GetBinContent(iphi + 1);
353 double phidiff = fabs(icnow - icref);
354 if (phidiff > m_phiwarn)isWarn = true;
355 if (phidiff > m_phialarm)isAlarm = true;
356 if (phidiff > maxphidiff) {
357 maxphidiff = phidiff;
358 maxphidiff_angle = m_hist_crphi->GetBinLowEdge(iphi + 1) + m_hist_crphi->GetBinWidth(iphi + 1);
359 }
360 }
361 m_hist_crphi->SetTitle(Form("%s (diff = %0.03f at %0.1f)", m_hist_crphi->GetTitle(), maxphidiff, maxphidiff_angle));
362 }
363 }
364 }
365 }
366 }
367 c_hist_crphi->cd();
368 gPad->SetGridx(1);
369 gPad->SetGridy(1);
370 if (!m_histref_phiindex)m_hist_crphi->SetTitle(Form("%s (no ref file)", m_hist_crphi->GetTitle()));
371 m_hist_crphi->Draw("hist");
373 else if (isAlarm)colorizeCanvas(c_hist_crphi, c_StatusError);
376 c_hist_crphi->Update();
378 }
379
380 //get tracking efficiency
381 auto m_delta_effphi = (TH2F*)getDelta(m_name_dir, m_hname_effphi, 0, true); //true=only if updated
382 if (m_delta_effphi) {
383 c_hist_effphi->Clear();
384 double eff = -1;
385 const int all_phibins = m_delta_effphi->GetNbinsX();
386 const int all_hitbins = m_delta_effphi->GetNbinsY();
387 const int thr_hitbin = m_delta_effphi->GetYaxis()->FindBin(20);//min hits bin
388 for (int iphi = 0; iphi < all_phibins; iphi++) {
389 TH1D* temp = (TH1D*)m_delta_effphi->ProjectionY(Form("hhits_bin_%d", iphi + 1), iphi + 1, iphi + 1, "");
390 Double_t num = temp->Integral(thr_hitbin, all_hitbins);
391 Double_t den = temp->Integral();
392 if (den > 0)eff = num * 100.0 / den;
393 m_hist_effphi->SetBinContent(iphi + 1, eff);
394 m_hist_effphi->SetBinError(iphi + 1, 0);
395 delete temp;
396 }
397 m_hist_effphi->GetYaxis()->SetRangeUser(80.0, 110.0); //per efficiency
398 m_hist_effphi->SetTitle("CDC track efficiency(cdchits>20/all); cdc-track #phi; tracking efficiency");
399 c_hist_effphi->cd();
400 gPad->SetGridx();
401 gPad->SetGridy();
402 m_hist_effphi->SetFillColor(kCyan);
403 m_hist_effphi->Draw("hist");
404 c_hist_effphi->Update();
406 }
407
408 //get cdc hits vs phi
409 auto m_delta_hitphi = (TH2F*)getDelta(m_name_dir, m_hname_hitsphi, 0, true); //true=only if updated
410 if (m_delta_hitphi) {
411 c_hist_hitsphi->Clear();
412 m_delta_hitphi->SetTitle("CDC track #phi vs cdchits; cdc-track #phi; nCDCHits");
413 c_hist_hitsphi->cd();
414 m_delta_hitphi->Draw("COLZ");
415 c_hist_hitsphi->Update();
417 }
418
419 // get wire efficiency
420 double meanWireAttachProb = 0;
421 double fracWiresWithLowAttachProb = 0;
422 double fracWiresWithHighAttachProb = 0;
423 gStyle->SetNumberContours(100);
424 auto m_delta_efflay = (TH2F*)getDelta(m_name_dir, m_histoTrackingWireEff, 0, true); //true=only if updated
425 if (m_delta_efflay) {
426 for (int ij = 0; ij < 4; ij++) c_hist_attach_eff[ij]->Clear();
428 int nEffiValues = 0;
429 for (int ij = 1; ij <= m_delta_efflay->GetNbinsX(); ij++) {
430 int halfYbin = m_delta_efflay->GetNbinsY() / 2;
431 for (int jk = 0; jk < halfYbin; jk++) {
432 if (m_delta_efflay->GetBinContent(ij, jk + 1) == 0) continue;
433 double binEffi = m_delta_efflay->GetBinContent(ij, jk + halfYbin + 1) / m_delta_efflay->GetBinContent(ij, jk + 1);
434 m_hist_wire_attach_eff_1d->Fill(binEffi);
435 meanWireAttachProb += binEffi;
436 nEffiValues++;
437 }
438 }
439 if (nEffiValues) meanWireAttachProb /= nEffiValues;
442 else
444 TLatex latex;
445 latex.SetTextSize(0.025);
446 for (int ij = 0; ij < 3; ij++) {
447 c_hist_attach_eff[ij]->cd();
449 m_hist_attach_eff_Poly[ij]->SetStats(0);
450 m_hist_attach_eff_Poly[ij]->Draw("COLZ");
451 } else {
452 m_hist_attach_eff[ij]->SetStats(0);
453 m_hist_attach_eff[ij]->Draw("COLZ");
454 int isl = 0;
455 TEllipse* el[9];
456 for (int ilay = 0; ilay < 56; ilay++) {
457 int rmdr = int(abs(ilay - 2) % 6);
458 if ((rmdr == 0 && ilay > 2) || ilay == 55) {
459 isl++;
460 el[isl] = new TEllipse(0, 0, lbinEdges[ilay], lbinEdges[ilay]);
461 el[isl]->SetLineColor(kRed);
462 el[isl]->SetLineWidth(2);
463 el[isl]->SetFillStyle(0);
464 el[isl]->Draw("same");
465 }
466 }
467 }
468 if (ij == 2)
469 latex.DrawLatexNDC(0.12, 0.87, TString::Format("mean = %.3f%%", meanWireAttachProb * 100.0));
470 }
471 c_hist_attach_eff[3]->cd();
472 if (nEffiValues) {
473 int firstBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_firstEffBoundary) - 1;
474 fracWiresWithLowAttachProb = m_hist_wire_attach_eff_1d->Integral(1, firstBoundaryBin) / nEffiValues;
475 int secondBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_secondEffBoundary) - 1;
476 fracWiresWithHighAttachProb = m_hist_wire_attach_eff_1d->Integral(secondBoundaryBin + 1,
477 m_hist_wire_attach_eff_1d->GetNbinsX()) / nEffiValues;
478 m_hist_wire_attach_eff_1d->SetStats(0);
480 latex.DrawLatexNDC(0.15, 0.87, TString::Format("%06.3f%% wire : eff < %.2f",
481 fracWiresWithLowAttachProb * 100,
483 latex.DrawLatexNDC(0.15, 0.84, TString::Format("%06.3f%% wire : %.2f < eff < %.2f",
484 (1. - fracWiresWithHighAttachProb - fracWiresWithLowAttachProb) * 100,
486 latex.DrawLatexNDC(0.15, 0.81, TString::Format("%06.3f%% wire : %.2f < eff",
487 fracWiresWithHighAttachProb * 100,
489 }
490 for (int ij = 0; ij < 4; ij++) {
491 c_hist_attach_eff[ij]->Update();
493 }
494 }
495
496 m_monObj->setVariable("meanWireAttachProb", meanWireAttachProb);
497 m_monObj->setVariable("fracWiresWithLowAttachProb", fracWiresWithLowAttachProb);
498 m_monObj->setVariable("fracWiresWithHighAttachProb", fracWiresWithHighAttachProb);
499
500 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end event");
501}
502
503//------------------------------------
505{
506 for (auto* line : m_lines) delete line;
507 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end run");
508}
509
510
511//------------------------------------
513{
514 B2DEBUG(20, "DQMHistAnalysisCDCEpics: terminate called");
515}
516
517
518//------------------------------------
520{
521 TH1D* hist = (TH1D*)h->Clone();
522 hist->SetBinContent(1, 0.0); // Exclude 0-th bin
523 float median = 0.0;
524 if (hist->GetMean() != 0) {
525 // Avoid an error if only TCD/ADC=0 entries
526 double quantiles[1] = {0.0}; // One element to store median
527 double probSums[1] = {0.5}; // Median definition
528 hist->GetQuantiles(1, quantiles, probSums);
529 median = quantiles[0];
530 }
531 delete hist;
532 return median;
533}
534
535
536void DQMHistAnalysisCDCEpicsModule::fillEffiTH2(TH2F* hist, TH2F* attached, TH2F* expected, TH2F* efficiency)
537{
539 int nSLayers = cdcgeo.getNumberOfSenseLayers();
540
541 // Array to hold bin edges, with nSLayers + 1 edges needed for nSLayers bins
542 std::vector<double> binEdges(nSLayers + 1);
543 // Calculate r bin edges
544 double firstR = cdcgeo.senseWireR(0);
545 double secondR = cdcgeo.senseWireR(1);
546 binEdges[0] = firstR - (secondR - firstR) / 2;
547 lbinEdges[0] = firstR;
548 for (int lay = 1; lay < nSLayers; lay++) {
549 double prevR = cdcgeo.senseWireR(lay - 1);
550 double currentR = cdcgeo.senseWireR(lay);
551 binEdges[lay] = (prevR + currentR) / 2;
552 lbinEdges[lay] = currentR;
553 }
554 double lastR = cdcgeo.senseWireR(nSLayers - 1);
555 double secondLastR = cdcgeo.senseWireR(nSLayers - 2);
556 binEdges[nSLayers] = lastR + (lastR - secondLastR) / 2;
557 // convenient histogram to get layer number
558 TH1F layerHist("layerHist", "Layer Histogram", nSLayers, binEdges.data());
559
560 for (int binx = 1; binx <= efficiency->GetNbinsX(); binx++) {
561 for (int biny = 1; biny <= efficiency->GetNbinsY(); biny++) {
562 double bincenterx = efficiency->GetXaxis()->GetBinCenter(binx);
563 double bincentery = efficiency->GetYaxis()->GetBinCenter(biny);
564 double r = TMath::Sqrt(bincenterx * bincenterx + bincentery * bincentery);
565 double phi = TMath::ATan2(bincentery, bincenterx);
566 if (phi < 0) phi += 2 * TMath::Pi();
567
568 int layerBin = layerHist.FindBin(r); // Get the bin corresponding to r
569 if (layerBin < 1 || layerBin > nSLayers) continue;
570 int layerExpected = layerBin - 1;
571
572 int nWires = cdcgeo.nWiresInLayer(layerExpected);
573 double offset = cdcgeo.offset(layerExpected);
574 int wireExpected = phi * nWires / (2 * TMath::Pi()) - offset + 0.5;
575 if (wireExpected < 0) wireExpected += nWires;
576 if (wireExpected >= nWires) wireExpected -= nWires;
577
578 int expBin = hist->GetYaxis()->FindBin(layerExpected);
579 int obsBin = expBin + nSLayers;
580 expected->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, expBin));
581 attached->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, obsBin));
582 }
583 }
584 efficiency->Divide(attached, expected);
585}
586
587TH2Poly* DQMHistAnalysisCDCEpicsModule::createEffiTH2Poly(const TString& name, const TString& title)
588{
590 int nSLayers = cdcgeo.getNumberOfSenseLayers();
591 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
592 TH2Poly* hist = new TH2Poly(name, title, -maxLayerR * 1.02, maxLayerR * 1.02, -maxLayerR * 1.02, maxLayerR * 1.02);
593 for (int lay = 0; lay < nSLayers; lay++) {
594 int nWires = cdcgeo.nWiresInLayer(lay);
595 double offset = cdcgeo.offset(lay);
596 double layerR = cdcgeo.senseWireR(lay);
597 double r_inner = 0;
598 double r_outer = 0;
599 if (lay == 0) {
600 r_inner = layerR - (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
601 r_outer = layerR + (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
602 } else if (lay == nSLayers - 1) {
603 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
604 r_outer = layerR + (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
605 } else {
606 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
607 r_outer = layerR + (cdcgeo.senseWireR(lay + 1) - cdcgeo.senseWireR(lay)) / 2;
608 }
609 for (int wire = 0; wire < nWires; wire++) {
610 double phi_inner = (wire - 0.5 + offset) * 2 * TMath::Pi() / nWires;
611 double phi_outer = (wire + 0.5 + offset) * 2 * TMath::Pi() / nWires;
612 // Calculate the four corners of the bin
613 double x0 = r_inner * TMath::Cos(phi_inner);
614 double y0 = r_inner * TMath::Sin(phi_inner);
615 double x1 = r_outer * TMath::Cos(phi_inner);
616 double y1 = r_outer * TMath::Sin(phi_inner);
617 double x2 = r_outer * TMath::Cos(phi_outer);
618 double y2 = r_outer * TMath::Sin(phi_outer);
619 double x3 = r_inner * TMath::Cos(phi_outer);
620 double y3 = r_inner * TMath::Sin(phi_outer);
621 double xx[] = {x0, x1, x2, x3};
622 double yy[] = {y0, y1, y2, y3};
623 hist->AddBin(4, xx, yy);
624 }
625 }
626 return hist;
627}
628
629void DQMHistAnalysisCDCEpicsModule::fillEffiTH2Poly(TH2F* hist, TH2Poly* attached, TH2Poly* expected, TH2Poly* efficiency)
630{
631 attached->Reset("ICES");
632 expected->Reset("ICES");
634 int nSLayers = cdcgeo.getNumberOfSenseLayers();
635 for (int lay = 0; lay < nSLayers; lay++) {
636 int nWires = cdcgeo.nWiresInLayer(lay);
637 double layerR = cdcgeo.senseWireR(lay);
638 double offset = cdcgeo.offset(lay);
639 int expBin = hist->GetYaxis()->FindBin(lay);
640 int obsBin = expBin + nSLayers;
641 // fill the bins for this layer
642 for (int wire = 0; wire < nWires; wire++) {
643 double phi = (wire + offset) * 2 * TMath::Pi() / nWires;
644 double fillX = layerR * TMath::Cos(phi);
645 double fillY = layerR * TMath::Sin(phi);
646 attached->Fill(fillX, fillY, hist->GetBinContent(wire + 1, obsBin));
647 expected->Fill(fillX, fillY, hist->GetBinContent(wire + 1, expBin));
648 }
649 }
650 efficiency->Divide(attached, expected);
651}
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
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
double lbinEdges[kNumLayers]
vector for radius edge 56
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.