Belle II Software development
CDCDedxCosineAlgorithm.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 <reconstruction/calibration/CDCdEdx/CDCDedxCosineAlgorithm.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 isMergePayload(true),
26 fSigLim(2.5),
27 fCosbins(100),
28 fCosMin(-1.0),
29 fCosMax(1.0),
30 fHistbins(600),
31 fdEdxMin(0.0),
32 fdEdxMax(3.0),
33 fStartRun(0)
34
35{
36 // Set module properties
37 setDescription("A calibration algorithm for CDC dE/dx electron cos(theta) dependence");
38
39}
40
41//-----------------------------------------------------------------
42// Run the calibration
43//-----------------------------------------------------------------
45{
46 B2INFO("Preparing dE/dx calibration for CDC dE/dx electron saturation");
47
48 // Get data objects
49 auto ttree = getObjectPtr<TTree>("tree");
50 if (ttree->GetEntries() < 100)return c_NotEnoughData;
51
52 double dedx, costh; int charge;
53 ttree->SetBranchAddress("dedx", &dedx);
54 ttree->SetBranchAddress("costh", &costh);
55 ttree->SetBranchAddress("charge", &charge);
56
57 const auto expRun = getRunList()[0];
58 updateDBObjPtrs(1, expRun.second, expRun.first);
59 fStartRun = expRun.second;
60
61 // make histograms to store dE/dx values in bins of cos(theta)
62 // bin size can be arbitrary, but for now just make uniform bins
63 std::vector<TH1D*> hdEdx_elCosbin(fCosbins), hdEdx_poCosbin(fCosbins), hdEdx_epCosbin(fCosbins);
64
65 const double binW = (fCosMax - fCosMin) / fCosbins;
66
67 for (unsigned int i = 0; i < fCosbins; ++i) {
68
69 double coslow = i * binW + fCosMin, coshigh = coslow + binW;
70
71 hdEdx_elCosbin[i] = new TH1D(Form("hdEdx_elCosbin%d_fRun%d", i, fStartRun), "", fHistbins, fdEdxMin, fdEdxMax);
72 hdEdx_elCosbin[i]->SetTitle(Form("dE/dx dist (e-) in costh (%0.02f, %0.02f), run start: %d", coslow, coshigh, fStartRun));
73 hdEdx_elCosbin[i]->GetXaxis()->SetTitle("dE/dx (no had sat, for e-)");
74 hdEdx_elCosbin[i]->GetYaxis()->SetTitle("Entries");
75
76 hdEdx_poCosbin[i] = new TH1D(Form("hdEdx_poCosbin%d_fRun%d", i, fStartRun), "", fHistbins, fdEdxMin, fdEdxMax);
77 hdEdx_poCosbin[i]->SetTitle(Form("dE/dx dist (e+) in costh (%0.02f, %0.02f), run start: %d", coslow, coshigh, fStartRun));
78 hdEdx_poCosbin[i]->GetXaxis()->SetTitle("dE/dx (no had sat, for e+)");
79 hdEdx_poCosbin[i]->GetYaxis()->SetTitle("Entries");
80
81 hdEdx_epCosbin[i] = new TH1D(Form("hdEdx_epCosbin%d_fRun%d", i, fStartRun), "", fHistbins, fdEdxMin, fdEdxMax);
82 hdEdx_epCosbin[i]->SetTitle(Form("dE/dx dist (e-,e+) in costh (%0.02f, %0.02f), run start: %d", coslow, coshigh, fStartRun));
83 hdEdx_epCosbin[i]->GetXaxis()->SetTitle("dE/dx (no had sat, for e-,e+)");
84 hdEdx_epCosbin[i]->GetYaxis()->SetTitle("Entries");
85 }
86
87 // fill histograms, bin size may be arbitrary
88 TH1D* hCosth_el = new TH1D(Form("hCosth_el_fRun%d", fStartRun),
89 Form("cos(#theta) dist (e- and e+), start run: %d; cos(#theta); Entries", fStartRun), fCosbins, fCosMin, fCosMax);
90 TH1D* hCosth_po = new TH1D(Form("hCosth_po_fRun%d", fStartRun), Form("cos(#theta) dist (e+), start run: %d; cos(#theta); Entries",
92 TH1D* hCosth_ep = new TH1D(Form("hCosth_ep_fRun%d", fStartRun),
93 Form("cos(#theta) dist (e- and e+), start run: %d; cos(#theta); Entries", fStartRun), fCosbins, fCosMin, fCosMax);
94
95 for (int i = 0; i < ttree->GetEntries(); ++i) {
96
97 ttree->GetEvent(i);
98
99 //if track is a junk
100 if (dedx <= 0 || charge == 0) continue;
101
102 //if track is in CDC acceptance (though it is inbuilt in collector module)
103 if (costh < TMath::Cos(150 * TMath::DegToRad()) || costh > TMath::Cos(17 * TMath::DegToRad())) continue;
104
105 int bin = int((costh - fCosMin) / binW);
106 if (bin < 0 || bin >= int(fCosbins)) continue;
107
108 if (isMethodSep) {
109 if (charge < 0) {
110 hCosth_el->Fill(costh);
111 hdEdx_elCosbin[bin]->Fill(dedx);
112 } else if (charge > 0) {
113 hCosth_po->Fill(costh);
114 hdEdx_poCosbin[bin]->Fill(dedx);
115 }
116 } else {
117 hCosth_ep->Fill(costh);
118 hdEdx_epCosbin[bin]->Fill(dedx);
119 }
120 }
121
122 //Plot constants
123 TH1D* hdEdxMeanvsCos_po = new TH1D(Form("hdEdxMeanvsCos_po_fRun%d", fStartRun),
124 Form("dE/dx(e+) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
125 TH1D* hdEdxSigmavsCos_po = new TH1D(Form("hdEdxSigmavsCos_po_fRun%d", fStartRun),
126 Form("dE/dx(e+) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
127
128 TH1D* hdEdxMeanvsCos_el = new TH1D(Form("hdEdxMeanvsCos_el_fRun%d", fStartRun),
129 Form("dE/dx(e-) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
130 TH1D* hdEdxSigmavsCos_el = new TH1D(Form("hdEdxSigmavsCos_el_fRun%d", fStartRun),
131 Form("dE/dx(e-) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
132
133 TH1D* hdEdxMeanvsCos_ep = new TH1D(Form("hdEdxMeanvsCos_ep_fRun%d", fStartRun),
134 Form("dE/dx(e+, e-) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
135 TH1D* hdEdxSigmavsCos_ep = new TH1D(Form("hdEdxSigmavsCos_ep_fRun%d", fStartRun),
136 Form("dE/dx(e+, e-) rel means, start run: %d; cos(#theta); dE/dx (#mu_{fit})", fStartRun), fCosbins, fCosMin, fCosMax);
137
138 // more validation plots
139 TCanvas* ctmp_ep = new TCanvas("ctmp_ep", "ctmp_ep", 800, 400);
140 if (isMethodSep)ctmp_ep->Divide(2, 1);
141 else {
142 ctmp_ep->Divide(2, 2);
143 ctmp_ep->SetCanvasSize(800, 800);
144 }
145 std::stringstream psname_ep;
146
147 //validation plots: individual bin dedx dist and fits
148 if (isMakePlots) {
149 psname_ep << Form("cdcdedx_coscal_fits_frun%d.pdf[", fStartRun);
150 ctmp_ep->Print(psname_ep.str().c_str());
151 psname_ep.str("");
152 psname_ep << Form("cdcdedx_coscal_fits_frun%d.pdf", fStartRun);
153 }
154
155 // fit histograms to get gains in bins of cos(theta)
156 std::vector<double> cosine;
157 for (unsigned int i = 0; i < fCosbins; ++i) {
158
159
160 TLine* tl = new TLine();
161 tl->SetLineColor(kBlack);
162
163 double fdEdxMean = 1.0; //This is what we need for calibration
164 double fdEdxMeanErr = 0.0;
165
166 if (!isMethodSep) {
167
168 TString status = "";
169
170 double fdEdxSigma = 0.0, fdEdxSigmaErr = 0.0;
171 FitGaussianWRange(hdEdx_epCosbin[i], status);
172
173 if (status != "FitOK") {
174 fdEdxMean = 1.0;
175 hdEdx_epCosbin[i]->SetTitle(Form("%s, Fit(%s)", hdEdx_epCosbin[i]->GetTitle(), status.Data()));
176 } else {
177 fdEdxMean = hdEdx_epCosbin[i]->GetFunction("gaus")->GetParameter(1);
178 fdEdxMeanErr = hdEdx_epCosbin[i]->GetFunction("gaus")->GetParError(1);
179 fdEdxSigma = hdEdx_epCosbin[i]->GetFunction("gaus")->GetParameter(2);
180 fdEdxSigmaErr = hdEdx_epCosbin[i]->GetFunction("gaus")->GetParError(2);
181 hdEdx_epCosbin[i]->SetTitle(Form("%s, Fit (%s), #mu_{fit}: %0.04f#pm%0.04f,, #sigma_{fit}: %0.04f", hdEdx_epCosbin[i]->GetTitle(),
182 status.Data(), fdEdxMean, fdEdxMeanErr, fdEdxSigma));
183 }
184
185 hdEdxMeanvsCos_ep->SetBinContent(i + 1, fdEdxMean);
186 hdEdxMeanvsCos_ep->SetBinError(i + 1, fdEdxMeanErr);
187 hdEdxSigmavsCos_ep->SetBinContent(i + 1, fdEdxSigma);
188 hdEdxSigmavsCos_ep->SetBinError(i + 1, fdEdxSigmaErr);
189
190 if (isMakePlots) {
191 ctmp_ep->cd(i % 4 + 1); // each canvas is 2x2
192 hdEdx_epCosbin[i]->SetFillColorAlpha(kYellow, 0.25);
193 hdEdx_epCosbin[i]->DrawCopy("hist");
194
195 tl->SetX1(fdEdxMean); tl->SetX2(fdEdxMean);
196 tl->SetY1(0); tl->SetY2(hdEdx_epCosbin[i]->GetMaximum());
197 tl->DrawClone("same");
198 if ((i + 1) % 4 == 0 || (i + 1 == fCosbins))ctmp_ep->Print(psname_ep.str().c_str());
199 }
200 } else {
201
202 double fdEdxMean_el = 1.0, fdEdxMean_elErr = 0.0;
203 double fdEdxSigma_el = 0.0, fdEdxSigma_elErr = 0.0;
204 double fdEdxMean_po = 1.0, fdEdxMean_poErr = 0.0;
205 double fdEdxSigma_po = 0.0, fdEdxSigma_poErr = 0.0;
206 TString status_el = "", status_po = "";
207
208 //Fit _eltrons in cos bins
209 FitGaussianWRange(hdEdx_elCosbin[i], status_el);
210 if (status_el != "FitOK") {
211 fdEdxMean_el = 1.0;
212 hdEdx_elCosbin[i]->SetTitle(Form("%s, Fit(%s)", hdEdx_elCosbin[i]->GetTitle(), status_el.Data()));
213 } else {
214 fdEdxMean_el = hdEdx_elCosbin[i]->GetFunction("gaus")->GetParameter(1);
215 fdEdxMean_elErr = hdEdx_elCosbin[i]->GetFunction("gaus")->GetParError(1);
216 fdEdxSigma_el = hdEdx_elCosbin[i]->GetFunction("gaus")->GetParameter(2);
217 fdEdxSigma_elErr = hdEdx_elCosbin[i]->GetFunction("gaus")->GetParError(2);
218 hdEdx_elCosbin[i]->SetTitle(Form("%s, Fit (%s), #mu_{fit}: %0.04f#pm%0.04f,, #sigma_{fit}: %0.04f", hdEdx_elCosbin[i]->GetTitle(),
219 status_el.Data(), fdEdxMean_el, fdEdxMean_elErr, fdEdxSigma_el));
220 }
221
222 hdEdxMeanvsCos_el->SetBinContent(i + 1, fdEdxMean_el);
223 hdEdxMeanvsCos_el->SetBinError(i + 1, fdEdxMean_elErr);
224 hdEdxSigmavsCos_el->SetBinContent(i + 1, fdEdxSigma_el);
225 hdEdxSigmavsCos_el->SetBinError(i + 1, fdEdxSigma_elErr);
226
227 //Fit _potron in cos bins
228 FitGaussianWRange(hdEdx_poCosbin[i], status_po);
229 if (status_po != "FitOK") {
230 fdEdxMean_po = 1.0;
231 hdEdx_poCosbin[i]->SetTitle(Form("%s, Fit(%s)", hdEdx_poCosbin[i]->GetTitle(), status_po.Data()));
232 } else {
233 fdEdxMean_po = hdEdx_poCosbin[i]->GetFunction("gaus")->GetParameter(1);
234 fdEdxMean_poErr = hdEdx_poCosbin[i]->GetFunction("gaus")->GetParError(1);
235 fdEdxSigma_po = hdEdx_poCosbin[i]->GetFunction("gaus")->GetParameter(2);
236 fdEdxSigma_poErr = hdEdx_poCosbin[i]->GetFunction("gaus")->GetParError(2);
237 hdEdx_poCosbin[i]->SetTitle(Form("%s, Fit (%s), #mu_{fit}: %0.04f#pm%0.04f,, #sigma_{fit}: %0.04f", hdEdx_poCosbin[i]->GetTitle(),
238 status_po.Data(), fdEdxMean_po, fdEdxMean_poErr, fdEdxSigma_po));
239 }
240
241 if (status_po != "FitOK" && status_el == "FitOK") {
242 fdEdxMean_po = fdEdxMean_el;
243 hdEdx_poCosbin[i]->SetTitle(Form("%s, mean (manual) = elec left", hdEdx_poCosbin[i]->GetTitle()));
244 } else if (status_el != "FitOK" && status_po == "FitOK") {
245 fdEdxMean_el = fdEdxMean_po;
246 hdEdx_elCosbin[i]->SetTitle(Form("%s, mean (manual) = posi right", hdEdx_elCosbin[i]->GetTitle()));
247 } else if (status_el != "FitOK" && status_po != "FitOK") {
248 fdEdxMean_po = 1.0; fdEdxMean_el = 1.0;
249 }
250
251 hdEdxMeanvsCos_po->SetBinContent(i + 1, fdEdxMean_po);
252 hdEdxMeanvsCos_po->SetBinError(i + 1, fdEdxMean_poErr);
253 hdEdxSigmavsCos_po->SetBinContent(i + 1, fdEdxSigma_po);
254 hdEdxSigmavsCos_po->SetBinError(i + 1, fdEdxSigma_poErr);
255
256 //for validation purpose
257 if (isMakePlots) {
258
259 ctmp_ep->cd(1); // each canvas is 2x2
260 hdEdx_elCosbin[i]->SetFillColorAlpha(kYellow, 0.25);
261 hdEdx_elCosbin[i]->DrawCopy("");
262 tl->SetX1(fdEdxMean_el); tl->SetX2(fdEdxMean_el);
263 tl->SetY1(0); tl->SetY2(hdEdx_elCosbin[i]->GetMaximum());
264 tl->DrawClone("same");
265
266 ctmp_ep->cd(2); // each canvas is 2x2
267 hdEdx_poCosbin[i]->SetFillColorAlpha(kBlue, 0.25);
268 hdEdx_poCosbin[i]->DrawCopy("");
269 tl->SetX1(fdEdxMean_po); tl->SetX2(fdEdxMean_po);
270 tl->SetY1(0); tl->SetY2(hdEdx_poCosbin[i]->GetMaximum());
271 tl->DrawClone("same");
272 ctmp_ep->Print(psname_ep.str().c_str());
273 }
274
275 //avg of both e+ and e- fdEdxMean
276 fdEdxMean = 0.5 * (fdEdxMean_po + fdEdxMean_el);
277 if (fdEdxMean <= 0)fdEdxMean = 1.0; //protection only
278 fdEdxMeanErr = 0.5 * TMath::Sqrt(fdEdxMean_elErr * fdEdxMean_elErr + fdEdxMean_poErr * fdEdxMean_poErr);
279 hdEdxMeanvsCos_ep->SetBinContent(i + 1, fdEdxMean);
280 hdEdxMeanvsCos_ep->SetBinError(i + 1, fdEdxMeanErr);
281 }
282
283 cosine.push_back(fdEdxMean);
284 delete tl;
285 }
286
287 //more validation plots for debugging
288 if (isMakePlots) {
289
290 psname_ep.str("");
291 psname_ep << Form("cdcdedx_coscal_fits_frun%d.pdf]", fStartRun);
292 ctmp_ep->Print(psname_ep.str().c_str());
293 delete ctmp_ep;
294
295 TCanvas* cstats = new TCanvas("cstats", "cstats", 1000, 500);
296 cstats->SetBatch(kTRUE);
297 cstats->Divide(2, 1);
298 cstats->cd(1);
299 auto hestats = getObjectPtr<TH1I>("hestats");
300 if (hestats) {
301 hestats->SetName(Form("hestats_fRun%d", fStartRun));
302 hestats->SetStats(0);
303 hestats->DrawCopy("");
304 }
305 cstats->cd(2);
306 auto htstats = getObjectPtr<TH1I>("htstats");
307 if (htstats) {
308 hestats->SetName(Form("htstats_fRun%d", fStartRun));
309 htstats->DrawCopy("");
310 hestats->SetStats(0);
311 }
312 cstats->Print(Form("cdcdedx_coscal_stats_frun%d.pdf", fStartRun));
313 delete cstats;
314
315 TCanvas* ctmp_epConst = new TCanvas("ctmp_epConst", "ctmp_epConst", 800, 400);
316 ctmp_epConst->Divide(2, 1);
317
318 TCanvas* ctmp_epCosth = new TCanvas("ctmp_epCosth", "ctmp_epCosth", 600, 500);
319
320 if (isMethodSep) {
321
322 ctmp_epConst->cd(1);
323 gPad->SetGridy(1);
324 hdEdxMeanvsCos_el->SetMarkerStyle(20);
325 hdEdxMeanvsCos_el->SetMarkerSize(0.60);
326 hdEdxMeanvsCos_el->SetMarkerColor(kRed);
327 hdEdxMeanvsCos_el->SetStats(0);
328 hdEdxMeanvsCos_el->SetTitle("comparison of dedx #mu_{fit}^{rel}: (e-=red, e+=blue, avg=black)");
329 hdEdxMeanvsCos_el->GetYaxis()->SetRangeUser(0.96, 1.04);
330 hdEdxMeanvsCos_el->DrawCopy("");
331
332 hdEdxMeanvsCos_po->SetMarkerStyle(20);
333 hdEdxMeanvsCos_po->SetMarkerSize(0.60);
334 hdEdxMeanvsCos_po->SetMarkerColor(kBlue);
335 hdEdxMeanvsCos_po->SetStats(0);
336 hdEdxMeanvsCos_po->DrawCopy("same");
337
338 hdEdxMeanvsCos_ep->SetMarkerStyle(20);
339 hdEdxMeanvsCos_ep->SetMarkerSize(0.60);
340 hdEdxMeanvsCos_ep->SetMarkerColor(kBlack);
341 hdEdxMeanvsCos_ep->SetStats(0);
342 hdEdxMeanvsCos_ep->DrawCopy("same");
343
344 ctmp_epConst->cd(2);
345 gPad->SetGridy(1);
346 hdEdxSigmavsCos_el->SetMarkerStyle(4);
347 hdEdxSigmavsCos_el->SetMarkerColor(kRed);
348 hdEdxSigmavsCos_el->SetMarkerSize(0.90);
349 hdEdxSigmavsCos_el->SetTitle("comparison of dedx #mu_{fit}^{rel}: (e-=open, e+=closed)");
350 hdEdxSigmavsCos_el->GetYaxis()->SetRangeUser(0.4, 0.12);
351 hdEdxSigmavsCos_el->SetStats(0);
352 hdEdxSigmavsCos_el->DrawCopy("");
353
354 hdEdxSigmavsCos_po->SetMarkerStyle(8);
355 hdEdxSigmavsCos_po->SetMarkerSize(0.80);
356 hdEdxSigmavsCos_po->SetMarkerColor(kBlue);
357 hdEdxSigmavsCos_po->SetStats(0);
358 hdEdxSigmavsCos_po->DrawCopy("same");
359
360 ctmp_epCosth->cd();
361 hCosth_el->SetStats(0);
362 hCosth_el->SetLineColor(kRed);
363 hCosth_el->SetFillColorAlpha(kYellow, 0.55);
364 hCosth_el->DrawCopy("");
365 hCosth_po->SetStats(0);
366 hCosth_po->SetLineColor(kBlue);
367 hCosth_po->SetFillColorAlpha(kGray, 0.35);
368 hCosth_po->DrawCopy("same");
369
370 } else {
371
372 ctmp_epConst->cd(1);
373 gPad->SetGridy(1);
374 hdEdxMeanvsCos_ep->SetMarkerStyle(20);
375 hdEdxMeanvsCos_ep->SetMarkerSize(0.60);
376 hdEdxMeanvsCos_ep->SetMarkerColor(kBlack);
377 hdEdxMeanvsCos_ep->SetStats(0);
378 hdEdxMeanvsCos_ep->SetTitle("dedx rel(#mu_{fit}) for e- and e+ combined");
379 hdEdxMeanvsCos_ep->GetYaxis()->SetRangeUser(0.97, 1.04);
380 hdEdxMeanvsCos_ep->DrawCopy("");
381
382 ctmp_epConst->cd(2);
383 gPad->SetGridy(1);
384 hdEdxSigmavsCos_ep->SetMarkerStyle(20);
385 hdEdxSigmavsCos_ep->SetMarkerColor(kRed);
386 hdEdxSigmavsCos_ep->SetMarkerSize(1.1);
387 hdEdxSigmavsCos_ep->SetTitle("dedx rel(#sigma_{fit}) for e- and e+ combined");
388 hdEdxSigmavsCos_ep->GetYaxis()->SetRangeUser(0.4, 0.12);
389 hdEdxSigmavsCos_ep->SetStats(0);
390 hdEdxSigmavsCos_ep->DrawCopy("");
391
392 ctmp_epCosth->cd();
393 hCosth_ep->SetStats(0);
394 hCosth_ep->SetLineColor(kGray);
395 hCosth_ep->SetFillColorAlpha(kGray, 0.25);
396 hCosth_ep->DrawCopy("same");
397 }
398
399 ctmp_epCosth->SaveAs(Form("cdcdedx_coscal_costhdist_frun%d.pdf", fStartRun));
400 delete ctmp_epCosth;
401
402 ctmp_epConst->SaveAs(Form("cdcdedx_coscal_relmeans_frun%d.pdf", fStartRun));
403 ctmp_epConst->SaveAs(Form("cdcdedx_coscal_relmeans_frun%d.root", fStartRun));
404 delete ctmp_epConst;
405 }
406
407 generateNewPayloads(cosine);
408 return c_OK;
409}
410
411void CDCDedxCosineAlgorithm::generateNewPayloads(std::vector<double> cosine)
412{
413
414 TH1D* hCosCorrOld = new TH1D(Form("hCosCorrOld_fRun%d", fStartRun),
415 Form("cos corr const comparison (red=old, blue=new), start run: %d;cos(#theta);dE/dx #mu_{fit}", fStartRun), fCosbins, fCosMin,
416 fCosMax);
417 TH1D* hCosCorrNew = new TH1D(Form("hCosCorrNew_fRun%d", fStartRun), Form("coss corr, start run: %d;cos(#theta);dE/dx #mu_{fit}",
419 TH1D* hCosCorrRel = new TH1D(Form("hCosCorrRel_fRun%d", fStartRun),
420 Form("new relative cos corr, start run: %d;cos(#theta);dE/dx #mu_{fit}", fStartRun), fCosbins, fCosMin, fCosMax);
421
422 if (isMergePayload) {
423 const auto expRun = getRunList()[0];
424 updateDBObjPtrs(1, expRun.second, expRun.first);
425 // bool refchange = m_DBCosineCor.hasChanged(); //Add this feature for major processing
426 B2INFO("Saving new rung for (Exp, Run) : (" << expRun.first << "," << expRun.second << ")");
427 for (unsigned int ibin = 0; ibin < m_DBCosineCor->getSize(); ibin++) {
428 hCosCorrOld->SetBinContent(ibin + 1, (double)m_DBCosineCor->getMean(ibin));
429 hCosCorrRel->SetBinContent(ibin + 1, cosine.at(ibin));
430 B2INFO("Cosine Corr for Bin # " << ibin << ", Previous = " << m_DBCosineCor->getMean(ibin) << ", Relative = " << cosine.at(
431 ibin) << ", Merged = " << m_DBCosineCor->getMean(ibin)*cosine.at(ibin));
432 cosine.at(ibin) *= (double)m_DBCosineCor->getMean(ibin);
433 hCosCorrNew->SetBinContent(ibin + 1, cosine.at(ibin));
434 }
435 }
436
437 if (isMakePlots) {
438 TCanvas* ctmp_const = new TCanvas("ctmp_const", "ctmp_const", 900, 450);
439 ctmp_const->Divide(2, 1);
440
441 ctmp_const->cd(1);
442 gPad->SetGridy(1);
443 gPad->SetGridx(1);
444 hCosCorrOld->SetStats(0);
445 hCosCorrOld->SetLineColor(kRed);
446 hCosCorrOld->GetYaxis()->SetRangeUser(0.64, 1.20);
447 hCosCorrOld->DrawCopy("");
448 hCosCorrNew->SetStats(0);
449 hCosCorrNew->SetLineColor(kBlue);
450 hCosCorrNew->DrawCopy("same");
451
452 ctmp_const->cd(2);
453 gPad->SetGridy(1);
454 hCosCorrRel->SetStats(0);
455 hCosCorrRel->GetYaxis()->SetRangeUser(0.97, 1.03);
456 hCosCorrRel->SetLineColor(kBlack);
457 hCosCorrRel->DrawCopy("");
458
459 ctmp_const->SaveAs(Form("cdcdedx_coscal_constants_frun%d.pdf", fStartRun));
460 ctmp_const->SaveAs(Form("cdcdedx_coscal_constants_frun%d.root", fStartRun));
461 delete ctmp_const;
462 }
463
464 B2INFO("dE/dx calibration done for CDC dE/dx _eltron saturation");
465 CDCDedxCosineCor* gain = new CDCDedxCosineCor(cosine);
466 saveCalibration(gain, "CDCDedxCosineCor");
467}
468
469void CDCDedxCosineAlgorithm::FitGaussianWRange(TH1D*& temphist, TString& status)
470{
471 if (temphist->Integral() < 2000) { //at least 1k bhabha events
472 B2INFO(Form("\tThis hist (%s) have insufficient entries to perform fit (%0.03f)", temphist->GetName(), temphist->Integral()));
473 status = "LowStats";
474 return;
475 } else {
476 temphist->GetXaxis()->SetRange(temphist->FindFirstBinAbove(0, 1), temphist->FindLastBinAbove(0, 1));
477 int fs = temphist->Fit("gaus", "QR");
478 if (fs != 0) {
479 B2INFO(Form("\tFit (round 1) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
480 status = "FitFailed";
481 return;
482 } else {
483 double fdEdxMean = temphist->GetFunction("gaus")->GetParameter(1);
484 double width = temphist->GetFunction("gaus")->GetParameter(2);
485 temphist->GetXaxis()->SetRangeUser(fdEdxMean - 5.0 * width, fdEdxMean + 5.0 * width);
486 fs = temphist->Fit("gaus", "QR", "", fdEdxMean - fSigLim * width, fdEdxMean + fSigLim * width);
487 if (fs != 0) {
488 B2INFO(Form("\tFit (round 2) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
489 status = "FitFailed";
490 return;
491 } else {
492 temphist->GetXaxis()->SetRangeUser(fdEdxMean - 5.0 * width, fdEdxMean + 5.0 * width);
493 B2INFO(Form("\tFit for hist (%s) successful (status = %d)", temphist->GetName(), fs));
494 status = "FitOK";
495 }
496 }
497 }
498}
void generateNewPayloads(std::vector< double > cosine)
function to store new payload after full calibration
int fStartRun
boundary start at this run
double fdEdxMax
max dedx range for gain cal
bool isMergePayload
merge payload at the of calibration
double fCosMax
max cosine angle for cal
DBObjPtr< CDCDedxCosineCor > m_DBCosineCor
Electron saturation correction DB object.
double fCosMin
min cosine angle for cal
CDCDedxCosineAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
virtual EResult calibrate() override
Cosine algorithm.
double fdEdxMin
min dedx range for gain cal
void FitGaussianWRange(TH1D *&temphist, TString &status)
function to fit histogram in each cosine bin
int fHistbins
number of bins for dedx histogram
bool isMethodSep
if e+e- need to be consider sep
unsigned int fCosbins
number of bins across cosine range
bool isMakePlots
produce plots for status
double fSigLim
gaussian fit sigma limit
dE/dx wire gain calibration constants
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.