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
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_histoDir, "CDC Dir of DQM Histogram", std::string("CDC"));
26 addParam("HistADC", m_histoADC, "ADC Histogram Name", std::string("hADC"));
27 addParam("HistTDC", m_histoTDC, "TDC Histogram Name", std::string("hTDC"));
28 addParam("HistPhiIndex", m_histoPhiIndex, "Phi Index Histogram Name", std::string("hPhiIndex"));
29 addParam("HistPhiEff", m_histoPhiEff, "Phi Eff Histogram Name", std::string("hPhiEff"));
30 addParam("HistHitsPhi", m_histoHitsPhi, "Phi Hits Histogram Name", std::string("hPhiNCDC"));
31 addParam("HistTrackingWireEff", m_histoTrackingWireEff, "Wire Eff Histogram Name", std::string("hTrackingWireEff"));
32 addParam("PvPrefix", m_pvPrefix, "PV Prefix and Name", std::string("CDC:"));
33 addParam("RefFilePhi", m_refNamePhi, "Reference histogram file name", std::string("CDCDQM_PhiRef.root"));
34 addParam("RefDirectory", m_refDir, "Reference histogram dir", std::string("ref/CDC/default"));
35 addParam("MinEvt", m_minevt, "Min events for intra-run point", 1000);
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_hADCs[i] = nullptr;
42 m_hTDCs[i] = nullptr;
43 }
44 B2DEBUG(20, "DQMHistAnalysisCDCEpics: Constructor done.");
45}
46
48{
49}
50
52{
53 gROOT->cd();
54 c_hist_adc = new TCanvas("CDC/c_hist_adc", "c_hist_adc", 500, 400);
55 m_hist_adc = new TH1F("CDC/hist_adc", "m_hist_adc", 300, 0, 300);
56 m_hist_adc->SetTitle("ADC Medians; CDC board index; ADC medians");
57
58 c_hist_tdc = new TCanvas("CDC/c_hist_tdc", "c_hist_tdc", 500, 400);
59 m_hist_tdc = new TH1F("CDC/hist_tdc", "m_hist_tdc", 300, 0, 300);
60 m_hist_tdc->SetTitle("TDC Medians; CDC board index; TDC medians");
61
62 //array of various phi histograms
63 for (int ic = 0; ic < 8; ic++) {
64 c_hist_skimphi[ic] = new TCanvas(Form("CDC/c_hist_skimphi_c%d", ic), Form("hist_skimphi_c%d", ic), 500, 400);
65 }
66
67 c_hist_crphi = new TCanvas("CDC/c_hist_crphi", "c_hist_crphi", 500, 400);
68 c_hist_hitsphi = new TCanvas("CDC/c_hist_hitsphi", "c_hist_hitsphi", 500, 400);
69
70 //CR alram reference
71 if (m_refNamePhi != "") {
72 m_fileRefPhi = TFile::Open(m_refNamePhi.data(), "READ");
73 if (m_fileRefPhi && m_fileRefPhi->IsOpen()) {
74 B2INFO("DQMHistAnalysisCDCEpics: reference (" << m_refNamePhi << ") found OK");
75 m_histref_phiindex = (TH2F*)m_fileRefPhi->Get((m_refDir + "/hPhiIndex").data());
76 if (!m_histref_phiindex)B2INFO("\t .. but (histogram) not found");
77 else B2INFO("\t ..and (cdcdqm_phiref) also exist");
78 }
79 }
80
81 c_hist_effphi = new TCanvas("CDC/c_hist_effphi", "c_hist_effphi", 500, 400);
82 m_hist_effphi = new TH1D("CDC/hist_effphi", "m_hist_effphi", 360, -180.0, 180.0);
83
84 c_hist_attach_eff[0] = new TCanvas("CDC/c_hist_attached_wires", "c_hist_attached_wires", 403, 400);
85 c_hist_attach_eff[1] = new TCanvas("CDC/c_hist_expected_wires", "c_hist_expected_wires", 403, 400);
86 c_hist_attach_eff[2] = new TCanvas("CDC/c_hist_attach_eff", "c_hist_attach_eff", 403, 400);
87 c_hist_attach_eff[3] = new TCanvas("CDC/c_hist_attach_eff_1d", "c_hist_attach_eff_1d", 403, 400);
89 m_hist_attach_eff_Poly[0] = createEffiTH2Poly("CDC/hist_attachedWires",
90 "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin");
91 m_hist_attach_eff_Poly[0]->GetYaxis()->SetTitleOffset(1.4);
92 m_hist_attach_eff_Poly[0]->SetDirectory(gDirectory);
93 m_hist_attach_eff_Poly[1] = (TH2Poly*)m_hist_attach_eff_Poly[0]->Clone();
94 m_hist_attach_eff_Poly[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
95 m_hist_attach_eff_Poly[1]->SetDirectory(gDirectory);
96 m_hist_attach_eff_Poly[2] = (TH2Poly*)m_hist_attach_eff_Poly[0]->Clone();
97 m_hist_attach_eff_Poly[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
98 m_hist_attach_eff_Poly[2]->SetDirectory(gDirectory);
99 } else {
101 int nSLayers = cdcgeo.getNumberOfSenseLayers();
102 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
103 m_hist_attach_eff[0] = new TH2F("CDC/hist_attachedWires", "hist_attachedWires (backplate view);X [cm];Y [cm]; Track / bin",
104 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02,
105 nSLayers * 6, -maxLayerR * 1.02, maxLayerR * 1.02);
106 m_hist_attach_eff[0]->GetYaxis()->SetTitleOffset(1.4);
107 m_hist_attach_eff[1] = (TH2F*)m_hist_attach_eff[0]->Clone();
108 m_hist_attach_eff[1]->SetNameTitle("CDC/hist_expectedWires", "hist_expectedWires (backplate view);X [cm];Y [cm]; Track / bin");
109 m_hist_attach_eff[2] = (TH2F*)m_hist_attach_eff[0]->Clone();
110 m_hist_attach_eff[2]->SetNameTitle("CDC/hist_wireAttachEff", "hist_wireAttachEff (backplate view);X [cm];Y [cm]; Efficiency");
111 }
112 m_hist_wire_attach_eff_1d = new TH1F("CDC/hist_wire_attach_eff_1d", "hist_wire_attach_eff_1d;Wire Efficiency;Wire / bin",
113 208, -0.02, 1.02);
114 m_hist_wire_attach_eff_1d->GetYaxis()->SetTitleOffset(1.4);
115
117 addDeltaPar(m_histoDir, m_histoADC, HistDelta::c_Entries, m_minevt, 1);
118
120 addDeltaPar(m_histoDir, m_histoTDC, HistDelta::c_Entries, m_minevt, 1);
121
123 addDeltaPar(m_histoDir, m_histoPhiIndex, HistDelta::c_Entries, m_minevt, 1);
124
126 addDeltaPar(m_histoDir, m_histoPhiEff, HistDelta::c_Entries, m_minevt, 1);
127
129 addDeltaPar(m_histoDir, m_histoHitsPhi, HistDelta::c_Entries, m_minevt, 1);
130
132 addDeltaPar(m_histoDir, m_histoTrackingWireEff, HistDelta::c_Events, m_minevt, 1);
133
134 registerEpicsPV(m_pvPrefix + "cdcboards_wadc", "adcboards");
135 registerEpicsPV(m_pvPrefix + "cdcboards_wtdc", "tdcboards");
136
137 registerEpicsPV(m_pvPrefix + "adc_median_window", "adcmedianwindow");
138 registerEpicsPV(m_pvPrefix + "tdc_median_window", "tdcmedianwindow");
139
140 registerEpicsPV(m_pvPrefix + "phi_compare_window", "phicomparewindow");
141
143
144 B2DEBUG(20, "DQMHistAnalysisCDCEpics: initialized.");
145}
146
148{
149 double unused = 0;
150 requestLimitsFromEpicsPVs("adcmedianwindow", unused, m_minadc, m_maxadc, unused);
151 requestLimitsFromEpicsPVs("tdcmedianwindow", unused, m_mintdc, m_maxtdc, unused);
152 requestLimitsFromEpicsPVs("phicomparewindow", m_phialarm, m_phiwarn, unused, unused);
153
154 //in case if something is wrong in config file
155 if (std::isnan(m_minadc)) m_minadc = 60.0;
156 if (std::isnan(m_maxadc)) m_maxadc = 130.0;
157 if (std::isnan(m_mintdc)) m_mintdc = 4600.0;
158 if (std::isnan(m_maxtdc)) m_maxtdc = 5000.0;
159
160 if (std::isnan(m_phiwarn)) m_phiwarn = 0.05; //>%5 is warning
161 if (std::isnan(m_phialarm)) m_phialarm = 0.15; //>%15 is warning
162
163 //creating box for normal adc and tdc windows
164 m_line_ladc = new TLine(0, m_minadc, 300, m_minadc);
165 m_line_ladc->SetLineColor(kRed);
166 m_line_ladc->SetLineWidth(2);
167
168 m_line_hadc = new TLine(0, m_maxadc, 300, m_maxadc);
169 m_line_hadc->SetLineColor(kRed);
170 m_line_hadc->SetLineWidth(2);
171
172 m_line_ltdc = new TLine(0, m_mintdc, 300, m_mintdc);
173 m_line_ltdc->SetLineColor(kRed);
174 m_line_ltdc->SetLineWidth(2);
175
176 m_line_htdc = new TLine(0, m_maxtdc, 300, m_maxtdc);
177 m_line_htdc->SetLineColor(kRed);
178 m_line_htdc->SetLineWidth(2);
179
180 B2DEBUG(20, "DQMHistAnalysisCDCEpics: beginRun run called");
181}
182
184{
185 //get intra-run histogram from CDC DQM module
186 auto m_delta_adc = (TH2F*)getDelta(m_histoDir, m_histoADC, 0, true); //true=only if updated
187 if (m_delta_adc) {
188 m_hist_adc->Reset();
189 int cadcgood = 0;
190 int cadcbad = 0;
191 double sumadcgood = 0;
192 for (int ic = 0; ic < 300; ++ic) {
193 if (ic == 0) continue; //299 boards only
194 if (m_hADCs[ic]) delete m_hADCs[ic];
195 m_hADCs[ic] = m_delta_adc->ProjectionY(Form("hADC%d", ic + 1), ic + 1, ic + 1, "");
196 m_hADCs[ic]->SetTitle(Form("hADC%d", ic));
197 float md_adc = getHistMedian(m_hADCs[ic]);
198 m_hist_adc->SetBinContent(ic + 1, md_adc);
199 if (md_adc >= m_minadc && md_adc <= m_maxadc) {
200 sumadcgood = sumadcgood + md_adc;
201 cadcgood++;
202 } else cadcbad++;
203 }
204 double adcfrac = cadcgood / 2.99; // (100.0/299) in %
205 setEpicsPV("adcboards", adcfrac);
206 // Draw canvas
207 c_hist_adc->Clear();
208 c_hist_adc->cd();
209 if (cadcgood > 0)sumadcgood = sumadcgood * 1.0 / cadcgood;
210 getHistStyle(m_hist_adc, "adc", sumadcgood);
211 m_hist_adc->SetTitle(Form("ADC Medians: Bad board count = %d (%0.01f%%)", cadcbad - 1, 100.0 - adcfrac));
212 m_hist_adc->Draw("");
213 m_line_ladc->Draw("same");
214 m_line_hadc->Draw("same");
215 c_hist_adc->Update();
217 }
218
219 auto m_delta_tdc = (TH2F*)getDelta(m_histoDir, m_histoTDC, 0, true);
220 if (m_delta_tdc) {
221 m_hist_tdc->Reset();
222 int ctdcgood = 0;
223 int ctdcbad = 0;
224 double sumtdcgood = 0;
225 for (int ic = 0; ic < 300; ++ic) {
226 if (ic == 0) continue; //299 boards only
227 if (m_hTDCs[ic]) delete m_hTDCs[ic];
228 m_hTDCs[ic] = m_delta_tdc->ProjectionY(Form("hTDC%d", ic + 1), ic + 1, ic + 1, "");
229 m_hTDCs[ic]->SetTitle(Form("hTDC%d", ic));
230 float md_tdc = getHistMedian(m_hTDCs[ic]);
231 m_hist_tdc->SetBinContent(ic + 1, md_tdc);
232 if (md_tdc >= m_mintdc && md_tdc <= m_maxtdc) {
233 ctdcgood++;
234 sumtdcgood = sumtdcgood + md_tdc;
235 } else ctdcbad++;
236
237 }
238 double tdcfrac = ctdcgood / 2.99;
239 setEpicsPV("tdcboards", tdcfrac);
240 c_hist_tdc->Clear();
241 c_hist_tdc->cd();
242 if (ctdcgood > 0)sumtdcgood = sumtdcgood * 1.0 / ctdcgood;
243 getHistStyle(m_hist_tdc, "tdc", sumtdcgood);
244 m_hist_tdc->SetTitle(Form("TDC Medians: Bad board count = %d (%0.01f%%)", ctdcbad - 1, 100.0 - tdcfrac));
245 m_hist_tdc->Draw("");
246 m_line_ltdc->Draw("same");
247 m_line_htdc->Draw("same");
248 c_hist_tdc->Update();
250 }
251
252 //get phi plots for various options
253 auto m_delta_skimphi = (TH2F*)getDelta(m_histoDir, m_histoPhiIndex, 0, true); //true=only if updated
254 if (m_delta_skimphi) {
255 TString sip[2] = {"OffIP", "IP"};
256 TString sname[4] = {"all", "bhabha", "hadron", "mumutrk"};
257 for (int j = 0; j < 2; j++) { //ip selections
258 for (int i = 0; i < 4; i++) { //skim selections
259 int k = 4 * j + i; //0 to 7
260 TString hname = TString::Format("histphi_%s_%sevt", sip[j].Data(), sname[i].Data());
261 m_hist_skimphi[k] = m_delta_skimphi->ProjectionX(hname, k + 1, k + 1, "");
262 m_hist_skimphi[k]->SetTitle(TString::Format("cdc-track #phi (%s, %s-events);#phi;entries", sip[j].Data(), sname[i].Data()));
263 if (k < 4)m_hist_skimphi[k]->SetFillColor(kGray);
264 else m_hist_skimphi[k]->SetFillColor(kCyan);
265 c_hist_skimphi[k]->Clear();
266 c_hist_skimphi[k]->cd();
267 gPad->SetGridx(1);
268 gPad->SetGridy(1);
269 m_hist_skimphi[k]->Draw("hist");
270 }
271 }
272 }
273
274 //for CR shifter IP + all hadrons including alarm system
275 if (m_delta_skimphi) {
276 c_hist_crphi->Clear();
277 bool isFew = false, isAlarm = false, isWarn = false;
278 m_hist_crphi = m_delta_skimphi->ProjectionX("histphi_ip_hadrons", 7, 7, "");
279 m_hist_crphi->SetTitle("cdc-track #phi (IP + hadrons);cdc-track #phi;norm entries");
280 if (m_hist_crphi) {
281 double maxnow = m_hist_crphi->Integral();
282 m_hist_crphi->Scale(1.0 / maxnow);
283 if (maxnow < 10000) isFew = true;
284 else {
285 if (m_histref_phiindex) {
286 m_hist_refphi = m_histref_phiindex->ProjectionX("histphi_ip_hadronsref", 7, 7, "");
287 double nbinref = m_hist_refphi->GetNbinsX();
288 double nbinnow = m_hist_crphi->GetNbinsX();
289 if (nbinref == nbinnow) { //same bins
290 double maxref = m_hist_refphi->Integral();
291 m_hist_refphi->Scale(1.0 / maxref);
292 double maxphidiff = 0;
293 double maxphidiff_angle = 0;
294 for (int iphi = 0; iphi < nbinnow; iphi++) {
295 double icnow = m_hist_crphi->GetBinContent(iphi + 1);
296 double icref = m_hist_refphi->GetBinContent(iphi + 1);
297 double phidiff = fabs(icnow - icref);
298 if (phidiff > m_phiwarn)isWarn = true;
299 if (phidiff > m_phialarm)isAlarm = true;
300 if (phidiff > maxphidiff) {
301 maxphidiff = phidiff;
302 maxphidiff_angle = m_hist_crphi->GetBinLowEdge(iphi + 1) + m_hist_crphi->GetBinWidth(iphi + 1);
303 }
304 }
305 m_hist_crphi->SetTitle(Form("%s (diff = %0.03f at %0.1f)", m_hist_crphi->GetTitle(), maxphidiff, maxphidiff_angle));
306 }
307 }
308 }
309 }
310 c_hist_crphi->cd();
311 gPad->SetGridx(1);
312 gPad->SetGridy(1);
313 if (!m_histref_phiindex)m_hist_crphi->SetTitle(Form("%s (no ref file)", m_hist_crphi->GetTitle()));
314 m_hist_crphi->Draw("hist");
316 else if (isAlarm)colorizeCanvas(c_hist_crphi, c_StatusError);
319 c_hist_crphi->Update();
321 }
322
323 //get tracking efficiency
324 auto m_delta_effphi = (TH2F*)getDelta(m_histoDir, m_histoPhiEff, 0, true); //true=only if updated
325 if (m_delta_effphi) {
326 c_hist_effphi->Clear();
327 double eff = -1;
328 const int all_phibins = m_delta_effphi->GetNbinsX();
329 const int all_hitbins = m_delta_effphi->GetNbinsY();
330 const int thr_hitbin = m_delta_effphi->GetYaxis()->FindBin(20);//min hits bin
331 for (int iphi = 0; iphi < all_phibins; iphi++) {
332 TH1D* temp = (TH1D*)m_delta_effphi->ProjectionY(Form("hhits_bin_%d", iphi + 1), iphi + 1, iphi + 1, "");
333 Double_t num = temp->Integral(thr_hitbin, all_hitbins);
334 Double_t den = temp->Integral();
335 if (den > 0)eff = num * 100.0 / den;
336 m_hist_effphi->SetBinContent(iphi + 1, eff);
337 m_hist_effphi->SetBinError(iphi + 1, 0);
338 }
339 m_hist_effphi->GetYaxis()->SetRangeUser(80.0, 110.0); //per efficiency
340 m_hist_effphi->SetTitle("CDC track efficiency(cdchits>20/all); cdc-track #phi; tracking efficiency");
341 c_hist_effphi->cd();
342 gPad->SetGridx();
343 gPad->SetGridy();
344 m_hist_effphi->SetFillColor(kCyan);
345 m_hist_effphi->Draw("hist");
346 c_hist_effphi->Update();
348 }
349
350 //get cdc hits vs phi
351 auto m_delta_hitphi = (TH2F*)getDelta(m_histoDir, m_histoHitsPhi, 0, true); //true=only if updated
352 if (m_delta_hitphi) {
353 c_hist_hitsphi->Clear();
354 m_delta_hitphi->SetTitle("CDC track #phi vs cdchits; cdc-track #phi; nCDCHits");
355 c_hist_hitsphi->cd();
356 m_delta_hitphi->Draw("COLZ");
357 c_hist_hitsphi->Update();
359 }
360
361 // get wire efficiency
362 double meanWireAttachProb = 0;
363 double fracWiresWithLowAttachProb = 0;
364 double fracWiresWithHighAttachProb = 0;
365 gStyle->SetNumberContours(100);
366 auto m_delta_efflay = (TH2F*)getDelta(m_histoDir, m_histoTrackingWireEff, 0, true); //true=only if updated
367 if (m_delta_efflay) {
368 for (int ij = 0; ij < 4; ij++) c_hist_attach_eff[ij]->Clear();
370 int nEffiValues = 0;
371 for (int ij = 1; ij <= m_delta_efflay->GetNbinsX(); ij++) {
372 int halfYbin = m_delta_efflay->GetNbinsY() / 2;
373 for (int jk = 0; jk < halfYbin; jk++) {
374 if (m_delta_efflay->GetBinContent(ij, jk + 1) == 0) continue;
375 double binEffi = m_delta_efflay->GetBinContent(ij, jk + halfYbin + 1) / m_delta_efflay->GetBinContent(ij, jk + 1);
376 m_hist_wire_attach_eff_1d->Fill(binEffi);
377 meanWireAttachProb += binEffi;
378 nEffiValues++;
379 }
380 }
381 if (nEffiValues) meanWireAttachProb /= nEffiValues;
384 else
386 TLatex latex;
387 latex.SetTextSize(0.025);
388 for (int ij = 0; ij < 3; ij++) {
389 c_hist_attach_eff[ij]->cd();
391 m_hist_attach_eff_Poly[ij]->SetStats(0);
392 m_hist_attach_eff_Poly[ij]->Draw("COLZ");
393 } else {
394 m_hist_attach_eff[ij]->SetStats(0);
395 m_hist_attach_eff[ij]->Draw("COLZ");
396 }
397 if (ij == 2)
398 latex.DrawLatexNDC(0.12, 0.87, TString::Format("mean = %.3f%%", meanWireAttachProb * 100.0));
399 }
400 c_hist_attach_eff[3]->cd();
401 if (nEffiValues) {
402 int firstBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_firstEffBoundary) - 1;
403 fracWiresWithLowAttachProb = m_hist_wire_attach_eff_1d->Integral(1, firstBoundaryBin) / nEffiValues;
404 int secondBoundaryBin = m_hist_wire_attach_eff_1d->GetXaxis()->FindBin(m_secondEffBoundary) - 1;
405 fracWiresWithHighAttachProb = m_hist_wire_attach_eff_1d->Integral(secondBoundaryBin + 1,
406 m_hist_wire_attach_eff_1d->GetNbinsX()) / nEffiValues;
407 m_hist_wire_attach_eff_1d->SetStats(0);
409 latex.DrawLatexNDC(0.15, 0.87, TString::Format("%06.3f%% wire : eff < %.2f",
410 fracWiresWithLowAttachProb * 100,
412 latex.DrawLatexNDC(0.15, 0.84, TString::Format("%06.3f%% wire : %.2f < eff < %.2f",
413 (1. - fracWiresWithHighAttachProb - fracWiresWithLowAttachProb) * 100,
415 latex.DrawLatexNDC(0.15, 0.81, TString::Format("%06.3f%% wire : %.2f < eff",
416 fracWiresWithHighAttachProb * 100,
418 }
419 for (int ij = 0; ij < 4; ij++) {
420 c_hist_attach_eff[ij]->Update();
422 }
423 }
424
425 m_monObj->setVariable("meanWireAttachProb", meanWireAttachProb);
426 m_monObj->setVariable("fracWiresWithLowAttachProb", fracWiresWithLowAttachProb);
427 m_monObj->setVariable("fracWiresWithHighAttachProb", fracWiresWithHighAttachProb);
428
429 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end event");
430}
431
432//------------------------------------
434{
435 B2DEBUG(20, "DQMHistAnalysisCDCEpics: end run");
436}
437
438//------------------------------------
440{
441 TH1D* hist = (TH1D*)h->Clone();
442 hist->SetBinContent(1, 0.0); // Exclude 0-th bin
443 float median = 0.0;
444 if (hist->GetMean() != 0) {
445 // Avoid an error if only TCD/ADC=0 entries
446 double quantiles[1] = {0.0}; // One element to store median
447 double probSums[1] = {0.5}; // Median definition
448 hist->GetQuantiles(1, quantiles, probSums);
449 median = quantiles[0];
450 }
451 delete hist;
452 return median;
453}
454
455//------------------------------------
457{
458 B2DEBUG(20, "DQMHistAnalysisCDCEpics: terminate called");
459}
460
461void DQMHistAnalysisCDCEpicsModule::fillEffiTH2(TH2F* hist, TH2F* attached, TH2F* expected, TH2F* efficiency)
462{
464 int nSLayers = cdcgeo.getNumberOfSenseLayers();
465
466 // Array to hold bin edges, with nSLayers + 1 edges needed for nSLayers bins
467 std::vector<double> binEdges(nSLayers + 1);
468 // Calculate r bin edges
469 double firstR = cdcgeo.senseWireR(0);
470 double secondR = cdcgeo.senseWireR(1);
471 binEdges[0] = firstR - (secondR - firstR) / 2;
472 for (int lay = 1; lay < nSLayers; lay++) {
473 double prevR = cdcgeo.senseWireR(lay - 1);
474 double currentR = cdcgeo.senseWireR(lay);
475 binEdges[lay] = (prevR + currentR) / 2;
476 }
477 double lastR = cdcgeo.senseWireR(nSLayers - 1);
478 double secondLastR = cdcgeo.senseWireR(nSLayers - 2);
479 binEdges[nSLayers] = lastR + (lastR - secondLastR) / 2;
480 // convenient histogram to get layer number
481 TH1F layerHist("layerHist", "Layer Histogram", nSLayers, binEdges.data());
482
483 for (int binx = 1; binx <= efficiency->GetNbinsX(); binx++) {
484 for (int biny = 1; biny <= efficiency->GetNbinsY(); biny++) {
485 double bincenterx = efficiency->GetXaxis()->GetBinCenter(binx);
486 double bincentery = efficiency->GetYaxis()->GetBinCenter(biny);
487 double r = TMath::Sqrt(bincenterx * bincenterx + bincentery * bincentery);
488 double phi = TMath::ATan2(bincentery, bincenterx);
489 if (phi < 0) phi += 2 * TMath::Pi();
490
491 int layerBin = layerHist.FindBin(r); // Get the bin corresponding to r
492 if (layerBin < 1 || layerBin > nSLayers) continue;
493 int layerExpected = layerBin - 1;
494
495 int nWires = cdcgeo.nWiresInLayer(layerExpected);
496 double offset = cdcgeo.offset(layerExpected);
497 int wireExpected = phi * nWires / (2 * TMath::Pi()) - offset + 0.5;
498 if (wireExpected < 0) wireExpected += nWires;
499 if (wireExpected >= nWires) wireExpected -= nWires;
500
501 int expBin = hist->GetYaxis()->FindBin(layerExpected);
502 int obsBin = expBin + nSLayers;
503 expected->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, expBin));
504 attached->SetBinContent(binx, biny, hist->GetBinContent(wireExpected + 1, obsBin));
505 }
506 }
507 efficiency->Divide(attached, expected);
508}
509
510TH2Poly* DQMHistAnalysisCDCEpicsModule::createEffiTH2Poly(const TString& name, const TString& title)
511{
513 int nSLayers = cdcgeo.getNumberOfSenseLayers();
514 double maxLayerR = cdcgeo.senseWireR(nSLayers - 1);
515 TH2Poly* hist = new TH2Poly(name, title, -maxLayerR * 1.02, maxLayerR * 1.02, -maxLayerR * 1.02, maxLayerR * 1.02);
516 for (int lay = 0; lay < nSLayers; lay++) {
517 int nWires = cdcgeo.nWiresInLayer(lay);
518 double offset = cdcgeo.offset(lay);
519 double layerR = cdcgeo.senseWireR(lay);
520 double r_inner = 0;
521 double r_outer = 0;
522 if (lay == 0) {
523 r_inner = layerR - (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
524 r_outer = layerR + (cdcgeo.senseWireR(1) - cdcgeo.senseWireR(0)) / 2;
525 } else if (lay == nSLayers - 1) {
526 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
527 r_outer = layerR + (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
528 } else {
529 r_inner = layerR - (cdcgeo.senseWireR(lay) - cdcgeo.senseWireR(lay - 1)) / 2;
530 r_outer = layerR + (cdcgeo.senseWireR(lay + 1) - cdcgeo.senseWireR(lay)) / 2;
531 }
532 for (int wire = 0; wire < nWires; wire++) {
533 double phi_inner = (wire - 0.5 + offset) * 2 * TMath::Pi() / nWires;
534 double phi_outer = (wire + 0.5 + offset) * 2 * TMath::Pi() / nWires;
535 // Calculate the four corners of the bin
536 double x0 = r_inner * TMath::Cos(phi_inner);
537 double y0 = r_inner * TMath::Sin(phi_inner);
538 double x1 = r_outer * TMath::Cos(phi_inner);
539 double y1 = r_outer * TMath::Sin(phi_inner);
540 double x2 = r_outer * TMath::Cos(phi_outer);
541 double y2 = r_outer * TMath::Sin(phi_outer);
542 double x3 = r_inner * TMath::Cos(phi_outer);
543 double y3 = r_inner * TMath::Sin(phi_outer);
544 double xx[] = {x0, x1, x2, x3};
545 double yy[] = {y0, y1, y2, y3};
546 hist->AddBin(4, xx, yy);
547 }
548 }
549 return hist;
550}
551
552void DQMHistAnalysisCDCEpicsModule::fillEffiTH2Poly(TH2F* hist, TH2Poly* attached, TH2Poly* expected, TH2Poly* efficiency)
553{
554 attached->Reset("ICES");
555 expected->Reset("ICES");
557 int nSLayers = cdcgeo.getNumberOfSenseLayers();
558 for (int lay = 0; lay < nSLayers; lay++) {
559 int nWires = cdcgeo.nWiresInLayer(lay);
560 double layerR = cdcgeo.senseWireR(lay);
561 double offset = cdcgeo.offset(lay);
562 int expBin = hist->GetYaxis()->FindBin(lay);
563 int obsBin = expBin + nSLayers;
564 // fill the bins for this layer
565 for (int wire = 0; wire < nWires; wire++) {
566 double phi = (wire + offset) * 2 * TMath::Pi() / nWires;
567 double fillX = layerR * TMath::Cos(phi);
568 double fillY = layerR * TMath::Sin(phi);
569 attached->Fill(fillX, fillY, hist->GetBinContent(wire + 1, obsBin));
570 expected->Fill(fillX, fillY, hist->GetBinContent(wire + 1, expBin));
571 }
572 }
573 efficiency->Divide(attached, expected);
574}
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
std::string m_refDir
reference histogram dir of CDC DQMs
void initialize() override final
Initialize the Module.
double m_minadc
min adc median thershold accepted
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_histoADC
ADC histogram names of CDC DQMs.
std::string m_histoDir
histogram dir of CDC DQMs
void fillEffiTH2Poly(TH2F *hist, TH2Poly *attached, TH2Poly *expected, TH2Poly *efficiency)
Populate the efficiency histograms.
TH2Poly * createEffiTH2Poly(const TString &name, const TString &title)
Convenient function to create a TH2Poly based on CDC geometry.
std::string m_histoTDC
TDC histogram names of CDC DQMs.
double m_phiwarn
warn thershold for phi differences
std::string m_refNamePhi
reference histogram of phi
std::string m_histoTrackingWireEff
Wire Eff histogram names of CDC DQMs.
TFile * m_fileRefPhi
reference histogram file point
TLine * m_line_htdc
line for higher TDC window
double m_phialarm
alram thershold for phi differences
double m_maxadc
max adc median thershold accepted
TH1D * m_hTDCs[300]
TDC histograms with track associated hits for each board (0-299)
double m_maxtdc
max tdc median thershold accepted
void getHistStyle(TH1F *&htemp, std::string label, double max) const
get histogram styles
MonitoringObject * m_monObj
monitoring object
TCanvas * c_hist_crphi
canvas for control shifter phi
void terminate() override final
Termination action.
void event() override final
intra-run actions (EPICC PVs).
std::string m_histoPhiEff
Phi Eff histogram names of CDC DQMs.
TCanvas * c_hist_tdc
canvas for tdc board median
TH1D * m_hADCs[300]
ADC histograms with track associated hits for each board (0-299)
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_histoHitsPhi
Phi Hits histogram names of CDC DQMs.
void endRun() override final
End-of-run action.
std::string m_histoPhiIndex
Phi Inedx histogram names of CDC DQMs.
TLine * m_line_ltdc
line for lower TDC window
TLine * m_line_ladc
line for lower ADC window
void beginRun() override final
Called when entering a new run.
float getHistMedian(TH1D *h) const
Get median of given histogram.
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)
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.