14#include <reconstruction/calibration/CDCdEdx/CDCDedxCosEdgeAlgorithm.h>
38 setDescription(
"A calibration algorithm for CDC dE/dx electron cos(theta) dependence");
50 auto ttree = getObjectPtr<TTree>(
"tree");
53 double dedx, costh;
int charge;
54 ttree->SetBranchAddress(
"dedx", &dedx);
55 ttree->SetBranchAddress(
"costh", &costh);
56 ttree->SetBranchAddress(
"charge", &charge);
59 vector<TH1D*> hdedx_negi, hdedx_posi;
64 for (
unsigned int i = 0; i <
m_npBins; ++i) {
66 double mincos = i * bwposi +
m_posMin;
67 double maxcos = mincos + bwposi;
68 string title = Form(
"costh: %0.04f, %0.04f(%s)", mincos, maxcos,
m_suffix.data());
70 hdedx_posi[i]->SetTitle(Form(
"%s;dedx;entries", title.data()));
73 maxcos = mincos + bwnegi;
74 title = Form(
"costh: %0.04f, %0.04f(%s)", mincos, maxcos,
m_suffix.data());
76 hdedx_negi[i]->SetTitle(Form(
"%s;dedx;entries", title.data()));
80 for (
int i = 0; i < ttree->GetEntries(); ++i) {
85 if (dedx <= 0 || charge == 0)
continue;
86 if (costh > -0.850 && costh < 0.950)
continue;
89 icosbin = int((costh -
m_posMin) / bwposi);
90 hdedx_posi[icosbin]->Fill(dedx);
91 }
else if (costh < 0) {
92 icosbin = int((costh -
m_negMin) / bwnegi);
93 hdedx_negi[icosbin]->Fill(dedx);
97 map<int, vector<double>> vneg_fitpars;
98 map<int, vector<double>> vpos_fitpars;
100 vector<double> vneg_const, vpos_const;
101 vector<vector<double>> vfinal_const;
103 for (
unsigned int i = 0; i <
m_npBins; ++i) {
109 if (status != FitOK) {
110 vneg_fitpars[0].push_back(1.0);
111 vneg_fitpars[1].push_back(0.0);
112 vneg_fitpars[2].push_back(0.0);
113 vneg_fitpars[3].push_back(0.0);
114 hdedx_negi[i]->SetTitle(Form(
"%s, Fit(%d)", hdedx_negi[i]->GetTitle(), status));
116 vneg_fitpars[0].push_back(hdedx_negi[i]->GetFunction(
"gaus")->GetParameter(1));
117 vneg_fitpars[1].push_back(hdedx_negi[i]->GetFunction(
"gaus")->GetParError(1));
118 vneg_fitpars[2].push_back(hdedx_negi[i]->GetFunction(
"gaus")->GetParameter(2));
119 vneg_fitpars[3].push_back(hdedx_negi[i]->GetFunction(
"gaus")->GetParError(2));
122 vneg_const.push_back(vneg_fitpars[0][i]);
126 if (status != FitOK) {
127 vpos_fitpars[0].push_back(1.0);
128 vpos_fitpars[1].push_back(0.0);
129 vpos_fitpars[2].push_back(0.0);
130 vpos_fitpars[3].push_back(0.0);
131 hdedx_posi[i]->SetTitle(Form(
"%s, Fit(%d)", hdedx_posi[i]->GetTitle(), status));
133 vpos_fitpars[0].push_back(hdedx_posi[i]->GetFunction(
"gaus")->GetParameter(1));
134 vpos_fitpars[1].push_back(hdedx_posi[i]->GetFunction(
"gaus")->GetParError(1));
135 vpos_fitpars[2].push_back(hdedx_posi[i]->GetFunction(
"gaus")->GetParameter(2));
136 vpos_fitpars[3].push_back(hdedx_posi[i]->GetFunction(
"gaus")->GetParError(2));
139 vpos_const.push_back(vpos_fitpars[0][i]);
142 vfinal_const.push_back(vneg_const);
143 vfinal_const.push_back(vpos_const);
150 plotHist(hdedx_posi, vpos_fitpars,
"pos");
151 plotHist(hdedx_negi, vneg_fitpars,
"neg");
173 if (cruns == 0)B2INFO(
"CDCDedxCosEdge: start exp " << expRun.first <<
" and run " << expRun.second <<
"");
178 int estart = erStart.first;
179 int rstart = erStart.second;
182 int rend = erEnd.second;
187 else m_suffix = Form(
"e%d_r%dr%d", estart, rstart, rend);
195 B2FATAL(
"CDCDedxCosEdgeAlgorithm: Can't merge paylaods with different size");
197 for (
unsigned int ibin = 0; ibin <
m_npBins; ibin++) {
201 double relg = vfinalconst[0].at(ibin);
202 double newg = prevg * relg;
203 B2INFO(
"CosEdge Const (<0), bin# " << ibin <<
", rel " << relg <<
", previous " << prevg <<
", merged " << newg);
204 vfinalconst[0].at(ibin) *= (double)
m_DBCosineCor->getMean(-1, ibin);
205 vfinalconst[0].at(ibin) /= (0.5 * (vfinalconst[0].at(
m_npBins - 1) + vfinalconst[0].at(
m_npBins - 2)));
209 relg = vfinalconst[1].at(ibin);
211 B2INFO(
"CosEdge Const (>0), bin# " << ibin <<
", rel " << relg <<
", previous " << prevg <<
", merged " << newg);
212 vfinalconst[1].at(ibin) *= (double)
m_DBCosineCor->getMean(1, ibin);
213 vfinalconst[1].at(ibin) /= (0.5 * (vfinalconst[1].at(0) + vfinalconst[1].at(1)));
217 B2INFO(
"CDCDedxCosineEdge calibration done");
225 if (temphist->Integral() < 500) {
226 B2INFO(Form(
"\t insufficient fit stats (%0.00f) for (%s)", temphist->Integral(), temphist->GetName()));
230 temphist->GetXaxis()->SetRange(temphist->FindFirstBinAbove(0, 1), temphist->FindLastBinAbove(0, 1));
231 int fs = temphist->Fit(
"gaus",
"QR");
233 B2INFO(Form(
"\tFit (round 1) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
237 double fdEdxMean = temphist->GetFunction(
"gaus")->GetParameter(1);
238 double width = temphist->GetFunction(
"gaus")->GetParameter(2);
239 temphist->GetXaxis()->SetRangeUser(fdEdxMean - 5.0 * width, fdEdxMean + 5.0 * width);
240 fs = temphist->Fit(
"gaus",
"QR",
"", fdEdxMean -
m_sigLim * width, fdEdxMean +
m_sigLim * width);
242 B2INFO(Form(
"\tFit (round 2) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
246 temphist->GetXaxis()->SetRangeUser(fdEdxMean - 5.0 * width, fdEdxMean + 5.0 * width);
247 B2INFO(Form(
"\tFit for hist (%s) successful (status = %d)", temphist->GetName(), fs));
258 TCanvas ctmp(
"ctmp",
"ctmp", 1200, 1200);
262 psname << Form(
"cdcdedx_cosedgecal_fits_%s_%s.pdf[", type.data(),
m_suffix.data());
263 ctmp.Print(psname.str().c_str());
265 psname << Form(
"cdcdedx_cosedgecal_fits_%s_%s.pdf", type.data(),
m_suffix.data());
267 for (
unsigned int i = 0; i <
m_npBins; ++i) {
270 hdedx[i]->SetStats(0);
271 hdedx[i]->SetFillColor(kAzure - 9);
272 hdedx[i]->DrawCopy();
274 TPaveText* pt =
new TPaveText(0.5, 0.73, 0.8, 0.89,
"NBNDC");
276 pt->AddText(Form(
"#mu_{fit}: %0.03f#pm%0.03f", vpars[0][i], vpars[1][i]));
277 pt->AddText(Form(
"#sigma_{fit}: %0.03f#pm%0.03f", vpars[2][i], vpars[3][i]));
280 if ((i + 1) % 20 == 0 || (i + 1) ==
m_npBins) {
281 ctmp.Print(psname.str().c_str());
289 psname << Form(
"cdcdedx_cosedgecal_fits_%s_%s.pdf]", type.data(),
m_suffix.data());
290 ctmp.Print(psname.str().c_str());
295 map<
int, vector<double>>& vpos_fitpars)
298 TCanvas cQa(
"cQa",
"cQa", 1200, 1200);
301 double min[2] = {0.85, 0.04};
302 double max[2] = {1.05, 0.3};
304 string vars[2] = {
"#mu_{fit}",
"#sigma_{fit}"};
305 string side[2] = {
"pcos",
"ncos"};
307 for (
int is = 0; is < 2; is++) {
315 for (
int iv = 0; iv < 2; iv++) {
317 string hname = Form(
"hpar_%s_%s_%s", vars[iv].data(), side[is].data(),
m_suffix.data());
319 TH1D htemp(Form(
"%s", hname.data()),
"",
m_npBins, minp, maxp);
320 htemp.SetTitle(Form(
"Constant (%s), cos#theta:(%0.02f, %0.02f);cos(#theta);const", vars[iv].data(), minp, maxp));
322 for (
unsigned int ib = 0; ib <
m_npBins; ib++) {
324 htemp.SetBinContent(ib + 1, vpos_fitpars[2 * iv][ib]);
325 htemp.SetBinError(ib + 1, vpos_fitpars[2 * iv + 1][ib]);
327 htemp.SetBinContent(ib + 1, vneg_fitpars[2 * iv][ib]);
328 htemp.SetBinError(ib + 1, vneg_fitpars[2 * iv + 1][ib]);
334 cQa.cd(2 * iv + 1 + is);
340 cQa.SaveAs(Form(
"cdcdedx_cosedgecal_relconst_%s.pdf",
m_suffix.data()));
341 cQa.SaveAs(Form(
"cdcdedx_cosedgecal_relconst_%s.root",
m_suffix.data()));
348 TCanvas ctmp_const(
"ctmp_const",
"ctmp_const", 900, 450);
349 ctmp_const.Divide(2, 1);
351 for (
int i = 0; i < 2; i++) {
359 TH1D holdconst(Form(
"holdconst%d_%s", i,
m_suffix.data()),
"",
m_npBins, min, max);
360 holdconst.SetTitle(Form(
"constant comparison, cos#theta:(%0.02f, %0.02f);cos(#theta);const", min, max));
362 TH1D hnewconst(Form(
"hnewconst%d_%s", i,
m_suffix.data()),
"",
m_npBins, min, max);
364 int iside = 2 * i - 1;
365 for (
int ibin = 0; ibin <
m_DBCosineCor->getSize(iside); ibin++) {
366 holdconst.SetBinContent(ibin + 1, (
double)
m_DBCosineCor->getMean(iside, ibin));
367 hnewconst.SetBinContent(ibin + 1, vfinalconst[i].at(ibin));
370 ctmp_const.cd(i + 1);
375 holdconst.DrawCopy(
"");
378 hnewconst.DrawCopy(
"same");
380 TPaveText* pt =
new TPaveText(0.47, 0.73, 0.77, 0.89,
"NBNDC");
383 TText* told = pt->AddText(
"old const");
384 told->SetTextColor(kBlack);
385 TText* tnew = pt->AddText(
"new const");
386 tnew->SetTextColor(kRed);
391 ctmp_const.SaveAs(Form(
"cdcdedx_cosedgecal_constcomp_%s.pdf",
m_suffix.data()));
392 ctmp_const.SaveAs(Form(
"cdcdedx_cosedgecal_constcomp_%s.root",
m_suffix.data()));
399 TCanvas cstats(
"cstats",
"cstats", 1000, 500);
400 cstats.SetBatch(kTRUE);
404 auto hestats = getObjectPtr<TH1I>(
"hestats");
406 hestats->SetName(Form(
"hestats_%s",
m_suffix.data()));
407 hestats->SetStats(0);
408 hestats->DrawCopy(
"");
412 auto htstats = getObjectPtr<TH1I>(
"htstats");
414 htstats->SetName(Form(
"htstats_%s",
m_suffix.data()));
415 htstats->SetStats(0);
416 htstats->DrawCopy(
"");
418 cstats.Print(Form(
"cdcdedx_cosedgecal_stats_%s.pdf",
m_suffix.data()));
void plotFitPars(std::map< int, std::vector< double > > &fPars_Neg, std::map< int, std::vector< double > > &fPars_Pos)
function to draw the fit parameters (relative gains and resolutions)
CDCDedxCosEdgeAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
bool m_isMerge
merge payload if calculated relative
void plotStats()
function to draw the stats plots
void setHistCosmetics(TH1D &hist, Color_t color, double min, double max, double size)
function to change histogram styles
void plotHist(std::vector< TH1D * > &hdedx, std::map< int, std::vector< double > > &fPars, std::string type)
function to draw dedx histograms for each bin
double m_negMin
min neg cosine angle
void getExpRunInfo()
function to get info about current exp and run
DBObjPtr< CDCDedxCosineEdge > m_DBCosineCor
CoseEdge correction DB object.
unsigned int m_npBins
number of bins across cosine range
bool m_isMakePlots
enable saving plots
void createPayload(std::vector< std::vector< double > > &vfinalconst)
function to store new payload after full calibration
std::string m_suffix
suffix for better plot naming
void setTextCosmetics(TPaveText *pt, double size)
function to change text styles
double m_posMax
max pos cosine angle
int m_dedxBins
number of bins for dedx histogram
void plotConstants(std::vector< std::vector< double > > &vfinalconst)
function to draw the final calibration constants and comparison with old constants
double m_posMin
min pos cosine angle
virtual EResult calibrate() override
Cosine edge algorithm.
double m_sigLim
gaussian fit sigma limit
double m_dedxMax
max dedx range
void fitGaussianWRange(TH1D *&temphist, fitstatus &status)
function to perform gauss fit for given histogram
double m_dedxMin
min dedx range
double m_negMax
max neg cosine angle
dE/dx special large cosine calibration to fix bending shoulder at large costh
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
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.
Abstract base class for different kinds of events.