Belle II Software development
HadronCalibration.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/HadronCalibration.h>
10
11
12using namespace Belle2;
13
15
16
17void HadronCalibration::fitBGCurve(std::vector< std::string > particles, const std::string& filename, const std::string& paramfile,
18 const std::string& suffix)
19{
20
21 // read in a file that contains fit results for bg bins
22 double bgmin1 = 0.25, bgmax1 = 5.1; //using until 0 --> 4.5
23 double bgmin2 = 3.9, bgmax2 = 15.0; //using till 4.5 --> 10
24 double bgmin3 = 7.5, bgmax3 = 5000; //using above 10 --> 6000 *use this range only
25
26 const int npart = 5;
27 TFile* infile = new TFile(filename.data());
28
29 CDCDedxMeanPred gpar;
30 gpar.setParameters(paramfile.data());
32
33 // multigraphs to hold the curve and residual results
34 TGraphErrors part_dedxvsbg[npart];
35 TMultiGraph* gr_dedxvsbg = new TMultiGraph(Form("gr_dedxvsbg_%s", suffix.data()), ";#beta#gamma;dE/dx");
36 TGraphErrors part_dedxvsp[npart];
37 TMultiGraph* gr_dedxvsp = new TMultiGraph(Form("gr_dedxvsp_%s", suffix.data()), ";momentum(GeV/c);dE/dx");
38
39 // --------------------------------------------------
40 // FILL BG CURVE VALUES
41 // --------------------------------------------------
42 TLegend tleg(0.4, 0.50, 0.65, 0.85);
43 tleg.SetBorderSize(0);
44
45 TLegend tlegPart(0.60, 0.60, 0.90, 0.90);
46 tlegPart.SetBorderSize(0);
47
48 for (int i = 0; i < int(particles.size()); ++i) {
49
50 std::string particle = particles[i];
51
52 double mass = m_prep.getParticleMass(particle);
53 if (mass == 0.0) B2FATAL("Mass of particle " << particle.data() << " is zero");
54
55 if (!infile->GetListOfKeys()->Contains(particle.data())) continue;
56
57 TTree* hadron = (TTree*) infile->Get(particle.data());
58 B2INFO("HadronCalibration: reading " << particle.data() << " in file " << filename.data());
59
60 double dedx, dedxerr, bg; // dE/dx without electron saturation correction
61
62 hadron->SetBranchAddress("dedx", &dedx);
63 hadron->SetBranchAddress("dedxerr", &dedxerr);
64 hadron->SetBranchAddress("bg_avg", &bg);
65
66 for (int j = 0; j < hadron->GetEntries(); ++j) {
67
68 hadron->GetEvent(j);
69
70 part_dedxvsbg[i].SetPoint(j, bg, dedx);
71 part_dedxvsbg[i].SetPointError(j, 0, dedxerr);
72
73 part_dedxvsp[i].SetPoint(j, bg * mass, dedx);
74 part_dedxvsp[i].SetPointError(j, 0, dedxerr);
75 }
76
77 part_dedxvsbg[i].SetName(particle.data());
78 if (i == 4) setGraphStyle(part_dedxvsbg[i], i + 2);
79 else setGraphStyle(part_dedxvsbg[i], i + 1);
80 gr_dedxvsbg->Add(&part_dedxvsbg[i]);
81
82 if (i == 4) setGraphStyle(part_dedxvsp[i], i + 2);
83 else setGraphStyle(part_dedxvsp[i], i + 1);
84 gr_dedxvsp->Add(&part_dedxvsp[i]);
85
86 tleg.AddEntry(&part_dedxvsbg[i], particles[i].data(), "p");
87 tlegPart.AddEntry(&part_dedxvsbg[i], particles[i].data(), "p");
88
89 }
90
91 TMultiGraph* grcopy1 = (TMultiGraph*)gr_dedxvsbg->Clone(Form("datapoints_%s", suffix.data()));
92
93 //Region 1
94 TF1* fdedx1 = new TF1("fdedx1", [gc](double * x, double * par) {
95 std::vector<double> parVec(par, par + 8); // Create a vector from the parameters
96 return gc->meanCurve(x, parVec); // Call the member function
97 }, bgmin1, bgmax1, 8, "WidgetCurve");
98
99 TF1* fdedx1Copy = new TF1("fdedx1Copy", [gc](double * x, double * par) {
100 std::vector<double> parVec(par, par + 8); // Create a vector from the parameters
101 return gc->meanCurve(x, parVec); // Call the member function
102 }, bgmin1, bgmax1, 8, "WidgetCurve");
103
104 fdedx1->SetParameter(0, 1);
105 fdedx1Copy->SetParameter(0, 1);
106 for (int i = 1; i < 8; ++i) {
107 fdedx1->SetParameter(i, gpar.getCurvePars(i - 1));
108 fdedx1Copy->SetParameter(i, gpar.getCurvePars(i - 1));
109 }
110
111 //Region 2
112 TF1* fdedx2 = new TF1("fdedx2", [gc](double * x, double * par) {
113 std::vector<double> parVec(par, par + 5); // Create a vector from the parameters
114 return gc->meanCurve(x, parVec); // Call the member function
115 }, bgmin2, bgmax2, 5, "WidgetCurve");
116
117 TF1* fdedx2Copy = new TF1("fdedx2Copy", [gc](double * x, double * par) {
118 std::vector<double> parVec(par, par + 5); // Create a vector from the parameters
119 return gc->meanCurve(x, parVec); // Call the member function
120 }, bgmin2, bgmax2, 5, "WidgetCurve");
121
122 fdedx2->SetParameter(0, 2);
123 fdedx2Copy->SetParameter(0, 2);
124 for (int i = 1; i < 5; ++i) {
125 fdedx2->SetParameter(i, gpar.getCurvePars(6 + i));
126 fdedx2Copy->SetParameter(i, gpar.getCurvePars(6 + i));
127 }
128
129 //Region 3
130 TF1* fdedx3 = new TF1("fdedx3", [gc](double * x, double * par) {
131 std::vector<double> parVec(par, par + 5); // Create a vector from the parameters
132 return gc->meanCurve(x, parVec); // Call the member function
133 }, bgmin3, bgmax3, 5, "WidgetCurve");
134
135 TF1* fdedx3Copy = new TF1("fdedx3Copy", [gc](double * x, double * par) {
136 std::vector<double> parVec(par, par + 5); // Create a vector from the parameters
137 return gc->meanCurve(x, parVec); // Call the member function
138 }, bgmin3, bgmax3, 5, "WidgetCurve");
139
140 fdedx3->SetParameter(0, 3);
141 fdedx3Copy->SetParameter(0, 3);
142 for (int i = 1; i < 5; ++i) {
143 fdedx3->SetParameter(i, gpar.getCurvePars(10 + i));
144 fdedx3Copy->SetParameter(i, gpar.getCurvePars(10 + i));
145 }
146
147 // --------------------------------------------------
148 // FIT BG CURVE
149 // --------------------------------------------------
150
151 // //Fitting part1 1/beta^2 region and new constants
152 // //----------------------------------------------
153
154 int stat1 = gr_dedxvsbg->Fit("fdedx1", "", "", bgmin1, bgmax1);
155 for (int i = 0; i < 50; ++i) {
156 if (stat1 == 0) {
157 B2INFO("\n\tPART-1 FIT STATUS is OK: irr # " << i);
158 break;
159 }
160 stat1 = gr_dedxvsbg->Fit("fdedx1", "", "", bgmin1, bgmax1);
161 }
162
163 // if the fit was successful, write out the updated parameters
164 if (stat1 == 0) {
165 B2INFO("\t--> HadronCalibration: ATTENTIONS: PART-1 FIT OK..updating parameters");
166 for (int i = 1; i < 8; ++i) {
167 B2INFO("\t" << i << ") Old = " << gpar.getCurvePars(i - 1) << " --> New = " << fdedx1->GetParameter(i));
168 gpar.setCurvePars(i - 1, fdedx1->GetParameter(i));
169 }
170 } else B2INFO("\t--> HadronCalibration: WARNING: PART-1 FIT FAILED...");
171
172
173 //Fitting part2 min ionisation region and new constants
174 //----------------------------------------------
175 int stat2 = gr_dedxvsbg->Fit("fdedx2", "FQR", "", bgmin2, bgmax2);
176 for (int i = 0; i < 50; ++i) {
177 if (stat2 == 0) {
178 B2INFO("\n\tPART-2 FIT STATUS is OK: irr # " << i);
179 break;
180 }
181 stat2 = gr_dedxvsbg->Fit("fdedx2", "FQR", "", bgmin2, bgmax2);
182 }
183 if (stat2 == 0) {
184 B2INFO("\t--> HadronCalibration: ATTENTIONS: PART-2 FIT OK..updating parameters");
185 for (int i = 1; i < 5; ++i) {
186 B2INFO("\t" << i << ") Old = " << gpar.getCurvePars(6 + i) << " --> New = " << fdedx2->GetParameter(i));
187 gpar.setCurvePars(6 + i, fdedx2->GetParameter(i));
188 }
189 } else B2INFO("\t--> HadronCalibration: WARNING: PART-2 FIT FAILED...");
190
191
192 // //Fitting part3 relativistic region and new constants
193 // //----------------------------------------------
194 int stat3 = gr_dedxvsbg->Fit("fdedx3", "FQR", "", bgmin3, bgmax3);
195 for (int i = 0; i < 50; ++i) {
196 if (stat3 == 0) {
197 B2INFO("\n\tPART-3 FIT STATUS is OK: irr # " << i);
198 break;
199 }
200 stat3 = gr_dedxvsbg->Fit("fdedx3", "FQR", "", bgmin3, bgmax3);
201 }
202
203 if (stat3 == 0) {
204 B2INFO("\t--> HadronCalibration: ATTENTIONS: PART-3 FIT OK..updating parameters");
205 for (int i = 1; i < 5; ++i) {
206 B2INFO("\t" << i << ") Old = " << gpar.getCurvePars(10 + i) << " --> New = " << fdedx3->GetParameter(i));
207 gpar.setCurvePars(10 + i, fdedx3->GetParameter(i));
208 }
209 } else B2INFO("\t--> HadronCalibration: WARNING: PART-3 FIT FAILED...");
210
211 // //Plot without fitting (old fits + data points)
212
213 TLine bgline1(4.5, 0.50, 4.5, 1.20);
214 bgline1.SetLineStyle(kDashed);
215 bgline1.SetLineColor(kGray);
216 TLine bgline2(10.0, 0.50, 10.0, 1.20);
217 bgline2.SetLineStyle(kDashed);
218 bgline2.SetLineColor(kGray);
219 TLine dedxline1(0.75, 1.0, 1000, 1.0);
220 dedxline1.SetLineStyle(kDashed);
221 dedxline1.SetLineColor(kGray);
222
223 setFitterStyle(fdedx1, 2, 1);
224 setFitterStyle(fdedx2, 5, 1);
225 setFitterStyle(fdedx3, 8, 1);
226
227 setFitterStyle(fdedx1Copy, 13, 6);
228 setFitterStyle(fdedx2Copy, 4, 6);
229 setFitterStyle(fdedx3Copy, 1, 6);
230
231 TCanvas bgcurvecan(Form("bgcurvecan_%s", suffix.data()), "bg curve and fitting", 1400, 800);
232 bgcurvecan.Divide(3, 2);
233 for (int i = 0; i < 6; i++) {
234 TMultiGraph* grcopy = (TMultiGraph*)grcopy1->Clone(Form("datapoints_%s_%d", suffix.data(), i));
235
236 bgcurvecan.cd(i + 1);
237 gPad->cd();
238 if (i == 0 || i == 3) gPad->SetLogy();
239 gPad->SetLogx();
240 grcopy->GetListOfGraphs()->SetDrawOption("AXIS");
241 grcopy->Draw("A*");
242 gPad->Modified(); gPad->Update();
243
244 if (i == 0 || i == 3) {
245 grcopy->GetXaxis()->SetLimits(0.10, 14500);
246 grcopy->SetMinimum(0.50);
247 grcopy->SetMaximum(50.0);
248 } else if (i == 1 || i == 4) {
249 grcopy->GetXaxis()->SetLimits(0.75, 100);
250 grcopy->SetMinimum(0.020);
251 grcopy->SetMaximum(3.0);
252 } else if (i == 2 || i == 5) {
253 grcopy->GetXaxis()->SetLimits(0.75, 50);
254 grcopy->SetMinimum(0.50);
255 grcopy->SetMaximum(1.20);
256 }
257 gPad->Modified(); gPad->Update();
258 TPaveText* ptold = new TPaveText(.35, .40, .75, .50, "blNDC");
259 ptold->SetBorderSize(0);
260 ptold->SetFillStyle(0);
261 if (i < 3) {
262 fdedx1Copy->Draw("same");
263 fdedx2Copy->Draw("same");
264 fdedx3Copy->Draw("same");
265 ptold->AddText("Old parameters");
266 } else {
267 fdedx1->Draw("same");
268 fdedx2->Draw("same");
269 fdedx3->Draw("same");
270 ptold->AddText("New parameters");
271
272 }
273
274 bgline1.Draw("same");
275 bgline2.Draw("same");
276 dedxline1.Draw("same");
277
278 if (i == 0) {
279 tleg.AddEntry(fdedx1Copy, "Pub-Fit: 1", "f1");
280 tleg.AddEntry(fdedx2Copy, "Pub-Fit: 2", "f1");
281 tleg.AddEntry(fdedx3Copy, "Pub-Fit: 3", "f1");
282 tleg.Draw("same");
283 }
284 if (i == 0 || i == 3) ptold->Draw("same");
285 }
286
287 bgcurvecan.SaveAs(Form("plots/HadronCal/BGfits/bgcurve_vsfits_%s.pdf", suffix.data()));
288
289 TCanvas bgcurveraw(Form("bgcurveraw_%s", suffix.data()), "bg curvs", 600, 600);
290 gPad->SetLogy();
291 gPad->SetLogx();
292 grcopy1->GetListOfGraphs()->SetDrawOption("AXIS");
293 grcopy1->Draw("A*");
294 gPad->Modified(); gPad->Update();
295 tlegPart.Draw("same");
296 fdedx1->Draw("same");
297 fdedx2->Draw("same");
298 fdedx3->Draw("same");
299 bgcurveraw.SaveAs(Form("plots/HadronCal/BGfits/bgcurve_raw_%s.root", suffix.data()));
300 bgcurveraw.SaveAs(Form("plots/HadronCal/BGfits/bgcurve_raw_%s.pdf", suffix.data()));
301
302 bgcurveraw.cd();
303 gPad->SetLogy();
304 gPad->SetLogx();
305 gr_dedxvsp->GetListOfGraphs()->SetDrawOption("AXIS");
306 gr_dedxvsp->Draw("A*");
307 gPad->Modified(); gPad->Update();
308 tlegPart.Draw("same");
309 bgcurveraw.SaveAs(Form("plots/HadronCal/BGfits/dedx_vs_mom_raw_%s.pdf", suffix.data()));
310
311
312 double func1a = fdedx1->Eval(4.5);
313 double func2a = fdedx2->Eval(4.5);
314 double func2b = fdedx2->Eval(10);
315 double func3a = fdedx3->Eval(10);
316 double diffval1 = 100 * abs(func1a - func2a) / func2a;
317 double diffval2 = 100 * abs(func2b - func3a) / func3a;
318 B2INFO("\t\n FIT Constraint for 1/beta^2 region (bg = 4.5): func1 --> " << func1a << ", func2 --> " << func2a <<
319 ", diff in % = " << diffval1);
320 B2INFO("\t\n FIT Constraint for 1/beta^2 region (bg = 10.): func1 --> " << func2b << ", func2 --> " << func3a <<
321 ", diff in % = " << diffval2);
322
323
324 // --------------------------------------------------
325 // GET RESIDUALS AND CHIS
326 // --------------------------------------------------
327 TMultiGraph* fit_bgratio = new TMultiGraph(Form("fit_bgratio_%s", suffix.data()), ";#beta#gamma;ratio");
328 TGraph part_bgfit_ratio[npart];
329
330 TMultiGraph* fit_residual = new TMultiGraph(Form("fit_residual_%s", suffix.data()), ";#beta#gamma;residual");
331 TGraph part_bgfit_residual[npart];
332
333 double A = 4.5, B = 10;
334 int respoint = 1;
335 double rmin = 1.0, rmax = 1.0;
336
337 for (int i = 0; i < npart; ++i) {
338
339 for (int j = 0; j < part_dedxvsbg[i].GetN(); ++j) {
340
341 double x, y, fit;
342 part_dedxvsbg[i].GetPoint(j, x, y);
343
344 if (y == 0) continue;
345
346 if (x < A)
347 fit = fdedx1->Eval(x);
348 else if (x < B)
349 fit = fdedx2->Eval(x);
350 else
351 fit = fdedx3->Eval(x);
352
353 // the curve is just 1 for electrons...
354 if (npart == 4) fit = 1.0;
355 if (x < 2000) {
356 part_bgfit_ratio[i].SetPoint(respoint++, x, fit / y);
357 part_bgfit_residual[i].SetPoint(respoint++, x, fit - y);
358 }
359
360 if (fit / y < rmin) rmin = fit / y;
361 else if (fit / y > rmax) rmax = fit / y;
362
363 }
364
365 part_bgfit_ratio[i].SetMarkerSize(0.50);
366 part_bgfit_ratio[i].SetMarkerStyle(4);
367 part_bgfit_ratio[i].SetMarkerColor(i + 1);
368 if (i == 4) part_bgfit_ratio[i].SetMarkerColor(i + 2);
369 if (i <= 3)fit_bgratio->Add(&part_bgfit_ratio[i]);
370
371 part_bgfit_residual[i].SetMarkerSize(0.50);
372 part_bgfit_residual[i].SetMarkerStyle(4);
373 part_bgfit_residual[i].SetMarkerColor(i + 1);
374 if (i == 4)part_bgfit_residual[i].SetMarkerColor(i + 2);
375 if (i <= 3)fit_residual->Add(&part_bgfit_residual[i]);
376 }
377
378 fit_bgratio->SetMinimum(rmin * 0.97);
379 fit_bgratio->SetMaximum(rmax * 1.03);
380
381 TCanvas* bgfitratiocan = new TCanvas(Form("bgfitratiocan_%s", suffix.data()), "dE/dx fit residual", 450, 350);
382 bgfitratiocan->cd()->SetLogx();
383 bgfitratiocan->cd()->SetGridy();
384 fit_bgratio->Draw("AP");
385 tlegPart.Draw("same");
386 bgfitratiocan->SaveAs(Form("plots/HadronCal/BGfits/bgfit_ratios_%s.pdf", suffix.data()));
387 delete bgfitratiocan;
388
389 fit_residual->SetMinimum(-0.12);
390 fit_residual->SetMaximum(+0.12);
391
392 TCanvas* bgrescan = new TCanvas(Form("bgrescan_%s", suffix.data()), "dE/dx fit residual", 450, 350);
393 bgrescan->cd()->SetLogx();
394 bgrescan->cd()->SetGridy();
395 fit_residual->Draw("AP");
396 tlegPart.Draw("same");
397 bgrescan->SaveAs(Form("plots/HadronCal/BGfits/bgfit_residual_%s.pdf", suffix.data()));
398 delete bgrescan;
399
400 // write out the (possibly) updated parameters to file
401 gpar.printParameters("parameters.bgcurve.fit"); //Creating new file with new parameters
402
403 delete gr_dedxvsbg;
404 delete gr_dedxvsp;
405
406 delete fdedx1;
407 delete fdedx2;
408 delete fdedx3;
409 delete fdedx1Copy;
410 delete fdedx2Copy;
411 delete fdedx3Copy;
412
413 infile->Close();
414}
415
416void HadronCalibration::plotBGMonitoring(std::vector< std::string > particles, const std::string& filename,
417 const std::string& suffix)
418{
419 //1. chi-mean vs bg
420 std::string title = "chi-fit-means of different particles;#beta#gamma;#chi(#mu)";
421 std::string sname = Form("gr_chimean_vs_bg_%s", suffix.data());
422 plotMonitoring(particles, filename, sname, title, "bg", "chi");
423
424 //2. Sigma vs bg
425 title = "chi-fit-width of different particles;#beta#gamma;#chi(#sigma)";
426 sname = Form("gr_chiwidth_vs_bg_%s", suffix.data());
427 plotMonitoring(particles, filename, sname, title, "bg", "sigma");
428
429 //3. chi mean vs p
430 title = "chi-fit-means of different particles: latest curve+sigma pars;p(GeV/c);#chi(#mu)";
431 sname = Form("gr_chimean_vs_mom_%s", suffix.data());
432 plotMonitoring(particles, filename, sname, title, "mom", "chi");
433
434 //4. Sigma vs p
435 title = "chi-fit-width of different particles: w/ latest curve+sigma pars;p(GeV/c);#chi(#sigma)";
436 sname = Form("gr_chiwidth_vs_mom_%s", suffix.data());
437 plotMonitoring(particles, filename, sname, title, "mom", "sigma");
438
439 std::string svar = "ler";
440 for (int ir = 0; ir < 2; ir++) {
441 if (ir == 1) svar = "her";
442
443 //5. chi mean vs injection time
444 title = Form("#chi mean vs injection time, %s;injection time;#chi_{#mu}", svar.data());
445 sname = Form("gr_chimean_vs_inj_%s_%s", suffix.data(), svar.data());
446 plotMonitoring(particles, filename, sname, title, svar, "chi");
447
448 //5. chi sigma vs injection time
449 title = Form("#chi sigma vs injection time, %s;injection time;#chi_{#sigma}", svar.data());
450 sname = Form("gr_chiwidth_vs_inj_%s_%s", suffix.data(), svar.data());
451 plotMonitoring(particles, filename, sname, title, svar, "sigma");
452 }
453}
454
455void HadronCalibration::plotMonitoring(std::vector< std::string > particles, const std::string& filename, const std::string& sname,
456 const std::string& title,
457 const std::string& sxvar, const std::string& syvar)
458{
459
460 const int npart = int(particles.size());
461
462 // read in a file that contains fit results for bg bins
463 TFile* infile = new TFile(filename.data());
464
465 // multigraphs to hold the curve and residual results
466 // TGraphErrors grchim[npart];
467 std::vector<TGraphErrors> grchim(npart);
468
469 TMultiGraph* gr_var = new TMultiGraph(Form("%s", sname.data()), "");
470
471 TLegend tlegPart(0.75, 0.65, 0.90, 0.90);
472 tlegPart.SetBorderSize(0);
473
474 for (int i = 0; i < npart; ++i) {
475 std::string particle = particles[i];
476 double mass = m_prep.getParticleMass(particle);
477 if (mass == 0.0) B2FATAL("Mass of particle " << particle.data() << " is zero");
478
479 if (!infile->GetListOfKeys()->Contains(particle.data())) continue;
480 TTree* hadron;
481 if (sxvar == "bg" || sxvar == "mom") hadron = (TTree*)infile->Get(particle.data());
482 else hadron = (TTree*)infile->Get(Form("%s_%s", particle.data(), sxvar.data()));
483
484 B2INFO("HadronCalibration: reading " << particle.data() << " in file " << filename.data());
485
486 double chimean, chisigma, avg, chimean_err, chisigmaerr;
487
488 hadron->SetBranchAddress("chimean", &chimean);
489 hadron->SetBranchAddress("chimean_err", &chimean_err);
490 hadron->SetBranchAddress("chisigma", &chisigma);
491 hadron->SetBranchAddress("chisigma_err", &chisigmaerr);
492 if (sxvar == "bg" || sxvar == "mom") hadron->SetBranchAddress("bg_avg", &avg);
493 else hadron->SetBranchAddress("inj_avg", &avg);
494
495 for (int j = 0; j < hadron->GetEntries(); ++j) {
496
497 hadron->GetEvent(j);
498 double var, xvar; //varerr
499 if (syvar == "chi") {var = chimean;} // varerr = chimean_err;}
500 else {var = chisigma;} // varerr = chisigmaerr;}
501 if (sxvar == "mom") xvar = avg * mass;
502 else xvar = avg;
503
504 grchim[i].SetPoint(j, xvar, var);
505 //grchim[i].SetPointError(j, 0, varerr);
506 }
507
508 tlegPart.AddEntry(&grchim[i], particles[i].data(), "p");
509
510 setGraphStyle(grchim[i], i + 1);
511 if (i == 4) grchim[i].SetMarkerColor(i + 2);
512 gr_var->Add(&grchim[i]);
513
514 }
515
516 TCanvas ctemp(Form("%s", sname.data()), Form("%s", sname.data()), 450, 350);
517 gPad->SetGridy();
518 if (sxvar == "bg" || sxvar == "mom") gPad->SetLogx();
519
520 if (syvar == "chi") { gr_var->SetMinimum(-1.0); gr_var->SetMaximum(+1.0);}
521 else { gr_var->SetMinimum(0.6); gr_var->SetMaximum(1.4); }
522
523 gr_var->SetTitle(Form("%s", title.data()));
524 gr_var->Draw("AP");
525 tlegPart.Draw("same");
526 ctemp.SaveAs(Form("plots/HadronCal/Monitoring/%s.pdf", sname.data()));
527 if (sxvar == "bg" || sxvar == "mom") {
528 gPad->SetLogx();
529 if (sxvar == "bg") gr_var->GetXaxis()->SetLimits(0.1, 20);
530 else gr_var->GetXaxis()->SetLimits(0.1, 1.0);
531 gr_var->Draw("AP");
532 tlegPart.Draw("same");
533 ctemp.SaveAs(Form("plots/HadronCal/Monitoring/%s_zoomed.pdf", sname.data()));
534 }
535 delete gr_var;
536}
537
538void HadronCalibration::fitSigmavsIonz(std::vector< std::string > particles, const std::string& filename,
539 const std::string& paramfile,
540 const std::string& suffix)
541{
542
543 // read in a file that contains fit results for bg bins
544 const int npart = int(particles.size());
545
546 CDCDedxSigmaPred gpar;
547 gpar.setParameters(paramfile.data());
548
549 TFile* infile = new TFile(filename.data());
550 std::vector<TGraphErrors> part_resovsdedx(npart);
551
552 TMultiGraph* gr_resovsdedx = new TMultiGraph("gr_resovsdedx", ";dedx;#sigma(ionz)");
553
554 TLegend tlegPart(0.72, 0.15, 0.88, 0.40);
555
556 for (int i = 0; i < int(particles.size()); ++i) {
557
558 std::string particle = particles[i];
559
560 double mass = m_prep.getParticleMass(particle);
561 if (mass == 0.0) B2FATAL("Mass of particle " << particle.data() << " is zero");
562
563 if (particle == "electron") continue;
564
565 if (!infile->GetListOfKeys()->Contains(particle.data())) continue;
566 TTree* hadron = (TTree*)infile->Get(particle.data());
567 B2INFO("\tHadronCalibration: reading " << particle << " in file " << filename.data());
568
569 double dedx, ionzres;
570
571 hadron->SetBranchAddress("dedx", &dedx);
572 hadron->SetBranchAddress("ionzres", &ionzres);
573
574 part_resovsdedx[i].SetName(particle.data());
575
576 for (int j = 0; j < hadron->GetEntries(); ++j) {
577 hadron->GetEvent(j);
578 part_resovsdedx[i].SetPoint(j, dedx, ionzres);
579 }
580
581 if (i == 4) setGraphStyle(part_resovsdedx[i], i + 2);
582 else setGraphStyle(part_resovsdedx[i], i + 1);
583 gr_resovsdedx->Add(&part_resovsdedx[i]);
584 tlegPart.AddEntry(&part_resovsdedx[i], particles[i].data(), "p");
585 }
586
587 gStyle->SetOptStat(0);
588 gStyle->SetStatY(0.9); // Set y-position (fraction of pad size)
589 gStyle->SetStatX(0.4); // Set x-position (fraction of pad size)
590 gStyle->SetStatW(0.15); // Set width of stat-box (fraction of pad size)
591 gStyle->SetStatH(0.15); // Set height of stat-box (fraction of pad size)
592
593 TF1* sigvsdedx = new TF1("sigvsdedx", "[0]+[1]*x", 0.50, 15.0);
594 sigvsdedx->SetParameter(0, gpar.getDedxPars(0));
595 sigvsdedx->SetParameter(1, gpar.getDedxPars(1));
596
597 TF1* sigvsdedxCopy = (TF1*)sigvsdedx->Clone("sigvsdedxcopy");
598 setFitterStyle(sigvsdedxCopy, 13, 6);
599
600 TCanvas sigcan("sigcan", " Reso(ionz) vs dE/dx", 820, 750);
601 sigcan.cd();
602 gr_resovsdedx->Draw("APE");
603 sigvsdedxCopy->Draw("same");
604 tlegPart.Draw("same");
605
606 int status = gr_resovsdedx->Fit("sigvsdedx", "MF", "", 0.50, 7.0);
607 for (int i = 0; i < 10; ++i) {
608 if (status == 0) break;
609 status = gr_resovsdedx->Fit("sigvsdedx", "", "", 0.50, 7.0);
610 }
611 gr_resovsdedx->SetTitle(Form("%s (slope = %0.03f, const = %0.03f)", gr_resovsdedx->GetTitle(), sigvsdedx->GetParameter(1),
612 sigvsdedx->GetParameter(0)));
613 gPad->Modified(); gPad->Update();
614 sigcan.SaveAs(Form("plots/HadronCal/Resofits/sigma_vsionz_%s.pdf", suffix.data()));
615
616 gr_resovsdedx->GetXaxis()->SetLimits(0.2, 2.00);
617 gr_resovsdedx->GetHistogram()->SetMaximum(0.50);
618 gr_resovsdedx->GetHistogram()->SetMinimum(0.00);
619 gr_resovsdedx->Draw("APE");
620 sigvsdedxCopy->Draw("same");
621 tlegPart.Draw("same");
622 sigcan.SaveAs(Form("plots/HadronCal/Resofits/sigma_vsionz_zoomed_%s.pdf", suffix.data()));
623 gStyle->SetOptStat(11);
624
625 // if the fit was successful, save the updated parameters
626 if (status == 0) {
627 B2INFO("\tHadronCalibration: SigmavsdEdx FITs Ok. updating parameters");
628 for (int i = 0; i < 2; ++i) {
629 B2INFO("\t" << i << ") Old = " << gpar.getDedxPars(i) << " --> New = " << sigvsdedx->GetParameter(i));
630 gpar.setDedxPars(i, sigvsdedx->GetParameter(i));
631 }
632 } else B2INFO("\tHadronCalibration: WARNING: SigmavsdEdx FIT FAILED... \n \tHadronCalibration: Skipping parameters");
633
634 // write out the (possibly) updated parameters to file
635 gpar.printParameters("parameters.ionz.fit"); //Creating new file with new parameters
636 infile->Close();
637
638 delete gr_resovsdedx;
639 delete sigvsdedx;
640}
641
642void HadronCalibration::fitSigmaVsNHit(std::vector< std::string > particles, const std::string& filename,
643 const std::string& paramsigma,
644 const std::string& suffix)
645{
646
647 const double lowernhit = 7, uppernhit = 39;
648
649 CDCDedxSigmaPred sgpar;
650 sgpar.setParameters(paramsigma.data());
651
653
654 TF1* fsigma = new TF1("fsigma", [gs](double * x, double * par) {
655 std::vector<double> parVec(par, par + 6); // Create a vector from the parameters
656 return gs->sigmaCurve(x, parVec); // Call the member function
657 }, lowernhit, uppernhit, 6, "CDCDedxWidgetSigma");
658
659 fsigma->SetParameter(0, 2);
660 for (int i = 1; i < 6; ++i) fsigma->SetParameter(i, sgpar.getNHitPars(i - 1));
661
662 TF1* fsigmacopy = (TF1*)fsigma->Clone("fsigmacopy");
663 setFitterStyle(fsigmacopy, 13, 6);
664
665 TFile* infile = new TFile(filename.data());
666
667 for (int ip = 0; ip < int(particles.size()); ++ip) {
668
669 std::string particle = particles[ip];
670 TGraphErrors gr_dedxvsbg;
671
672 if (!infile->GetListOfKeys()->Contains(Form("%s_nhit", particle.data()))) continue;
673 TTree* hadron = (TTree*)infile->Get(Form("%s_nhit", particle.data()));
674 B2INFO("\tHadronCalibration: reading " << particle << " in file " << filename.data());
675
676 double avg, sigma, sigmaerr;
677
678 hadron->SetBranchAddress("avg", &avg);
679 hadron->SetBranchAddress("chisigma", &sigma);
680 hadron->SetBranchAddress("chisigma_err", &sigmaerr);
681
682 for (int j = 0; j < hadron->GetEntries(); ++j) {
683 hadron->GetEvent(j);
684 gr_dedxvsbg.SetPoint(j, avg, sigma);
685 gr_dedxvsbg.SetPointError(j, 0, sigmaerr);
686 }
687
688 // --------------------------------------------------
689 // FIT SIGMA VS NHIT CURVE
690 // --------------------------------------------------
691 gStyle->SetOptFit(0);
692 TCanvas sigvsnhitcan(Form("sigvsnhitcan_%s", suffix.data()), "#sigma vs. nHit", 600, 600);
693
694 gr_dedxvsbg.SetMarkerStyle(8);
695 gr_dedxvsbg.SetMarkerSize(0.5);
696 gr_dedxvsbg.SetMaximum(2.2);
697 gr_dedxvsbg.SetMinimum(0.0);
698 gr_dedxvsbg.SetTitle(Form("width of (dedx-pred)/(#sigma_{Cos * Ion * InjReso}) vs lNHitsUsed, %s ;lNHitsUsed; #sigma",
699 particle.data()));
700 gr_dedxvsbg.Draw("AP");
701 fsigmacopy->Draw("same");
702
703 TLegend tleg(0.4, 0.70, 0.65, 0.85);
704 tleg.SetBorderSize(0);
705 tleg.AddEntry(&gr_dedxvsbg, "Data points", "P");
706 tleg.AddEntry(fsigmacopy, "Public Fit", "f1");
707
708 if (particle == "muon") {
709
710 // if the fit succeeds, write out the new parameters
711 int status = gr_dedxvsbg.Fit("fsigma", "FR", "", lowernhit, uppernhit);
712
713 for (int i = 0; i < 20; ++i) {
714 if (status == 0) break;
715 status = gr_dedxvsbg.Fit("fsigma", "FR", "", lowernhit, uppernhit);
716 }
717
718 if (status == 0) {
719 B2INFO("\tHadronCalibration::fitSigmaVsNHit --> FIT OK..updating parameters");
720 for (int j = 1; j < 6; ++j) {
721 B2INFO("\t" << j << ") Old = " << sgpar.getNHitPars(j - 1) << " --> New = " << fsigma->GetParameter(j));
722 sgpar.setNHitPars(j - 1, fsigma->GetParameter(j));
723 }
724 } else B2INFO("\tHadronCalibration::fitSigmaVsNHit --> WARNING: FIT FAILED..: status = " << status);
725
726 // write out the (possibly) updated parameters to file
727 sgpar.printParameters("parameters.sigmanhit.fit");
728
729 tleg.AddEntry(fsigma, "New Fit", "f1");
730 }
731
732 else {
733 sgpar.setParameters("parameters.sigmanhit.fit");
734 for (int i = 1; i < 6; ++i) fsigma->SetParameter(i, sgpar.getNHitPars(i - 1));
735 fsigma->SetRange(7, 39);
736 fsigma->Draw("same");
737 tleg.AddEntry(fsigma, "New (param. from muon fit)", "f1");
738 }
739
740 tleg.Draw("same");
741
742 sigvsnhitcan.SaveAs(Form("plots/HadronCal/Resofits/sigma_vsnhits_%s_%s.pdf", suffix.data(), particle.data()));
743 }
744}
745
746void HadronCalibration::fitSigmaVsCos(std::vector< std::string > particles, const std::string& filename,
747 const std::string& paramsigma,
748 const std::string& suffix)
749{
750 double lowercos = -0.84, uppercos = 0.96;
751
752 CDCDedxSigmaPred gpar;
753 gpar.setParameters(paramsigma.data());
754
756
757 TF1* total = new TF1("total", [gs](double * x, double * par) {
758 std::vector<double> parVec(par, par + 11); // Create a vector from the parameters
759 return gs->sigmaCurve(x, parVec); // Call the member function
760 }, lowercos, uppercos, 11, "CDCDedxWidgetSigma"); // 6 parameters for this example
761
762 for (int i = 0; i < 10; ++i) total->SetParameter(i + 1, gpar.getCosPars(i));
763 total->FixParameter(0, 3);
764 total->FixParameter(2, 0.0);
765
766 TF1* fsigmacopy = (TF1*)total->Clone("fsigmacopy");
767 setFitterStyle(fsigmacopy, 13, 6);
768
769 TFile* infile = new TFile(filename.data());
770
771 for (int ip = 0; ip < int(particles.size()); ++ip) {
772
773 std::string particle = particles[ip];
774 TGraphErrors gr_dedx;
775
776 if (!infile->GetListOfKeys()->Contains(Form("%s_costh", particle.data()))) continue;
777 TTree* hadron = (TTree*)infile->Get(Form("%s_costh", particle.data()));
778 B2INFO("\tHadronCalibration: reading " << particle << " in file " << filename.data());
779
780 double avg, sigma, sigmaerr;
781
782 hadron->SetBranchAddress("avg", &avg);
783 hadron->SetBranchAddress("chisigma", &sigma);
784 hadron->SetBranchAddress("chisigma_err", &sigmaerr);
785
786 for (int j = 0; j < hadron->GetEntries(); ++j) {
787 hadron->GetEvent(j);
788 gr_dedx.SetPoint(j, avg, sigma);
789 gr_dedx.SetPointError(j, 0, sigmaerr);
790 }
791
792 // --------------------------------------------------
793 // FIT SIGMA VS COS CURVE
794 // --------------------------------------------------
795 gStyle->SetOptFit(0);
796
797 TCanvas sigvscos("sigvscos", "#sigma vs. cos(#theta)", 400, 400);
798
799 gr_dedx.SetMaximum(1.8);
800 gr_dedx.SetMinimum(0.4);
801 gr_dedx.SetTitle(Form("(dedx-pred)/(#sigma_{Nhit * Ion * InjReso}) vs cos(#theta), %s;cos(#theta);#sigma", particle.data()));
802 gr_dedx.Draw("AP");
803
804 fsigmacopy->Draw("same");
805
806 TLegend tleg(0.75, 0.75, 0.89, 0.89);
807 tleg.SetBorderSize(0);
808 tleg.AddEntry(&gr_dedx, "Data points", "P");
809 tleg.AddEntry(fsigmacopy, "Public Fit", "f1");
810
811 if (particle == "muon") {
812
813 int status = gr_dedx.Fit("total", "FR", "", lowercos, uppercos);
814
815 for (int i = 0; i < 20; ++i) {
816 if (status == 0) break;
817 status = gr_dedx.Fit("total", "FR", "", lowercos, uppercos);
818 }
819 if (status == 0) {
820 B2INFO("\tHadronCalibration::fitSigmaVsCos --> FIT OK..updating parameters");
821 for (int j = 1; j < 11; ++j) {
822 B2INFO("\t" << j - 1 << ") Old = " << gpar.getCosPars(j - 1) << " --> New = " << total->GetParameter(j));
823 gpar.setCosPars(j - 1, total->GetParameter(j));
824 }
825 } else B2INFO("\tHadronCalibration::fitSigmaVsCos --> WARNING: FIT FAILED..: status = " << status);
826
827 gpar.printParameters("parameters.sigmacos.fit");
828 tleg.AddEntry(total, "New Fit", "f1");
829
830 } else {
831 gpar.setParameters("parameters.sigmacos.fit");
832 for (int i = 1; i < 11; ++i) total->SetParameter(i, gpar.getCosPars(i - 1));
833 total->Draw("same");
834 tleg.AddEntry(total, "New (param. from muon fit)", "f1");
835
836 }
837
838 tleg.Draw("same");
839 sigvscos.SaveAs(Form("plots/HadronCal/Resofits/sigma_vscos_%s_%s.pdf", suffix.data(), particle.data()));
840 }
841
842}
Class to hold the prediction of mean as a function of beta-gamma (bg)
void setCurvePars(int i, double val)
set the curve parameters
void printParameters(std::string infile)
write the parameters in file
double getCurvePars(int i)
get the curve parameters
void setParameters(std::string infile)
set the parameters from file
Class to hold the prediction of resolution depending dE/dx, nhit, and cos(theta)
void setNHitPars(int i, double val)
set the nhit parameters
double getCosPars(int i)
get the cos(theta) parameters
double getDedxPars(int i)
get the dedx parameters
void setDedxPars(int i, double val)
set the dedx parameters
void setCosPars(int i, double val)
set the cos(theta) parameters
void printParameters(std::string infile)
write the parameters in file
void setParameters(std::string infile)
set the parameters from file
double getNHitPars(int i)
get the nhit parameters
Class to hold the beta-gamma (bg) mean function.
double meanCurve(double *x, const std::vector< double > &par) const
calculate the predicted mean value as a function of beta-gamma (bg) this is done with a different fun...
Class to hold the beta-gamma (bg) resolution function.
double sigmaCurve(double *x, const std::vector< double > &par) const
calculate the predicted sigma value as a function of beta-gamma (bg) this is done with a different fu...
double getParticleMass(const std::string &particle)
function to get the particle mass
Definition: HadronBgPrep.h:160
void plotMonitoring(std::vector< std::string > particles, const std::string &filename, const std::string &sname, const std::string &title, const std::string &sx, const std::string &sy)
plots chi and width after fitting - main function
void fitSigmaVsCos(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffx)
fit sigma vs.
void setFitterStyle(TF1 *&fitt, const int ic, const int il)
function to set fitter cosmetics
void fitSigmaVsNHit(std::vector< std::string > particles, const std::string &filename, const std::string &paramsigma, const std::string &suffx)
fit sigma vs.
void fitBGCurve(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffx)
fit the beta-gamma curve
void plotBGMonitoring(std::vector< std::string > particles, const std::string &filename, const std::string &suffix)
plots mean and width after fitting
void setGraphStyle(TGraphErrors &gr, const int ic)
function to set graph cosmetics
HadronBgPrep m_prep
object for dE/dx to prepare sample
void fitSigmavsIonz(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffix)
fit sigma vs.
HadronCalibration()
Constructor: Sets the description, the properties and the parameters of the algorithm.
Abstract base class for different kinds of events.