9#include <cdc/calibration/CDCdEdx/CDCDedxCosLayerAlgorithm.h>
39 setDescription(
"A calibration algorithm for CDC dE/dx electron cos(theta) dependence");
52 B2FATAL(
"There is no valid previous payload for CDCDedxCosineCor");
54 B2INFO(
"Preparing dE/dx calibration for CDC dE/dx electron saturation");
60 std::vector<double>* lDedx =
nullptr;
61 std::vector<int>* lLayer =
nullptr;
65 ttree->SetBranchAddress(
"ldedx", &lDedx);
66 ttree->SetBranchAddress(
"lLayer", &lLayer);
67 ttree->SetBranchAddress(
"costh", &costh);
68 ttree->SetBranchAddress(
"charge", &charge);
75 std::array<std::vector<double>,
m_kNGroups> corrFactor;
78 corrFactor[ig].assign(
m_cosBin, 1.0);
81 constexpr int nIterations = 3;
83 for (
int iter = 0; iter < nIterations; iter++) {
85 const bool isFirstIteration = (iter == 0);
86 const bool isFinalIteration = (iter == nIterations - 1);
88 const bool makeIterationSummary =
isMakePlots && (isFirstIteration || isFinalIteration);
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;
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+");
99 std::array<TH1D*, m_kNGroups> hDedxGroup{};
101 std::string title = Form(
"dedxhit dist (%s); dedxhit;entries",
m_label[il].data());
104 hDedxGroup[il]->SetTitle(title.c_str());
109 for (
int i = 0; i < ttree->GetEntries(); ++i) {
113 if (!lDedx || !lLayer)
continue;
114 if (lDedx->size() != lLayer->size())
continue;
115 if (charge == 0)
continue;
117 if (costh < TMath::Cos(150 * TMath::DegToRad()) ||
118 costh > TMath::Cos(17 * TMath::DegToRad()))
continue;
120 int bin = int((costh -
m_cosMin) / binW);
121 if (bin < 0 || bin >=
int(
m_cosBin))
continue;
123 for (
size_t j = 0; j < lDedx->size(); ++j) {
125 double val = lDedx->at(j);
126 int lay = lLayer->at(j);
128 if (val <= 0)
continue;
130 int ig = (lay < 8) ? 0 : ((lay < 14) ? 1 : 2);
132 val /= corrFactor[ig][bin];
136 hDedxCos_neg[ig][bin]->Fill(val);
138 hDedxCos_pos[ig][bin]->Fill(val);
141 hDedxCos_all[ig][bin]->Fill(val);
143 hDedxGroup[ig]->Fill(val);
149 if (charge < 0) hCosth_neg->Fill(costh);
150 else if (charge > 0) hCosth_pos->Fill(costh);
152 hCosth_all->Fill(costh);
156 std::array<std::vector<double>,
m_kNGroups> cosine;
157 std::array<std::array<std::vector<double>, 3>, 3> cosMeanSets;
160 int minGroup = 0, maxGroup = 0;
161 std::vector<double> vmean_neg, vmean_pos;
165 hDedxGroup[il]->SetTitle(
166 Form(
"%s;%d;%d", hDedxGroup[il]->GetTitle(), minGroup, maxGroup));
171 for (
unsigned int ibin = 0; ibin <
m_cosBin; ++ibin) {
177 double mean_neg =
extractCosMean(hDedxCos_neg[il][ibin], minGroup, maxGroup);
178 double mean_pos =
extractCosMean(hDedxCos_pos[il][ibin], minGroup, maxGroup);
180 bool has_neg = (hDedxCos_neg[il][ibin]->Integral() > 0);
181 bool has_pos = (hDedxCos_pos[il][ibin]->Integral() > 0);
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);
190 mean =
extractCosMean(hDedxCos_all[il][ibin], minGroup, maxGroup);
193 cosine[il].push_back(mean);
194 if (mean > 0) corrFactor[il][ibin] *= (mean / 1.25);
196 if (
isMethodSep && makeIterationSummary) cosMeanSets[il] = {vmean_neg, vmean_pos, cosine[il]};
200 if (makeIterationSummary) {
203 plotdedxHist(hDedxCos_all, hDedxCos_neg, hDedxCos_pos, iter);
217 delete hDedxGroup[il];
219 for (
auto* hist : hDedxCos_neg[il])
222 for (
auto* hist : hDedxCos_pos[il])
225 for (
auto* hist : hDedxCos_all[il])
237 plotQaPars(hCosth_all, hCosth_pos, hCosth_neg);
259 if (cruns == 0) B2INFO(
"CDCDedxBadWires: start exp " << expRun.first <<
" and run " << expRun.second <<
"");
264 int estart = erStart.first;
265 int rstart = erStart.second;
268 int eend = erEnd.first;
269 int rend = erEnd.second;
273 m_runExp = Form(
"Range (%d:%d,%d:%d)", estart, rstart, eend, rend);
275 else m_suffix = Form(
"e%d_r%dr%d", estart, rstart, rend);
283 hist->SetTitle(Form(
"cos(#theta) dist (%s); cos(#theta); Entries", chargeLabel.c_str()));
290 const std::string& chargeLabel)
298 for (
unsigned int i = 0; i <
m_cosBin; ++i) {
299 double coslow = i * binW +
m_cosMin;
300 double coshigh = coslow + binW;
302 hdedx[il].push_back(
new TH1D(Form(
"hDedxCos_%s_g%d_bin%d_%s", tag.c_str(), il, i,
m_suffix.data()),
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));
308 hdedx[il][i]->GetXaxis()->SetTitle(
" layer dE/dx");
309 hdedx[il][i]->GetYaxis()->SetTitle(
"Entries");
318 for (
unsigned int il = 0; il <
m_kNGroups; il++) {
322 B2ERROR(
"merging failed because of unmatch bins (old " << nbins <<
" new " <<
m_cosBin <<
")");
324 for (
unsigned int ibin = 0; ibin < nbins; 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]);
335 B2INFO(
"dE/dx calibration done for CDC dE/dx electron saturation");
337 std::vector<unsigned int> layerToGroup(56);
339 for (
unsigned int layer = 0; layer < 56; layer++) {
340 if (layer < 8) layerToGroup[layer] = 0;
341 else if (layer < 14) layerToGroup[layer] = 1;
342 else layerToGroup[layer] = 2;
351 std::array<std::vector<TH1D*>, 3>& hDedxCos_neg,
352 std::array<std::vector<TH1D*>, 3>& hDedxCos_pos,
int iter)
355 TCanvas ctmp(
"tmp",
"tmp", 1200, 1200);
358 unsigned int nPads = nx * ny;
361 std::stringstream psname;
363 psname << Form(
"cdcdedx_coscorr_ldedx_%s_iter%d.pdf[",
m_suffix.data(), iter);
364 ctmp.Print(psname.str().c_str());
366 psname << Form(
"cdcdedx_coscorr_ldedx_%s_iter%d.pdf",
m_suffix.data(), iter);
370 for (
unsigned int ic = 0; ic <
m_cosBin; ic++) {
372 ctmp.cd(ic % nPads + 1);
373 hDedxCos_all[il][ic]->SetFillColor(4 + il);
375 hDedxCos_all[il][ic]->DrawClone(
"hist");
377 if (ic % nPads == nPads - 1 || ic ==
m_cosBin - 1) {
378 ctmp.Print(psname.str().c_str());
386 hDedxCos_neg[il][ic]->SetFillColor(4 + il);
387 hDedxCos_neg[il][ic]->DrawCopy();
392 hDedxCos_pos[il][ic]->SetFillColor(4 + il);
393 hDedxCos_pos[il][ic]->DrawCopy();
395 ctmp.Print(psname.str().c_str());
403 psname << Form(
"cdcdedx_coscorr_ldedx_%s_iter%d.pdf]",
m_suffix.data(), iter);
404 ctmp.Print(psname.str().c_str());
411 TCanvas cdedxlayer(Form(
"layerdedxhit_iter%d", iter),
"Inner and Outer Layer dedxhit dist", 2400, 800);
412 cdedxlayer.Divide(3, 1);
415 int minlay = 0, maxlay = 0;
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,
425 cdedxlayer.cd(il + 1);
426 hDedxGroup[il]->SetFillColor(kYellow);
427 hDedxGroup[il]->Draw(
"histo");
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");
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));
445 TCanvas ceadist(
"ceadist",
"Cosine distributions", 800, 600);
448 TLegend* leg =
new TLegend(0.6, 0.7, 0.8, 0.9);
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");
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");
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");
481 ceadist.SaveAs(Form(
"cdcdedx_coscorr_cosine_%s.pdf",
m_suffix.data()));
482 ceadist.SaveAs(Form(
"cdcdedx_coscorr_cosine_%s.root",
m_suffix.data()));
488 TCanvas cconst(
"cconst",
"calibration Constants", 800, 600);
491 TLegend* leg =
new TLegend(0.6, 0.8, 0.9, 0.9);
492 leg->SetBorderSize(0);
493 leg->SetFillStyle(0);
495 std::vector<TH1D*> hists;
496 std::vector<int> colors = {kRed, kBlue, kBlack};
501 TH1D* h =
new TH1D(Form(
"hconst_%d_%s", il,
m_suffix.data()),
"Relative constants; cos(#theta); constant",
m_cosBin,
m_cosMin,
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));
510 double hmax = h->GetMaximum();
511 if (hmax > ymax) ymax = hmax;
519 hists[il]->SetLineColor(colors[il]);
520 hists[il]->SetStats(0);
524 hists[il]->SetMaximum(ymax + 0.01);
525 hists[il]->Draw(
"hist");
527 hists[il]->Draw(
"hist same");
530 leg->AddEntry(hists[il],
m_label[il].data(),
"l");
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));
539 for (
auto h : hists)
delete h;
546 const std::string pdfName =
547 Form(
"cdcdedx_coscorr_fconsts_%s.pdf",
m_suffix.data());
549 const std::string rootName =
550 Form(
"cdcdedx_coscorr_fconsts_%s.root",
m_suffix.data());
552 TFile rootFile(rootName.c_str(),
"RECREATE");
565 for (
unsigned int iea = 0; iea < nbins; iea++) {
569 hold->SetBinContent(iea + 1, oldv);
570 hnew->SetBinContent(iea + 1, newv);
574 TH1D* hratio = (TH1D*)hnew->Clone(Form(
"hratio_%s",
m_label[il].data()));
575 hratio->Divide(hold);
577 TCanvas c(Form(
"c_%s",
m_label[il].data()), Form(
"Final constants %s",
m_label[il].data()), 1000, 500);
581 hnew->SetLineColor(kBlack);
583 hold->SetLineColor(kRed);
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);
591 hold->Draw(
"hist same");
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");
602 hratio->SetLineColor(kBlue);
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");
609 line->SetLineStyle(2);
615 c.Print((pdfName +
"(").c_str());
617 c.Print((pdfName +
")").c_str());
619 c.Print(pdfName.c_str());
638 const std::string pdfName =
639 Form(
"cdcdedx_coscorr_relmean_%s_iter%d.pdf",
m_suffix.data(), iter);
641 TCanvas cconst(Form(
"cconst_iter%d", iter),
"calibration Constants", 800, 600);
644 std::array<std::string, 3> labels = {
"e^{+}",
"e^{-}",
"Average"};
645 std::vector<int> colors = {kRed, kBlue, kBlack};
647 for (
int isl = 0; isl < 3; isl++) {
651 TLegend leg(0.60, 0.80, 0.90, 0.90);
652 leg.SetBorderSize(0);
654 std::vector<TH1D*> hists;
657 for (
int icharge = 0; icharge < 3; icharge++) {
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),
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));
668 h->SetLineColor(colors[icharge]);
671 h->Draw(icharge == 0 ?
"hist" :
"hist same");
673 leg.AddEntry(h, labels[icharge].c_str(),
"l");
683 cconst.Print((pdfName +
"(").c_str());
684 }
else if (isl == 2) {
685 cconst.Print((pdfName +
")").c_str());
687 cconst.Print(pdfName.c_str());
692 for (
auto h : hists)
delete h;
701 TCanvas cstats(
"cstats",
"cstats", 1000, 500);
702 cstats.SetBatch(kTRUE);
708 hestats->SetName(Form(
"hestats_%s",
m_suffix.data()));
709 hestats->SetStats(0);
710 hestats->DrawCopy(
"");
716 htstats->SetName(Form(
"htstats_%s",
m_suffix.data()));
717 htstats->SetStats(0);
718 htstats->DrawCopy(
"");
720 cstats.Print(Form(
"cdcdedx_coscorr_stats_%s.pdf",
m_suffix.data()));
728 double sum = hist->Integral();
729 if (sum <= 0 || hist->GetNbinsX() <= 0) {
730 binlow = 1; binhigh = 1;
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);
755 if (hist->Integral() < 100)
return 1.0;
757 if (binlow <= 0 || binhigh > hist->GetNbinsX())
return 1.0;
759 double binweights = 0., sumofbc = 0.;
760 for (
int ibin = binlow; ibin <= binhigh; ibin++) {
761 double bcdedx = hist->GetBinContent(ibin);
763 binweights += (bcdedx * hist->GetBinCenter(ibin));
767 if (sumofbc > 0)
return binweights / sumofbc;
773 if (!hist || hist->Integral() <= 0)
return 1.0;
778 hist->SetTitle(Form(
"%s, mean = %0.5f", hist->GetTitle(), hist->GetMean()));
779 return hist->GetMean();
782 int minbin = 1, maxbin = 1;
792 hist->SetTitle(Form(
"%s, mean = %0.5f;%d;%d", hist->GetTitle(), mean, minbin, maxbin));
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.