Which Chi2 value is correct?

Dear friends,

I made just 3 bins simple histogram, like below on ROOT5.25(RooFit3.10).

TH1F h(“h”, “h”, 3, 0.5, 3.5);
for (int i=0;i<3;i++) {
h.Fill(1.0);
}
for (int i=0;i<5;i++) {
h.Fill(2.0);
}
for (int i=0;i<4;i++) {
h.Fill(3.0);
}

I fitted this histogram with linear function.
By hand calculation, Chi2/ndf is about 2.5.
However, I got Chi2/ndf = 12 from RooChi2Var, Chi2/ndf = 0.134345
from plot->chiSquare(), and Chi2/ndf = 0.33333 from GUI(ROOT).
What is the cause?

Best regards,
K
------------------------ output ---------------------------

reduced chi2 from RooChi2Var = 12
reduced chi2 from plot = 0.134345
Warning in TROOT::Append: Replacing existing TH1: data (Potential memory leak).
root [1]

Minimizer is Linear
Chi2 = 0.333333
NDf = 1
Par_0 = 2.77778 +/- 2.74199
Par_1 = 0.555556 +/- 1.31937

root [1] .q

----------------- source code ----------------
{
using namespace RooFit;
TH1F h(“h”, “h”, 3, 0.5, 3.5);
for (int i=0;i<3;i++) {
h.Fill(1.0);
}
for (int i=0;i<5;i++) {
h.Fill(2.0);
}
for (int i=0;i<4;i++) {
h.Fill(3.0);
}
TCanvas c1(“c1”, “c1”, 400, 400);
h->Fit(“poly”);
h->Draw();
c1->Draw();
//
RooRealVar x (“x”, “x”, 0.0, 4.0);
RooRealVar a (“a”, “a”, 0.0, 3.0);
RooPolynomial poly (“poly”, “poly”, x, RooArgList(a));
double integral_lower = 0.0;
double integral_upper = 10000000.0;
RooRealVar poly_integral (“poly_integral”, “poly_integral”, integral_lower, integral_upper);
RooAddPdf pdf(“pdf”, “pdf”, RooArgList(poly), RooArgList(poly_integral));
RooDataHist data (“data”, “data”, x, &h);
//
pdf.fitTo(data, Extended(kTRUE));
//
RooChi2Var chi2 (“chi2”, “chi2”, pdf, data, Extended(kTRUE));
Double_t chi2_val = chi2.getVal();
//
TCanvas c2(“c2”, “c2”, 400, 400);
RooPlot* plot = x.frame();
data.plotOn(plot, Name(“data”));
pdf.plotOn(plot, Name(“pdf”));
pdf.plotOn(plot, RooFit::Components(poly), RooFit::LineColor(2));
plot->Draw();
//
cout << "reduced chi2 from RooChi2Var = " << chi2_val/(h.GetNbinsX()-2.0) << endl;
cout << "reduced chi2 from plot = " << plot->chiSquare(“pdf”, “data”, (h.GetNbinsX()-2.0)) << endl;
}

Hi,

There a couple of reasons why you can get different answers out.

Class RooChi2Var does not calculate the reduced chi^2, but the plain chi2,
so that explains the much larger value.

Method RooPlot::chiSquare() calculated the reduced chi^2, assuming zero floating parameters. If you had floating parameters in your fit, you need to pass the number to RooPlot::chiSquare() to adjust nDOF appropriately
(there is no bullet proof automated way to do this automatically).

Also note, that for both RooChi2Var and RooPlot::chiSquare() the answer also depends on the type of errors calculated for data. In most cases the default error bar calculated for a RooPlot is the Poisson interval (you can override this by adding DataError(RooAbsData::SumW2) to the plotOn() call of the data), whereas the default for RooChi2Var is RooAbsData::SumW2 (you can override this by adding a DataError(RooAbsData::Poisson) to the RooChi2Var constructor (or to the RooAbsReal::createChi2() method).

Wouter

2 Likes

I turn down this comment.