19 #include "TGraphErrors.h"
28 #include "TPaveText.h"
30 #include "TStopwatch.h"
72 double F1Gaus(
double* x,
double* p)
78 double Return = Height * TMath::Gaus(X, Center, Width);
83 double F1Pol3(
double* x,
double* p)
86 double Return = (X - p[0]) * (p[1] + p[2]*X + p[3]*std::pow(X, 2));
91 double F1Comb(
double* x,
double* p)
93 return F1Gaus(x, p) + F1Pol3(x, &p[3]);
97 void GetMapChToBS(
const char* inList, map<int, int> chToBS[4],
bool PRINT =
false)
103 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
107 in >> detId >> ch >> bs;
108 if (!in.good()) {
break; in.close(); }
110 chToBS[detId-8].insert(pair<int, int>(ch, bs));
111 if (PRINT) cout <<Form(
"%2i %3i %2i", detId, ch, bs) <<endl;
118 void GetMapChToCellStat(
const char* inList, map<int, int> chToCellStat[4],
bool PRINT =
false)
124 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
128 in >> detId >> ch >> stat;
129 if (!in.good()) {
break; in.close(); }
131 chToCellStat[detId-8].insert(pair<int, int>(ch, stat));
132 if (PRINT) cout <<Form(
"%2i %3i %i", detId, ch, stat) <<endl;
139 void GetMapChToFitR(
const char* inList, map<int, st_fitR> chToFitR[4],
bool PRINT =
false)
145 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
148 int detId, ch, nRefit;
149 float chi2, mass, massErr, width, widthErr;
150 in >> detId >> ch >> nRefit >> chi2 >> mass >> massErr >> width >> widthErr;
151 if (!in.good()) {
break; in.close(); }
154 fitR.nRefit = nRefit;
157 fitR.massErr = massErr;
159 fitR.widthErr = widthErr;
160 chToFitR[detId-8].insert(pair<int, st_fitR>(ch, fitR));
163 cout <<Form(
"%2i %3i %2i %7.3f %6.3f %6.3f %6.3f %6.3f",
164 detId,ch,nRefit,chi2,mass,massErr,width,widthErr) <<endl;
172 void GetMapChToGain(
const char* inList, map<int, float> chToGain[4],
bool PRINT =
false)
178 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
181 int detId, ch, col, row;
182 float gain, chX, chY;
183 in >> detId >> ch >> gain >> col >> row >> chX >> chY;
184 if (!in.good()) {
break; in.close(); }
186 if (gain == 0.)
continue;
190 chToGain[a].insert(pair<int, float>(ch, gain));
191 if (PRINT) cout <<Form(
"%2i %3i %5.3f", a+8, ch, gain) <<endl;
199 void GetMapChToGainCorr(
const char* inList, map<int, float> chToGainCorr[4],
bool PRINT =
false)
205 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
210 in >> index >> nstb >> ch >> gainCorr;
211 if (!in.good()) {
break; in.close(); }
213 if (index == 1)
continue;
217 chToGainCorr[a].insert(pair<int, float>(ch, gainCorr));
218 if (PRINT) cout <<Form(
"%2i %3i %5.3f", a+8, ch, gainCorr) <<endl;
226 void GetMapChToPos(
const char* inList, map<int, st_pos> chToPos[4],
bool PRINT =
false)
232 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
235 int detId, ch, col, row;
236 float gain, chX, chY;
237 in >> detId >> ch >> gain >> col >> row >> chX >> chY;
238 if (!in.good()) {
break; in.close(); }
240 if (gain == 0.)
continue;
249 chToPos[a].insert(pair<int, st_pos>(ch, pos));
250 if (PRINT) cout <<Form(
"%2i %3i %2i %2i %6.2f %6.2f", detId, ch, col, row, chX, chY) <<endl;
258 void GetMapChToSkew(
const char* inList, map<int, int> chToSkew[4],
bool PRINT =
false)
264 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
267 int detId, ch, nSkew;
268 in >> detId >> ch >> nSkew;
269 if (!in.good()) {
break; in.close(); }
271 chToSkew[detId-8].insert(pair<int, int>(ch, nSkew));
272 if (PRINT) cout <<Form(
"%2i %3i %i", detId, ch, nSkew) <<endl;
279 void GetMapIndexToCh(
const char* inList, map<int, int> iToCh[4],
bool PRINT =
false)
287 if (!in.is_open()) { cout <<
"Cannot open " <<inList <<endl;
return; }
290 int detId, ch, col, row;
291 float gain, chX, chY;
292 in >> detId >> ch >> gain >> col >> row >> chX >> chY;
293 if (!in.good()) {
break; in.close(); }
295 if (gain==0.)
continue;
299 iToCh[a].insert(pair<int, int>(index[a], ch));
300 if (PRINT) cout <<Form(
"%2i %3i %3i", detId, ch, index[a]) <<endl;
309 void GetMapManualGainCorr(
const char* inList, map<int, float> manGainCorr[4])
315 cout <<Form(
"\nNo manual gainCorr update list found: skip manual correction...\n") <<endl;
319 cout <<
"\nManual gainCorr update list found: enforce following values for next iteration..." <<endl;
324 in >> detId >> ch >> gainCorr;
325 if (!in.good()) {
break; in.close(); }
327 cout <<Form(
"%2i, %3i: %4.3f", detId, ch, gainCorr) <<endl;
328 manGainCorr[detId-8].insert(pair<int, float>(ch, gainCorr));
336 void SetPi0Range(TH1F* H1,
float* pi0R,
bool PRINT =
false)
339 const float min = 0.135 - 0.06;
340 const float max = 0.135 + 0.06;
343 const float tempPeak = H1->GetBinCenter(H1->GetMaximumBin());
344 if (tempPeak >= min && tempPeak <= max)
351 if (tempPeak < min) pi0R[0] = 0.;
352 if (tempPeak > max) pi0R[1] = 0.35;
353 if (PRINT) cout <<Form(
"Rearranging pi0 range of %s to [%4.3f, %4.3f]\n", H1->GetName(),pi0R[0],pi0R[1]);
360 float SearchFirstNonzeroBinPosition(TH1F* H1BG)
363 for (
int a=0; a<H1BG->GetNbinsX(); a++)
365 int BinC = H1BG->GetBinContent(a+1);
368 BGStart = H1BG->GetBinCenter(a+1);
372 if (BGStart < 0.01 || BGStart > 0.10) BGStart = 0.05;
383 map<int, int>chToCellStat,
384 map<int, float>chToGainCorr,
385 map<int, st_pos>chToPos,
386 map<int, st_fitR>&chToFitR,
390 const int nEventsMin = 100;
391 const int nRefitMax = 10;
392 const float maxMass = 0.5;
399 gStyle->SetOptDate(0);
400 gStyle->SetOptStat(
"e");
402 c1 =
new TCanvas(
"c1",
"", 800, 800);
404 LPi0 =
new TLine(0.135, 0, 0.135, 1);
405 LPi0->SetLineColor(kMagenta);
406 LPi0->SetLineStyle(2);
410 TF1* F1Pi0 =
new TF1(
"F1Pi0", F1Gaus, 0, maxMass, 3);
411 TF1* F1BG =
new TF1(
"F1BG", F1Pol3, 0, maxMass, 4);
412 TF1* F1 =
new TF1(
"F1", F1Comb, 0, maxMass, 7);
413 F1Pi0->SetLineColor(4);
414 F1Pi0->SetLineStyle(2);
415 F1Pi0->SetParNames(
"GausH",
"GausM",
"GausW");
416 F1BG->SetLineColor(3);
417 F1BG->SetLineStyle(2);
418 F1BG->SetParNames(
"Pol3p0",
"Pol3p1",
"Pol3p2",
"Pol3p3");
421 F1->SetParNames(
"GausH",
"GausM",
"GausW",
"Pol3p0",
"Pol3p1",
"Pol3p2",
"Pol3p3");
424 TH1F* H1Pi0 =
new TH1F();
425 TH1F* H1BG =
new TH1F();
426 TH1F* H1 =
new TH1F();
429 for (
unsigned int b=0; b<iToCh.size(); b++)
436 const int ch = iToCh[b];
437 const int tBS = chToBS[ch];
438 const int tCol = chToPos[ch].col;
439 const int tRow = chToPos[ch].row;
440 const float tGainCorr = chToGainCorr[ch];
441 const char* titleInfo = Form(
"%5.3f, [%i, %i], BS=%i", tGainCorr, tCol, tRow, tBS);
444 H1 = (TH1F*)H2_mass->ProjectionY(Form(
"%s_ch%i", H2_mass->GetName(), ch), ch, ch);
445 if (H1->GetXaxis()->GetXmax() != maxMass) cout <<
"WARNING: max X exceeds prepared fit range!" <<endl;
448 if (chToCellStat[ch]==BAD || chToCellStat[ch]==DEAD || H1->GetEntries()<nEventsMin)
453 c1->SetName(Form(
"%s", H1->GetName()));
455 const char* titleStat =
"";
456 if (chToCellStat[ch] == BAD) titleStat =
"BAD";
457 else if (chToCellStat[ch] == DEAD) titleStat =
"DEAD";
458 else if (H1->GetEntries() < nEventsMin) titleStat = Form(
"<%i", nEventsMin);
459 H1->SetTitle(Form(
"i=%i, %s, %s", iIter, titleInfo, titleStat));
460 H1->DrawCopy(
"hist e");
462 c1->SetTitle(Form(
"Skip, %s", titleStat));
471 float pi0R[2] = {0.135-0.06, 0.135+0.06};
472 SetPi0Range(H1, pi0R,
true);
475 const int mMaxB = H1->GetXaxis()->FindBin(maxMass);
476 const float pi0B0 = H1->GetXaxis()->FindBin(pi0R[0]);
477 const float pi0B1 = H1->GetXaxis()->FindBin(pi0R[1]);
478 H1Pi0 = (TH1F*)H1->Clone(Form(
"%s_pi0", H1->GetName()));
479 H1BG = (TH1F*)H1->Clone(Form(
"%s_bg", H1->GetName()));
480 for (
int c=0; c<mMaxB; c++)
482 (c+1>=pi0B0 && c+1<=pi0B1)?H1BG->SetBinContent(c+1, 0):H1Pi0->SetBinContent(c+1, 0);
483 (c+1>=pi0B0 && c+1<=pi0B1)?H1BG->SetBinError (c+1, 0):H1Pi0->SetBinError (c+1, 0);
489 for (
int i=0; i<F1Pi0->GetNpar(); i++) F1Pi0->ReleaseParameter(i);
490 const float pi0H = H1Pi0->GetMaximum();
491 const float pi0C = H1Pi0->GetBinCenter(H1Pi0->GetMaximumBin());
492 const float pi0W = 0.03;
493 const float pi0HL[2] = {pi0H*0.1, pi0H};
494 const float pi0CL[2] = {(pi0C<0.1)?0:(pi0C-0.05), pi0C+0.05};
495 const float pi0WL[2] = {H1Pi0->GetBinWidth(1), 0.15};
496 F1Pi0->SetParameters(pi0H*0.9, pi0C, pi0W);
497 F1Pi0->SetParLimits(0, pi0HL[0], pi0HL[1]);
498 F1Pi0->SetParLimits(1, pi0CL[0], pi0CL[1]);
499 F1Pi0->SetParLimits(2, pi0WL[0], pi0WL[1]);
500 H1Pi0->Fit(F1Pi0->GetName(),
"EQR0",
"", pi0R[0], pi0R[1]);
501 const float GausH = F1Pi0->GetParameter(0);
502 const float GausC = F1Pi0->GetParameter(1);
503 const float GausW = F1Pi0->GetParameter(2);
506 for (
int i=0; i<F1BG->GetNpar(); i++) F1BG->ReleaseParameter(i);
507 const float Pol3p0 = SearchFirstNonzeroBinPosition(H1BG);
508 F1BG->SetParameters(1, 1, 1, 1);
509 F1BG->FixParameter(0, Pol3p0);
510 H1BG->Fit(F1BG->GetName(),
"EQR0",
"", 0, maxMass);
511 const float Pol3p1 = F1BG->GetParameter(1);
512 const float Pol3p2 = F1BG->GetParameter(2);
513 const float Pol3p3 = F1BG->GetParameter(3);
516 for (
int i=0; i<F1->GetNpar(); i++) F1->ReleaseParameter(i);
517 F1->SetParameters(GausH, GausC, GausW, Pol3p0, Pol3p1, Pol3p2, Pol3p3);
518 F1->SetParLimits(0, pi0HL[0], pi0HL[1]);
519 F1->SetParLimits(1, pi0CL[0], pi0CL[1]);
520 F1->SetParLimits(2, pi0WL[0], pi0WL[1]);
521 F1->FixParameter(3, Pol3p0);
522 H1->Fit(F1->GetName(),
"EQR0",
"", 0, maxMass);
528 float massDev = fabs(F1->GetParameter(1) - 0.1349766);
529 float fitChi2 = F1->GetChisquare()/F1->GetNDF();
530 if (massDev>0.03 && (fitChi2<0.5 || fitChi2>3.0))
532 while (nRefit < nRefitMax)
535 if (massDev<0.03 && fitChi2>0.5 && fitChi2<3.0)
break;
539 TRandom2 RNDM(DT.GetTime() + nRefit);
540 const float pNew[7] =
542 RNDM.Uniform(H1->GetMaximum()*0.5, H1->GetMaximum()),
543 RNDM.Gaus(0.135, 0.05),
544 RNDM.Uniform(H1->GetBinWidth(1), 0.3),
548 for (
int i=0; i<F1->GetNpar(); i++) { F1->ReleaseParameter(i); F1->SetParameter(i, pNew[i]); }
549 F1->SetParLimits(0, H1->GetMaximum()*0.5, H1->GetMaximum());
550 F1->SetParLimits(1, 0, maxMass);
551 F1->SetParLimits(2, H1->GetBinWidth(1), 0.3);
552 F1->FixParameter(3, Pol3p0);
554 H1->Fit(F1->GetName(),
"EQR0",
"", 0, maxMass);
555 massDev = fabs(F1->GetParameter(1) - 0.1349766);
556 fitChi2 = F1->GetChisquare()/F1->GetNDF();
564 fitR.nRefit = nRefit;
566 fitR.mass = F1->GetParameter(1);
567 fitR.massErr = F1->GetParError(1);
568 fitR.width = F1->GetParameter(2);
569 fitR.widthErr = F1->GetParError(2);
570 chToFitR.insert(pair<int, st_fitR>(ch, fitR));
575 c1->SetName(Form(
"%s", H1->GetName()));
577 const char* titleStat =
"";
578 if (chToCellStat[ch] == GOOD) titleStat =
"";
579 else if (chToCellStat[ch] == CONVERGED) titleStat =
", CONV";
580 const char* titleRefit = (nRefit!=0)?Form(
", nRefit=%i", nRefit):
"";
581 H1->SetTitle(Form(
"i=%i, %s%s%s", iIter, titleInfo, titleStat, titleRefit));
582 H1->DrawCopy(
"hist e");
584 F1Pi0->SetParameter(0, F1->GetParameter(0));
585 F1Pi0->SetParameter(1, F1->GetParameter(1));
586 F1Pi0->SetParameter(2, F1->GetParameter(2));
588 F1BG->SetParameter(0, F1->GetParameter(3));
589 F1BG->SetParameter(1, F1->GetParameter(4));
590 F1BG->SetParameter(2, F1->GetParameter(5));
591 F1BG->SetParameter(3, F1->GetParameter(6));
595 LPi0->SetY2(H1->GetMaximum());
598 c1->SetTitle(titleRefit);
615 void PrintCellStat(
const char* outName, map<int, int>iToCh[4], map<int, int> chToCellStat[4])
619 for (
unsigned int a=0; a<4; a++)
620 for (
unsigned int b=0; b<iToCh[a].size(); b++)
622 const int ch = iToCh[a][b];
623 const int cellStat = chToCellStat[a][ch];
624 out <<Form(
"%2i %3i %i", a+8, ch, cellStat) <<endl;
631 void PrintFitResults(
const char* outName, map<int, int> iToCh[4], map<int, st_fitR> chToFitR[4])
635 for (
int a=0; a<4; a++)
636 for (
unsigned int b=0; b<iToCh[a].size(); b++)
638 const int detId = a+8;
639 const int ch = iToCh[a][b];
641 const int nRefit = chToFitR[a][ch].nRefit;
642 const float chi2 = chToFitR[a][ch].chi2;
643 const float mass = chToFitR[a][ch].mass;
644 const float massErr = chToFitR[a][ch].massErr;
645 const float width = chToFitR[a][ch].width;
646 const float widthErr = chToFitR[a][ch].widthErr;
647 out <<Form(
"%2i %3i %2i %7.3f %6.5f %6.5f %6.5f %6.5f",
648 detId,ch,nRefit,chi2,mass,massErr,width,widthErr) <<endl;
656 void PrintGainCorr(
const char* outName, map<int, float> chToGainCorr[4])
660 for (
int i=1; i<=2; i++)
664 for (
int a=1; a<=6; a++)
666 if (a<=2) {
for (
int b=1; b<=49; b++) out <<Form(
"%i %i %2i %5.3f", i, a, b, 0.000) <<endl; }
667 else if (a<=4) {
for (
int b=1; b<=25; b++) out <<Form(
"%i %i %2i %5.3f", i, a, b, 0.000) <<endl; }
668 else if (a<=6) {
for (
int b=1; b<= 7; b++) out <<Form(
"%i %i %2i %5.3f", i, a, b, 0.000) <<endl; }
673 for (
int a=0; a<4; a++)
675 const int maxCh = (a<2)?578:288;
676 for (
int b=0; b<maxCh; b++)
679 const float gainCorr = chToGainCorr[a][ch];
680 out <<Form(
"%i %i %3i %5.3f", i, a+1, ch, gainCorr) <<endl;
690 void PrintSkewMonitor(
const char* outName, map<int, int>iToCh[4], map<int, int> chToSkew[4])
694 for (
unsigned int a=0; a<4; a++)
695 for (
unsigned int b=0; b<iToCh[a].size(); b++)
697 const int ch = iToCh[a][b];
698 const int nSkew = chToSkew[a][ch];
699 out <<Form(
"%2i %3i %i", a+8, ch, nSkew) <<endl;
706 void TestConvergence(
708 map<int, int> iToCh[4],
709 map<int, int> chToCellStat[4],
710 const char* outPath =
"./Iterations"
715 if (iIter < nIter) { cout <<
"Require more iterations: skip the convervence test..." <<endl;
return; }
716 else cout <<Form(
"Starting convergence test for iterations %i - %i...", iIter-nIter, iIter) <<endl;
719 map<int, float> chToGainCorr[nIter+1][4];
720 map<int, st_fitR> chToFitR[nIter+1][4];
721 for (
int i=0; i<=nIter; i++)
723 GetMapChToGainCorr(Form(
"%s/FmsGainCorr_%i.txt", outPath, (iIter-nIter)+i), chToGainCorr[i]);
724 GetMapChToFitR(Form(
"%s/out_fmsCalibFit_%i.txt", outPath, (iIter-nIter)+i), chToFitR[i]);
730 const int convNReq = 3;
731 const float convTolM = 0.005;
732 const float convTolG = 0.035;
735 map<int, int> chToCellStatNext[4];
736 for (
unsigned int a=0; a<4; a++)
737 for (
unsigned int b=0; b<iToCh[a].size(); b++)
739 const int ch = iToCh[a][b];
740 int cellStat = chToCellStat[a][ch];
742 if (cellStat == GOOD)
746 for (
int i=0; i<nIter; i++)
748 const float massFitR = chToFitR[i][a][ch].mass;
749 if (chToGainCorr[i][a][ch] == 0. || massFitR == 0.)
continue;
751 const float ratioAdj = fabs(chToGainCorr[i][a][ch] - chToGainCorr[i+1][a][ch])/chToGainCorr[i][a][ch];
752 if ((fabs(massFitR - 0.1349766) < convTolM) && (ratioAdj < convTolG)) convCounter++;
756 if (convCounter >= convNReq)
758 const float gainCorr1st = chToGainCorr[0][a][ch];
759 const float gainCorrFin = chToGainCorr[nIter][a][ch];
760 const float ratioWide = fabs(gainCorr1st - gainCorrFin)/gainCorr1st;
761 if (ratioWide < convTolG)
763 cellStat = CONVERGED;
764 cout <<Form(
"Converged: %2i, %3i", a+8, ch) <<endl;
769 if (cellStat == CONVERGED) nConv[a]++;
770 chToCellStatNext[a].insert(pair<int, int>(ch, cellStat));
776 PrintCellStat(Form(
"FmsCellStatNew_%i.txt", iIter), iToCh, chToCellStatNext);
777 gSystem->Exec(Form(
"mv FmsCellStat.txt %s/FmsCellStat_%i.txt", outPath, iIter));
778 gSystem->Exec(Form(
"mv FmsCellStatNew_%i.txt FmsCellStat.txt", iIter));
783 for (
int a=0; a<4; a++)
785 const int nCh = iToCh[a].size();
786 cout <<Form(
"detId=%2i: %3i/%3i (%6.4f)", a+8, nConv[a], nCh, (
float)nConv[a]/nCh) <<endl;
788 const int nConvAll = nConv[0] + nConv[1] + nConv[2] + nConv[3];
789 const float rConvAll = (float)nConvAll/1264.;
790 cout <<Form(
"Total: %i/1264 (%6.4f)", nConvAll, rConvAll) <<endl;