{
"cells": [
{
"cell_type": "markdown",
"id": "7fe30cfa",
"metadata": {},
"source": [
"# rf701_efficiencyfit\n",
"Special pdf's: unbinned maximum likelihood fit of an efficiency eff(x) function\n",
"\n",
"to a dataset D(x,cut), where cut is a category encoding a selection, of which the\n",
"efficiency as function of x should be described by eff(x)\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:34 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "26dde609",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:16.059496Z",
"iopub.status.busy": "2026-05-19T20:34:16.059386Z",
"iopub.status.idle": "2026-05-19T20:34:16.074698Z",
"shell.execute_reply": "2026-05-19T20:34:16.074171Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooConstVar.h\"\n",
"#include \"RooFormulaVar.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"RooEfficiency.h\"\n",
"#include \"RooPolynomial.h\"\n",
"#include \"RooCategory.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"RooPlot.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "c26982a3",
"metadata": {},
"source": [
"Construct efficiency function e(x)\n",
"-------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "b8685809",
"metadata": {},
"source": [
"Declare variables x,mean,sigma with associated name, title, initial value and allowed range"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b19a3e6f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:16.075953Z",
"iopub.status.busy": "2026-05-19T20:34:16.075843Z",
"iopub.status.idle": "2026-05-19T20:34:16.391697Z",
"shell.execute_reply": "2026-05-19T20:34:16.391067Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -10, 10);"
]
},
{
"cell_type": "markdown",
"id": "73acfd12",
"metadata": {},
"source": [
"Efficiency function eff(x;a,b)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "dc26f4ec",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:16.393304Z",
"iopub.status.busy": "2026-05-19T20:34:16.393186Z",
"iopub.status.idle": "2026-05-19T20:34:16.601963Z",
"shell.execute_reply": "2026-05-19T20:34:16.601309Z"
}
},
"outputs": [],
"source": [
"RooRealVar a(\"a\", \"a\", 0.4, 0, 1);\n",
"RooRealVar b(\"b\", \"b\", 5);\n",
"RooRealVar c(\"c\", \"c\", -1, -10, 10);\n",
"RooFormulaVar effFunc(\"effFunc\", \"(1-a)+a*cos((x-c)/b)\", RooArgList(a, b, c, x));"
]
},
{
"cell_type": "markdown",
"id": "2fe6c783",
"metadata": {},
"source": [
"Construct conditional efficiency pdf E(cut|x)\n",
"------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "b530fd30",
"metadata": {},
"source": [
"Acceptance state cut (1 or 0)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "c206116a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:16.603580Z",
"iopub.status.busy": "2026-05-19T20:34:16.603463Z",
"iopub.status.idle": "2026-05-19T20:34:16.809253Z",
"shell.execute_reply": "2026-05-19T20:34:16.808648Z"
}
},
"outputs": [],
"source": [
"RooCategory cut(\"cut\", \"cutr\", { {\"accept\", 1}, {\"reject\", 0} });"
]
},
{
"cell_type": "markdown",
"id": "fea81594",
"metadata": {},
"source": [
"Construct efficiency pdf eff(cut|x)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "55169641",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:16.811166Z",
"iopub.status.busy": "2026-05-19T20:34:16.811049Z",
"iopub.status.idle": "2026-05-19T20:34:17.017020Z",
"shell.execute_reply": "2026-05-19T20:34:17.016244Z"
}
},
"outputs": [],
"source": [
"RooEfficiency effPdf(\"effPdf\", \"effPdf\", effFunc, cut, \"accept\");"
]
},
{
"cell_type": "markdown",
"id": "0fd1314b",
"metadata": {},
"source": [
"Generate data (x, cut) from a toy model\n",
"-----------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "49d6db43",
"metadata": {},
"source": [
"Construct global shape pdf shape(x) and product model(x,cut) = eff(cut|x)*shape(x)\n",
"(These are _only_ needed to generate some toy MC here to be used later)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "0399fc76",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:17.018559Z",
"iopub.status.busy": "2026-05-19T20:34:17.018441Z",
"iopub.status.idle": "2026-05-19T20:34:17.227325Z",
"shell.execute_reply": "2026-05-19T20:34:17.226697Z"
}
},
"outputs": [],
"source": [
"RooPolynomial shapePdf(\"shapePdf\", \"shapePdf\", x, RooConst(-0.095));\n",
"RooProdPdf model(\"model\", \"model\", shapePdf, Conditional(effPdf, cut));"
]
},
{
"cell_type": "markdown",
"id": "415c99ed",
"metadata": {},
"source": [
"Generate some toy data from model"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6257e57e",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:17.228944Z",
"iopub.status.busy": "2026-05-19T20:34:17.228826Z",
"iopub.status.idle": "2026-05-19T20:34:17.437950Z",
"shell.execute_reply": "2026-05-19T20:34:17.437361Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_60:2:2: 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, cut}, 10000)};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{model.generate({x, cut}, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "00d8d71d",
"metadata": {},
"source": [
"Fit conditional efficiency pdf to data\n",
"--------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "be946cda",
"metadata": {},
"source": [
"Fit conditional efficiency pdf to data"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e45d54f2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:17.439237Z",
"iopub.status.busy": "2026-05-19T20:34:17.439124Z",
"iopub.status.idle": "2026-05-19T20:34:17.648722Z",
"shell.execute_reply": "2026-05-19T20:34:17.648166Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_61:2:16: error: reference to 'data' is ambiguous\n",
" effPdf.fitTo(*data, ConditionalObservables(x), PrintLevel(-1));\n",
" ^\n",
"input_line_60:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, cut}, 10000)};\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": [
"effPdf.fitTo(*data, ConditionalObservables(x), PrintLevel(-1));"
]
},
{
"cell_type": "markdown",
"id": "d9388536",
"metadata": {},
"source": [
"Plot fitted, data efficiency\n",
"--------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "5d94d2a4",
"metadata": {},
"source": [
"Plot distribution of all events and accepted fraction of events on frame"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "3c220ac8",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:17.650082Z",
"iopub.status.busy": "2026-05-19T20:34:17.649966Z",
"iopub.status.idle": "2026-05-19T20:34:17.860215Z",
"shell.execute_reply": "2026-05-19T20:34:17.859659Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_62:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame1);\n",
"^\n",
"input_line_60:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, cut}, 10000)};\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",
"input_line_62:4:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame1, Cut(\"cut==cut::accept\"), MarkerColor(kRed), LineColor(kRed));\n",
"^\n",
"input_line_60:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, cut}, 10000)};\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 *frame1 = x.frame(Bins(20), Title(\"Data (all, accepted)\"));\n",
"data->plotOn(frame1);\n",
"data->plotOn(frame1, Cut(\"cut==cut::accept\"), MarkerColor(kRed), LineColor(kRed));"
]
},
{
"cell_type": "markdown",
"id": "1a5fb02a",
"metadata": {},
"source": [
"Plot accept/reject efficiency on data overlay fitted efficiency curve"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "b3e3c4dc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:17.861807Z",
"iopub.status.busy": "2026-05-19T20:34:17.861693Z",
"iopub.status.idle": "2026-05-19T20:34:18.071208Z",
"shell.execute_reply": "2026-05-19T20:34:18.070689Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_63:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame2, Efficiency(cut)); // needs ROOT version >= 5.21\n",
"^\n",
"input_line_60:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, cut}, 10000)};\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 *frame2 = x.frame(Bins(20), Title(\"Fitted efficiency\"));\n",
"data->plotOn(frame2, Efficiency(cut)); // needs ROOT version >= 5.21\n",
"effFunc.plotOn(frame2, LineColor(kRed));"
]
},
{
"cell_type": "markdown",
"id": "5a305959",
"metadata": {},
"source": [
"Draw all frames on a canvas"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "6abe53e4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:18.072782Z",
"iopub.status.busy": "2026-05-19T20:34:18.072657Z",
"iopub.status.idle": "2026-05-19T20:34:18.281850Z",
"shell.execute_reply": "2026-05-19T20:34:18.281129Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_65:2:3: error: use of undeclared identifier 'frame1'\n",
" (frame1->GetYaxis()->SetTitleOffset(1.6000000000000001))\n",
" ^\n",
"Error in : Error evaluating expression (frame1->GetYaxis()->SetTitleOffset(1.6000000000000001))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"TCanvas *ca = new TCanvas(\"rf701_efficiency\", \"rf701_efficiency\", 800, 400);\n",
"ca->Divide(2);\n",
"ca->cd(1);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame1->GetYaxis()->SetTitleOffset(1.6);\n",
"frame1->Draw();\n",
"ca->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame2->GetYaxis()->SetTitleOffset(1.4);\n",
"frame2->Draw();"
]
},
{
"cell_type": "markdown",
"id": "298e9273",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "e5d4c361",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:34:18.283135Z",
"iopub.status.busy": "2026-05-19T20:34:18.283021Z",
"iopub.status.idle": "2026-05-19T20:34:18.512658Z",
"shell.execute_reply": "2026-05-19T20:34:18.511899Z"
}
},
"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
}