33 #include <TIterator.h> 40 #include <TFitResult.h> 41 #include <TParameter.h> 43 #include <TPaveText.h> 44 #include <TVirtualFitter.h> 64 void addFitsMacro(TList* l) {
65 TMacro* m =
new TMacro(
"fits");
66 m->AddLine(
"void fits() {");
67 m->AddLine(
" if (!gPad) { Printf(\"No gPad\"); return; }");
68 m->AddLine(
" TList* lp = gPad->GetListOfPrimitives();");
69 m->AddLine(
" if (!lp) return;");
70 m->AddLine(
" TObject* po = 0;");
71 m->AddLine(
" TIter next(lp);");
72 m->AddLine(
" while ((po = next())) {");
73 m->AddLine(
" if (!po->IsA()->InheritsFrom(TH1::Class())) continue;");
74 m->AddLine(
" TH1* htmp = dynamic_cast<TH1*>(po);");
75 m->AddLine(
" TList* lf = htmp->GetListOfFunctions();");
76 m->AddLine(
" TObject* pso = (lf ? lf->FindObject(\"stats\") : 0);");
77 m->AddLine(
" if (!pso) continue;");
78 m->AddLine(
" TPaveStats* ps = static_cast<TPaveStats*>(pso);");
79 m->AddLine(
" ps->SetOptFit(111);");
80 m->AddLine(
" UShort_t qual = htmp->GetUniqueID();");
81 m->AddLine(
" ps->SetFillColor(qual >= 3 ? kRed-4 : qual >= 2 ? kOrange-4 : qual >= 1 ? kYellow-4 : kGreen-4);");
84 m->AddLine(
" break;");
89 TObject* old = l->FindObject(m->GetName());
90 if (old) l->Remove(old);
94 const Double_t kROErrorsLabelY = .30;
96 const Int_t kConvolutionSteps = 100;
97 const Double_t kConvolutionNSigma = 5;
102 const Double_t kMpShift = -0.22278298;
106 const Double_t kInvSq2Pi = 1. / TMath::Sqrt(2*TMath::Pi());
108 Double_t
landau(Double_t x, Double_t delta, Double_t xi)
128 return TMath::Landau(x, delta - xi * kMpShift, xi);
130 Double_t landauGaus(Double_t x, Double_t delta, Double_t xi,
131 Double_t sigma, Double_t sigmaN)
166 Double_t deltap = delta - xi * kMpShift;
167 Double_t sigma2 = sigmaN*sigmaN + sigma*sigma;
168 Double_t sigma1 = sigmaN == 0 ? sigma : TMath::Sqrt(sigma2);
169 Double_t xlow = x - kConvolutionNSigma * sigma1;
170 Double_t xhigh = x + kConvolutionNSigma * sigma1;
171 Double_t step = (xhigh - xlow) / kConvolutionSteps;
174 for (Int_t i = 0; i <= kConvolutionSteps/2; i++) {
175 Double_t x1 = xlow + (i - .5) * step;
176 Double_t x2 = xhigh - (i - .5) * step;
178 sum += TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma1);
179 sum += TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma1);
181 return step *
sum * kInvSq2Pi / sigma1;
187 Double_t landauGaus1(Double_t* xp, Double_t* pp)
190 Double_t constant = pp[0];
191 Double_t delta = pp[1];
193 Double_t sigma = pp[3];
194 Double_t sigmaN = pp[4];
196 return constant * landauGaus(x, delta, xi, sigma, sigmaN);
200 TF1* makeLandauGaus(
const char* ,
202 Double_t delta=.5, Double_t xi=0.07,
203 Double_t sigma=.1, Double_t sigmaN=-1,
204 Double_t xmin=0, Double_t xmax=15)
222 TF1* func =
new TF1(
"landauGaus",
223 &landauGaus1,xmin,xmax,npar);
225 func->SetLineColor(kBlack);
226 func->SetLineWidth(2);
228 func->SetParNames(
"C",
"#Delta_{p}",
"#xi",
"#sigma",
"#sigma_{n}");
231 func->SetParameter(0, c);
232 func->SetParameter(1, delta);
233 func->SetParameter(2, xi);
234 func->SetParameter(3, sigma);
235 func->SetParameter(4, sigmaN);
237 func->SetParLimits(1, 0, xmax);
238 func->SetParLimits(2, 0, xmax);
239 func->SetParLimits(3, 0.01, 1);
241 if (sigmaN < 0) func->FixParameter(4, 0);
242 else func->SetParLimits(4, 0, xmax);
253 fShowFitResults(true),
257 fELossFkupChi2Nu(100),
258 fELossMinEntries(1000),
259 fELossMaxEntries(-1),
260 fELossGoodParError(0.1),
261 fELossMinSharing(0.1),
314 TParameter<double>*
p =
static_cast<TParameter<double>*
>(o);
316 AliDebugF(3,
"External parameter: %-20s=%lf", name, v);
323 const char*
path =
"GRP/Calib/QAThresholds";
327 AliWarningF(
"Failed to get CDB entry at %s", path);
333 AliWarningF(
"Failed to get CDB object at %s", path);
337 TObject* fmdObj = cdbObj->FindObject(
"FMD");
339 AliWarningF(
"Failed to get FMD object at from CDB %s", path);
345 for (Int_t i = 0; i < nThr; i++) {
349 TParameter<double>* d =
dynamic_cast<TParameter<double>*
>(thr);
351 AliWarningF(
"Parameter %s not of type double", thr->GetName());
354 Double_t val = d->GetVal();
355 TString name(thr->GetName());
359 else if (name.EqualTo(
"ROErrorsBad"))
fROErrorsBad = val;
361 else if (name.EqualTo(
"MaxNProblem"))
fMaxNProblem = val;
362 else if (name.EqualTo(
"MaxNBad"))
fMaxNBad = val;
363 else if (name.EqualTo(
"ELossMinMPV"))
fMinMPV = val;
364 else if (name.EqualTo(
"ELossMaxXi"))
fMaxXi = val;
365 else if (name.EqualTo(
"ELossMaxSigma"))
fMaxSigma = val;
367 AliDebugF(3,
"Threshold %s=%f", name.Data(), val);
400 UShort_t value = values[specie];
413 if (hist->GetEntries() <= 0)
return kOK;
437 Double_t Chi2Scale(TH1* h, Double_t base=10000)
439 return 1. / TMath::Max(1., h->GetEntries() / base);
442 Double_t x1, Double_t x2, Double_t x3,
443 Double_t y, Double_t dy,
444 const char* name, Double_t val, Double_t lim,
445 Bool_t ok, Int_t color)
447 TString n; n.Form(
"%s:", name);
448 TLatex* ltx =
new TLatex(x1, y, n);
450 ltx->SetTextSize(dy-0.01);
451 ltx->SetTextColor(color);
454 n.Form(
"%7.3f", val);
455 ltx =
new TLatex(x2, y, n);
457 ltx->SetTextSize(dy-0.01);
458 ltx->SetTextColor(color);
461 if (lim < 0) n =
"(ignored)";
462 else n.Form(
"%c %4.2f", ok ?
'<' :
'>', lim);
463 ltx =
new TLatex(x3, y, n);
465 ltx->SetTextSize(dy-0.01);
466 ltx->SetTextColor(color);
474 Double_t low, Double_t high, Int_t& color)
const 479 if (!res.Get())
return 0;
482 Int_t nPar = res->NPar();
488 Double_t
chi2 = res->Chi2();
489 Int_t nu = res->Ndf();
498 printf(
"FIT: %s, 1, %d, %f, %f\n", hist->GetName(),
499 Int_t(hist->GetEntries()), red, s * red);
516 lines->SetName(
"lines");
517 lines->SetOwner(
true);
519 AddLine(lines, x, x2, x3, y, dy,
"#chi^{2}/#nu", red, chi2Lim,
520 chi2Check < 1, chi2Check < 1 ? color :
521 chi2Check < 2 ? kOrange+2 : kRed+2);
527 ltx =
new TLatex(x1, y1, Form(
"Fit range: [%6.2f,%6.2f]", low, high));
528 ltx->SetTextColor(kGray+3);
529 ltx->SetTextSize(dy-.01);
530 ltx->SetTextAlign(31);
535 ltx =
new TLatex(x1, y1, Form(
"Entries: %d (%d)",
536 Int_t(hist->GetEffectiveEntries()),
538 ltx->SetTextColor(kGray+3);
539 ltx->SetTextSize(dy-.01);
540 ltx->SetTextAlign(31);
545 ltx =
new TLatex(x1, y1, Form(
"%s: %f #pm %f",
546 res->ParName(1).c_str(),
549 ltx->SetTextColor(kGray+3);
550 ltx->SetTextSize(dy-.01);
551 ltx->SetTextAlign(31);
558 for (Int_t i = 0; i < nPar; i++) {
559 if (res->IsParameterFixed(i))
continue;
561 Double_t pv = res->Parameter(i);
562 Double_t pe = res->ParError(i);
563 Double_t rel = (pv == 0 ? 100 : pe / pv);
564 Bool_t ok = (i == 3) || (rel < thr);
567 if (i == 2 && pv >
fMaxXi) {
573 AddLine(lines, x, x2, x3, y, dy,Form(
"#delta%s/%s",
574 res->ParName(i).c_str(),
575 res->ParName(i).c_str()),
576 rel, (i == 3 ? -1 : thr), ok, ok ? color : kOrange+2);
578 if (i == 3)
continue;
582 ret = TMath::Max(ret-(parsOk-1),0);
583 if (ret > 1) color = kRed+2;
584 if (ret > 0) color = kOrange+2;
587 TList* lf = hist->GetListOfFunctions();
588 TObject* old = lf->FindObject(lines->GetName());
595 hist->SetStats(
false);
606 TString name(hist->GetName());
607 if (name.Contains(
"readouterrors", TString::kIgnoreCase)) {
609 TH2* roErrors =
static_cast<TH2*
>(hist);
610 Int_t nY = roErrors->GetNbinsY();
612 TLatex* ltx =
new TLatex(.15, .9, Form(
"Thresholds: %5.2f,%5.2f",
614 ltx->SetName(
"thresholds");
615 ltx->SetTextColor(kGray+3);
618 TList* ll = hist->GetListOfFunctions();
619 TObject* old = ll->FindObject(ltx->GetName());
626 for (Int_t i = 1; i <= 3; i++) {
629 for (Int_t j = 1; j <= nY; j++) {
630 Int_t n = roErrors->GetBinContent(i, j);
631 sum += n * roErrors->GetYaxis()->GetBinCenter(j);
634 Double_t mean = (cnt <= 0 ? 0 : sum / cnt);
635 Double_t x = ((i-.5) * (1-0.1-0.1) / 3 + 0.1);
637 ltx =
new TLatex(x, kROErrorsLabelY, Form(
"Mean: %6.3f", mean));
638 ltx->SetName(Form(
"FMD%d", i));
640 ltx->SetTextAngle(90);
641 ltx->SetTextColor(kGreen+4);
642 old = ll->FindObject(ltx->GetName());
650 AliWarningF(
"Mean of readout errors for FMD%d = %f > %f (%f)",
653 ltx->SetTextColor(kOrange+2);
656 ltx->SetTextColor(kRed+2);
661 else if (name.Contains(
"eloss",TString::kIgnoreCase)) {
673 Double_t xMin = hist->GetXaxis()->GetXmin();
674 Double_t xMax = hist->GetXaxis()->GetXmax();
677 Int_t bMaxY = hist->GetMaximumBin();
678 Double_t xMaxY = hist->GetXaxis()->GetBinCenter(bMaxY);
679 Double_t rms = hist->GetRMS();
680 Double_t low = hist->GetXaxis()->GetBinCenter(bMaxY-4);
681 hist->GetXaxis()->SetRangeUser(0.2, xMaxY+(
fELossNRMS+1)*rms);
682 rms = hist->GetRMS();
683 hist->GetXaxis()->SetRange(0,-1);
684 TF1* func = makeLandauGaus(name);
685 func->SetParameter(1, xMaxY);
686 func->SetLineColor(kGreen+4);
688 Double_t high = xMax;
692 if (low >= high)
return ret;
695 Int_t bLow = hist->FindBin(low);
696 Int_t bHigh = hist->FindBin(high);
701 TString fitOpt(
"QS");
702 TFitResultPtr
res = hist->Fit(func, fitOpt,
"", low, high);
703 Int_t color = func->GetLineColor();
704 UShort_t qual =
CheckFit(hist, res, low, high, color);
707 func = hist->GetFunction(
"landauGaus");
708 if (
fELossNRMS <= 0) func->SetRange(xMin, xMax);
710 func->Save(xMin, xMax, 0, 0, 0, 0);
711 func->SetLineColor(color);
715 func = hist->GetFunction(
"pol2");
717 Double_t
chi2 = (!res.Get() ? 0 : res->Chi2());
718 Int_t nu = (!res.Get() ? 1 : res->Ndf());
721 printf(
"FIT: %s, 2, %d, %f, %f\n", hist->GetName(),
722 Int_t(hist->GetEntries()), red, s * red);
725 else func->SetLineColor(kGreen+4);
731 func->SetLineWidth(3);
732 func->SetLineStyle(1);
734 func->SetLineWidth(4);
764 Double_t xl, Double_t yl,
765 Double_t xh, Double_t yh)
const 770 if (xh < 0) xh =
gStyle->GetStatX();
771 if (xl < 0) xl = xh -
gStyle->GetStatW();
772 if (yh < 0) yh =
gStyle->GetStatY();
773 if (yl < 0) yl = xl -
gStyle->GetStatH();
775 TPaveText* text =
new TPaveText(xl, yl, xh, yh,
"brNDC");
776 Int_t
bg = kGreen-10;
779 if (qual >=
kWhatTheFk) { bg = kRed+1; fg = kWhite; msg =
"Argh!"; }
780 else if (qual >=
kBad) { bg = kRed-3; fg = kWhite; msg =
"Bad"; }
781 else if (qual >=
kProblem) { bg = kOrange-4; msg =
"Warning"; }
783 text->SetTextFont(62);
784 text->SetTextColor(fg);
785 text->SetFillColor(bg);
787 TList* ll = hist->GetListOfFunctions();
788 TObject* old = ll->FindObject(text->GetName());
830 if(!list[specie])
continue;
833 Int_t nHist = list[specie]->GetEntriesFast();
839 status =
dynamic_cast<TH2*
>(list[specie]->At(istatus));
842 for(Int_t i= 0; i< nHist; i++) {
843 if (!(hist = static_cast<TH1*>(list[specie]->At(i))))
continue;
844 if (hist == status)
continue;
852 if (!status)
continue;
856 TString nme(hist->GetName());
857 Char_t cD = nme[nme.Length()-2];
858 Char_t cR = nme[nme.Length()-1];
861 case '1': xbin = 1;
break;
862 case '2': xbin = 2 + ((cR ==
'i' || cR ==
'I') ? 0 : 1);
break;
863 case '3': xbin = 4 + ((cR ==
'i' || cR ==
'I') ? 0 : 1);
break;
865 if (xbin == 0)
continue;
866 status->Fill(xbin, qual);
874 AliDebugF(3,
"Combined sum is %d -> %f", ret, rv[specie]);
879 for (Int_t i = 1; i < status->GetXaxis()->GetNbins(); i++) {
880 nProblem += status->GetBinContent(i, 3);
881 nBad += status->GetBinContent(i, 4);
895 Int_t CheckForLog(TAxis* axis,
900 TString t(axis->GetTitle());
901 if (!t.Contains(
"[log]", TString::kIgnoreCase))
return 0;
902 t.ReplaceAll(
"[log]",
"");
904 case 1: pad->SetLogx(); ret |= 0x1;
break;
905 case 2: pad->SetLogy(); ret |= 0x2;
break;
906 case 3: pad->SetLogz(); ret |= 0x4;
break;
911 void RestoreLog(TAxis* axis, Bool_t log)
914 TString t(axis->GetTitle());
921 void FindMinMax(TH1* h, Double_t& min, Double_t& max)
925 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
926 Double_t c = h->GetBinContent(i);
927 if (c < 1e-8)
continue;
928 tmin = TMath::Min(tmin, c);
929 tmax = TMath::Max(tmax, c);
937 Int_t GetHalfringPad(TH1* h) {
938 TString nme(h->GetName());
939 Char_t cD = nme[nme.Length()-2];
940 Char_t cR = nme[nme.Length()-1];
943 case '1': xbin = 1;
break;
944 case '2': xbin = ((cR ==
'i' || cR ==
'I') ? 2 : 5);
break;
945 case '3': xbin = ((cR ==
'i' || cR ==
'I') ? 3 : 6);
break;
967 Double_t min = 10000;
973 ->IsEventSpecieSet(spe))
977 if(!list[specie] || list[specie]->GetEntriesFast() == 0)
continue;
982 Int_t nHist = list[specie]->GetEntriesFast();
983 for(Int_t i= 0; i< nHist; i++) {
984 hist =
static_cast<TH1F*
>(list[specie]->At(i));
987 TString name(hist->GetName());
988 if (name.Contains(
"readouterrors", TString::kIgnoreCase) ||
989 name.Contains(
"status", TString::kIgnoreCase))
continue;
996 FindMinMax(hist, hMin, hMax);
997 max = TMath::Max(max, hMax);
998 min = TMath::Min(min, hMin);
1006 min = TMath::Max(1e-1, min);
1007 max = TMath::Max(1e5, max);
1012 Form(
"No histogram will be plotted for %s %s\n", GetName(),
1018 Form(
"%d histograms will be plotted for %s %s\n",
1025 ->IsEventSpecieSet(specie))
continue;
1028 if(!list[specie] || list[specie]->GetEntries() <= 0 ||
1029 nImages <= 0)
continue;
1032 const Char_t * title = Form(
"QA_%s_%s_%s", GetName(),
1035 if (!
fImage[specie])
fImage[specie] =
new TCanvas(title, title) ;
1036 fImage[specie]->Clear() ;
1037 fImage[specie]->SetTitle(title) ;
1041 TPaveText someText(0.015, 0.015, 0.98, 0.98) ;
1042 someText.AddText(title) ;
1043 someText.SetFillColor(0);
1044 someText.SetFillStyle(0);
1045 someText.SetBorderSize(0);
1046 someText.SetTextColor(kRed+1);
1052 fImage[specie]->Print(outName,
"ps") ;
1056 fImage[specie]->SetTopMargin(0.10);
1057 fImage[specie]->SetBottomMargin(0.15);
1058 fImage[specie]->SetLeftMargin(0.15);
1059 fImage[specie]->SetRightMargin(0.05);
1062 const char* topT = Form(
"Mode: %s, Task: %s, Specie: %s, Run: %d",
1067 TLatex* topText =
new TLatex(.5, .99, topT);
1068 topText->SetTextAlign(23);
1069 topText->SetTextSize(.038);
1070 topText->SetTextFont(42);
1071 topText->SetTextColor(kBlue+3);
1078 if (istatus < list[specie]->GetEntriesFast())
1079 status =
dynamic_cast<TH2*
>(list[specie]->At(istatus));
1083 TVirtualPad* plots =
fImage[specie];
1084 TVirtualPad*
stat = 0;
1087 TPad* pM =
new TPad(
"plots",
"Plots Pad", 0, .2, 1., .9, 0, 0);
1092 TPad* pS =
new TPad(
"status",
"Status Pad", 0, 0, 1., .2, 0, 0);
1102 Int_t ny = (nImages + .5) / nx;
1103 plots->Divide(nx, ny, 0, 0);
1109 Int_t nHist = list[specie]->GetEntriesFast();
1110 for (Int_t i = 0; i < nHist; i++) {
1111 hist =
static_cast<TH1*
>(list[specie]->At(i));
1113 if (hist == status)
continue;
1114 TString name(hist->GetName());
1115 Bool_t isROE = name.Contains(
"readouterrors", TString::kIgnoreCase);
1118 TVirtualPad* pad = 0;
1119 if (isROE) pad = plots->cd(4);
1120 else pad = plots->cd(GetHalfringPad(hist));
1122 pad->SetRightMargin(0.01);
1124 pad->SetLeftMargin(0.10);
1125 pad->SetBottomMargin(0.10);
1130 logOpts |= CheckForLog(hist->GetXaxis(), pad, 1);
1131 logOpts |= CheckForLog(hist->GetYaxis(), pad, 2);
1132 logOpts |= CheckForLog(hist->GetZaxis(), pad, 3);
1137 pad->SetRightMargin(0.15);
1138 pad->SetBottomMargin(0.10);
1146 hist->SetMinimum(min);
1147 hist->SetMaximum(max);
1155 hist->DrawCopy(opt);
1158 if (!name.Contains(
"readouterrors", TString::kIgnoreCase)) {
1160 TPad* insert =
new TPad(
"insert",
"Zoom",
1161 .5,.5, .99, .95, 0, 0, 0);
1162 insert->SetTopMargin(0.01);
1163 insert->SetRightMargin(0.01);
1164 insert->SetFillColor(0);
1165 insert->SetBorderSize(1);
1166 insert->SetBorderMode(0);
1169 if (logOpts & 0x1) insert->SetLogx();
1170 if (logOpts & 0x2) insert->SetLogy();
1171 if (logOpts & 0x4) insert->SetLogz();
1172 hist->GetXaxis()->SetRange(1, hist->GetNbinsX()/8);
1173 TH1* copy = hist->DrawCopy(opt);
1174 copy->GetXaxis()->SetNdivisions(408,
false);
1176 hist->GetXaxis()->SetRange(0, 0);
1181 RestoreLog(hist->GetXaxis(), logOpts & 0x1);
1182 RestoreLog(hist->GetYaxis(), logOpts & 0x2);
1183 RestoreLog(hist->GetZaxis(), logOpts & 0x4);
1185 if (status && stat) {
1187 status->DrawCopy(
"BOX TEXT");
1190 fImage[specie]->Print(outName,
"ps");
1192 fImage[specie]->Print(Form(
"%s_%d.png",
static const char * GetEventSpecieName(EventSpecie_t es)
static UInt_t GetImageBit()
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
UShort_t CheckRaw(AliRecoParam::EventSpecie_t specie, TH1 *hist) const
AliQAv1::QABIT_t Quality2Bit(UShort_t qual) const
static UInt_t GetExpertBit()
UShort_t BasicCheck(TH1 *hist) const
Double_t landau(Double_t *xp, Double_t *pp)
UShort_t CheckSim(AliRecoParam::EventSpecie_t specie, TH1 *hist) const
UShort_t CheckESD(AliRecoParam::EventSpecie_t specie, TH1 *hist) const
static const char * GetImageFileFormat()
void MakeImage(TObjArray **list, AliQAv1::TASKINDEX_t task, AliQAv1::MODE_t mode)
Quality assurance checker for the FMD.
static const char * GetImageFileName()
Double_t fELossFkupChi2Nu
void Check(Double_t *rv, AliQAv1::ALITASK_t what, TObjArray **list, const AliDetectorRecoParam *t)
TList * fExternParamList
flag to print the images or not
AliCDBEntry * Get(const AliCDBId &query, Bool_t forceCaching=kFALSE)
UShort_t CheckRec(AliRecoParam::EventSpecie_t specie, TH1 *hist) const
static DETECTORINDEX_t GetDetIndex(const char *name)
static EventSpecie_t ConvertIndex(Int_t index)
void ProcessExternalParams()
Double_t fELossMinSharing
#define AliWarningF(message,...)
void ProcessExternalParam(const char *name, Double_t &v)
#define AliDebug(logLevel, message)
static const char * GetModeName(MODE_t mode)
void Set(QABIT_t bit, AliRecoParam::EventSpecie_t es)
UShort_t CheckOne(AliQAv1::ALITASK_t what, AliRecoParam::EventSpecie_t specie, TH1 *hist) const
void SetQA(AliQAv1::ALITASK_t index, Double_t *values) const
Bool_t IsEventSpecieSet(AliRecoParam::EventSpecie_t es) const
void AddStatusPave(TH1 *hist, Int_t qual, Double_t xl=-1, Double_t yl=-1, Double_t xh=-1, Double_t yh=-1) const
static AliCDBManager * Instance(TMap *entryCache=NULL, Int_t run=-1)
static Int_t GetQADebugLevel()
#define AliDebugF(logLevel, format,...)
static AliQAChecker * Instance()
Double_t fELossGoodParError
static Int_t GetHalfringIndex(UShort_t det, Char_t ring, UShort_t board, UShort_t monitor=0)
static TString GetTaskName(UInt_t tsk)
UShort_t CheckFit(TH1 *hist, const TFitResultPtr &res, Double_t low, Double_t high, Int_t &color) const
static AliQAv1 * Instance()
TObject * GetThreshold(Int_t i)