{
"cells": [
{
"cell_type": "markdown",
"id": "963a5fc4",
"metadata": {},
"source": [
"# rf316_llratioplot\n",
"Multidimensional models: using the likelihood ratio technique to construct a signal\n",
"enhanced one-dimensional projection of a multi-dimensional pdf\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": "62412658",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:24.853974Z",
"iopub.status.busy": "2026-05-19T20:31:24.853864Z",
"iopub.status.idle": "2026-05-19T20:31:24.867764Z",
"shell.execute_reply": "2026-05-19T20:31:24.867178Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooPolynomial.h\"\n",
"#include \"RooAddPdf.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"RooPlot.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "9d23e656",
"metadata": {},
"source": [
"Create 3D pdf and data\n",
"-------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "361fdf70",
"metadata": {},
"source": [
"Create observables"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a015d99d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:24.868968Z",
"iopub.status.busy": "2026-05-19T20:31:24.868856Z",
"iopub.status.idle": "2026-05-19T20:31:25.181871Z",
"shell.execute_reply": "2026-05-19T20:31:25.181187Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -5, 5);\n",
"RooRealVar y(\"y\", \"y\", -5, 5);\n",
"RooRealVar z(\"z\", \"z\", -5, 5);"
]
},
{
"cell_type": "markdown",
"id": "2ca7fe16",
"metadata": {},
"source": [
"Create signal pdf gauss(x)*gauss(y)*gauss(z)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1ea3db27",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:25.183742Z",
"iopub.status.busy": "2026-05-19T20:31:25.183616Z",
"iopub.status.idle": "2026-05-19T20:31:25.391634Z",
"shell.execute_reply": "2026-05-19T20:31:25.390950Z"
}
},
"outputs": [],
"source": [
"RooGaussian gx(\"gx\", \"gx\", x, 0.0, 1.0);\n",
"RooGaussian gy(\"gy\", \"gy\", y, 0.0, 1.0);\n",
"RooGaussian gz(\"gz\", \"gz\", z, 0.0, 1.0);\n",
"RooProdPdf sig(\"sig\", \"sig\", RooArgSet(gx, gy, gz));"
]
},
{
"cell_type": "markdown",
"id": "e77c8bf8",
"metadata": {},
"source": [
"Create background pdf poly(x)*poly(y)*poly(z)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "d2bc59e0",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:25.402505Z",
"iopub.status.busy": "2026-05-19T20:31:25.402372Z",
"iopub.status.idle": "2026-05-19T20:31:25.610344Z",
"shell.execute_reply": "2026-05-19T20:31:25.609758Z"
}
},
"outputs": [],
"source": [
"RooPolynomial px(\"px\", \"px\", x, RooArgSet(-0.1, 0.004));\n",
"RooPolynomial py(\"py\", \"py\", y, RooArgSet(0.1, -0.004));\n",
"RooPolynomial pz(\"pz\", \"pz\", z);\n",
"RooProdPdf bkg(\"bkg\", \"bkg\", RooArgSet(px, py, pz));"
]
},
{
"cell_type": "markdown",
"id": "24639840",
"metadata": {},
"source": [
"Create composite pdf sig+bkg"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "666f44ac",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:25.612237Z",
"iopub.status.busy": "2026-05-19T20:31:25.612119Z",
"iopub.status.idle": "2026-05-19T20:31:25.820357Z",
"shell.execute_reply": "2026-05-19T20:31:25.819789Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_52:5:1: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n",
"std::unique_ptr data{model.generate({x, y, z}, 20000)};\n",
"^\n"
]
}
],
"source": [
"RooRealVar fsig(\"fsig\", \"signal fraction\", 0.1, 0., 1.);\n",
"RooAddPdf model(\"model\", \"model\", RooArgList(sig, bkg), fsig);\n",
"\n",
"std::unique_ptr data{model.generate({x, y, z}, 20000)};"
]
},
{
"cell_type": "markdown",
"id": "7127bcf2",
"metadata": {},
"source": [
"Project pdf and data on x\n",
"-------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "56978435",
"metadata": {},
"source": [
"Make plain projection of data and pdf on x observable"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "ce08194f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:25.821911Z",
"iopub.status.busy": "2026-05-19T20:31:25.821795Z",
"iopub.status.idle": "2026-05-19T20:31:26.031349Z",
"shell.execute_reply": "2026-05-19T20:31:26.030767Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_53:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame);\n",
"^\n",
"input_line_52:5:29: note: candidate found by name lookup is 'data'\n",
"std::unique_ptr data{model.generate({x, y, z}, 20000)};\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:323:5: note: candidate found by name lookup is 'std::data'\n",
" data(const _Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:334:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"RooPlot *frame = x.frame(Title(\"Projection of 3D data and pdf on X\"), Bins(40));\n",
"data->plotOn(frame);\n",
"model.plotOn(frame);"
]
},
{
"cell_type": "markdown",
"id": "c0e1b262",
"metadata": {},
"source": [
"Define projected signal likelihood ratio\n",
"----------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "25d64ff8",
"metadata": {},
"source": [
"Calculate projection of signal and total likelihood on (y,z) observables\n",
"i.e. integrate signal and composite model over x"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "ffcfc255",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:26.033152Z",
"iopub.status.busy": "2026-05-19T20:31:26.033040Z",
"iopub.status.idle": "2026-05-19T20:31:26.240935Z",
"shell.execute_reply": "2026-05-19T20:31:26.240362Z"
}
},
"outputs": [],
"source": [
"RooAbsPdf *sigyz = sig.createProjection(x);\n",
"RooAbsPdf *totyz = model.createProjection(x);"
]
},
{
"cell_type": "markdown",
"id": "ef68b100",
"metadata": {},
"source": [
"Construct the log of the signal / signal+background probability"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "a7dd21fe",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:26.242800Z",
"iopub.status.busy": "2026-05-19T20:31:26.242680Z",
"iopub.status.idle": "2026-05-19T20:31:26.450636Z",
"shell.execute_reply": "2026-05-19T20:31:26.450102Z"
}
},
"outputs": [],
"source": [
"RooFormulaVar llratio_func(\"llratio\", \"log10(@0)-log10(@1)\", RooArgList(*sigyz, *totyz));"
]
},
{
"cell_type": "markdown",
"id": "d97a9e80",
"metadata": {},
"source": [
"Plot data with a LLratio cut\n",
"-------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "88a6796e",
"metadata": {},
"source": [
"Calculate the llratio value for each event in the dataset"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "63c85e57",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:26.452662Z",
"iopub.status.busy": "2026-05-19T20:31:26.452525Z",
"iopub.status.idle": "2026-05-19T20:31:26.661381Z",
"shell.execute_reply": "2026-05-19T20:31:26.660808Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_62:2:2: error: reference to 'data' is ambiguous\n",
" data->addColumn(llratio_func);\n",
" ^\n",
"input_line_52:5:29: note: candidate found by name lookup is 'data'\n",
"std::unique_ptr data{model.generate({x, y, z}, 20000)};\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:323:5: note: candidate found by name lookup is 'std::data'\n",
" data(const _Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:334:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"data->addColumn(llratio_func);"
]
},
{
"cell_type": "markdown",
"id": "e2de1bc8",
"metadata": {},
"source": [
"Extract the subset of data with large signal likelihood"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "6c53ce18",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:26.663014Z",
"iopub.status.busy": "2026-05-19T20:31:26.662902Z",
"iopub.status.idle": "2026-05-19T20:31:26.869983Z",
"shell.execute_reply": "2026-05-19T20:31:26.869364Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_63:2:38: error: reference to 'data' is ambiguous\n",
" std::unique_ptr dataSel{data->reduce(Cut(\"llratio>0.7\"))};\n",
" ^\n",
"input_line_52:5:29: note: candidate found by name lookup is 'data'\n",
"std::unique_ptr data{model.generate({x, y, z}, 20000)};\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:323:5: note: candidate found by name lookup is 'std::data'\n",
" data(const _Container& __cont) noexcept(noexcept(__cont.data()))\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:334:5: note: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr dataSel{data->reduce(Cut(\"llratio>0.7\"))};"
]
},
{
"cell_type": "markdown",
"id": "bc0230cd",
"metadata": {},
"source": [
"Make plot frame"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "08f60b8f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:26.871665Z",
"iopub.status.busy": "2026-05-19T20:31:26.871532Z",
"iopub.status.idle": "2026-05-19T20:31:27.079595Z",
"shell.execute_reply": "2026-05-19T20:31:27.078889Z"
}
},
"outputs": [],
"source": [
"RooPlot *frame2 = x.frame(Title(\"Same projection on X with LLratio(y,z)>0.7\"), Bins(40));"
]
},
{
"cell_type": "markdown",
"id": "83d2f59a",
"metadata": {},
"source": [
"Plot select data on frame"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "6050135d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:27.081404Z",
"iopub.status.busy": "2026-05-19T20:31:27.081291Z",
"iopub.status.idle": "2026-05-19T20:31:27.290318Z",
"shell.execute_reply": "2026-05-19T20:31:27.289673Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_66:2:3: error: use of undeclared identifier 'dataSel'\n",
" (dataSel->plotOn(((*(RooPlot **)0x7f5f18032000))))\n",
" ^\n",
"Error in : Error evaluating expression (dataSel->plotOn(((*(RooPlot **)0x7f5f18032000))))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"dataSel->plotOn(frame2);"
]
},
{
"cell_type": "markdown",
"id": "a9301f0d",
"metadata": {},
"source": [
"Make MC projection of pdf with same LLratio cut\n",
"---------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "33cb1595",
"metadata": {},
"source": [
"Generate large number of events for MC integration of pdf projection"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d7817c13",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:27.291898Z",
"iopub.status.busy": "2026-05-19T20:31:27.291784Z",
"iopub.status.idle": "2026-05-19T20:31:27.499800Z",
"shell.execute_reply": "2026-05-19T20:31:27.499138Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr mcprojData{model.generate({x, y, z}, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "d4e32271",
"metadata": {},
"source": [
"Calculate LL ratio for each generated event and select MC events with llratio)0.7"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "0e87e9e9",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:27.501584Z",
"iopub.status.busy": "2026-05-19T20:31:27.501470Z",
"iopub.status.idle": "2026-05-19T20:31:27.706827Z",
"shell.execute_reply": "2026-05-19T20:31:27.706443Z"
}
},
"outputs": [],
"source": [
"mcprojData->addColumn(llratio_func);\n",
"std::unique_ptr mcprojDataSel{mcprojData->reduce(Cut(\"llratio>0.7\"))};"
]
},
{
"cell_type": "markdown",
"id": "a2589e65",
"metadata": {},
"source": [
"Project model on x, integrating projected observables (y,z) with Monte Carlo technique\n",
"on set of events with the same llratio cut as was applied to data"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "ec92ac47",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:27.728037Z",
"iopub.status.busy": "2026-05-19T20:31:27.727899Z",
"iopub.status.idle": "2026-05-19T20:31:27.935903Z",
"shell.execute_reply": "2026-05-19T20:31:27.935614Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_76:2:3: error: use of undeclared identifier 'frame'\n",
" (frame->GetYaxis()->SetTitleOffset(1.3999999999999999))\n",
" ^\n",
"Error in : Error evaluating expression (frame->GetYaxis()->SetTitleOffset(1.3999999999999999))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"model.plotOn(frame2, ProjWData(*mcprojDataSel));\n",
"\n",
"TCanvas *c = new TCanvas(\"rf316_llratioplot\", \"rf316_llratioplot\", 800, 400);\n",
"c->Divide(2);\n",
"c->cd(1);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame->GetYaxis()->SetTitleOffset(1.4);\n",
"frame->Draw();\n",
"c->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame2->GetYaxis()->SetTitleOffset(1.4);\n",
"frame2->Draw();"
]
},
{
"cell_type": "markdown",
"id": "57aa61b3",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "42bb096b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:27.958168Z",
"iopub.status.busy": "2026-05-19T20:31:27.958037Z",
"iopub.status.idle": "2026-05-19T20:31:28.202725Z",
"shell.execute_reply": "2026-05-19T20:31:28.197356Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%jsroot on\n",
"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
}