{
"cells": [
{
"cell_type": "markdown",
"id": "157fb207",
"metadata": {},
"source": [
"# rf312_multirangefit\n",
"Multidimensional models: performing fits in multiple (disjoint) ranges in one or more dimensions\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:31 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "32e3e043",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:09.862477Z",
"iopub.status.busy": "2026-05-19T20:31:09.862362Z",
"iopub.status.idle": "2026-05-19T20:31:09.876624Z",
"shell.execute_reply": "2026-05-19T20:31:09.876131Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"RooAddPdf.h\"\n",
"#include \"RooPolynomial.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"RooFitResult.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "382e20f1",
"metadata": {},
"source": [
"Create 2D pdf and data\n",
"-------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "468d479a",
"metadata": {},
"source": [
"Define observables x,y"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a7abef88",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:09.877897Z",
"iopub.status.busy": "2026-05-19T20:31:09.877779Z",
"iopub.status.idle": "2026-05-19T20:31:10.205055Z",
"shell.execute_reply": "2026-05-19T20:31:10.204462Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -10, 10);\n",
"RooRealVar y(\"y\", \"y\", -10, 10);"
]
},
{
"cell_type": "markdown",
"id": "20a05d1a",
"metadata": {},
"source": [
"Construct the signal pdf gauss(x)*gauss(y)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "246ae334",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:10.206734Z",
"iopub.status.busy": "2026-05-19T20:31:10.206590Z",
"iopub.status.idle": "2026-05-19T20:31:10.415030Z",
"shell.execute_reply": "2026-05-19T20:31:10.414234Z"
}
},
"outputs": [],
"source": [
"RooRealVar mx(\"mx\", \"mx\", 1, -10, 10);\n",
"RooRealVar my(\"my\", \"my\", 1, -10, 10);\n",
"\n",
"RooGaussian gx(\"gx\", \"gx\", x, mx, 1.0);\n",
"RooGaussian gy(\"gy\", \"gy\", y, my, 1.0);\n",
"\n",
"RooProdPdf sig(\"sig\", \"sig\", gx, gy);"
]
},
{
"cell_type": "markdown",
"id": "cf66d0fd",
"metadata": {},
"source": [
"Construct the background pdf (flat in x,y)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4df936f7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:10.416749Z",
"iopub.status.busy": "2026-05-19T20:31:10.416598Z",
"iopub.status.idle": "2026-05-19T20:31:10.624649Z",
"shell.execute_reply": "2026-05-19T20:31:10.624094Z"
}
},
"outputs": [],
"source": [
"RooPolynomial px(\"px\", \"px\", x);\n",
"RooPolynomial py(\"py\", \"py\", y);\n",
"RooProdPdf bkg(\"bkg\", \"bkg\", px, py);"
]
},
{
"cell_type": "markdown",
"id": "f2319593",
"metadata": {},
"source": [
"Construct the composite model sig+bkg"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5d2c3436",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:10.626309Z",
"iopub.status.busy": "2026-05-19T20:31:10.626185Z",
"iopub.status.idle": "2026-05-19T20:31:10.834350Z",
"shell.execute_reply": "2026-05-19T20:31:10.833828Z"
}
},
"outputs": [],
"source": [
"RooRealVar f(\"f\", \"f\", 0., 1.);\n",
"RooAddPdf model(\"model\", \"model\", RooArgList(sig, bkg), f);"
]
},
{
"cell_type": "markdown",
"id": "ea0d5b3a",
"metadata": {},
"source": [
"Sample 10000 events in (x,y) from the model"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "2d4c2c6d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:10.836218Z",
"iopub.status.busy": "2026-05-19T20:31:10.836091Z",
"iopub.status.idle": "2026-05-19T20:31:11.077985Z",
"shell.execute_reply": "2026-05-19T20:31:11.067391Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr modelData{model.generate({x, y}, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "e3336f87",
"metadata": {},
"source": [
"Define signal and sideband regions\n",
"-------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "9135e028",
"metadata": {},
"source": [
"Construct the SideBand1,SideBand2,Signal regions\n",
"\n",
"|\n",
"+-------------+-----------+\n",
"| | |\n",
"| Side | Sig |\n",
"| Band1 | nal |\n",
"| | |\n",
"--+-------------+-----------+--\n",
"| |\n",
"| Side |\n",
"| Band2 |\n",
"| |\n",
"+-------------+-----------+\n",
"|"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f50fb0a3",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:11.097585Z",
"iopub.status.busy": "2026-05-19T20:31:11.097422Z",
"iopub.status.idle": "2026-05-19T20:31:11.303427Z",
"shell.execute_reply": "2026-05-19T20:31:11.303033Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'SB1' created with bounds [-10,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'SB1' created with bounds [-10,0]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'SB2' created with bounds [-10,0]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'SB2' created with bounds [0,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'SIG' created with bounds [0,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'SIG' created with bounds [0,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'FULL' created with bounds [-10,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'FULL' created with bounds [-10,10]\n"
]
}
],
"source": [
"x.setRange(\"SB1\", -10, +10);\n",
"y.setRange(\"SB1\", -10, 0);\n",
"\n",
"x.setRange(\"SB2\", -10, 0);\n",
"y.setRange(\"SB2\", 0, +10);\n",
"\n",
"x.setRange(\"SIG\", 0, +10);\n",
"y.setRange(\"SIG\", 0, +10);\n",
"\n",
"x.setRange(\"FULL\", -10, +10);\n",
"y.setRange(\"FULL\", -10, +10);"
]
},
{
"cell_type": "markdown",
"id": "cf2cc83b",
"metadata": {},
"source": [
"Perform fits in individual sideband regions\n",
"-------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "add62ead",
"metadata": {},
"source": [
"Perform fit in SideBand1 region (RooAddPdf coefficients will be interpreted in full range)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "bdbc06a5",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:11.305357Z",
"iopub.status.busy": "2026-05-19T20:31:11.305241Z",
"iopub.status.idle": "2026-05-19T20:31:11.514856Z",
"shell.execute_reply": "2026-05-19T20:31:11.514077Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'fit_nll_model_modelData' created with bounds [-10,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'fit_nll_model_modelData' created with bounds [-10,0]\n",
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(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:Fitting -- Creation of NLL object took 1.7411 ms\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_modelData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
}
],
"source": [
"std::unique_ptr r_sb1{model.fitTo(*modelData, Range(\"SB1\"), Save(), PrintLevel(-1))};"
]
},
{
"cell_type": "markdown",
"id": "5e4dbbc1",
"metadata": {},
"source": [
"Perform fit in SideBand2 region (RooAddPdf coefficients will be interpreted in full range)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "ce540482",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:11.516379Z",
"iopub.status.busy": "2026-05-19T20:31:11.516238Z",
"iopub.status.idle": "2026-05-19T20:31:11.725814Z",
"shell.execute_reply": "2026-05-19T20:31:11.725168Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(model) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- Creation of NLL object took 591.543 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_modelData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
}
],
"source": [
"std::unique_ptr r_sb2{model.fitTo(*modelData, Range(\"SB2\"), Save(), PrintLevel(-1))};"
]
},
{
"cell_type": "markdown",
"id": "7bcd3e27",
"metadata": {},
"source": [
"Perform fits in joint sideband regions\n",
"-----------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "f095adea",
"metadata": {},
"source": [
"Now perform fit to joint 'L-shaped' sideband region 'SB1|SB2'\n",
"(RooAddPdf coefficients will be interpreted in full range)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "5e271800",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:11.727328Z",
"iopub.status.busy": "2026-05-19T20:31:11.727202Z",
"iopub.status.idle": "2026-05-19T20:31:11.936790Z",
"shell.execute_reply": "2026-05-19T20:31:11.936146Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'fit_nll_model_modelData_SB1' created with bounds [-10,10]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'fit_nll_model_modelData_SB1' created with bounds [-10,0]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'fit_nll_model_modelData_SB2' created with bounds [-10,0]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'fit_nll_model_modelData_SB2' created with bounds [0,10]\n",
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(model) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- Creation of NLL object took 850.374 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_modelData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
}
],
"source": [
"std::unique_ptr r_sb12{model.fitTo(*modelData, Range(\"SB1,SB2\"), Save(), PrintLevel(-1))};"
]
},
{
"cell_type": "markdown",
"id": "c0524ae9",
"metadata": {},
"source": [
"Print results for comparison"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "4f7f8b6a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:11.938239Z",
"iopub.status.busy": "2026-05-19T20:31:11.938112Z",
"iopub.status.idle": "2026-05-19T20:31:12.148140Z",
"shell.execute_reply": "2026-05-19T20:31:12.147406Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" RooFitResult: minimized FCN value: 16261.4, estimated distance to minimum: 5.06415e-07\n",
" covariance matrix quality: Full, accurate covariance matrix\n",
" Status : MINIMIZE=0 HESSE=0 \n",
"\n",
" Floating Parameter FinalValue +/- Error \n",
" -------------------- --------------------------\n",
" f 5.1135e-01 +/- 3.58e-02\n",
" mx 9.8740e-01 +/- 4.03e-02\n",
" my 9.9305e-01 +/- 9.39e-02\n",
"\n",
"\n",
" RooFitResult: minimized FCN value: 7578.28, estimated distance to minimum: 3.07865e-06\n",
" covariance matrix quality: Full, accurate covariance matrix\n",
" Status : MINIMIZE=0 HESSE=0 \n",
"\n",
" Floating Parameter FinalValue +/- Error \n",
" -------------------- --------------------------\n",
" f 5.4586e-01 +/- 4.46e-02\n",
" mx 1.1276e+00 +/- 1.10e-01\n",
" my 9.6462e-01 +/- 5.60e-02\n",
"\n",
"\n",
" RooFitResult: minimized FCN value: 27252.6, estimated distance to minimum: 2.25202e-06\n",
" covariance matrix quality: Full, accurate covariance matrix\n",
" Status : MINIMIZE=0 HESSE=0 \n",
"\n",
" Floating Parameter FinalValue +/- Error \n",
" -------------------- --------------------------\n",
" f 5.0082e-01 +/- 1.29e-02\n",
" mx 1.0100e+00 +/- 3.26e-02\n",
" my 9.6348e-01 +/- 3.31e-02\n",
"\n"
]
}
],
"source": [
"r_sb1->Print();\n",
"r_sb2->Print();\n",
"r_sb12->Print();"
]
}
],
"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
}