Chi2 in the case of weighted data non integers values sum2w

Hello experts, I’m fitting a weighted MC dataset with non-integer values using the chi2FitTo() method and a minimization algorithm to optimize chi2/ndof . In my case, Fval is equivalent to chi2/ndof.
Since I’m working with weighted data, I’m using SumW2 to correctly compute the uncertainty (sigma) for chi2. Unlike standard bins where sigma= root square of y data, in this case, sigma is computed as the sum of the square root of weights in each bin: I obtain correct results using:

chi2_var = ROOT.RooChi2Var("chi2", "chi2", model,data,False,ROOT.RooDataHist.SumW2)
chi2_value = chi2_var.getVal()

#chi2 = frame.chiSquare("model", "data", npar)
ndof = dataHist.numEntries() - npar
chi2= chi2_value/ndof  

However, this does not work when using: frame.chiSquare(npar)
Does frame.chiSquare(npar) handle weighted data differently? Any suggestions on how to correctly use it in this case?

Hi @abaoud,
welcome to the ROOT forum!

Could you please add more context to your code snippet by explaining 1. if frame.chiSquare(npar) raises an error (and which one if so) and 2. how did you define the frame object?

Cheers,
Monica

Hi @mdessole, frame.chiSquare did not raise an error, but it gave me an unexpectedly high value of chi²/ndof. I suspect that it does not compute the uncertainty as sqrt(sum of squares of weights), which may explain the odd result. About the frame object aims to creat a rooplot object, where i can plot my data as well as my model.

    frame = var.frame()
    ROOT.SetOwnership(frame, True)
    data.plotOn(frame, ROOT.RooFit.Name("data"))
    model.plotOn(frame, ROOT.RooFit.Name("model"), ROOT.RooFit.LineColor(ROOT.kRed))
    chi2_var = ROOT.RooChi2Var("chi2", "chi2", model, data, False, ROOT.RooDataHist.SumW2)
    chi2_value = chi2_var.getVal()
    #chi2 = frame.chiSquare("model", "data", npar)
    ndof = dataHist.numEntries() - npar
    chi2= chi2_value/ndof
    col = 0
    cols = [ROOT.kGreen+2, ROOT.kBlue, ROOT.kOrange+1, ROOT.kCyan]
    frame.Draw()
    frame.GetYaxis().SetRangeUser(0, frame.GetMaximum()*1.5)
    leg = ROOT.TLegend(0.7, 0.63, 0.91, 0.85)
    ROOT.SetOwnership(leg, True)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)
    leg.AddEntry("data", "Data", "LP")
    leg.AddEntry("model", "model", "L")
    for name, comp in components.items():
        leg.AddEntry(name, name, "L")
    leg.Draw()
    ltx = ROOT.TLatex()
    ROOT.SetOwnership(ltx, True)
    ltx.SetNDC()
    ltx.SetTextColor(ROOT.kBlack)
    pos_y = 0.85
    ltx.DrawLatex(0.2, pos_y, "#chi^{{2}}/dof={chi2:.3f}".format(chi2=chi2))

best, Abdessamad

Let me add in the loop our RooFit experts @jonas @StephanH

1 Like