9#include <cdc/calibration/CDCdEdx/CDCDedxCosineAlgorithm.h>
38 setDescription(
"A calibration algorithm for CDC dE/dx electron cos(theta) dependence");
51 B2FATAL(
"There is no valid previous payload for CDCDedxCosineCor");
53 B2INFO(
"Preparing dE/dx calibration for CDC dE/dx electron saturation");
58 B2ERROR(
"Input tree 'tree' not found");
63 double dedx, costh;
int charge;
64 ttree->SetBranchAddress(
"dedx", &dedx);
65 ttree->SetBranchAddress(
"costh", &costh);
66 ttree->SetBranchAddress(
"charge", &charge);
71 std::vector<TH1D*> hDedxCos_neg, hDedxCos_pos, hDedxCos_all;
84 for (
int i = 0; i < ttree->GetEntries(); ++i) {
89 if (dedx <= 0 || charge == 0)
continue;
92 if (costh < TMath::Cos(150 * TMath::DegToRad()) || costh > TMath::Cos(17 * TMath::DegToRad()))
continue;
94 int bin = int((costh -
m_cosMin) / binW);
95 if (bin < 0 || bin >=
static_cast<int>(
m_cosBin))
continue;
99 hCosth_neg->Fill(costh);
100 hDedxCos_neg[bin]->Fill(dedx);
101 }
else if (charge > 0) {
102 hCosth_pos->Fill(costh);
103 hDedxCos_pos[bin]->Fill(dedx);
106 hCosth_all->Fill(costh);
107 hDedxCos_all[bin]->Fill(dedx);
112 std::vector<double> cosine;
114 std::vector<std::vector<double>> dedxAll(4);
115 std::vector<std::vector<double>> dedxNeg(4);
116 std::vector<std::vector<double>> dedxPos(4);
118 for (
unsigned int i = 0; i <
m_cosBin; ++i) {
120 double meanDedx = 1.0;
123 double meanDedxErr = 0.0;
128 meanDedx = fitAll.
mean;
130 dedxAll[0].push_back(fitAll.
mean);
131 dedxAll[1].push_back(fitAll.
meanErr);
132 dedxAll[2].push_back(fitAll.
sigma);
133 dedxAll[3].push_back(fitAll.
sigmaErr);
143 if (fitPos.
status !=
"FitOK" && fitNeg.
status ==
"FitOK") {
145 hDedxCos_pos[i]->SetTitle(Form(
"%s, mean (manual) = elec left", hDedxCos_pos[i]->GetTitle()));
146 }
else if (fitNeg.
status !=
"FitOK" && fitPos.
status ==
"FitOK") {
148 hDedxCos_neg[i]->SetTitle(Form(
"%s, mean (manual) = posi right", hDedxCos_neg[i]->GetTitle()));
149 }
else if (fitNeg.
status !=
"FitOK" && fitPos.
status !=
"FitOK") {
154 dedxNeg[0].push_back(fitNeg.
mean);
155 dedxNeg[1].push_back(fitNeg.
meanErr);
156 dedxNeg[2].push_back(fitNeg.
sigma);
157 dedxNeg[3].push_back(fitNeg.
sigmaErr);
159 dedxPos[0].push_back(fitPos.
mean);
160 dedxPos[1].push_back(fitPos.
meanErr);
161 dedxPos[2].push_back(fitPos.
sigma);
162 dedxPos[3].push_back(fitPos.
sigmaErr);
164 meanDedx = 0.5 * (fitNeg.
mean + fitPos.
mean);
165 if (meanDedx <= 0.0) meanDedx = 1.0;
170 dedxAll[0].push_back(meanDedx);
171 dedxAll[1].push_back(meanDedxErr);
175 cosine.push_back(meanDedx);
210 if (cruns == 0) B2INFO(
"CDCDedxCosineCor: start exp " << expRun.first <<
" and run " << expRun.second <<
"");
215 int estart = erStart.first;
216 int rstart = erStart.second;
219 int rend = erEnd.second;
224 else m_suffix = Form(
"e%d_r%dr%d", estart, rstart, rend);
229 const std::string& chargeLabel)
236 for (
unsigned int i = 0; i <
m_cosBin; ++i) {
237 double coslow = i * binW +
m_cosMin;
238 double coshigh = coslow + binW;
242 hdedx[i]->SetTitle(Form(
"dE/dx dist (%s) in costh (%0.02f, %0.02f);dE/dx (no had sat, for %s);Entries", chargeLabel.c_str(), coslow,
243 coshigh, chargeLabel.c_str()));
253 hist->SetTitle(
"cos(#theta) dist (e- and e+); cos(#theta); Entries");
265 hist->SetFillColorAlpha(kAzure + 1, 0.30);
267 if (fitValues.
status ==
"FitOK") {
268 TF1* fitFunc = hist->GetFunction(
"gaus");
270 fitValues.
mean = fitFunc->GetParameter(1);
271 fitValues.
meanErr = fitFunc->GetParError(1);
272 fitValues.
sigma = fitFunc->GetParameter(2);
273 fitValues.
sigmaErr = fitFunc->GetParError(2);
275 std::string fitSummary = Form(
"#mu_{fit}: %0.03f #pm %0.03f, #sigma_{fit}: %0.03f",
278 hist->SetTitle(Form(
"%s, %s", hist->GetTitle(), fitSummary.data()));
288 if (temphist->Integral() < 2000) {
289 B2INFO(Form(
"\tThis hist (%s) have insufficient entries to perform fit (%0.03f)", temphist->GetName(), temphist->Integral()));
293 temphist->GetXaxis()->SetRange(temphist->FindFirstBinAbove(0, 1), temphist->FindLastBinAbove(0, 1));
294 int fs = temphist->Fit(
"gaus",
"QR");
296 B2INFO(Form(
"\tFit (round 1) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
297 status =
"FitFailed";
300 double meanDedx = temphist->GetFunction(
"gaus")->GetParameter(1);
301 double width = temphist->GetFunction(
"gaus")->GetParameter(2);
302 temphist->GetXaxis()->SetRangeUser(meanDedx - 5.0 * width, meanDedx + 5.0 * width);
303 fs = temphist->Fit(
"gaus",
"QR",
"", meanDedx -
m_sigLim * width, meanDedx +
m_sigLim * width);
305 B2INFO(Form(
"\tFit (round 2) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
306 status =
"FitFailed";
309 temphist->GetXaxis()->SetRangeUser(meanDedx - 5.0 * width, meanDedx + 5.0 * width);
310 B2INFO(Form(
"\tFit for hist (%s) sucessfull (status = %d)", temphist->GetName(), fs));
322 for (
unsigned int il = 0; il <
m_kNGroups; il++) {
327 B2ERROR(
"merging failed because of unmatch bins (old "
328 << nbins <<
" new " <<
m_cosBin <<
")");
332 for (
unsigned int ibin = 0; ibin < nbins; ibin++) {
334 double value = cosine[ibin];
341 B2INFO(
"Cosine Corr for " <<
m_label[il]
343 <<
", Previous = " << prev
344 <<
", Relative = " << cosine[ibin]
345 <<
", Merged = " << value);
353 B2INFO(
"dE/dx calibration done for CDC dE/dx electron saturation");
355 std::vector<unsigned int> layerToGroup(56);
357 for (
unsigned int layer = 0; layer < 56; layer++) {
358 if (layer < 8) layerToGroup[layer] = 0;
359 else if (layer < 14) layerToGroup[layer] = 1;
360 else layerToGroup[layer] = 2;
369 std::vector<TH1D*>& hDedxCos_neg,
370 std::vector<TH1D*>& hDedxCos_pos)
373 TCanvas ctmp(
"tmp",
"tmp", 1200, 1200);
376 unsigned int nPads = nx * ny;
379 std::stringstream psname;
381 psname << Form(
"cdcdedx_coscorr_dedx_%s.pdf[",
m_suffix.data());
382 ctmp.Print(psname.str().c_str());
384 psname << Form(
"cdcdedx_coscorr_dedx_%s.pdf",
m_suffix.data());
386 for (
unsigned int ic = 0; ic <
m_cosBin; ic++) {
388 ctmp.cd(ic % nPads + 1);
389 hDedxCos_all[ic]->SetStats(0);
390 hDedxCos_all[ic]->SetFillColorAlpha(kYellow, 0.25);
391 hDedxCos_all[ic]->DrawCopy();
393 if (ic % nPads == nPads - 1 || ic ==
m_cosBin - 1) {
394 ctmp.Print(psname.str().c_str());
402 hDedxCos_neg[ic]->SetFillColorAlpha(kRed, 0.25);
403 hDedxCos_neg[ic]->DrawCopy();
408 hDedxCos_pos[ic]->SetFillColorAlpha(kBlue, 0.25);
409 hDedxCos_pos[ic]->DrawCopy();
411 ctmp.Print(psname.str().c_str());
419 psname << Form(
"cdcdedx_coscorr_dedx_%s.pdf]",
m_suffix.data());
420 ctmp.Print(psname.str().c_str());
427 TCanvas ceadist(
"ceadist",
"Cosine distributions", 800, 600);
433 TLegend* leg =
new TLegend(0.6, 0.7, 0.8, 0.9);
436 hCosth_neg->SetLineColor(kRed);
437 hCosth_neg->SetFillColorAlpha(kYellow, 0.55);
438 hCosth_neg->SetStats(0);
439 hCosth_neg->Draw(
"hist");
440 leg->AddEntry(hCosth_neg,
"neg",
"f");
443 hCosth_pos->SetLineColor(kBlue);
444 hCosth_pos->SetFillColorAlpha(kGray, 0.35);
445 hCosth_pos->SetStats(0);
446 hCosth_pos->Draw(
"hist same");
447 leg->AddEntry(hCosth_pos,
"pos",
"f");
454 hCosth_all->SetFillColorAlpha(kGray, 0.25);
455 hCosth_all->SetLineColor(kGray);
456 hCosth_all->SetStats(0);
457 hCosth_all->Draw(
"hist");
461 ceadist.SaveAs(Form(
"cdcdedx_coscorr_cosine_%s.pdf",
m_suffix.data()));
462 ceadist.SaveAs(Form(
"cdcdedx_coscorr_cosine_%s.root",
m_suffix.data()));
468 const std::vector<std::vector<double>>& dedxNeg,
469 const std::vector<std::vector<double>>& dedxPos)
487 for (
unsigned int i = 0; i <
m_cosBin; i++) {
488 hMean_all->SetBinContent(i + 1, dedxAll[0][i]);
489 hMean_all->SetBinError(i + 1, dedxAll[1][i]);
492 hMean_el->SetBinContent(i + 1, dedxNeg[0][i]);
493 hMean_el->SetBinError(i + 1, dedxNeg[1][i]);
494 hSig_el->SetBinContent(i + 1, dedxNeg[2][i]);
495 hSig_el->SetBinError(i + 1, dedxNeg[3][i]);
497 hMean_po->SetBinContent(i + 1, dedxPos[0][i]);
498 hMean_po->SetBinError(i + 1, dedxPos[1][i]);
499 hSig_po->SetBinContent(i + 1, dedxPos[2][i]);
500 hSig_po->SetBinError(i + 1, dedxPos[3][i]);
502 hSig_all->SetBinContent(i + 1, dedxAll[2][i]);
503 hSig_all->SetBinError(i + 1, dedxAll[3][i]);
508 TCanvas* ctmp =
new TCanvas(
"c_fit",
"Mean & Sigma", 1000, 500);
513 setHist(hMean_all, kBlack,
"dedx rel(#mu_{fit}) for e- and e+ combined", 0.97, 1.04);
517 setHist(hMean_el, kRed,
"comparison of dedx #mu_{fit}^{rel}", 0.96, 1.04);
518 setHist(hMean_po, kBlue,
"", 0.96, 1.04);
520 hMean_el->Draw(
"E1");
521 hMean_po->Draw(
"E1 same");
522 hMean_all->Draw(
"E1 same");
525 hMean_all->Draw(
"E1");
531 setHist(hSig_all, kBlack,
"dedx rel(#sigma_{fit}) for e- and e+ combined", 0.05, 0.23);
535 setHist(hSig_el, kRed,
"comparison of dedx #sigma_{fit}^{rel}", 0.05, 0.23, 24);
536 setHist(hSig_po, kBlue,
"", 0.05, 0.23, 25);
539 hSig_po->Draw(
"E1 same");
542 hSig_all->Draw(
"E1");
544 B2INFO(
"Plotting finished ");
547 ctmp->SaveAs(Form(
"cdcdedx_coscorr_fit_%s.pdf",
m_suffix.data()));
561 const std::string pdfName =
562 Form(
"cdcdedx_coscorr_fconsts_%s.pdf",
m_suffix.data());
564 const std::string rootName =
565 Form(
"cdcdedx_coscorr_fconsts_%s.root",
m_suffix.data());
567 TFile rootFile(rootName.c_str(),
"RECREATE");
574 TH1D* hnew =
new TH1D(Form(
"hnew_%s",
m_label[il].data()), Form(
"Final const: %s;cos(#theta);dedx #mu_{fit}",
m_label[il].data()),
578 TH1D* hold =
new TH1D(Form(
"hold_%s",
m_label[il].data()), Form(
"Final const: %s;cos(#theta);dedx #mu_{fit}",
m_label[il].data()),
582 for (
unsigned int iea = 0; iea < nbins; iea++) {
586 hold->SetBinContent(iea + 1, oldv);
587 hnew->SetBinContent(iea + 1, newv);
591 TH1D* hratio =
static_cast<TH1D*
>(hnew->Clone(Form(
"hratio_%s",
m_label[il].data())));
592 hratio->Divide(hold);
594 TCanvas c(Form(
"c_%s",
m_label[il].data()), Form(
"Final constants %s",
m_label[il].data()), 1000, 500);
600 hnew->SetLineColor(kBlack);
602 hold->SetLineColor(kRed);
605 double min = std::min(hnew->GetMinimum(), hold->GetMinimum());
606 double max = std::max(hnew->GetMaximum(), hold->GetMaximum());
607 hnew->GetYaxis()->SetRangeUser(min * 0.95, max * 1.05);
610 hold->Draw(
"hist same");
612 auto leg =
new TLegend(0.6, 0.75, 0.85, 0.88);
613 leg->SetBorderSize(0);
614 leg->SetFillStyle(0);
615 leg->AddEntry(hnew,
"New",
"l");
616 leg->AddEntry(hold,
"Old",
"l");
621 hratio->SetLineColor(kBlue);
623 hratio->SetTitle(Form(
"Ratio: new/old, %s;cos(#theta); New / Old",
m_label[il].data()));
624 hratio->GetYaxis()->SetRangeUser(0.8, 1.2);
625 hratio->Draw(
"hist");
628 line->SetLineStyle(2);
634 c.Print((pdfName +
"(").c_str());
636 c.Print((pdfName +
")").c_str());
638 c.Print(pdfName.c_str());
657 TCanvas cstats(
"cstats",
"cstats", 1000, 500);
658 cstats.SetBatch(kTRUE);
664 hestats->SetName(Form(
"hestats_%s",
m_suffix.data()));
665 hestats->SetStats(0);
666 hestats->DrawCopy(
"");
672 htstats->SetName(Form(
"htstats_%s",
m_suffix.data()));
673 htstats->SetStats(0);
674 htstats->DrawCopy(
"");
676 cstats.Print(Form(
"cdcdedx_coscorr_stats_%s.pdf",
m_suffix.data()));
static void setHist(TH1D *h, int color, const char *title, double ymin, double ymax, int marker=20)
Set basic style (color, marker, title, y-range) for a TH1D histogram.
FitValues fitHistogram(TH1D *&hist)
Fit histogram with Gaussian and return mean, error, and width.
void getExpRunInfo()
function to extract calibration run/exp
TH1D * defineCosthHist(const std::string &tag)
function to define cosine histograms
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
void plotCosThetaDist(TH1D *hCosth_all, TH1D *hCosth_pos, TH1D *hCosth_neg)
Plot cos(theta) distributions for all, positive, and negative tracks.
bool isMergePayload
merge payload at the time of calibration
static unsigned int getRepresentativeLayer(unsigned int igroup)
Representative CDC layer for each SL group (used to access group-wise constants): SL0 => 1,...
std::string m_suffix
add suffix to all plot name
DBObjPtr< CDCDedxCosineCor > m_DBCosineCor
Electron saturation correction DB object.
void plotConstants()
function to draw the old/new final constants
CDCDedxCosineAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
void fitGaussianWithRange(TH1D *&temphist, TString &status)
function to fit histogram in each cosine bin
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.
void createPayload(const std::vector< double > &cosine)
function to store new payload after full calibration
double m_sigLim
gaussian fit sigma limit
void plotFitResults(const std::vector< std::vector< double > > &dedxAll, const std::vector< std::vector< double > > &dedxNeg, const std::vector< std::vector< double > > &dedxPos)
Plot dE/dx fit results for all, negative, and positive tracks.
void plotdedxHist(std::vector< TH1D * > &hDedxCos_all, std::vector< TH1D * > &hDedxCos_neg, std::vector< TH1D * > &hDedxCos_pos)
function to draw the dE/dx histogram in costh bins
bool isMethodSep
if e+ e- need to be consider sep
double m_dedxMax
max dedx range for gain cal
bool isMakePlots
produce plots for status
double m_dedxMin
min dedx range for gain cal
unsigned int m_cosBin
number of bins across cosine range
void defineHisto(std::vector< TH1D * > &hdedx, const std::string &tag, const std::string &chargeLabel)
function to define dE/dx histograms
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.
@ c_Failure
Failed =3 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.
Container for Gaussian fit results of a histogram.
double sigma
sigma : fitted width
double meanErr
meanErr : uncertainty on the mean
double sigmaErr
sigmaErr : uncertainty on the width
double mean
mean : fitted mean value
TString status
status : fit status flag (e.g.