{ "cells": [ { "cell_type": "markdown", "id": "61e8978b", "metadata": {}, "source": [ "# rf105_funcbinding\n", "Basic functionality: binding ROOT math functions as RooFit functions and pdfs\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:28 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "10ea046d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:42.212817Z", "iopub.status.busy": "2026-05-19T20:28:42.212702Z", "iopub.status.idle": "2026-05-19T20:28:42.225651Z", "shell.execute_reply": "2026-05-19T20:28:42.225221Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \"RooRealVar.h\"\n", "#include \"RooDataSet.h\"\n", "#include \"RooGaussian.h\"\n", "#include \"TCanvas.h\"\n", "#include \"TAxis.h\"\n", "#include \"RooPlot.h\"\n", "#include \"TMath.h\"\n", "#include \"TF1.h\"\n", "#include \"Math/DistFunc.h\"\n", "#include \"RooTFnBinding.h\"\n", "\n", "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "2d75ad08", "metadata": {}, "source": [ "Bind TMath::Erf C function\n", "---------------------------------------------------" ] }, { "cell_type": "markdown", "id": "3393b63a", "metadata": {}, "source": [ "Bind one-dimensional TMath::Erf function as RooAbsReal function" ] }, { "cell_type": "code", "execution_count": 2, "id": "b8136443", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:42.227185Z", "iopub.status.busy": "2026-05-19T20:28:42.227071Z", "iopub.status.idle": "2026-05-19T20:28:42.558133Z", "shell.execute_reply": "2026-05-19T20:28:42.557543Z" } }, "outputs": [], "source": [ "RooRealVar x(\"x\", \"x\", -3, 3);\n", "RooAbsReal *errorFunc = bindFunction(\"erf\", TMath::Erf, x);" ] }, { "cell_type": "markdown", "id": "d1b45151", "metadata": {}, "source": [ "Print erf definition" ] }, { "cell_type": "code", "execution_count": 3, "id": "ca2cca7b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:42.559915Z", "iopub.status.busy": "2026-05-19T20:28:42.559798Z", "iopub.status.idle": "2026-05-19T20:28:42.767292Z", "shell.execute_reply": "2026-05-19T20:28:42.766827Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RooCFunction1Binding::erf[ function=TMath::Erf x=x ] = 0\n" ] } ], "source": [ "errorFunc->Print();" ] }, { "cell_type": "markdown", "id": "25c0e65d", "metadata": {}, "source": [ "Plot erf on frame" ] }, { "cell_type": "code", "execution_count": 4, "id": "9c27054e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:42.768692Z", "iopub.status.busy": "2026-05-19T20:28:42.768556Z", "iopub.status.idle": "2026-05-19T20:28:42.975786Z", "shell.execute_reply": "2026-05-19T20:28:42.975263Z" } }, "outputs": [], "source": [ "RooPlot *frame1 = x.frame(Title(\"TMath::Erf bound as RooFit function\"));\n", "errorFunc->plotOn(frame1);" ] }, { "cell_type": "markdown", "id": "87fca677", "metadata": {}, "source": [ "Bind ROOT::Math::beta_pdf C function\n", "-----------------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "36ea3109", "metadata": {}, "source": [ "Bind pdf ROOT::Math::Beta with three variables as RooAbsPdf function" ] }, { "cell_type": "code", "execution_count": 5, "id": "c3e183d6", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:42.991041Z", "iopub.status.busy": "2026-05-19T20:28:42.990907Z", "iopub.status.idle": "2026-05-19T20:28:43.198327Z", "shell.execute_reply": "2026-05-19T20:28:43.197856Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_52:5:1: warning: 'beta' shadows a declaration with the same name in the 'std' namespace; use '::beta' to reference this declaration\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);\n", "^\n" ] } ], "source": [ "RooRealVar x2(\"x2\", \"x2\", 0, 0.999);\n", "RooRealVar a(\"a\", \"a\", 5, 0, 10);\n", "RooRealVar b(\"b\", \"b\", 2, 0, 10);\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);" ] }, { "cell_type": "markdown", "id": "71ae97db", "metadata": {}, "source": [ "Perf beta definition" ] }, { "cell_type": "code", "execution_count": 6, "id": "541cbf9d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:43.199993Z", "iopub.status.busy": "2026-05-19T20:28:43.199882Z", "iopub.status.idle": "2026-05-19T20:28:43.407851Z", "shell.execute_reply": "2026-05-19T20:28:43.407295Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_53:2:2: error: reference to 'beta' is ambiguous\n", " beta->Print();\n", " ^\n", "input_line_52:5:12: note: candidate found by name lookup is 'beta'\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/specfun.h:341:5: note: candidate found by name lookup is 'std::beta'\n", " beta(_Tpa __a, _Tpb __b)\n", " ^\n" ] } ], "source": [ "beta->Print();" ] }, { "cell_type": "markdown", "id": "03eab713", "metadata": {}, "source": [ "Generate some events and fit" ] }, { "cell_type": "code", "execution_count": 7, "id": "22fbbf50", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:43.409532Z", "iopub.status.busy": "2026-05-19T20:28:43.409416Z", "iopub.status.idle": "2026-05-19T20:28:43.617653Z", "shell.execute_reply": "2026-05-19T20:28:43.616940Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_54:2:35: error: reference to 'beta' is ambiguous\n", " std::unique_ptr data{beta->generate(x2, 10000)};\n", " ^\n", "input_line_52:5:12: note: candidate found by name lookup is 'beta'\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/specfun.h:341:5: note: candidate found by name lookup is 'std::beta'\n", " beta(_Tpa __a, _Tpb __b)\n", " ^\n", "input_line_54:3:1: error: reference to 'beta' is ambiguous\n", "beta->fitTo(*data, PrintLevel(-1));\n", "^\n", "input_line_52:5:12: note: candidate found by name lookup is 'beta'\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/specfun.h:341:5: note: candidate found by name lookup is 'std::beta'\n", " beta(_Tpa __a, _Tpb __b)\n", " ^\n", "input_line_54: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{beta->generate(x2, 10000)};\n", " ^\n" ] } ], "source": [ "std::unique_ptr data{beta->generate(x2, 10000)};\n", "beta->fitTo(*data, PrintLevel(-1));" ] }, { "cell_type": "markdown", "id": "47e8901e", "metadata": {}, "source": [ "Plot data and pdf on frame" ] }, { "cell_type": "code", "execution_count": 8, "id": "ddab9ec3", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:43.618976Z", "iopub.status.busy": "2026-05-19T20:28:43.618867Z", "iopub.status.idle": "2026-05-19T20:28:43.827010Z", "shell.execute_reply": "2026-05-19T20:28:43.826415Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_55:3:1: error: reference to overloaded function could not be resolved; did you mean to call it?\n", "data->plotOn(frame2);\n", "^~~~\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: possible target for call\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: possible target for call\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: possible target for call\n", " data(_Tp (&__array)[_Nm]) noexcept\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: possible target for call\n", " data(initializer_list<_Tp> __il) noexcept\n", " ^\n", "input_line_55:4:1: error: reference to 'beta' is ambiguous\n", "beta->plotOn(frame2);\n", "^\n", "input_line_52:5:12: note: candidate found by name lookup is 'beta'\n", "RooAbsPdf *beta = bindPdf(\"beta\", ROOT::Math::beta_pdf, x2, a, b);\n", " ^\n", "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/specfun.h:341:5: note: candidate found by name lookup is 'std::beta'\n", " beta(_Tpa __a, _Tpb __b)\n", " ^\n" ] } ], "source": [ "RooPlot *frame2 = x2.frame(Title(\"ROOT::Math::Beta bound as RooFit pdf\"));\n", "data->plotOn(frame2);\n", "beta->plotOn(frame2);" ] }, { "cell_type": "markdown", "id": "5b2bb366", "metadata": {}, "source": [ "Bind ROOT TF1 as RooFit function\n", "---------------------------------------------------------------" ] }, { "cell_type": "markdown", "id": "ce8bcfea", "metadata": {}, "source": [ "Create a ROOT TF1 function" ] }, { "cell_type": "code", "execution_count": 9, "id": "64e0ca71", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:43.828487Z", "iopub.status.busy": "2026-05-19T20:28:43.828373Z", "iopub.status.idle": "2026-05-19T20:28:44.035709Z", "shell.execute_reply": "2026-05-19T20:28:44.034899Z" } }, "outputs": [], "source": [ "TF1 *fa1 = new TF1(\"fa1\", \"sin(x)/x\", 0, 10);" ] }, { "cell_type": "markdown", "id": "19306642", "metadata": {}, "source": [ "Create an observable" ] }, { "cell_type": "code", "execution_count": 10, "id": "3cdd01c4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:44.037335Z", "iopub.status.busy": "2026-05-19T20:28:44.037219Z", "iopub.status.idle": "2026-05-19T20:28:44.249109Z", "shell.execute_reply": "2026-05-19T20:28:44.248529Z" } }, "outputs": [], "source": [ "RooRealVar x3(\"x3\", \"x3\", 0.01, 20);" ] }, { "cell_type": "markdown", "id": "7fd60862", "metadata": {}, "source": [ "Create binding of TF1 object to above observable" ] }, { "cell_type": "code", "execution_count": 11, "id": "9d5c14aa", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:44.251261Z", "iopub.status.busy": "2026-05-19T20:28:44.251141Z", "iopub.status.idle": "2026-05-19T20:28:44.458220Z", "shell.execute_reply": "2026-05-19T20:28:44.457642Z" } }, "outputs": [], "source": [ "RooAbsReal *rfa1 = bindFunction(fa1, x3);" ] }, { "cell_type": "markdown", "id": "388cbedb", "metadata": {}, "source": [ "Print rfa1 definition" ] }, { "cell_type": "code", "execution_count": 12, "id": "2f6442d0", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:44.460331Z", "iopub.status.busy": "2026-05-19T20:28:44.460212Z", "iopub.status.idle": "2026-05-19T20:28:44.667566Z", "shell.execute_reply": "2026-05-19T20:28:44.666983Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RooTFnBinding::fa1[ TFn={fa1=sin(x)/x} obs=(x3) params=() ] = -0.0547936\n" ] } ], "source": [ "rfa1->Print();" ] }, { "cell_type": "markdown", "id": "f1ce8bfb", "metadata": {}, "source": [ "Make plot frame in observable, plot TF1 binding function" ] }, { "cell_type": "code", "execution_count": 13, "id": "bad052cb", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:44.669260Z", "iopub.status.busy": "2026-05-19T20:28:44.669146Z", "iopub.status.idle": "2026-05-19T20:28:44.876924Z", "shell.execute_reply": "2026-05-19T20:28:44.876350Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "input_line_64:2:3: error: use of undeclared identifier 'frame2'\n", " (frame2->GetYaxis()->SetTitleOffset(1.6000000000000001))\n", " ^\n", "Error in : Error evaluating expression (frame2->GetYaxis()->SetTitleOffset(1.6000000000000001))\n", "Execution of your code was aborted.\n" ] } ], "source": [ "RooPlot *frame3 = x3.frame(Title(\"TF1 bound as RooFit function\"));\n", "rfa1->plotOn(frame3);\n", "\n", "TCanvas *c = new TCanvas(\"rf105_funcbinding\", \"rf105_funcbinding\", 1200, 400);\n", "c->Divide(3);\n", "c->cd(1);\n", "gPad->SetLeftMargin(0.15);\n", "frame1->GetYaxis()->SetTitleOffset(1.6);\n", "frame1->Draw();\n", "c->cd(2);\n", "gPad->SetLeftMargin(0.15);\n", "frame2->GetYaxis()->SetTitleOffset(1.6);\n", "frame2->Draw();\n", "c->cd(3);\n", "gPad->SetLeftMargin(0.15);\n", "frame3->GetYaxis()->SetTitleOffset(1.6);\n", "frame3->Draw();" ] }, { "cell_type": "markdown", "id": "b735ad2b", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 14, "id": "2c8b48ae", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:28:44.878549Z", "iopub.status.busy": "2026-05-19T20:28:44.878440Z", "iopub.status.idle": "2026-05-19T20:28:45.105698Z", "shell.execute_reply": "2026-05-19T20:28:45.104948Z" } }, "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 }