Belle II Software  release-08-01-10
CDCDedxInjectTimeAlgorithm.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/CDCDedxInjectTimeAlgorithm.h>
10 
11 using namespace Belle2;
12 
13 //-----------------------------------------------------------------
14 // Implementation
15 //-----------------------------------------------------------------
17  CalibrationAlgorithm("CDCDedxElectronCollector"),
18  m_sigmaR(2.0),
19  m_dedxBins(250),
20  m_dedxMin(0.0),
21  m_dedxMax(2.5),
22  m_chiBins(250),
23  m_chiMin(-10.0),
24  m_chiMax(10.0),
25  m_countR(0),
26  m_thersE(1000),
27  m_isminStat(false),
28  m_ismakePlots(true),
29  m_isMerge(true),
30  m_prefix("cdcdedx_injcal"),
31  m_suffix("")
32 {
33  // Set module properties
34  setDescription("A calibration algorithm for CDC dE/dx injection time gain and reso");
35 }
36 
37 //-----------------------------------------------------------------
38 // Run the calibration
39 //-----------------------------------------------------------------
41 {
42 
43  getExpRunInfo();
44 
45  //existing inject time payload for merging
46  if (!m_DBInjectTime.isValid())
47  B2FATAL("There is no valid payload for Injection time");
48 
49  // Get data objects
50  auto ttree = getObjectPtr<TTree>("tree");
51  if (!ttree) return c_NotEnoughData;
52 
53  double dedx = 0.0, injtime = 0.0, injring = 1.0, costh, mom;
54  int nhits;
55  ttree->SetBranchAddress("dedx", &dedx);
56  ttree->SetBranchAddress("injtime", &injtime);
57  ttree->SetBranchAddress("injring", &injring);
58  ttree->SetBranchAddress("costh", &costh);
59  ttree->SetBranchAddress("p", &mom);
60  ttree->SetBranchAddress("nhits", &nhits);
61 
62  //way to define time bins/edges only once
63  if (m_countR == 0) {
64  defineTimeBins(); //returns m_vtlocaledges
65  m_tbins = m_vtlocaledges.size() - 1;
67  m_countR++;
68  }
69 
70  TH1D* htimes = new TH1D(Form("htimes_%s", m_suffix.data()), "", m_tbins, m_tedges);
71 
72  //time bins are changable from out so vector is used
73  std::array<std::vector<TH1D*>, numdedx::nrings> hdedx, htime, hchi, hdedx_corr;
74  defineHisto(hdedx, "dedx");
75  defineHisto(hdedx_corr, "dedx_corr");
76  defineHisto(htime, "timeinj");
77  defineHisto(hchi, "chi");
78 
79  const double tzedges[4] = {0, 2.0e3, 0.1e6, 20e6};
80  std::array<std::array<TH1D*, 3>, numdedx::nrings> hztime;
81  defineTimeHisto(hztime);
82 
83  //fill histograms
84  for (int i = 0; i < ttree->GetEntries(); ++i) {
85 
86  ttree->GetEvent(i);
87  if (dedx <= 0 || injtime < 0 || injring < 0) continue;
88 
89  //add larger times to the last bin
90  if (injtime > m_tedges[m_tbins]) injtime = m_tedges[m_tbins] - 10.0;
91 
92  //injection ring
93  int wr = 0;
94  if (injring > 0.5) wr = 1;
95 
96  //injection time bin
97  unsigned int tb = htimes->GetXaxis()->FindBin(injtime);
98  if (tb > m_tbins)tb = m_tbins; //overflow
99  tb = tb - 1;
100 
101  htimes->Fill(injtime);
102  if (injtime < tzedges[1]) hztime[wr][0]->Fill(injtime);
103  else if (injtime < tzedges[2]) hztime[wr][1]->Fill(injtime);
104  else hztime[wr][2]->Fill(injtime);
105 
106  hdedx[wr][tb]->Fill(dedx);
107  htime[wr][tb]->Fill(injtime);
108  }
109 
110  //keep merging runs to achive enough stats
111  m_isminStat = false;
112  checkStatistics(hdedx);
113  if (m_isminStat) {
114  deleteHisto(htime);
115  deleteHisto(hdedx);
116  deleteHisto(hdedx_corr);
117  deleteHisto(hchi);
118  deleteTimeHisto(hztime);
119  delete htimes;
120  return c_NotEnoughData;
121  }
122 
123  //clear vector of existing constants
124  std::map<int, std::vector<double>> vmeans, vresos, vtimes;
125 
126  // get time vector
127  for (unsigned int ir = 0; ir < c_rings; ir++) {
128  for (unsigned int it = 0; it < m_tbins; it++) {
129  double avgtime = htime[ir][it]->GetMean();
130  double avgtimeerr = htime[ir][it]->GetMeanError();
131  vtimes[ir * 2].push_back(avgtime);
132  vtimes[ir * 2 + 1].push_back(avgtimeerr);
133  }
134  }
135 
136  //Fit dedx to get mean and resolution
137  getMeanReso(hdedx, vmeans, vresos);
138 
139  //Bin-bias correction to mean
140  std::map<int, std::vector<double>> vmeanscorr;
141  correctBinBias(vmeanscorr, vmeans, vtimes, htimes);
142 
143  //scale the mean and merge with old constants
144  std::array<double, numdedx::nrings> scale;
145  std::map<int, std::vector<double>> vmeanscal;
146  createPayload(scale, vmeanscorr, vmeanscal, "mean");
147 
148  //................................................
149  // Do the calibration for resolution
150  //................................................
151  CDCDedxMeanPred m;
153  //fill histograms for the resolution
154  for (int i = 0; i < ttree->GetEntries(); ++i) {
155 
156  ttree->GetEvent(i);
157  if (dedx <= 0 || injtime < 0 || injring < 0) continue;
158 
159  double corrcetion = getCorrection(injring, injtime, vmeanscal);
160  double old_cor = m_DBInjectTime->getCorrection("mean", injring, injtime);
161 
162  dedx = (dedx * old_cor) / corrcetion;
163  //add larger times to the last bin
164  if (injtime > m_tedges[m_tbins]) injtime = m_tedges[m_tbins] - 10.0;
165 
166  //injection ring
167  int wr = 0;
168  if (injring > 0.5) wr = 1;
169 
170  //injection time bin
171  unsigned int tb = htimes->GetXaxis()->FindBin(injtime);
172  if (tb > m_tbins)tb = m_tbins; //overflow
173  tb = tb - 1;
174 
175  double predmean = m.getMean(mom / Const::electron.getMass());
176  double predsigma = s.nhitPrediction(nhits) * s.ionzPrediction(dedx) * s.cosPrediction(costh);
177 
178  double chi = (dedx - predmean) / predsigma;
179  hdedx_corr[wr][tb]->Fill(dedx);
180  hchi[wr][tb]->Fill(chi);
181  }
182 
183  // fit chi to get mean and resolution
184  std::map<int, std::vector<double>> vmeans_chi, vresos_chi;
185  getMeanReso(hchi, vmeans_chi, vresos_chi);
186 
187  //bin-bias correction to the resolution
188  std::map<int, std::vector<double>> vresoscorr;
189  correctBinBias(vresoscorr, vresos_chi, vtimes, htimes);
190 
191  // scale the resolution
192  std::map<int, std::vector<double>> vresoscal;
193  std::array<double, numdedx::nrings> scale_reso;
194  createPayload(scale_reso, vresoscorr, vresoscal, "reso");
195 
196  //Fit the corrected mean to check for consistency
197  std::map<int, std::vector<double>> vmeans_corr, vresos_corr;
198  getMeanReso(hdedx_corr, vmeans_corr, vresos_corr);
199 
200  //................................................
201  //preparing final payload
202  //................................................
203  m_vinjPayload.clear();
204  m_vinjPayload.reserve(6);
205  for (int ir = 0; ir < 2; ir++) {
206  m_vinjPayload.push_back(m_vtlocaledges);
207  m_vinjPayload.push_back(vmeanscal[ir * 2]);
208  m_vinjPayload.push_back(vresoscal[ir * 2]);
209  }
210 
211  if (m_ismakePlots) {
212 
213  //0 plot event track statistics
214  plotEventStats();
215 
216  //1 plot injection time
217  plotInjectionTime(hztime);
218 
219  //2. Draw dedxfits
220  plotBinLevelDist(hdedx, "dedxfits");
221 
222  //3. Draw chifits
223  plotBinLevelDist(hchi, "chifits");
224 
225  //4. Draw timedist
226  plotBinLevelDist(htime, "timedist");
227 
228  //5. plot relative const., bias-bias corrected for dedx
229  plotRelConstants(vmeans, vresos, vmeanscorr, "dedx");
230 
231  //6. plot relative const., bias-bias corrected for chi
232  plotRelConstants(vmeans_chi, vresos_chi, vresoscorr, "chi");
233 
234  //7. plot mean and resolution of corrected dedx to check for consistency
235  plotRelConstants(vmeans_corr, vresos_corr, vresoscorr, "dedx_corr");
236 
237  //8. plot time statistics dist
238  plotTimeStat(htime);
239 
240  //9. plot final merged const. and comparison to old
241  plotFinalConstants(vmeanscal, vresoscal, scale, scale_reso);
242  }
243 
244  //saving payloads;
246  saveCalibration(gains, "CDCDedxInjectionTime");
247  B2INFO("dE/dx Injection time calibration done");
248 
249  //delete all histograms
250  deleteHisto(htime);
251  deleteHisto(hdedx);
252  deleteHisto(hdedx_corr);
253  deleteHisto(hchi);
254  deleteTimeHisto(hztime);
255  delete htimes;
256 
257  B2INFO("Saving calibration for: " << m_suffix << "");
258  return c_OK;
259 }
260 
261 //------------------------------------
262 void CDCDedxInjectTimeAlgorithm::getMeanReso(std::array<std::vector<TH1D*>, numdedx::nrings>& hvar,
263  std::map<int, std::vector<double>>& vmeans, std::map<int, std::vector<double>>& vresos)
264 {
265  for (unsigned int ir = 0; ir < c_rings; ir++) {
266 
267  for (unsigned int it = 0; it < m_tbins; it++) {
268  double mean = 1.00, meanerr = 0.0;
269  double reso = 1.00, resoerr = 0.0;
270  if (hvar[ir][it]->Integral() > 250) {
271  fstatus status;
272  fitGaussianWRange(hvar[ir][it], status);
273  if (status != fitOK) {
274  mean = hvar[ir][it]->GetMean();
275  hvar[ir][it]->SetTitle(Form("%s, (%d)", hvar[ir][it]->GetTitle(), status));
276  } else {
277  mean = hvar[ir][it]->GetFunction("gaus")->GetParameter(1);
278  meanerr = hvar[ir][it]->GetFunction("gaus")->GetParError(1);
279  reso = hvar[ir][it]->GetFunction("gaus")->GetParameter(2);
280  resoerr = hvar[ir][it]->GetFunction("gaus")->GetParError(2);
281  std::string title = Form("#mu_{fit}: %0.03f, #sigma_{fit}: %0.03f", mean, reso);
282  hvar[ir][it]->SetTitle(Form("%s, %s", hvar[ir][it]->GetTitle(), title.data()));
283  }
284  }
285 
286  vmeans[ir * 2].push_back(mean);
287  vresos[ir * 2].push_back(reso);
288  vmeans[ir * 2 + 1].push_back(meanerr);
289  vresos[ir * 2 + 1].push_back(resoerr);
290  }
291  }
292 }
293 
294 //----------------------------------------
295 void CDCDedxInjectTimeAlgorithm::fitGaussianWRange(TH1D*& temphist, fstatus& status)
296 {
297  double histmean = temphist->GetMean();
298  double histrms = temphist->GetRMS();
299  temphist->GetXaxis()->SetRangeUser(histmean - 5.0 * histrms, histmean + 5.0 * histrms);
300 
301  int fs = temphist->Fit("gaus", "Q0");
302  if (fs != 0) {
303  B2INFO(Form("\tFit (round 1) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
304  status = fitFailed;
305  return;
306  } else {
307  double mean = temphist->GetFunction("gaus")->GetParameter(1);
308  double width = temphist->GetFunction("gaus")->GetParameter(2);
309  temphist->GetXaxis()->SetRangeUser(mean - 5.0 * width, mean + 5.0 * width);
310  fs = temphist->Fit("gaus", "QR", "", mean - m_sigmaR * width, mean + m_sigmaR * width);
311  if (fs != 0) {
312  B2INFO(Form("\tFit (round 2) for hist (%s) failed (status = %d)", temphist->GetName(), fs));
313  status = fitFailed;
314  return;
315  } else {
316  temphist->GetXaxis()->SetRangeUser(mean - 5.0 * width, mean + 5.0 * width);
317  B2INFO(Form("\tFit for hist (%s) sucessfull (status = %d)", temphist->GetName(), fs));
318  status = fitOK;
319  }
320  }
321 }
322 
323 //------------------------------------
325 {
326  int cruns = 0;
327  for (auto expRun : getRunList()) {
328  if (cruns == 0)B2INFO("CDCDedxInjectTimeAlgorithm: start exp " << expRun.first << " and run " << expRun.second << "");
329  cruns++;
330  }
331 
332  const auto erStart = getRunList()[0];
333  int estart = erStart.first;
334  int rstart = erStart.second;
335 
336  const auto erEnd = getRunList()[cruns - 1];
337  int rend = erEnd.second;
338 
339  updateDBObjPtrs(1, erStart.second, erStart.first);
340 
341  if (m_isminStat) {
342  m_suffix = Form("e%dr%dto%d_nruns%d", estart, rstart, rend, cruns);
343  B2INFO("\t+ run = " << rend << ", m_suffix = " << m_suffix << "");
344  } else {
345  m_suffix = Form("e%dr%d", estart, rstart);
346  B2INFO("tool run = " << estart << ", exp = " << estart << ", m_suffix = " << m_suffix << "");
347  }
348 }
349 
350 //------------------------------------
352 {
353  //empty local vector or find a way to execulate this function
354  //only once
355  if (!m_vtlocaledges.empty()) m_vtlocaledges.clear();
356  if (m_vtedges.empty()) {
357  double fixedges[69];
358  for (int ib = 0; ib < 69; ib++) {
359  fixedges[ib] = ib * 0.5 * 1e3;
360  if (ib > 40 && ib <= 60) fixedges[ib] = fixedges[ib - 1] + 1.0 * 1e3;
361  else if (ib > 60 && ib <= 64) fixedges[ib] = fixedges[ib - 1] + 10.0 * 1e3;
362  else if (ib > 64 && ib <= 65) fixedges[ib] = fixedges[ib - 1] + 420.0 * 1e3;
363  else if (ib > 65 && ib <= 66) fixedges[ib] = fixedges[ib - 1] + 500.0 * 1e3;
364  else if (ib > 66) fixedges[ib] = fixedges[ib - 1] + 2e6;
365  m_vtlocaledges.push_back(fixedges[ib]);
366  }
367  } else {
368  for (unsigned int ib = 0; ib < m_vtedges.size(); ib++)
369  m_vtlocaledges.push_back(m_vtedges.at(ib));
370  }
371 }
372 
373 //------------------------------------
374 void CDCDedxInjectTimeAlgorithm::defineHisto(std::array<std::vector<TH1D*>, numdedx::nrings>& htemp, std::string var)
375 {
376  for (unsigned int ir = 0; ir < c_rings; ir++) {
377  htemp[ir].resize(m_tbins);
378  for (unsigned int it = 0; it < m_tbins; it++) {
379  std::string label = getTimeBinLabel(m_tedges[it], it);
380  std::string title = Form("%s(%s), time(%s)", m_suffix.data(), m_sring[ir].data(), label.data());
381  std::string hname = Form("h%s_%s_%s_t%d", var.data(), m_sring[ir].data(), m_suffix.data(), it);
382  if (var == "dedx" or var == "dedx_corr") htemp[ir][it] = new TH1D(hname.data(), "", m_dedxBins, m_dedxMin, m_dedxMax);
383  else if (var == "chi") htemp[ir][it] = new TH1D(hname.data(), "", m_chiBins, m_chiMin, m_chiMax);
384  else htemp[ir][it] = new TH1D(hname.data(), "", 50, m_tedges[it], m_tedges[it + 1]);
385  htemp[ir][it]->SetTitle(Form("%s;%s;entries", title.data(), var.data()));
386  }
387  }
388 }
389 
390 //------------------------------------
391 void CDCDedxInjectTimeAlgorithm::defineTimeHisto(std::array<std::array<TH1D*, 3>, numdedx::nrings>& htemp)
392 {
393  const int tzoom = 3;
394  const int nt[tzoom] = {50, 500, 1000};
395  double tzedges[tzoom + 1] = {0, 2.0e3, 0.1e6, 20e6};
396  std::string stname[tzoom] = {"early", "mid", "later"};
397  std::string stlabel[tzoom] = {"zoom <2ms", "early time <= 100ms", "later time >100ms"};
398  for (unsigned int ir = 0; ir < c_rings; ir++) {
399  for (int wt = 0; wt < tzoom; wt++) {
400  std::string title = Form("inject time (%s), %s (%s)", stlabel[wt].data(), m_sring[ir].data(), m_suffix.data());
401  std::string hname = Form("htimezoom_%s_%s_%s", m_sring[ir].data(), stname[wt].data(), m_suffix.data());
402  htemp[ir][wt] = new TH1D(Form("%s", hname.data()), "", nt[wt], tzedges[wt], tzedges[wt + 1]);
403  htemp[ir][wt]->SetTitle(Form("%s;injection time(#mu-sec);entries", title.data()));
404  }
405  }
406 }
407 
408 //------------------------------------
409 void CDCDedxInjectTimeAlgorithm::checkStatistics(std::array<std::vector<TH1D*>, numdedx::nrings>& hvar)
410 {
411  for (unsigned int ir = 0; ir < c_rings; ir++) {
412  for (unsigned int it = 3; it < m_tbins; it++) {
413  //check statiscs from 1-40ms
414  if (m_tedges[it] < 4e4 && hvar[ir][it]->Integral() < m_thersE) {
415  m_isminStat = true;
416  break;
417  } else continue;
418  }
419  }
420 }
421 
422 //------------------------------------
423 void CDCDedxInjectTimeAlgorithm::correctBinBias(std::map<int, std::vector<double>>& varcorr,
424  std::map<int, std::vector<double>>& var,
425  std::map<int, std::vector<double>>& time, TH1D*& htimes)
426 {
427  //Deep copy OK
428  varcorr = var;
429 
430  for (int ir = 0; ir < 2; ir++) {
431 
432  for (int ix = varcorr[ir * 2].size(); ix -- > 0;) {
433 
434  double var_thisbin = 1.0;
435  var_thisbin = var[ir * 2].at(ix);
436 
437  double atime_thisbin = time[ir * 2].at(ix);
438  double ctime_thisbin = htimes->GetBinCenter(ix + 1);
439 
440  if (atime_thisbin > 0 && atime_thisbin < 4e4 * 0.99) {
441 
442  double var_nextbin = 1.0;
443  var_nextbin = var[ir * 2].at(ix + 1);
444  double var_diff = var_nextbin - var_thisbin;
445 
446  double atime_nextbin = time[ir * 2].at(ix + 1);
447  double atime_diff = atime_nextbin - atime_thisbin;
448 
449  double slope = (atime_diff > 0) ? var_diff / atime_diff : -1.0;
450 
451  //extrapolation after veto only
452  if (var_diff > 0 && slope > 0)varcorr[ir * 2].at(ix) = var_thisbin + (ctime_thisbin - atime_thisbin) * (slope);
453  printf("\t %s ix = %d, center = %0.2f(%0.3f), var = %0.5f(%0.5f) \n", m_sring[ir].data(), ix, ctime_thisbin, atime_thisbin,
454  var_thisbin, varcorr[ir * 2].at(ix));
455  } else {
456  printf("\t %s --> ix = %d, center = %0.2f(%0.3f), var = %0.5f(%0.5f) \n", m_sring[ir].data(), ix, ctime_thisbin, atime_thisbin,
457  var_thisbin, varcorr[ir * 2].at(ix));
458  }
459  }
460  }
461 }
462 
463 //-------------------------------------
464 void CDCDedxInjectTimeAlgorithm::createPayload(std::array<double, numdedx::nrings>& scale,
465  std::map<int, std::vector<double>>& var,
466  std::map<int, std::vector<double>>& varscal, std::string svar)
467 {
468  varscal = var;
469 
470  B2INFO("CDCDedxInjectTimeAlgorithm: normalising constants with plateau");
471  for (unsigned int ir = 0; ir < c_rings; ir++) {
472  //scaling means with time >40ms
473  unsigned int msize = varscal[ir * 2].size();
474  int countsum = 0;
475  scale[ir] = 0;
476  for (unsigned int im = 0; im < msize; im++) {
477  double time = m_vtlocaledges.at(im);
478  double mean = varscal[ir * 2].at(im);
479  if (time > 4e4 && mean > 0) {
480  scale[ir] += mean;
481  countsum++;
482  }
483  }
484  if (countsum > 0 && scale[ir] > 0) {
485  scale[ir] /= countsum;
486  for (unsigned int im = 0; im < msize; im++) {
487  varscal[ir * 2].at(im) /= scale[ir];
488  }
489  }
490  }
491  if (m_isMerge && svar == "mean") {
492  //merge only no change in payload structure
493  bool incomp_bin = false;
494  std::vector<std::vector<double>> oldvectors;
495  if (m_DBInjectTime) oldvectors = m_DBInjectTime->getConstVector();
496  int vsize = oldvectors.size();
497  if (vsize != 6) incomp_bin = true;
498  else {
499  for (int iv = 0; iv < 2; iv++) {
500  if (oldvectors[iv * 3 + 1].size() != varscal[iv * 2].size()) incomp_bin = true;
501  }
502  }
503  if (!incomp_bin) {
504  B2INFO("CDCDedxInjectTimeAlgorithm: started merging relative constants");
505  for (int ir = 0; ir < 2; ir++) {//merging only means
506  unsigned int msize = varscal[ir * 2].size();
507  for (unsigned int im = 0; im < msize; im++) {
508  double relvalue = varscal[ir * 2].at(im);
509  double oldvalue = oldvectors[ir * 3 + 1].at(im);
510  double merged = oldvalue * relvalue;
511  printf("%s: rel %0.03f, old %0.03f, merged %0.03f\n", m_suffix.data(), relvalue, oldvalue, merged);
512  varscal[ir * 2].at(im) *= oldvectors[ir * 3 + 1].at(im) ;
513  }
514  }
515  } else B2ERROR("CDCDedxInjectTimeAlgorithm: found incompatible bins for merging");
516  } else B2INFO("CDCDedxInjectTimeAlgorithm: saving final (abs) calibration");
517 }
518 
519 //------------------------------------
520 void CDCDedxInjectTimeAlgorithm::plotBinLevelDist(std::array<std::vector<TH1D*>, numdedx::nrings>& hvar, std::string var)
521 {
522  TCanvas cfit("cfit", "cfit", 1000, 500);
523  cfit.Divide(2, 1);
524  std::stringstream psname_fit;
525  psname_fit << Form("%s_%s_%s.pdf[", m_prefix.data(), var.data(), m_suffix.data());
526  cfit.Print(psname_fit.str().c_str());
527  psname_fit.str("");
528  psname_fit << Form("%s_%s_%s.pdf", m_prefix.data(), var.data(), m_suffix.data());
529  for (unsigned int it = 0; it < m_tbins; it++) {
530  for (unsigned int ir = 0; ir < c_rings; ir++) {
531  cfit.cd(ir + 1);
532  hvar[ir][it]->SetFillColorAlpha(ir + 5, 0.25);
533  hvar[ir][it]->Draw();
534  }
535  cfit.Print(psname_fit.str().c_str());
536  }
537  psname_fit.str("");
538  psname_fit << Form("%s_%s_%s.pdf]", m_prefix.data(), var.data(), m_suffix.data());
539  cfit.Print(psname_fit.str().c_str());
540 }
541 
542 //----------------------------------------
544 {
545  // draw event and track statistics
546  TCanvas cestat("cestat", "cestat", 1000, 500);
547  cestat.SetBatch(kTRUE);
548  cestat.Divide(2, 1);
549 
550  cestat.cd(1);
551  auto hestats = getObjectPtr<TH1I>("hestats");
552  if (hestats) {
553  hestats->SetName(Form("hestats_%s", m_suffix.data()));
554  hestats->SetStats(0);
555  hestats->Draw("hist text");
556  }
557  cestat.cd(2);
558  auto htstats = getObjectPtr<TH1I>("htstats");
559  if (htstats) {
560  htstats->SetName(Form("htstats_%s", m_suffix.data()));
561  htstats->SetStats(0);
562  htstats->Draw("hist text");
563  }
564  cestat.Print(Form("%s_eventstat_%s.pdf", m_prefix.data(), m_suffix.data()));
565 }
566 
567 //------------------------------------
568 void CDCDedxInjectTimeAlgorithm::plotInjectionTime(std::array<std::array<TH1D*, 3>, numdedx::nrings>& hvar)
569 {
570  TCanvas ctzoom("ctzoom", "ctzoom", 1500, 450);
571  ctzoom.SetBatch(kTRUE);
572  ctzoom.Divide(3, 1);
573  for (int wt = 0; wt < 3; wt++) {
574  ctzoom.cd(wt + 1);
575  if (wt == 2) gPad->SetLogy();
576  for (unsigned int ir = 0; ir < c_rings; ir++) {
577  hvar[ir][wt]->SetStats(0);
578  hvar[ir][wt]->SetFillColorAlpha(5 + ir, 0.20);
579  if (ir == 0) {
580  double max1 = hvar[ir][wt]->GetMaximum();
581  double max2 = hvar[c_rings - 1][wt]->GetMaximum();
582  if (max2 > max1) hvar[ir][wt]->SetMaximum(max2 * 1.05);
583  hvar[ir][wt]->Draw("");
584  } else hvar[ir][wt]->Draw("same");
585  }
586  }
587  ctzoom.Print(Form("%s_timezoom_%s.pdf]", m_prefix.data(), m_suffix.data()));
588 }
589 
590 //------------------------------------
591 void CDCDedxInjectTimeAlgorithm::plotRelConstants(std::map<int, std::vector<double>>& vmeans,
592  std::map<int, std::vector<double>>& vresos, std::map<int, std::vector<double>>& corr, std::string svar)
593 {
594  std::string sname[3] = {"mean", "reso"};
595  const int lcolors[c_rings] = {2, 4};
596 
597  TH1D* hmean[c_rings], *hcorr[c_rings];
598  TH1D* hreso[c_rings];
599 
600  TCanvas* cconst[2];
601  for (int ic = 0; ic < 2; ic++) {
602  cconst[ic] = new TCanvas(Form("c%sconst", sname[ic].data()), "", 900, 500);
603  cconst[ic]->SetGridy(1);
604  }
605 
606  TLegend* mleg = new TLegend(0.50, 0.54, 0.80, 0.75, NULL, "brNDC");
607  mleg->SetBorderSize(0);
608  mleg->SetFillStyle(0);
609 
610  for (unsigned int ir = 0; ir < c_rings; ir++) {
611 
612  std::string mtitle = Form("#mu(dedx), relative const. compare, (%s)", m_suffix.data());
613  hmean[ir] = new TH1D(Form("hmean_%s_%s", m_suffix.data(), m_sring[ir].data()), "", m_tbins, 0, m_tbins);
614 
615  std::string rtitle = Form("#sigma(#chi), relative const. compare, (%s)", m_suffix.data());
616  hreso[ir] = new TH1D(Form("hreso_%s_%s", m_suffix.data(), m_sring[ir].data()), "", m_tbins, 0, m_tbins);
617 
618  hcorr[ir] = new TH1D(Form("hcorr_%s_%s", m_suffix.data(), m_sring[ir].data()), "", m_tbins, 0, m_tbins);
619  if (svar == "chi") {
620  hmean[ir]->SetTitle(Form("%s;injection time(#mu-second);#mu (#chi-fit)", rtitle.data()));
621  hreso[ir]->SetTitle(Form("%s;injection time(#mu-second);#sigma (#chi-fit)", rtitle.data()));
622  hcorr[ir]->SetTitle(Form("%s;injection time(#mu-second);#sigma (#chi-fit bin-bais-corr)", rtitle.data()));
623 
624  } else {
625  hmean[ir]->SetTitle(Form("%s;injection time(#mu-second);#mu (dedx-fit)", mtitle.data()));
626  hreso[ir]->SetTitle(Form("%s;injection time(#mu-second);#sigma (dedx-fit)", mtitle.data()));
627  hcorr[ir]->SetTitle(Form("%s;injection time(#mu-second);#mu (dedx-fit, bin-bais-corr)", mtitle.data()));
628  }
629 
630 
631  for (unsigned int it = 0; it < m_tbins; it++) {
632 
633  std::string label = getTimeBinLabel(m_tedges[it], it);
634 
635  hmean[ir]->SetBinContent(it + 1, vmeans[ir * 2].at(it));
636  hmean[ir]->SetBinError(it + 1, vmeans[ir * 2 + 1].at(it));
637  hmean[ir]->GetXaxis()->SetBinLabel(it + 1, label.data());
638 
639  hreso[ir]->SetBinContent(it + 1, vresos[ir * 2].at(it));
640  hreso[ir]->SetBinError(it + 1, vresos[ir * 2 + 1].at(it));
641  hreso[ir]->GetXaxis()->SetBinLabel(it + 1, label.data());
642 
643  hcorr[ir]->SetBinContent(it + 1, corr[ir * 2].at(it));
644  hcorr[ir]->SetBinError(it + 1, corr[ir * 2 + 1].at(it));
645  hcorr[ir]->GetXaxis()->SetBinLabel(it + 1, label.data());
646  }
647 
648  mleg->AddEntry(hmean[ir], Form("%s", m_sring[ir].data()), "lep");
649  cconst[0]->cd();
650  if (svar == "chi") setHistStyle(hmean[ir], lcolors[ir], ir + 24, -0.60, 0.60);
651  else if (svar == "dedx") setHistStyle(hmean[ir], lcolors[ir], ir + 24, 0.60, 1.10);
652  else setHistStyle(hmean[ir], lcolors[ir], ir + 24, 0.9, 1.10);
653 
654  if (ir == 0)hmean[ir]->Draw("");
655  else hmean[ir]->Draw("same");
656  if (svar == "dedx") {
657  mleg->AddEntry(hcorr[ir], Form("%s (bin-bias-corr)", m_sring[ir].data()), "lep");
658  setHistStyle(hcorr[ir], lcolors[ir], ir + 20, 0.60, 1.10);
659  hcorr[ir]->Draw("same");
660  }
661  if (ir == 1)mleg->Draw("same");
662 
663  cconst[1]->cd();
664  if (svar == "chi") setHistStyle(hreso[ir], lcolors[ir], ir + 24, 0.5, 1.50);
665  else setHistStyle(hreso[ir], lcolors[ir], ir + 24, 0.0, 0.15);
666  if (ir == 0)hreso[ir]->Draw("");
667  else hreso[ir]->Draw("same");
668  if (svar == "chi") {
669  mleg->AddEntry(hcorr[ir], Form("%s (bin-bias-corr)", m_sring[ir].data()), "lep");
670  setHistStyle(hcorr[ir], lcolors[ir], ir + 20, 0.5, 1.50);
671  hcorr[ir]->Draw("same");
672  }
673  if (ir == 1)mleg->Draw("same");
674  }
675 
676  for (int ic = 0; ic < 2; ic++) {
677  cconst[ic]->SaveAs(Form("%s_relconst_%s_%s_%s.pdf", m_prefix.data(), sname[ic].data(), svar.data(), m_suffix.data()));
678  cconst[ic]->SaveAs(Form("%s_relconst_%s_%s_%s.root", m_prefix.data(), sname[ic].data(), svar.data(), m_suffix.data()));
679  delete cconst[ic];
680  }
681  for (int ic = 0; ic < 2; ic++) {
682 
683  delete hmean[ic];
684  delete hreso[ic];
685  delete hcorr[ic];
686  }
687 }
688 
689 //------------------------------------
690 void CDCDedxInjectTimeAlgorithm::plotTimeStat(std::array<std::vector<TH1D*>, numdedx::nrings>& htime)
691 {
692  const int lcolors[c_rings] = {2, 4};
693 
694  TH1D* htimestat[c_rings];
695 
696  TCanvas* cconst = new TCanvas("ctimestatconst", "", 900, 500);
697  cconst->SetGridy(1);
698 
699  TLegend* rleg = new TLegend(0.40, 0.60, 0.80, 0.72, NULL, "brNDC");
700  rleg->SetBorderSize(0);
701  rleg->SetFillStyle(0);
702 
703  for (unsigned int ir = 0; ir < c_rings; ir++) {
704 
705  std::string title = Form("injection time, her-ler comparision, (%s)", m_suffix.data());
706  htimestat[ir] = new TH1D(Form("htimestat_%s_%s", m_suffix.data(), m_sring[ir].data()), "", m_tbins, 0, m_tbins);
707  htimestat[ir]->SetTitle(Form("%s;injection time(#mu-second);norm. entries", title.data()));
708 
709  for (unsigned int it = 0; it < m_tbins; it++) {
710  std::string label = getTimeBinLabel(m_tedges[it], it);
711  htimestat[ir]->SetBinContent(it + 1, htime[ir][it]->Integral());
712  htimestat[ir]->SetBinError(it + 1, 0);
713  htimestat[ir]->GetXaxis()->SetBinLabel(it + 1, label.data());
714  }
715 
716  cconst->cd();
717  double norm = htimestat[ir]->GetMaximum();
718  rleg->AddEntry(htimestat[ir], Form("%s (scaled with %0.02f)", m_sring[ir].data(), norm), "lep");
719  htimestat[ir]->Scale(1.0 / norm);
720  setHistStyle(htimestat[ir], lcolors[ir], ir + 20, 0.0, 1.10);
721  htimestat[ir]->SetFillColorAlpha(lcolors[ir], 0.30);
722  if (ir == 0) htimestat[ir]->Draw("hist");
723  else htimestat[ir]->Draw("hist same");
724  if (ir == 1)rleg->Draw("same");
725  }
726 
727  cconst->SaveAs(Form("%s_relconst_timestat_%s.pdf", m_prefix.data(), m_suffix.data()));
728  cconst->SaveAs(Form("%s_relconst_timestat_%s.root", m_prefix.data(), m_suffix.data()));
729  delete cconst;
730 }
731 
732 //------------------------------------
733 void CDCDedxInjectTimeAlgorithm::plotFinalConstants(std::map<int, std::vector<double>>& vmeans,
734  std::map<int, std::vector<double>>& vresos,
735  std::array<double, numdedx::nrings>& scale, std::array<double, numdedx::nrings>& scale_reso)
736 {
737 
738  std::vector<std::vector<double>> oldvectors;
739  if (m_DBInjectTime)oldvectors = m_DBInjectTime->getConstVector();
740 
741  const int c_type = 2; //old and new
742  std::string sname[c_rings] = {"mean", "reso"};
743  std::string stype[c_type] = {"new", "old"};
744  const int lcolors[c_rings] = {2, 4};
745  const int lmarker[c_type] = {20, 24}; //+2 for different rings
746 
747  TH1D* hmean[c_rings][c_type], *hreso[c_rings][c_type];
748 
749  TCanvas* cconst[c_rings];
750  for (int ic = 0; ic < 2; ic++) {
751  cconst[ic] = new TCanvas(Form("c%sconst", sname[ic].data()), "", 900, 500);
752  cconst[ic]->SetGridy(1);
753  }
754 
755  TLegend* mleg = new TLegend(0.50, 0.54, 0.80, 0.75, NULL, "brNDC");
756  mleg->SetBorderSize(0);
757  mleg->SetFillStyle(0);
758 
759  TLegend* rleg = new TLegend(0.50, 0.54, 0.80, 0.75, NULL, "brNDC");
760  rleg->SetBorderSize(0);
761  rleg->SetFillStyle(0);
762 
763  for (unsigned int ip = 0; ip < c_type; ip++) {
764 
765  for (unsigned int ir = 0; ir < c_rings; ir++) {
766 
767  std::string hname = Form("hfmean_%s_%s_%s", m_sring[ir].data(), stype[ip].data(), m_suffix.data());
768  hmean[ir][ip] = new TH1D(hname.data(), "", m_tbins, 0, m_tbins);
769  std::string title = Form("#mu(dedx), final-mean-compare (%s)", m_suffix.data());
770  hmean[ir][ip]->SetTitle(Form("%s;injection time(#mu-second);#mu (dedx-fit)", title.data()));
771 
772  hname = Form("hfreso_%s_%s_%s", m_sring[ir].data(), stype[ip].data(), m_suffix.data());
773  hreso[ir][ip] = new TH1D(hname.data(), "", m_tbins, 0, m_tbins);
774  title = Form("#sigma(#chi), final-reso-compare (%s)", m_suffix.data());
775  hreso[ir][ip]->SetTitle(Form("%s;injection time(#mu-second);#sigma (#chi-fit)", title.data()));
776 
777  for (unsigned int it = 0; it < m_tbins; it++) {
778 
779  std::string label = getTimeBinLabel(m_tedges[it], it);
780  double mean = 0.0, reso = 0.0;
781  if (ip == 0) {
782  mean = m_vinjPayload[ir * 3 + 1].at(it);
783  //reso is reso/mu (reso is relative so mean needs to be relative)
784  reso = m_vinjPayload[ir * 3 + 2].at(it);
785 
786  } else {
787  mean = oldvectors[ir * 3 + 1].at(it);
788  reso = oldvectors[ir * 3 + 2].at(it);
789 
790  }
791 
792  //old payloads
793  hmean[ir][ip]->SetBinContent(it + 1, mean);
794  hmean[ir][ip]->SetBinError(it + 1, vmeans[ir * 2 + 1].at(it));
795  hmean[ir][ip]->GetXaxis()->SetBinLabel(it + 1, label.data());
796 
797  hreso[ir][ip]->SetBinContent(it + 1, reso);
798  hreso[ir][ip]->SetBinError(it + 1, vresos[ir * 2 + 1].at(it));
799  hreso[ir][ip]->GetXaxis()->SetBinLabel(it + 1, label.data());
800  }
801 
802  cconst[0]->cd();
803  if (ip == 1)mleg->AddEntry(hmean[ir][ip], Form("%s, %s", m_sring[ir].data(), stype[ip].data()), "lep");
804  else mleg->AddEntry(hmean[ir][ip], Form("%s, %s (scaled by %0.03f)", m_sring[ir].data(), stype[ip].data(), scale[ir]), "lep");
805  setHistStyle(hmean[ir][ip], lcolors[ir], lmarker[ip] + ir * 2, 0.60, 1.05);
806  if (ir == 0 && ip == 0)hmean[ir][ip]->Draw("");
807  else hmean[ir][ip]->Draw("same");
808  if (ir == 1 && ip == 1)mleg->Draw("same");
809 
810  cconst[1]->cd();
811  if (ip == 1)rleg->AddEntry(hreso[ir][ip], Form("%s, %s", m_sring[ir].data(), stype[ip].data()), "lep");
812  else rleg->AddEntry(hreso[ir][ip], Form("%s, %s (scaled by %0.03f)", m_sring[ir].data(), stype[ip].data(), scale_reso[ir]), "lep");
813  setHistStyle(hreso[ir][ip], lcolors[ir], lmarker[ip] + ir * 2, 0.6, 1.9);
814  if (ir == 0 && ip == 0)hreso[ir][ip]->Draw("");
815  else hreso[ir][ip]->Draw("same");
816  if (ir == 1 && ip == 1)rleg->Draw("same");
817  }
818  }
819 
820  for (int ic = 0; ic < 2; ic++) {
821  cconst[ic]->SaveAs(Form("%s_finalconst_%s_%s.pdf", m_prefix.data(), sname[ic].data(), m_suffix.data()));
822  cconst[ic]->SaveAs(Form("%s_finalconst_%s_%s.root", m_prefix.data(), sname[ic].data(), m_suffix.data()));
823  delete cconst[ic];
824  }
825 
826  for (unsigned int ir = 0; ir < c_rings; ir++) {
827  for (unsigned int ip = 0; ip < c_type; ip++) {
828  delete hmean[ir][ip];
829  delete hreso[ir][ip];
830  }
831  }
832 }
833 
834 //------------------------------------
835 double CDCDedxInjectTimeAlgorithm::getCorrection(unsigned int ring, unsigned int time,
836  std::map<int, std::vector<double>>& vmeans)
837 {
838 
839  unsigned int iv = ring * 2;
840 
841  unsigned int sizet = m_vtlocaledges.size(); //time
842 
843  std::vector<unsigned int> tedges(sizet); //time edges array
844  std::copy(m_vtlocaledges.begin(), m_vtlocaledges.end(), tedges.begin());
845 
846  if (time >= 5e6) time = 5e6 - 10;
847  unsigned int it = m_DBInjectTime->getTimeBin(tedges, time);
848 
849  double center = 0.5 * (m_vtlocaledges.at(it) + m_vtlocaledges.at(it + 1));
850 
851  //no corr before veto bin (usually one or two starting bin)
852  //intrapolation for entire range except
853  //--extrapolation (for first half and last half of intended bin)
854  int thisbin = it, nextbin = it;
855  if (center != time && it > 0) {
856 
857  if (time < center) {
858  thisbin = it - 1;
859  } else {
860  if (it < sizet - 2)nextbin = it + 1;
861  else thisbin = it - 1;
862  }
863 
864  if (it <= 2) {
865  double diff = vmeans[iv].at(2) - vmeans[iv].at(1) ;
866  if (diff < -0.015) { //difference above 1.0%
867  thisbin = it;
868  if (it == 1) nextbin = it;
869  else nextbin = it + 1;
870  } else {
871  if (it == 1) {
872  thisbin = it;
873  nextbin = it + 1;
874  }
875  }
876  }
877  }
878 
879  double thisdedx = vmeans[iv].at(thisbin);
880  double nextdedx = vmeans[iv].at(nextbin);
881 
882  double thistime = 0.5 * (m_vtlocaledges.at(thisbin) + m_vtlocaledges.at(thisbin + 1));
883  double nexttime = 0.5 * (m_vtlocaledges.at(nextbin) + m_vtlocaledges.at(nextbin + 1));
884 
885  double newdedx = vmeans[iv].at(it);
886  if (thisbin != nextbin)
887  newdedx = thisdedx + ((nextdedx - thisdedx) / (nexttime - thistime)) * (time - thistime);
888 
889  return newdedx;
890 }
void getMeanReso(std::array< std::vector< TH1D * >, numdedx::nrings > &hvar, std::map< int, std::vector< double >> &vmeans, std::map< int, std::vector< double >> &vresos)
function to get mean and reso of histogram
double getCorrection(unsigned int ring, unsigned int time, std::map< int, std::vector< double >> &vmeans)
function to get the correction factor of mean
bool m_isMerge
merge payload when rel constant
void plotFinalConstants(std::map< int, std::vector< double >> &vmeans, std::map< int, std::vector< double >> &vresos, std::array< double, numdedx::nrings > &scale, std::array< double, numdedx::nrings > &scale_reso)
function to final constant from merging or abs fits
void plotBinLevelDist(std::array< std::vector< TH1D * >, numdedx::nrings > &hvar, std::string var)
function to draw dedx, chi and time dist.
std::vector< double > m_vtlocaledges
internal time vector
double m_sigmaR
fit dedx dist in sigma range
void defineHisto(std::array< std::vector< TH1D * >, numdedx::nrings > &htemp, std::string var)
function to define histograms for dedx and time dist.
std::string m_prefix
string prefix for plot names
void getExpRunInfo()
function to get exp/run information (payload object, plotting)
void setHistStyle(TH1D *&htemp, const int ic, const int is, const double min, const double max)
function to set histogram cosmetics
int m_countR
a hack for running functions once
double * m_tedges
internal time array (copy of vtlocaledges)
void createPayload(std::array< double, numdedx::nrings > &scale, std::map< int, std::vector< double >> &vmeans, std::map< int, std::vector< double >> &varscal, std::string svar)
function to store payloads after full calibration
bool m_ismakePlots
produce plots for monitoring
std::string m_suffix
string suffix for object names
void correctBinBias(std::map< int, std::vector< double >> &varcorr, std::map< int, std::vector< double >> &var, std::map< int, std::vector< double >> &time, TH1D *&htimes)
function to correct dedx mean/reso and return corrected vector map
static const int c_rings
injection ring constants
void plotInjectionTime(std::array< std::array< TH1D *, 3 >, numdedx::nrings > &hvar)
function to injection time distributions (HER/LER in three bins)
void plotRelConstants(std::map< int, std::vector< double >> &vmeans, std::map< int, std::vector< double >> &vresos, std::map< int, std::vector< double >> &corr, std::string svar)
function to relative constant from dedx fit mean and chi fit reso
void plotTimeStat(std::array< std::vector< TH1D * >, numdedx::nrings > &htime)
function to draw time stats
void fitGaussianWRange(TH1D *&temphist, fstatus &status)
function to perform gaus fit for input histogram
void defineTimeBins()
function to set/reset time bins
void defineTimeHisto(std::array< std::array< TH1D *, 3 >, numdedx::nrings > &htemp)
function to define injection time bins histograms (monitoring only)
void deleteHisto(std::array< std::vector< TH1D * >, numdedx::nrings > &htemp)
function to delete histograms for dedx and time dist.
void deleteTimeHisto(std::array< std::array< TH1D *, 3 >, numdedx::nrings > &htemp)
function to define injection time bins histograms (monitoring only)
void plotEventStats()
function to draw event/track statistics plots
virtual EResult calibrate() override
CDC dE/dx Injection time algorithm.
void checkStatistics(std::array< std::vector< TH1D * >, numdedx::nrings > &hvar)
check statistics for obtaining calibration const.
std::vector< double > m_vtedges
external time vector
std::vector< std::vector< double > > m_vinjPayload
vector to store payload values
bool m_isminStat
flag to merge runs for statistics thershold
CDCDedxInjectTimeAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
std::array< std::string, numdedx::nrings > m_sring
injection ring name
DBObjPtr< CDCDedxInjectionTime > m_DBInjectTime
Injection time DB object.
unsigned int m_tbins
internal time bins
int m_thersE
min tracks to start calibration
std::string getTimeBinLabel(const double &tedges, const int &it)
function to return time label for histograms labeling
dE/dx injection time calibration constants
Class to hold the prediction of mean as a function of beta-gamma (bg)
Class to hold the prediction of resolution depending dE/dx, nhit, and cos(theta)
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)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
static const ChargedStable electron
electron particle
Definition: Const.h:650
Abstract base class for different kinds of events.