Dear experts,
I’m reaching out to seek feedback regarding an issue with the χ²/ndof calculation. I performed a fit to my data, and the fit looks good both visually and in the model/data ratio plot. However, the χ²/ndof value is always quite large. I verified that the number of degrees of freedom (ndof) is correct and stable, so I started investigating the χ² itself. Initially, I computed it using: frame.chiSquare(“model”, “data”, npar) Then I wrote a custom function [1] to compute the χ² manually, and this time I obtained a more reasonable value. However, I still don’t fully understand why the two results differ.
For reference, I’m using the chi2FitTo method for the fitting.
Please let me know if you need any additional details.
[1]
`
def calculate_chi2_manual(data_hist, model, var, n_params):`
chi2 = 0.0
n_bins = data_hist.numEntries()
x_min = var.getMin()
x_max = var.getMax()
total_range = x_max - x_min
`for i in range(n_bins):`
data_val = data_hist.weight(i)
data_point = data_hist.get(i)
x_val = data_point.getRealValue("t_Time")
var.setVal(x_val)
pdf_val = model.getVal(ROOT.RooArgSet(var))
bin_width = total_range / n_bins
expected_val = pdf_val \* bin_width \* data_hist.sumEntries()
error = data_val\*\*0.5 if data_val > 0 else 1.0
`if error > 0:`
chi2 += ((data_val - expected_val) / error)\*\*2
ndf = n_bins - n_params
chi2_per_ndf = chi2 / ndf if ndf > 0 else float('inf')
`return chi2, ndf, chi2_per_ndf`
Model:
modeldata = ROOT.RooAddPdf("combined_model", "Prompt + NonPrompt in Data",
ROOT.RooArgList(modelp, t_SigNonPromptModel),ROOT.RooArgList(yieldP,yieldNP))
result_data = modeldata.chi2FitTo(dataHist,ROOT.RooFit.Save(True),
ROOT.RooFit.Extended(True),ROOT.RooFit.Strategy(2))