{ "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 }