15 #include <TGraphAsymmErrors.h>
37 , fHistogramBinomial(0)
54 , fHistogramBinomial(0)
71 , fHistogramBinomial(0)
90 , fHistogramBinomial(0)
108 if (!hist1 || !hist2) {
109 BCLog::OutError(
"BCEfficiencyFitter::SetHistograms : TH1D not created.");
114 if (hist1->GetNbinsX() != hist2->GetNbinsX()) {
115 BCLog::OutError(
"BCEfficiencyFitter::SetHistograms : Histograms do not have the same number of bins.");
120 for (
int i = 1; i <= hist1->GetNbinsX(); ++i)
121 if (hist1->GetBinContent(i) < hist2->GetBinContent(i)) {
122 BCLog::OutError(
"BCEfficiencyFitter::SetHistograms : Histogram 1 has fewer entries than histogram 2.");
137 for (
int i = 0; i < nbins; ++i) {
146 double xmin = hist1->GetBinLowEdge(1);
147 double xmax = hist1->GetBinLowEdge(nbins+1);
175 BCLog::OutError(
"BCEfficiencyFitter::SetFitFunction : TF1 not created.");
190 int n = func->GetNpar();
193 for (
int i = 0; i < n; ++i)
198 func->GetParLimits(i, xmin, xmax);
222 if(type < 0 || type > 2)
223 BCLog::OutError(Form(
"BCEfficiencyFitter::SetDataPointType : Unknown data point type %d (should be between 0 and 2).",type));
234 double loglikelihood = 0;
243 double dx =
fHistogram1->GetXaxis()->GetBinWidth(0);
246 for (
int ibin = 1; ibin <= nbins; ++ibin)
261 eff =
fFitFunction->Integral(x - dx/2., x + dx/2.) / dx;
271 return loglikelihood;
292 BCLog::OutError(
"BCEfficiencyFitter::Fit : Histogram(s) not defined.");
300 BCLog::OutError(
"BCEfficiencyFitter::Fit : Fit function not defined.");
313 BCLog::OutError(
"BCEfficiencyFitter::Fit : Histogram(s) not defined.");
319 BCLog::OutError(
"BCEfficiencyFitter::Fit : Fit function not defined.");
334 double pvalue, pvalueCorrected;
338 BCLog::OutError(
"BCEfficiencyFitter::Fit : Could not use the fast p-value evaluation.");
352 BCLog::OutError(
"BCEfficiencyFitter::DrawFit : Histogram(s) not defined.");
357 BCLog::OutError(
"BCEfficiencyFitter::DrawFit : Fit function not defined.");
362 TGraphAsymmErrors * histRatio =
new TGraphAsymmErrors();
363 histRatio->SetMarkerStyle(20);
364 histRatio->SetMarkerSize(1.5);
369 for (
int i = 1; i <=
fHistogram1->GetNbinsX(); ++i)
377 double xexp, xmin, xmax;
380 histRatio->SetPoint( npoints,
fHistogram1->GetBinCenter(i), xexp);
383 histRatio->SetPointEXhigh(npoints, 0.);
384 histRatio->SetPointEXlow(npoints, 0.);
387 histRatio->SetPointEYhigh(npoints, xmax - xexp);
388 histRatio->SetPointEYlow(npoints, xexp - xmin);
395 TString opt = options;
399 if(!opt.Contains(
"same"))
402 TH2D * hist_axes =
new TH2D(
"hist_axes",
403 Form(
";%s;ratio",
fHistogram1->GetXaxis()->GetTitle()),
408 hist_axes->SetStats(kFALSE);
411 histRatio->Draw(TString::Format(
"%sp",opt.Data()));
419 histRatio->SetMarkerSize(.7);
420 histRatio->Draw(TString::Format(
"%ssamep",opt.Data()));
431 TLegend * legend =
new TLegend(0.25, 0.75, 0.55, 0.95);
432 legend->SetBorderSize(0);
433 legend->SetFillColor(kWhite);
434 legend->AddEntry(histRatio,
"Data",
"L");
436 legend->AddEntry(
fErrorBand,
"Error band",
"F");
444 double & pvalueCorrected,
unsigned nIterations)
453 double & pvalueCorrected,
unsigned nIterations)
457 BCLog::OutError(
"BCEfficiencyFitter::CalculatePValueFast : Number of parameters is inconsistent.");
463 BCLog::OutError(
"BCEfficiencyFitter::CalculatePValueFast : Histogram not defined.");
470 std::vector<unsigned> histogram(nbins, 0);
471 std::vector<double> expectation(nbins, 0);
474 double logp_start = 0;
475 int counter_pvalue = 0;
478 for (
int ibin = 0; ibin < nbins; ++ibin) {
493 expectation[ibin] = n * yexp;
501 for (
unsigned iiter = 0; iiter < nIterations; ++iiter)
504 for (
int ibin = 0; ibin < nbins; ++ibin)
510 int k = histogram.at(ibin);
515 yexp = expectation.at(ibin)/n;
518 double ptest =
fRandom->Rndm() - 0.5;
521 if (!(yexp > 0. || yexp < 1.0))
525 if (ptest > 0 && (k < n))
528 double r = (double(n)-double(k))/(
double(k)+1.) * yexp / (1. - yexp);
533 histogram[ibin] = k + 1;
539 else if (ptest <= 0 && (k > 0))
542 double r = double(k) / (double(n)-(double(k)-1)) * (1-yexp)/yexp;
547 histogram[ibin] = k - 1;
557 (*callback)(expectation, histogram);
560 if (logp < logp_start)
566 pvalue = double(counter_pvalue) / double(nIterations);
595 for (
int i = 1; i <= 1000; ++i) {
613 xexp = (double)k/(
double)n;
616 int ninter = intervals.size();
618 xmin = xmax = xexp = 0.;
631 probSum[0] = (1.-p)/2.;
632 probSum[1] = 1.-(1.-p)/2.;
643 BCLog::OutDebug(Form(
" - efficiency = %f , range (%f - %f)",xexp,xmin,xmax));