{
"cells": [
{
"cell_type": "markdown",
"id": "e09e2adf",
"metadata": {},
"source": [
"# rf602_chi2fit\n",
"Likelihood and minimization: setting up a chi^2 fit to a binned dataset\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Wouter Verkerke \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:32 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "59e35f4d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:57.987799Z",
"iopub.status.busy": "2026-05-19T20:32:57.987644Z",
"iopub.status.idle": "2026-05-19T20:32:58.002629Z",
"shell.execute_reply": "2026-05-19T20:32:58.002052Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooChebychev.h\"\n",
"#include \"RooAddPdf.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"RooPlot.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "296f1ed8",
"metadata": {},
"source": [
"Setup model\n",
"---------------------"
]
},
{
"cell_type": "markdown",
"id": "474b60e0",
"metadata": {},
"source": [
"Declare observable x"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6ebb1b3b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:58.004177Z",
"iopub.status.busy": "2026-05-19T20:32:58.004062Z",
"iopub.status.idle": "2026-05-19T20:32:58.319104Z",
"shell.execute_reply": "2026-05-19T20:32:58.318509Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", 0, 10);"
]
},
{
"cell_type": "markdown",
"id": "ad32f52e",
"metadata": {},
"source": [
"Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e7b02a1d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:58.321192Z",
"iopub.status.busy": "2026-05-19T20:32:58.321068Z",
"iopub.status.idle": "2026-05-19T20:32:58.529958Z",
"shell.execute_reply": "2026-05-19T20:32:58.529453Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#0] WARNING:InputArguments -- The parameter 'sigma1' with range [-inf, inf] of the RooGaussian 'sig1' exceeds the safe range of (0, inf). Advise to limit its range.\n",
"[#0] WARNING:InputArguments -- The parameter 'sigma2' with range [-inf, inf] of the RooGaussian 'sig2' exceeds the safe range of (0, inf). Advise to limit its range.\n"
]
}
],
"source": [
"RooRealVar mean(\"mean\", \"mean of gaussians\", 5);\n",
"RooRealVar sigma1(\"sigma1\", \"width of gaussians\", 0.5);\n",
"RooRealVar sigma2(\"sigma2\", \"width of gaussians\", 1);\n",
"\n",
"RooGaussian sig1(\"sig1\", \"Signal component 1\", x, mean, sigma1);\n",
"RooGaussian sig2(\"sig2\", \"Signal component 2\", x, mean, sigma2);"
]
},
{
"cell_type": "markdown",
"id": "85bfdef6",
"metadata": {},
"source": [
"Build Chebychev polynomial pdf"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "839ac97d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:58.531713Z",
"iopub.status.busy": "2026-05-19T20:32:58.531572Z",
"iopub.status.idle": "2026-05-19T20:32:58.740252Z",
"shell.execute_reply": "2026-05-19T20:32:58.739467Z"
}
},
"outputs": [],
"source": [
"RooRealVar a0(\"a0\", \"a0\", 0.5, 0., 1.);\n",
"RooRealVar a1(\"a1\", \"a1\", 0.2, 0., 1.);\n",
"RooChebychev bkg(\"bkg\", \"Background\", x, RooArgSet(a0, a1));"
]
},
{
"cell_type": "markdown",
"id": "92d8b0a4",
"metadata": {},
"source": [
"Sum the signal components into a composite signal pdf"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "9f085b89",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:58.741929Z",
"iopub.status.busy": "2026-05-19T20:32:58.741807Z",
"iopub.status.idle": "2026-05-19T20:32:58.950380Z",
"shell.execute_reply": "2026-05-19T20:32:58.949707Z"
}
},
"outputs": [],
"source": [
"RooRealVar sig1frac(\"sig1frac\", \"fraction of component 1 in signal\", 0.8, 0., 1.);\n",
"RooAddPdf sig(\"sig\", \"Signal\", RooArgList(sig1, sig2), sig1frac);"
]
},
{
"cell_type": "markdown",
"id": "07ba7b54",
"metadata": {},
"source": [
"Sum the composite signal and background"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7252f403",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:58.952217Z",
"iopub.status.busy": "2026-05-19T20:32:58.952091Z",
"iopub.status.idle": "2026-05-19T20:32:59.160742Z",
"shell.execute_reply": "2026-05-19T20:32:59.160026Z"
}
},
"outputs": [],
"source": [
"RooRealVar bkgfrac(\"bkgfrac\", \"fraction of background\", 0.5, 0., 1.);\n",
"RooAddPdf model(\"model\", \"g1+g2+a\", RooArgList(bkg, sig), bkgfrac);"
]
},
{
"cell_type": "markdown",
"id": "51424778",
"metadata": {},
"source": [
"Create binned dataset\n",
"-----------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b23a605b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:59.162367Z",
"iopub.status.busy": "2026-05-19T20:32:59.162250Z",
"iopub.status.idle": "2026-05-19T20:32:59.370797Z",
"shell.execute_reply": "2026-05-19T20:32:59.370123Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr d{model.generate(x, 10000)};\n",
"std::unique_ptr dh{d->binnedClone()};"
]
},
{
"cell_type": "markdown",
"id": "a675afd3",
"metadata": {},
"source": [
"Construct a chi^2 of the data and the model.\n",
"When a pdf is used in a chi^2 fit, the probability density scaled\n",
"by the number of events in the dataset to obtain the fit function\n",
"If model is an extended pdf, the expected number events is used\n",
"instead of the observed number of events."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "ee13c3b0",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:59.372579Z",
"iopub.status.busy": "2026-05-19T20:32:59.372464Z",
"iopub.status.idle": "2026-05-19T20:32:59.581423Z",
"shell.execute_reply": "2026-05-19T20:32:59.580798Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- createChi2(model) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- using generic CPU library compiled with no vectorizations\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
}
],
"source": [
"model.chi2FitTo(*dh, PrintLevel(-1));"
]
},
{
"cell_type": "markdown",
"id": "01287e1a",
"metadata": {},
"source": [
"NB: It is also possible to fit a RooAbsReal function to a RooDataHist\n",
"using chi2FitTo()."
]
},
{
"cell_type": "markdown",
"id": "ea0b3056",
"metadata": {},
"source": [
"Note that entries with zero bins are _not_ allowed\n",
"for a proper chi^2 calculation and will give error\n",
"messages"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "32d4585e",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:59.582941Z",
"iopub.status.busy": "2026-05-19T20:32:59.582822Z",
"iopub.status.idle": "2026-05-19T20:32:59.791521Z",
"shell.execute_reply": "2026-05-19T20:32:59.790943Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- createChi2(model) fixing normalization set for coefficient determination to observables in data\n",
"90.865\n"
]
}
],
"source": [
"std::unique_ptr dsmall{d->reduce(EventRange(1, 100))};\n",
"std::unique_ptr dhsmall{static_cast(*dsmall).binnedClone()};\n",
"std::unique_ptr chi2_lowstat{model.createChi2(*dhsmall)};\n",
"cout << chi2_lowstat->getVal() << endl;"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}