94 const Double_t kDefaultEpsilon = 1E-12;
96 ClassImp(TBinomialEfficiencyFitter);
102 TBinomialEfficiencyFitter::TBinomialEfficiencyFitter() {
109 fEpsilon = kDefaultEpsilon;
122 TBinomialEfficiencyFitter::TBinomialEfficiencyFitter(
const TH1 *numerator,
const TH1 *denominator) {
123 fEpsilon = kDefaultEpsilon;
126 Set(numerator,denominator);
132 TBinomialEfficiencyFitter::~TBinomialEfficiencyFitter() {
133 if (fFitter)
delete fFitter;
140 void TBinomialEfficiencyFitter::Set(
const TH1 *numerator,
const TH1 *denominator)
142 fNumerator = (TH1*)numerator;
143 fDenominator = (TH1*)denominator;
153 void TBinomialEfficiencyFitter::SetPrecision(Double_t epsilon)
163 ROOT::Fit::Fitter* TBinomialEfficiencyFitter::GetFitter()
165 if (!fFitter) fFitter =
new ROOT::Fit::Fitter();
196 TFitResultPtr TBinomialEfficiencyFitter::Fit(TF1 *f1, Option_t* option)
198 TString opt = option;
200 fAverage = opt.Contains(
"I");
201 fRange = opt.Contains(
"R");
202 Bool_t verbose = opt.Contains(
"V");
203 Bool_t quiet = opt.Contains(
"Q");
204 Bool_t saveResult = opt.Contains(
"S");
206 fFunction = (TF1*)f1;
208 npar = f1->GetNpar();
210 Error(
"Fit",
"function %s has illegal number of parameters = %d",
211 f1->GetName(), npar);
216 if (!fNumerator || !fDenominator) {
217 Error(
"Fit",
"No numerator or denominator histograms set");
220 if (f1->GetNdim() != fNumerator->GetDimension()) {
221 Error(
"Fit",
"function %s dimension, %d, does not match histogram dimension, %d",
222 f1->GetName(), f1->GetNdim(), fNumerator->GetDimension());
226 if (fNumerator->GetNbinsX() != fDenominator->GetNbinsX() ||
227 (f1->GetNdim() > 1 && fNumerator->GetNbinsY() != fDenominator->GetNbinsY()) ||
228 (f1->GetNdim() > 2 && fNumerator->GetNbinsZ() != fDenominator->GetNbinsZ())) {
229 Error(
"Fit",
"numerator and denominator histograms do not have identical numbers of bins");
236 fFitter =
new ROOT::Fit::Fitter();
240 std::vector<ROOT::Fit::ParameterSettings> & parameters = fFitter->Config().ParamsSettings();
241 parameters.reserve(npar);
242 for (i = 0; i < npar; i++) {
245 Double_t we = f1->GetParError(i);
246 if (we <= 0) we = 0.3*TMath::Abs(f1->GetParameter(i));
247 if (we == 0) we = 0.01;
249 parameters.push_back(ROOT::Fit::ParameterSettings(f1->GetParName(i), f1->GetParameter(i), we) );
252 f1->GetParLimits(i,plow,pup);
255 if (plow >= pup && (plow==f1->GetParameter(i) || pup==f1->GetParameter(i) ||
256 ( f1->GetParameter(i) == 0 && plow==1. && pup == 1.) ) ) {
257 parameters.back().Fix();
258 Info(
"Fit",
"Fixing parameter %s to value %f", f1->GetParName(i), f1->GetParameter(i));
259 }
else if (plow < pup) {
260 parameters.back().SetLimits(plow,pup);
261 Info(
"Fit",
"Setting limits for parameter %s to [%f,%f]", f1->GetParName(i), plow,pup);
266 ROOT::Math::Functor fcnFunction(
this, &TBinomialEfficiencyFitter::EvaluateFCN, npar);
270 fFitter->SetFCN(static_cast<ROOT::Math::IMultiGenFunction &>(fcnFunction), ROOT::Math::WrappedMultiTF1(*f1));
273 if (fFitter->Config().MinimizerOptions().ErrorDef() == 1.0 ) {
274 fFitter->Config().MinimizerOptions().SetErrorDef(0.5);
278 fFitter->Config().MinimizerOptions().SetPrintLevel(3);
281 fFitter->Config().MinimizerOptions().SetPrintLevel(0);
287 Bool_t status = fFitter->FitFCN();
288 if ( !status && !quiet)
289 Warning(
"Fit",
"Abnormal termination of minimization.");
293 const ROOT::Fit::FitResult & fitResult = fFitter->Result();
294 if (!fitResult.IsEmpty() ) {
296 f1->SetNDF(fitResult.Ndf() );
300 f1->SetParameters( &(fitResult.Parameters().front()) );
301 if (
int( fitResult.Errors().size()) >= f1->GetNpar() )
302 f1->SetParErrors( &(fitResult.Errors().front()) );
304 f1->SetChisquare(2.*fitResult.MinFcnValue());
305 f1->SetNDF(f1->GetNumberFitPoints()- fitResult.NFreeParameters());
306 Info(
"result",
" chi2 %f ndf %d ",2.*fitResult.MinFcnValue(), fitResult.Ndf() );
311 TFitResult* fr =
new TFitResult(fitResult);
312 TString name = TString::Format(
"TBinomialEfficiencyFitter_result_of_%s",f1->GetName() );
313 fr->SetName(name); fr->SetTitle(name);
314 return TFitResultPtr(fr);
317 return TFitResultPtr(fitResult.Status() );
325 void TBinomialEfficiencyFitter::ComputeFCN(Double_t& f,
const Double_t* par)
327 int nDim = fDenominator->GetDimension();
329 int xlowbin = fDenominator->GetXaxis()->GetFirst();
330 int xhighbin = fDenominator->GetXaxis()->GetLast();
331 int ylowbin = 0, yhighbin = 0, zlowbin = 0, zhighbin = 0;
333 ylowbin = fDenominator->GetYaxis()->GetFirst();
334 yhighbin = fDenominator->GetYaxis()->GetLast();
336 zlowbin = fDenominator->GetZaxis()->GetFirst();
337 zhighbin = fDenominator->GetZaxis()->GetLast();
341 fFunction->SetParameters(par);
344 double xmin, xmax, ymin, ymax, zmin, zmax;
350 fFunction->GetRange(xmin, xmax);
351 xlowbin = fDenominator->GetXaxis()->FindBin(xmin);
352 xhighbin = fDenominator->GetXaxis()->FindBin(xmax);
353 }
else if (nDim == 2) {
354 fFunction->GetRange(xmin, ymin, xmax, ymax);
355 xlowbin = fDenominator->GetXaxis()->FindBin(xmin);
356 xhighbin = fDenominator->GetXaxis()->FindBin(xmax);
357 ylowbin = fDenominator->GetYaxis()->FindBin(ymin);
358 yhighbin = fDenominator->GetYaxis()->FindBin(ymax);
359 }
else if (nDim == 3) {
360 fFunction->GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
361 xlowbin = fDenominator->GetXaxis()->FindBin(xmin);
362 xhighbin = fDenominator->GetXaxis()->FindBin(xmax);
363 ylowbin = fDenominator->GetYaxis()->FindBin(ymin);
364 yhighbin = fDenominator->GetYaxis()->FindBin(ymax);
365 zlowbin = fDenominator->GetZaxis()->FindBin(zmin);
366 zhighbin = fDenominator->GetZaxis()->FindBin(zmax);
377 for (
int xbin = xlowbin; xbin <= xhighbin; ++xbin) {
380 Double_t xlow = fDenominator->GetXaxis()->GetBinLowEdge(xbin);
381 Double_t xup = fDenominator->GetXaxis()->GetBinLowEdge(xbin+1);
383 for (
int ybin = ylowbin; ybin <= yhighbin; ++ybin) {
386 Double_t ylow = (nDim > 1) ? fDenominator->GetYaxis()->GetBinLowEdge(ybin) : 0;
387 Double_t yup = (nDim > 1) ? fDenominator->GetYaxis()->GetBinLowEdge(ybin+1) : 0;
389 for (
int zbin = zlowbin; zbin <= zhighbin; ++zbin) {
392 Double_t zlow = (nDim > 2) ? fDenominator->GetZaxis()->GetBinLowEdge(zbin) : 0;
393 Double_t zup = (nDim > 2) ? fDenominator->GetZaxis()->GetBinLowEdge(zbin+1) : 0;
395 int bin = fDenominator->GetBin(xbin, ybin, zbin);
396 Double_t nDen = fDenominator->GetBinContent(bin);
397 Double_t nNum = fNumerator->GetBinContent(bin);
401 if (nDen> nmax) nmax = nDen;
402 if (nDen <= 0.)
continue;
414 fFunction->Integral(xlow, xup, fEpsilon)
416 fFunction->Eval(fDenominator->GetBinCenter(bin));
421 ((TF2*)fFunction)->Integral(xlow, xup, ylow, yup, fEpsilon)
422 / ((xup-xlow)*(yup-ylow)) :
423 fFunction->Eval(fDenominator->GetXaxis()->GetBinCenter(xbin),
424 fDenominator->GetYaxis()->GetBinCenter(ybin));
430 ((TF3*)fFunction)->Integral(xlow, xup, ylow, yup, zlow, zup, fEpsilon)
431 / ((xup-xlow)*(yup-ylow)*(zup-zlow)) :
432 fFunction->Eval(fDenominator->GetXaxis()->GetBinCenter(xbin),
433 fDenominator->GetYaxis()->GetBinCenter(ybin),
434 fDenominator->GetZaxis()->GetBinCenter(zbin));
441 f -= nNum * TMath::Log(mu*nDen/nNum);
445 if (nDen - nNum != 0.) {
447 f -= (nDen - nNum) * TMath::Log((1. - mu)*nDen/(nDen-nNum));
455 fFunction->SetNumberFitPoints(npoints);