Belle II Software development
CDCDedxCosLayerAlgorithm.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 <cdc/calibration/CDCdEdx/CDCDedxCosLayerAlgorithm.h>
10
11#include <TF1.h>
12#include <TLine.h>
13#include <TCanvas.h>
14#include <TH1I.h>
15#include <vector>
16
17using namespace Belle2;
18//-----------------------------------------------------------------
19// Implementation
20//-----------------------------------------------------------------
22 CalibrationAlgorithm("CDCDedxElectronCollector"),
23 isMethodSep(true),
24 isMakePlots(true),
25 isMerge(true),
26 isFixTrunc(false),
27 isUseTrunc(false),
28 m_truncMin(0.05),
29 m_truncMax(0.75),
30 m_cosBin(100),
31 m_cosMin(-1.0),
32 m_cosMax(1.0),
33 m_dedxBin(250),
34 m_dedxMin(0.0),
35 m_dedxMax(5.0),
36 m_suffix("")
37{
38 // Set module properties
39 setDescription("A calibration algorithm for CDC dE/dx electron cos(theta) dependence");
40
41}
42
43//-----------------------------------------------------------------
44// Run the calibration
45//-----------------------------------------------------------------
47{
48
50
51 if (!m_DBCosineCor.isValid())
52 B2FATAL("There is no valid previous payload for CDCDedxCosineCor");
53
54 B2INFO("Preparing dE/dx calibration for CDC dE/dx electron saturation");
55
56 // Get data objects
57 auto ttree = getObjectPtr<TTree>("tree");
58 if (ttree->GetEntries() < 100)return c_NotEnoughData;
59
60 std::vector<double>* lDedx = nullptr;
61 std::vector<int>* lLayer = nullptr;
62 double costh = 0.0;
63 int charge = 0;
64
65 ttree->SetBranchAddress("ldedx", &lDedx);
66 ttree->SetBranchAddress("lLayer", &lLayer);
67 ttree->SetBranchAddress("costh", &costh);
68 ttree->SetBranchAddress("charge", &charge);
69
70 // fill histograms, bin size may be arbitrary
71 TH1D* hCosth_neg = defineCosthHist("neg", "e-");
72 TH1D* hCosth_pos = defineCosthHist("pos", "e+");
73 TH1D* hCosth_all = defineCosthHist("all", "e-,e+");
74
75 std::array<std::vector<double>, m_kNGroups> corrFactor;
76
77 for (int ig = 0; ig < m_kNGroups; ig++) {
78 corrFactor[ig].assign(m_cosBin, 1.0);
79 }
80
81 constexpr int nIterations = 3;
82
83 for (int iter = 0; iter < nIterations; iter++) {
84
85 const bool isFirstIteration = (iter == 0);
86 const bool isFinalIteration = (iter == nIterations - 1);
87
88 const bool makeIterationSummary = isMakePlots && (isFirstIteration || isFinalIteration);
89
90 // make histograms to store dE/dx values in bins of cos(theta)
91 std::array<std::vector<TH1D*>, m_kNGroups> hDedxCos_neg;
92 std::array<std::vector<TH1D*>, m_kNGroups> hDedxCos_pos;
93 std::array<std::vector<TH1D*>, m_kNGroups> hDedxCos_all;
94
95 defineHisto(hDedxCos_neg, Form("neg_iter%d", iter), "e-");
96 defineHisto(hDedxCos_pos, Form("pos_iter%d", iter), "e+");
97 defineHisto(hDedxCos_all, Form("all_iter%d", iter), "e-,e+");
98
99 std::array<TH1D*, m_kNGroups> hDedxGroup{};
100 for (int il = 0; il < m_kNGroups; il++) {
101 std::string title = Form("dedxhit dist (%s); dedxhit;entries", m_label[il].data());
102 hDedxGroup[il] = new TH1D(Form("hDedxGroup_%s_%s_iter%d", m_label[il].data(), m_suffix.data(), iter), "", m_dedxBin, m_dedxMin,
103 m_dedxMax);
104 hDedxGroup[il]->SetTitle(title.c_str());
105 }
106
107 const double binW = (m_cosMax - m_cosMin) / m_cosBin;
108
109 for (int i = 0; i < ttree->GetEntries(); ++i) {
110
111 ttree->GetEvent(i);
112
113 if (!lDedx || !lLayer) continue;
114 if (lDedx->size() != lLayer->size()) continue;
115 if (charge == 0) continue;
116
117 if (costh < TMath::Cos(150 * TMath::DegToRad()) ||
118 costh > TMath::Cos(17 * TMath::DegToRad())) continue;
119
120 int bin = int((costh - m_cosMin) / binW);
121 if (bin < 0 || bin >= int(m_cosBin)) continue;
122
123 for (size_t j = 0; j < lDedx->size(); ++j) {
124
125 double val = lDedx->at(j);
126 int lay = lLayer->at(j);
127
128 if (val <= 0) continue;
129
130 int ig = (lay < 8) ? 0 : ((lay < 14) ? 1 : 2);
131
132 val /= corrFactor[ig][bin];
133
134 if (isMethodSep) {
135 if (charge < 0)
136 hDedxCos_neg[ig][bin]->Fill(val);
137 else if (charge > 0)
138 hDedxCos_pos[ig][bin]->Fill(val);
139
140 }
141 hDedxCos_all[ig][bin]->Fill(val);
142
143 hDedxGroup[ig]->Fill(val);
144
145 }
146 if (iter == 0) {
147 // costh histo
148 if (isMethodSep) {
149 if (charge < 0) hCosth_neg->Fill(costh);
150 else if (charge > 0) hCosth_pos->Fill(costh);
151 }
152 hCosth_all->Fill(costh);
153 }
154 }
155
156 std::array<std::vector<double>, m_kNGroups> cosine;
157 std::array<std::array<std::vector<double>, 3>, 3> cosMeanSets;
158 for (int il = 0; il < m_kNGroups; ++il) {
159
160 int minGroup = 0, maxGroup = 0;
161 std::vector<double> vmean_neg, vmean_pos;
162
163 if (isFixTrunc && isUseTrunc) {
164 getTruncatedBins(hDedxGroup[il], minGroup, maxGroup);
165 hDedxGroup[il]->SetTitle(
166 Form("%s;%d;%d", hDedxGroup[il]->GetTitle(), minGroup, maxGroup));
167 }
168
169 cosine[il].reserve(m_cosBin);
170
171 for (unsigned int ibin = 0; ibin < m_cosBin; ++ibin) {
172
173 double mean = 1.0;
174
175 if (isMethodSep) {
176
177 double mean_neg = extractCosMean(hDedxCos_neg[il][ibin], minGroup, maxGroup);
178 double mean_pos = extractCosMean(hDedxCos_pos[il][ibin], minGroup, maxGroup);
179
180 bool has_neg = (hDedxCos_neg[il][ibin]->Integral() > 0);
181 bool has_pos = (hDedxCos_pos[il][ibin]->Integral() > 0);
182
183 if (has_neg && has_pos) mean = 0.5 * (mean_neg + mean_pos);
184 else if (has_neg) mean = mean_neg;
185 else if (has_pos) mean = mean_pos;
186 vmean_neg.push_back(mean_neg);
187 vmean_pos.push_back(mean_pos);
188
189 } else {
190 mean = extractCosMean(hDedxCos_all[il][ibin], minGroup, maxGroup);
191 }
192
193 cosine[il].push_back(mean);
194 if (mean > 0) corrFactor[il][ibin] *= (mean / 1.25);
195 }
196 if (isMethodSep && makeIterationSummary) cosMeanSets[il] = {vmean_neg, vmean_pos, cosine[il]};
197
198 }
199
200 if (makeIterationSummary) {
201
202 //1. dE/dx dist. for cosine bins
203 plotdedxHist(hDedxCos_all, hDedxCos_neg, hDedxCos_pos, iter);
204 // 2. charge overlay plots
205 if (isMethodSep)
206 plotmeanChargeOverlay(cosMeanSets, iter);
207
208 //3. Inner and Outer layer dE/dx distributions
209 // plotLayerDist(hDedxGroup, iter);
210
211 //5. draw the relative constants
212 plotRelConst(corrFactor, iter);
213 }
214
215 // Cleanup
216 for (int il = 0; il < m_kNGroups; ++il) {
217 delete hDedxGroup[il];
218
219 for (auto* hist : hDedxCos_neg[il])
220 delete hist;
221
222 for (auto* hist : hDedxCos_pos[il])
223 delete hist;
224
225 for (auto* hist : hDedxCos_all[il])
226 delete hist;
227 }
228 }
229
230 for (int il = 0; il < m_kNGroups; ++il)
231 m_coscors.push_back(corrFactor[il]);
232
234
235 if (isMakePlots) {
236 //4. costh distribution
237 plotQaPars(hCosth_all, hCosth_pos, hCosth_neg);
238
239 //6. draw the final constants
241
242 //7. plot statistics related plots here
244
245 }
246
247
248 m_suffix.clear();
249 m_coscors.clear();
250 return c_OK;
251}
252
253//--------------------------------------------------
255{
256
257 int cruns = 0;
258 for (auto expRun : getRunList()) {
259 if (cruns == 0) B2INFO("CDCDedxBadWires: start exp " << expRun.first << " and run " << expRun.second << "");
260 cruns++;
261 }
262
263 const auto erStart = getRunList()[0];
264 int estart = erStart.first;
265 int rstart = erStart.second;
266
267 const auto erEnd = getRunList()[cruns - 1];
268 int eend = erEnd.first;
269 int rend = erEnd.second;
270
271 updateDBObjPtrs(1, rstart, estart);
272
273 m_runExp = Form("Range (%d:%d,%d:%d)", estart, rstart, eend, rend);
274 if (m_suffix.length() > 0) m_suffix = Form("%s_e%d_r%dr%d", m_suffix.data(), estart, rstart, rend);
275 else m_suffix = Form("e%d_r%dr%d", estart, rstart, rend);
276}
277
278//--------------------------------------------------
279TH1D* CDCDedxCosLayerAlgorithm::defineCosthHist(const std::string& tag, const std::string& chargeLabel)
280{
281
282 TH1D* hist = new TH1D(Form("hCosth_%s_%s", tag.c_str(), m_suffix.data()), " ", m_cosBin, m_cosMin, m_cosMax);
283 hist->SetTitle(Form("cos(#theta) dist (%s); cos(#theta); Entries", chargeLabel.c_str()));
284
285 return hist;
286}
287
288//--------------------------------------------------
289void CDCDedxCosLayerAlgorithm::defineHisto(std::array<std::vector<TH1D*>, m_kNGroups>& hdedx, const std::string& tag,
290 const std::string& chargeLabel)
291{
292
293 const double binW = (m_cosMax - m_cosMin) / m_cosBin;
294
295 for (int il = 0; il < m_kNGroups; il++) {
296 hdedx[il].reserve(m_cosBin);
297
298 for (unsigned int i = 0; i < m_cosBin; ++i) {
299 double coslow = i * binW + m_cosMin;
300 double coshigh = coslow + binW;
301
302 hdedx[il].push_back(new TH1D(Form("hDedxCos_%s_g%d_bin%d_%s", tag.c_str(), il, i, m_suffix.data()),
304
305 hdedx[il][i]->SetTitle(Form("%s dE/dx dist (%s) in costh (%0.02f, %0.02f)",
306 m_label[il].c_str(), chargeLabel.c_str(), coslow, coshigh));
307
308 hdedx[il][i]->GetXaxis()->SetTitle(" layer dE/dx");
309 hdedx[il][i]->GetYaxis()->SetTitle("Entries");
310 }
311 }
312}
313
314//--------------------------------------------------
316{
317
318 for (unsigned int il = 0; il < m_kNGroups; il++) {
319 if (isMerge) {
320 unsigned int nbins = m_DBCosineCor->getSize(getRepresentativeLayer(il));
321 if (nbins != m_cosBin)
322 B2ERROR("merging failed because of unmatch bins (old " << nbins << " new " << m_cosBin << ")");
323
324 for (unsigned int ibin = 0; ibin < nbins; ibin++) {
325 double prev = m_DBCosineCor->getMean(getRepresentativeLayer(il), ibin);
326 B2INFO("Cosine Corr for " << m_label[il] << " Bin # " << ibin << ", Previous = " << prev << ", Relative = " << m_coscors[il][ibin]
327 << ", Merged = " << prev * m_coscors[il][ibin]);
328 m_coscors[il][ibin] *= prev;
329
330 }
331 }
332 }
333
334 //Saving constants
335 B2INFO("dE/dx calibration done for CDC dE/dx electron saturation");
336
337 std::vector<unsigned int> layerToGroup(56);
338
339 for (unsigned int layer = 0; layer < 56; layer++) {
340 if (layer < 8) layerToGroup[layer] = 0; // SL0
341 else if (layer < 14) layerToGroup[layer] = 1; // SL1
342 else layerToGroup[layer] = 2; // SL2-8
343 }
344
345 CDCDedxCosineCor* gain = new CDCDedxCosineCor(m_coscors, layerToGroup);
346 saveCalibration(gain, "CDCDedxCosineCor");
347}
348
349//--------------------------------------------------
350void CDCDedxCosLayerAlgorithm::plotdedxHist(std::array<std::vector<TH1D*>, 3>& hDedxCos_all,
351 std::array<std::vector<TH1D*>, 3>& hDedxCos_neg,
352 std::array<std::vector<TH1D*>, 3>& hDedxCos_pos, int iter)
353{
354
355 TCanvas ctmp("tmp", "tmp", 1200, 1200);
356 int nx = isMethodSep ? 2 : 2;
357 int ny = isMethodSep ? 1 : 2;
358 unsigned int nPads = nx * ny;
359 if (isMethodSep) ctmp.SetCanvasSize(1200, 600);
360 ctmp.Divide(nx, ny);
361 std::stringstream psname;
362
363 psname << Form("cdcdedx_coscorr_ldedx_%s_iter%d.pdf[", m_suffix.data(), iter);
364 ctmp.Print(psname.str().c_str());
365 psname.str("");
366 psname << Form("cdcdedx_coscorr_ldedx_%s_iter%d.pdf", m_suffix.data(), iter);
367
368 for (int il = 0; il < m_kNGroups; il++) {
369
370 for (unsigned int ic = 0; ic < m_cosBin; ic++) {
371 if (!isMethodSep) {
372 ctmp.cd(ic % nPads + 1);
373 hDedxCos_all[il][ic]->SetFillColor(4 + il);
374
375 hDedxCos_all[il][ic]->DrawClone("hist");
376
377 if (ic % nPads == nPads - 1 || ic == m_cosBin - 1) {
378 ctmp.Print(psname.str().c_str());
379 gPad->Clear("D");
380 ctmp.Clear("D");
381 }
382 } else {
383
384 // left: electron
385 ctmp.cd(1);
386 hDedxCos_neg[il][ic]->SetFillColor(4 + il);
387 hDedxCos_neg[il][ic]->DrawCopy();
388
389
390 // right: positron
391 ctmp.cd(2);
392 hDedxCos_pos[il][ic]->SetFillColor(4 + il);
393 hDedxCos_pos[il][ic]->DrawCopy();
394
395 ctmp.Print(psname.str().c_str());
396 ctmp.Clear();
397 ctmp.Divide(nx, ny);
398
399 }
400 }
401 }
402 psname.str("");
403 psname << Form("cdcdedx_coscorr_ldedx_%s_iter%d.pdf]", m_suffix.data(), iter);
404 ctmp.Print(psname.str().c_str());
405}
406
407//--------------------------------------------------
408void CDCDedxCosLayerAlgorithm::plotLayerDist(std::array<TH1D*, 3>& hDedxGroup, int iter)
409{
410
411 TCanvas cdedxlayer(Form("layerdedxhit_iter%d", iter), "Inner and Outer Layer dedxhit dist", 2400, 800);
412 cdedxlayer.Divide(3, 1);
413
414 for (int il = 0; il < m_kNGroups; il++) {
415 int minlay = 0, maxlay = 0;
416 if (isFixTrunc) {
417 minlay = std::stoi(hDedxGroup[il]->GetXaxis()->GetTitle());
418 maxlay = std::stoi(hDedxGroup[il]->GetYaxis()->GetTitle());
419 double lowedge = hDedxGroup[il]->GetXaxis()->GetBinLowEdge(minlay);
420 double upedge = hDedxGroup[il]->GetXaxis()->GetBinUpEdge(maxlay);
421 hDedxGroup[il]->SetTitle(Form("%s, trunc #rightarrow: %0.02f - %0.02f;dedxhit;entries", hDedxGroup[il]->GetTitle(), lowedge,
422 upedge));
423 }
424
425 cdedxlayer.cd(il + 1);
426 hDedxGroup[il]->SetFillColor(kYellow);
427 hDedxGroup[il]->Draw("histo");
428
429 if (isFixTrunc) {
430 TH1D* hDedxGroupC = (TH1D*)hDedxGroup[il]->Clone(Form("hDedxGroupC%d", il));
431 hDedxGroupC->GetXaxis()->SetRange(minlay, maxlay);
432 hDedxGroupC->SetFillColor(kAzure + 1);
433 hDedxGroupC->Draw("same histo");
434 }
435 }
436
437 cdedxlayer.SaveAs(Form("cdcdedx_coscorr_dedxlay%s_iter%d.pdf", m_suffix.data(), iter));
438 cdedxlayer.SaveAs(Form("cdcdedx_coscorr_dedxlay%s_iter%d.root", m_suffix.data(), iter));
439}
440
441//--------------------------------------------------
442void CDCDedxCosLayerAlgorithm::plotQaPars(TH1D* hCosth_all, TH1D* hCosth_pos, TH1D* hCosth_neg)
443{
444
445 TCanvas ceadist("ceadist", "Cosine distributions", 800, 600);
446 ceadist.cd();
447
448 TLegend* leg = new TLegend(0.6, 0.7, 0.8, 0.9);
449
450 // Always draw ALL first
451 if (hCosth_all) {
452 hCosth_all->SetFillColor(kYellow);
453 hCosth_all->SetLineColor(kBlack);
454 hCosth_all->SetStats(0);
455 hCosth_all->Draw("hist");
456 leg->AddEntry(hCosth_all, "all", "f");
457 }
458
459 // If method separation, overlay pos/neg
460 if (isMethodSep) {
461
462 if (hCosth_pos) {
463 hCosth_pos->SetLineColor(kRed);
464 hCosth_pos->SetFillStyle(0);
465 hCosth_pos->SetStats(0);
466 hCosth_pos->Draw("hist same");
467 leg->AddEntry(hCosth_pos, "pos", "l");
468 }
469
470 if (hCosth_neg) {
471 hCosth_neg->SetLineColor(kBlue);
472 hCosth_neg->SetFillStyle(0);
473 hCosth_neg->SetStats(0);
474 hCosth_neg->Draw("hist same");
475 leg->AddEntry(hCosth_neg, "neg", "l");
476 }
477 }
478
479 leg->Draw();
480
481 ceadist.SaveAs(Form("cdcdedx_coscorr_cosine_%s.pdf", m_suffix.data()));
482 ceadist.SaveAs(Form("cdcdedx_coscorr_cosine_%s.root", m_suffix.data()));
483}
484
485//--------------------------------------------------
486void CDCDedxCosLayerAlgorithm::plotRelConst(const std::array<std::vector<double>, m_kNGroups>& cosine, int iter)
487{
488 TCanvas cconst("cconst", "calibration Constants", 800, 600);
489 cconst.cd();
490
491 TLegend* leg = new TLegend(0.6, 0.8, 0.9, 0.9);
492 leg->SetBorderSize(0);
493 leg->SetFillStyle(0);
494
495 std::vector<TH1D*> hists;
496 std::vector<int> colors = {kRed, kBlue, kBlack};
497 double ymax = 0.0;
498
499 for (int il = 0; il < m_kNGroups; il++) {
500
501 TH1D* h = new TH1D(Form("hconst_%d_%s", il, m_suffix.data()), "Relative constants; cos(#theta); constant", m_cosBin, m_cosMin,
502 m_cosMax);
503
504 // fill histogram
505 for (unsigned int jea = 0; jea < m_cosBin; jea++) {
506 if (jea < cosine[il].size())
507 h->SetBinContent(jea + 1, cosine[il].at(jea));
508 }
509
510 double hmax = h->GetMaximum();
511 if (hmax > ymax) ymax = hmax;
512
513
514 hists.push_back(h);
515 }
516
517 for (int il = 0; il < m_kNGroups; il++) {
518
519 hists[il]->SetLineColor(colors[il]);
520 hists[il]->SetStats(0);
521
522 // draw
523 if (il == 0) {
524 hists[il]->SetMaximum(ymax + 0.01);
525 hists[il]->Draw("hist");
526 } else {
527 hists[il]->Draw("hist same");
528 }
529
530 leg->AddEntry(hists[il], m_label[il].data(), "l");
531 }
532
533 leg->Draw();
534
535 cconst.SaveAs(Form("cdcdedx_coscorr_relconst_%s_iter%d.pdf", m_suffix.data(), iter));
536 cconst.SaveAs(Form("cdcdedx_coscorr_relconst_%s_iter%d.root", m_suffix.data(), iter));
537
538 // cleanup
539 for (auto h : hists) delete h;
540}
541
542//--------------------------------------------------
544{
545
546 const std::string pdfName =
547 Form("cdcdedx_coscorr_fconsts_%s.pdf", m_suffix.data());
548
549 const std::string rootName =
550 Form("cdcdedx_coscorr_fconsts_%s.root", m_suffix.data());
551
552 TFile rootFile(rootName.c_str(), "RECREATE");
553
554 for (int il = 0; il < m_kNGroups; il++) {
555
556 unsigned int nbins = m_DBCosineCor->getSize(getRepresentativeLayer(il));
557
558 // --- Create histograms ---
559 TH1D* hnew = new TH1D(Form("hnew_%s", m_label[il].data()), Form("Final const: %s", m_label[il].data()), m_cosBin, m_cosMin,
560 m_cosMax);
561
562 TH1D* hold = new TH1D(Form("hold_%s", m_label[il].data()), Form("Final const: %s", m_label[il].data()), m_cosBin, m_cosMin,
563 m_cosMax);
564
565 for (unsigned int iea = 0; iea < nbins; iea++) {
566 double oldv = m_DBCosineCor->getMean(getRepresentativeLayer(il), iea);
567 double newv = m_coscors[il][iea];
568
569 hold->SetBinContent(iea + 1, oldv);
570 hnew->SetBinContent(iea + 1, newv);
571 }
572
573 // --- Ratio ---
574 TH1D* hratio = (TH1D*)hnew->Clone(Form("hratio_%s", m_label[il].data()));
575 hratio->Divide(hold);
576
577 TCanvas c(Form("c_%s", m_label[il].data()), Form("Final constants %s", m_label[il].data()), 1000, 500);
578 c.Divide(2, 1);
579 c.cd(1);
580
581 hnew->SetLineColor(kBlack);
582 hnew->SetStats(0);
583 hold->SetLineColor(kRed);
584 hold->SetStats(0);
585
586 double min = std::min(hnew->GetMinimum(), hold->GetMinimum());
587 double max = std::max(hnew->GetMaximum(), hold->GetMaximum());
588 hnew->GetYaxis()->SetRangeUser(min * 0.95, max * 1.05);
589
590 hnew->Draw("hist");
591 hold->Draw("hist same");
592
593 auto leg = new TLegend(0.6, 0.75, 0.85, 0.88);
594 leg->SetBorderSize(0);
595 leg->SetFillStyle(0);
596 leg->AddEntry(hnew, "New", "l");
597 leg->AddEntry(hold, "Old", "l");
598 leg->Draw();
599
600 c.cd(2);
601
602 hratio->SetLineColor(kBlue);
603 hratio->SetStats(0);
604 hratio->SetTitle(Form("Ratio: new/old, %s;cos(#theta); New / Old", m_label[il].data()));
605 hratio->GetYaxis()->SetRangeUser(0.2, 1.2);
606 hratio->Draw("hist");
607
608 TLine* line = new TLine(m_cosMin, 1.0, m_cosMax, 1.0);
609 line->SetLineStyle(2);
610 line->Draw();
611
612 c.Update();
613
614 if (il == 0) {
615 c.Print((pdfName + "(").c_str());
616 } else if (il == m_kNGroups - 1) {
617 c.Print((pdfName + ")").c_str());
618 } else {
619 c.Print(pdfName.c_str());
620 }
621
622 // Save this canvas in the ROOT file
623 rootFile.cd();
624 c.Write();
625
626 // cleanup
627 delete hnew;
628 delete hold;
629 delete hratio;
630 delete line;
631 }
632}
633
634//--------------------------------------------------
635void CDCDedxCosLayerAlgorithm::plotmeanChargeOverlay(const std::array<std::array<std::vector<double>, 3>, 3>& mean, int iter)
636{
637
638 const std::string pdfName =
639 Form("cdcdedx_coscorr_relmean_%s_iter%d.pdf", m_suffix.data(), iter);
640
641 TCanvas cconst(Form("cconst_iter%d", iter), "calibration Constants", 800, 600);
642 cconst.cd();
643
644 std::array<std::string, 3> labels = {"e^{+}", "e^{-}", "Average"};
645 std::vector<int> colors = {kRed, kBlue, kBlack};
646
647 for (int isl = 0; isl < 3; isl++) {
648 cconst.Clear();
649 cconst.cd();
650
651 TLegend leg(0.60, 0.80, 0.90, 0.90);
652 leg.SetBorderSize(0);
653 leg.SetFillStyle(0);
654 std::vector<TH1D*> hists;
655 hists.reserve(3);
656
657 for (int icharge = 0; icharge < 3; icharge++) {
658
659 TH1D* h = new TH1D(Form("hconst_%d_%s_%s_iter%d", icharge, m_label[isl].c_str(), m_suffix.data(), iter),
660 Form("Relative mean %s, iter %d; cos(#theta); constant", m_label[isl].c_str(), iter),
662
663 for (unsigned int jea = 0; jea < m_cosBin; jea++) {
664 if (jea < mean[isl][icharge].size())
665 h->SetBinContent(jea + 1, mean[isl][icharge].at(jea));
666 }
667
668 h->SetLineColor(colors[icharge]);
669 h->SetStats(0);
670
671 h->Draw(icharge == 0 ? "hist" : "hist same");
672
673 leg.AddEntry(h, labels[icharge].c_str(), "l");
674 hists.push_back(h);
675 }
676
677 leg.Draw();
678 cconst.Modified();
679 cconst.Update();
680
681 // Save all SL plots into one multipage PDF
682 if (isl == 0) {
683 cconst.Print((pdfName + "(").c_str());
684 } else if (isl == 2) {
685 cconst.Print((pdfName + ")").c_str());
686 } else {
687 cconst.Print(pdfName.c_str());
688 }
689 // cconst.SaveAs(Form("cdcdedx_coscorr_relmean_iter%d_%s_%s.pdf", iter, sltag.c_str(), m_suffix.data()));
690 // cconst.SaveAs(Form("cdcdedx_coscorr_relmean_iter%d_%s_%s.root", iter, sltag.c_str(), m_suffix.data()));
691
692 for (auto h : hists) delete h;
693 }
694 // delete leg;
695}
696
697//------------------------------------
699{
700
701 TCanvas cstats("cstats", "cstats", 1000, 500);
702 cstats.SetBatch(kTRUE);
703 cstats.Divide(2, 1);
704
705 cstats.cd(1);
706 auto hestats = getObjectPtr<TH1I>("hestats");
707 if (hestats) {
708 hestats->SetName(Form("hestats_%s", m_suffix.data()));
709 hestats->SetStats(0);
710 hestats->DrawCopy("");
711 }
712
713 cstats.cd(2);
714 auto htstats = getObjectPtr<TH1I>("htstats");
715 if (htstats) {
716 htstats->SetName(Form("htstats_%s", m_suffix.data()));
717 htstats->SetStats(0);
718 htstats->DrawCopy("");
719 }
720 cstats.Print(Form("cdcdedx_coscorr_stats_%s.pdf", m_suffix.data()));
721}
722
723//--------------------------------------------------
724void CDCDedxCosLayerAlgorithm::getTruncatedBins(TH1D* hist, int& binlow, int& binhigh)
725{
726
727 //calculating truncation average
728 double sum = hist->Integral();
729 if (sum <= 0 || hist->GetNbinsX() <= 0) {
730 binlow = 1; binhigh = 1;
731 return ;
732 }
733
734 binlow = 1.0; binhigh = 1.0;
735 double sumPer5 = 0.0, sumPer75 = 0.0;
736 for (int ibin = 1; ibin <= hist->GetNbinsX(); ibin++) {
737 double bcdedx = hist->GetBinContent(ibin);
738 if (sumPer5 <= m_truncMin * sum) {
739 sumPer5 += bcdedx;
740 binlow = ibin;
741 }
742 if (sumPer75 <= m_truncMax * sum) {
743 sumPer75 += bcdedx;
744 binhigh = ibin;
745 }
746 }
747 return;
748}
749
750//--------------------------
751double CDCDedxCosLayerAlgorithm::getTruncationMean(TH1D* hist, int binlow, int binhigh)
752{
753
754 //calculating truncation average
755 if (hist->Integral() < 100) return 1.0;
756
757 if (binlow <= 0 || binhigh > hist->GetNbinsX())return 1.0;
758
759 double binweights = 0., sumofbc = 0.;
760 for (int ibin = binlow; ibin <= binhigh; ibin++) {
761 double bcdedx = hist->GetBinContent(ibin);
762 if (bcdedx > 0) {
763 binweights += (bcdedx * hist->GetBinCenter(ibin));
764 sumofbc += bcdedx;
765 }
766 }
767 if (sumofbc > 0) return binweights / sumofbc;
768 else return 1.0;
769}
770
771double CDCDedxCosLayerAlgorithm::extractCosMean(TH1D*& hist, int fixedLow, int fixedHigh)
772{
773 if (!hist || hist->Integral() <= 0) return 1.0;
774
775 // Default for SL0, SL1: simple mean
776 if (!isUseTrunc) {
777
778 hist->SetTitle(Form("%s, mean = %0.5f", hist->GetTitle(), hist->GetMean()));
779 return hist->GetMean();
780 }
781
782 int minbin = 1, maxbin = 1;
783 if (isFixTrunc) {
784 minbin = fixedLow;
785 maxbin = fixedHigh;
786 } else {
787 getTruncatedBins(hist, minbin, maxbin);
788 }
789
790 double mean = getTruncationMean(hist, minbin, maxbin);
791
792 hist->SetTitle(Form("%s, mean = %0.5f;%d;%d", hist->GetTitle(), mean, minbin, maxbin));
793
794 return mean;
795}
void plotRelConst(const std::array< std::vector< double >, m_kNGroups > &cosine, int iter)
Plot relative calibration constants vs costh for all SL groups (overlayed)
void plotQaPars(TH1D *hCosth_all, TH1D *hCosth_pos, TH1D *hCosth_neg)
function to costh distribution for Inner/Outer layer
double m_truncMax
upper threshold on truncation
void plotLayerDist(std::array< TH1D *, m_kNGroups > &hdedxlay, int iter)
function to draw dedx dist.
double m_truncMin
lower threshold on truncation
void getTruncatedBins(TH1D *hist, int &binlow, int &binhigh)
function to get bins of truncation from histogram
void defineHisto(std::array< std::vector< TH1D * >, m_kNGroups > &hdedx, const std::string &tag, const std::string &chargeLabel)
function to define dE/dx histograms
void getExpRunInfo()
function to get extract calibration run/exp
void plotdedxHist(std::array< std::vector< TH1D * >, 3 > &hDedxCos_all, std::array< std::vector< TH1D * >, 3 > &hDedxCos_neg, std::array< std::vector< TH1D * >, 3 > &hDedxCos_pos, int iter)
function to draw the dE/dx histogram in costh bins
static constexpr int m_kNGroups
SL grouping: inner (SL0), middle (SL1), outer (SL2–8)
int m_dedxBin
number of bins for dedx histogram
double m_cosMax
max cosine angle for cal
unsigned int getRepresentativeLayer(unsigned int igroup) const
Representative CDC layer for each SL group (used to access group-wise constants): SL0 => 1,...
CDCDedxCosLayerAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
TH1D * defineCosthHist(const std::string &tag, const std::string &chargeLabel)
function to define cosine histograms
std::string m_suffix
add suffix to all plot name
double extractCosMean(TH1D *&hist, int fixedLow=1, int fixedHigh=1)
Extract mean dE/dx vs costh for a given group from the histogram.
double getTruncationMean(TH1D *hist, int binlow, int binhigh)
function to get truncated mean
void plotmeanChargeOverlay(const std::array< std::array< std::vector< double >, 3 >, 3 > &mean, int iter)
Plot overlay of positive, negative, and average cosine means for one SL group.
DBObjPtr< CDCDedxCosineCor > m_DBCosineCor
Electron saturation correction DB object.
void plotConstants()
function to draw the old/new final constants
bool isFixTrunc
true = fix window for all out/inner layers
std::string m_runExp
add run and exp to title of plot
const std::array< std::string, m_kNGroups > m_label
add inner/outer superlayer label
double m_cosMin
min cosine angle for cal
void plotEventStats()
function to draw the stats plots
virtual EResult calibrate() override
Cosine algorithm.
bool isMethodSep
if e+e- need to be consider sep
double m_dedxMax
max dedx range for gain cal
void createPayload()
function to store new payload after full calibration
bool isMakePlots
produce plots for status
bool isMerge
merge payload at the of calibration
bool isUseTrunc
true if truncated mean for SL0,1
double m_dedxMin
min dedx range for gain cal
unsigned int m_cosBin
number of bins across cosine range
std::vector< std::vector< double > > m_coscors
final vectors of calibration
dE/dx cosine gain calibration constants
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
static void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
Abstract base class for different kinds of events.