{
"cells": [
{
"cell_type": "markdown",
"id": "23360ca3",
"metadata": {},
"source": [
"# rf308_normintegration2d\n",
"Multidimensional models: normalization and integration of pdfs, construction of\n",
"cumulative distribution functions from pdfs in two 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:30 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "98c66df1",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:54.687949Z",
"iopub.status.busy": "2026-05-19T20:30:54.687821Z",
"iopub.status.idle": "2026-05-19T20:30:54.701880Z",
"shell.execute_reply": "2026-05-19T20:30:54.701072Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"RooAbsReal.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"TH1.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "432e65fb",
"metadata": {},
"source": [
"Setup model\n",
"---------------------"
]
},
{
"cell_type": "markdown",
"id": "97a72ef0",
"metadata": {},
"source": [
"Create observables x,y"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "47b35935",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:54.703230Z",
"iopub.status.busy": "2026-05-19T20:30:54.703104Z",
"iopub.status.idle": "2026-05-19T20:30:55.016997Z",
"shell.execute_reply": "2026-05-19T20:30:55.016233Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -10, 10);\n",
"RooRealVar y(\"y\", \"y\", -10, 10);"
]
},
{
"cell_type": "markdown",
"id": "c91df759",
"metadata": {},
"source": [
"Create pdf gaussx(x,-2,3), gaussy(y,2,2)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "47dfbccf",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:55.023257Z",
"iopub.status.busy": "2026-05-19T20:30:55.023064Z",
"iopub.status.idle": "2026-05-19T20:30:55.231535Z",
"shell.execute_reply": "2026-05-19T20:30:55.230478Z"
}
},
"outputs": [],
"source": [
"RooGaussian gx(\"gx\", \"gx\", x, -2.0, 3.0);\n",
"RooGaussian gy(\"gy\", \"gy\", y, +2.0, 2.0);"
]
},
{
"cell_type": "markdown",
"id": "c346f247",
"metadata": {},
"source": [
"Create gxy = gx(x)*gy(y)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b1888858",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:55.233124Z",
"iopub.status.busy": "2026-05-19T20:30:55.233003Z",
"iopub.status.idle": "2026-05-19T20:30:55.440725Z",
"shell.execute_reply": "2026-05-19T20:30:55.440244Z"
}
},
"outputs": [],
"source": [
"RooProdPdf gxy(\"gxy\", \"gxy\", RooArgSet(gx, gy));"
]
},
{
"cell_type": "markdown",
"id": "a930e0aa",
"metadata": {},
"source": [
"Retrieve raw & normalized values of RooFit p.d.f.s\n",
"--------------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "dd5a3524",
"metadata": {},
"source": [
"Return 'raw' unnormalized value of gx"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d8630996",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:55.442854Z",
"iopub.status.busy": "2026-05-19T20:30:55.442729Z",
"iopub.status.idle": "2026-05-19T20:30:55.651277Z",
"shell.execute_reply": "2026-05-19T20:30:55.650453Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gxy = 0.485672\n"
]
}
],
"source": [
"cout << \"gxy = \" << gxy.getVal() << endl;"
]
},
{
"cell_type": "markdown",
"id": "3024923b",
"metadata": {},
"source": [
"Return value of gxy normalized over x _and_ y in range [-10,10]"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c192f269",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:55.652801Z",
"iopub.status.busy": "2026-05-19T20:30:55.652672Z",
"iopub.status.idle": "2026-05-19T20:30:55.860890Z",
"shell.execute_reply": "2026-05-19T20:30:55.860099Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gx_Norm[x,y] = 0.0129332\n"
]
}
],
"source": [
"RooArgSet nset_xy(x, y);\n",
"cout << \"gx_Norm[x,y] = \" << gxy.getVal(&nset_xy) << endl;"
]
},
{
"cell_type": "markdown",
"id": "e87b74a2",
"metadata": {},
"source": [
"Create object representing integral over gx\n",
"which is used to calculate gx_Norm[x,y] == gx / gx_Int[x,y]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "79c974db",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:55.862408Z",
"iopub.status.busy": "2026-05-19T20:30:55.862284Z",
"iopub.status.idle": "2026-05-19T20:30:56.070755Z",
"shell.execute_reply": "2026-05-19T20:30:56.069936Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gx_Int[x,y] = 37.5523\n"
]
}
],
"source": [
"std::unique_ptr igxy{gxy.createIntegral(RooArgSet(x, y))};\n",
"cout << \"gx_Int[x,y] = \" << igxy->getVal() << endl;"
]
},
{
"cell_type": "markdown",
"id": "98e4cd77",
"metadata": {},
"source": [
"NB: it is also possible to do the following"
]
},
{
"cell_type": "markdown",
"id": "dc5dac97",
"metadata": {},
"source": [
"Return value of gxy normalized over x in range [-10,10] (i.e. treating y as parameter)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "689e29ae",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:56.072327Z",
"iopub.status.busy": "2026-05-19T20:30:56.072191Z",
"iopub.status.idle": "2026-05-19T20:30:56.281503Z",
"shell.execute_reply": "2026-05-19T20:30:56.280716Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gx_Norm[x] = 0.106896\n"
]
}
],
"source": [
"RooArgSet nset_x(x);\n",
"cout << \"gx_Norm[x] = \" << gxy.getVal(&nset_x) << endl;"
]
},
{
"cell_type": "markdown",
"id": "86273e9a",
"metadata": {},
"source": [
"Return value of gxy normalized over y in range [-10,10] (i.e. treating x as parameter)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "2bf06b9f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:56.283083Z",
"iopub.status.busy": "2026-05-19T20:30:56.282953Z",
"iopub.status.idle": "2026-05-19T20:30:56.491251Z",
"shell.execute_reply": "2026-05-19T20:30:56.490652Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gx_Norm[y] = 0.120989\n"
]
}
],
"source": [
"RooArgSet nset_y(y);\n",
"cout << \"gx_Norm[y] = \" << gxy.getVal(&nset_y) << endl;"
]
},
{
"cell_type": "markdown",
"id": "249f7d33",
"metadata": {},
"source": [
"Integrate normalized pdf over subrange\n",
"----------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "bb8aaf47",
"metadata": {},
"source": [
"Define a range named \"signal\" in x from -5,5"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "174b08ae",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:56.492959Z",
"iopub.status.busy": "2026-05-19T20:30:56.492834Z",
"iopub.status.idle": "2026-05-19T20:30:56.701193Z",
"shell.execute_reply": "2026-05-19T20:30:56.700680Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Eval -- RooRealVar::setRange(x) new range named 'signal' created with bounds [-5,5]\n",
"[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'signal' created with bounds [-3,3]\n"
]
}
],
"source": [
"x.setRange(\"signal\", -5, 5);\n",
"y.setRange(\"signal\", -3, 3);"
]
},
{
"cell_type": "markdown",
"id": "4a789036",
"metadata": {},
"source": [
"Create an integral of gxy_Norm[x,y] over x and y in range \"signal\"\n",
"This is the fraction of of pdf gxy_Norm[x,y] which is in the\n",
"range named \"signal\""
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "42ce0e34",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:56.702976Z",
"iopub.status.busy": "2026-05-19T20:30:56.702841Z",
"iopub.status.idle": "2026-05-19T20:30:56.911215Z",
"shell.execute_reply": "2026-05-19T20:30:56.910652Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"gx_Int[x,y|signal]_Norm[x,y] = 0.572035\n"
]
}
],
"source": [
"std::unique_ptr igxy_sig{gxy.createIntegral({x, y}, NormSet(RooArgSet(x, y)), Range(\"signal\"))};\n",
"cout << \"gx_Int[x,y|signal]_Norm[x,y] = \" << igxy_sig->getVal() << endl;"
]
},
{
"cell_type": "markdown",
"id": "054e9f83",
"metadata": {},
"source": [
"Construct cumulative distribution function from pdf\n",
"-----------------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "6669bca0",
"metadata": {},
"source": [
"Create the cumulative distribution function of gx\n",
"i.e. calculate Int[-10,x] gx(x') dx'"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "a5ca127a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:56.912872Z",
"iopub.status.busy": "2026-05-19T20:30:56.912748Z",
"iopub.status.idle": "2026-05-19T20:30:57.121826Z",
"shell.execute_reply": "2026-05-19T20:30:57.121203Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr gxy_cdf{gxy.createCdf(RooArgSet(x, y))};"
]
},
{
"cell_type": "markdown",
"id": "b88bd4f0",
"metadata": {},
"source": [
"Plot cdf of gx versus x"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "14400d34",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:57.123745Z",
"iopub.status.busy": "2026-05-19T20:30:57.123616Z",
"iopub.status.idle": "2026-05-19T20:30:57.328952Z",
"shell.execute_reply": "2026-05-19T20:30:57.328326Z"
}
},
"outputs": [],
"source": [
"TH1 *hh_cdf = gxy_cdf->createHistogram(\"hh_cdf\", x, Binning(40), YVar(y, Binning(40)));\n",
"hh_cdf->SetLineColor(kBlue);\n",
"\n",
"new TCanvas(\"rf308_normintegration2d\", \"rf308_normintegration2d\", 600, 600);\n",
"gPad->SetLeftMargin(0.15);\n",
"hh_cdf->GetZaxis()->SetTitleOffset(1.8);\n",
"hh_cdf->Draw(\"surf\");"
]
},
{
"cell_type": "markdown",
"id": "76568577",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "12c6308c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:57.330806Z",
"iopub.status.busy": "2026-05-19T20:30:57.330675Z",
"iopub.status.idle": "2026-05-19T20:30:57.538479Z",
"shell.execute_reply": "2026-05-19T20:30:57.537972Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"gROOT->GetListOfCanvases()->Draw()"
]
}
],
"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
}