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