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