{
"cells": [
{
"cell_type": "markdown",
"id": "e33b02a3",
"metadata": {},
"source": [
"# rf104_classfactory\n",
"Basic functionality: The class factory for functions and pdfs\n",
"\n",
" NOTE: This demo uses code that is generated by the macro,\n",
" therefore it cannot be compiled in one step by ACliC.\n",
" To run this macro compiled with ACliC do\n",
"\n",
"``` cpp\n",
" root>.x rf104_classfactory.C // run interpreted to generate code\n",
" root>.L MyPdfV3.cxx+ // Compile and load created class\n",
" root>.x rf104_classfactory.C+ // run compiled code\n",
"```\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": "976476b8",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:57.537219Z",
"iopub.status.busy": "2026-05-19T20:28:57.537110Z",
"iopub.status.idle": "2026-05-19T20:28:57.549617Z",
"shell.execute_reply": "2026-05-19T20:28:57.549047Z"
}
},
"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 \"RooClassFactory.h\"\n",
"#include \"TROOT.h\"\n",
"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "bb3a247f",
"metadata": {},
"source": [
"Write class skeleton code\n",
"--------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "054eabd3",
"metadata": {},
"source": [
"Write skeleton pdf class with variable x,a,b\n",
"To use this class,\n",
"- Edit the file MyPdfV1.cxx and implement the evaluate() method in terms of x,a and b\n",
"- Compile and link class with '.x MyPdfV1.cxx+'"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7c9398fa",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:57.550860Z",
"iopub.status.busy": "2026-05-19T20:28:57.550749Z",
"iopub.status.idle": "2026-05-19T20:28:57.867261Z",
"shell.execute_reply": "2026-05-19T20:28:57.866570Z"
}
},
"outputs": [],
"source": [
"RooClassFactory::makePdf(\"MyPdfV1\", \"x,A,B\");"
]
},
{
"cell_type": "markdown",
"id": "79d11b14",
"metadata": {},
"source": [
"With added initial value expression\n",
"---------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "4ff1b5c9",
"metadata": {},
"source": [
"Write skeleton pdf class with variable x,a,b and given formula expression\n",
"To use this class,\n",
"- Compile and link class with '.x MyPdfV2.cxx+'"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "fee8d96d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:57.868959Z",
"iopub.status.busy": "2026-05-19T20:28:57.868829Z",
"iopub.status.idle": "2026-05-19T20:28:58.074019Z",
"shell.execute_reply": "2026-05-19T20:28:58.073262Z"
}
},
"outputs": [],
"source": [
"RooClassFactory::makePdf(\"MyPdfV2\", \"x,A,B\", \"\", \"A*fabs(x)+pow(x-B,2)\");"
]
},
{
"cell_type": "markdown",
"id": "fd3d5a16",
"metadata": {},
"source": [
"With added analytical integral expression\n",
"---------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "0ad1165c",
"metadata": {},
"source": [
"Write skeleton pdf class with variable x,a,b, given formula expression _and_\n",
"given expression for analytical integral over x\n",
"To use this class,\n",
"- Compile and link class with '.x MyPdfV3.cxx+'"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e2300ccc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:58.075470Z",
"iopub.status.busy": "2026-05-19T20:28:58.075349Z",
"iopub.status.idle": "2026-05-19T20:28:58.280274Z",
"shell.execute_reply": "2026-05-19T20:28:58.279649Z"
}
},
"outputs": [],
"source": [
"RooClassFactory::makePdf(\"MyPdfV3\", \"x,A,B\", \"\", \"A*fabs(x)+pow(x-B,2)\", true, false,\n",
" \"x:(A/2)*(pow(x.max(rangeName),2)+pow(x.min(rangeName),2))+(1./\"\n",
" \"3)*(pow(x.max(rangeName)-B,3)-pow(x.min(rangeName)-B,3))\");"
]
},
{
"cell_type": "markdown",
"id": "18bac68f",
"metadata": {},
"source": [
"Use instance of created class\n",
"---------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "4f641b3f",
"metadata": {},
"source": [
"Compile MyPdfV3 class"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d64c041f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:58.282191Z",
"iopub.status.busy": "2026-05-19T20:28:58.282054Z",
"iopub.status.idle": "2026-05-19T20:29:03.753669Z",
"shell.execute_reply": "2026-05-19T20:29:03.753246Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(MyPdfV3) An instance of MyPdfV3.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Info in : creating shared library /github/home/master/notebooks/./MyPdfV3_cxx.so\n"
]
}
],
"source": [
"gROOT->ProcessLineSync(\".x MyPdfV3.cxx+\");"
]
},
{
"cell_type": "markdown",
"id": "bcc5ec26",
"metadata": {},
"source": [
"Create instance of MyPdfV3 class"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9e52ffb3",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:03.755139Z",
"iopub.status.busy": "2026-05-19T20:29:03.755020Z",
"iopub.status.idle": "2026-05-19T20:29:03.973079Z",
"shell.execute_reply": "2026-05-19T20:29:03.972646Z"
}
},
"outputs": [],
"source": [
"RooRealVar a(\"a\", \"a\", 1);\n",
"RooRealVar b(\"b\", \"b\", 2, -10, 10);\n",
"RooRealVar y(\"y\", \"y\", -10, 10);"
]
},
{
"cell_type": "markdown",
"id": "ca2d3790",
"metadata": {},
"source": [
"We need to hide the type to run in a ROOT macro"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "fe361818",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:03.993295Z",
"iopub.status.busy": "2026-05-19T20:29:03.993098Z",
"iopub.status.idle": "2026-05-19T20:29:04.206297Z",
"shell.execute_reply": "2026-05-19T20:29:04.205649Z"
}
},
"outputs": [],
"source": [
"RooWorkspace w(\"w\");\n",
"w.factory(\"MyPdfV3::pdf(y[-10,10], a[1], b[2,-10,10])\");\n",
"auto pdf = w.pdf(\"pdf\");"
]
},
{
"cell_type": "markdown",
"id": "5f0e841a",
"metadata": {},
"source": [
"Generate toy data from pdf and plot data and pdf on frame"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9249caa6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:04.208337Z",
"iopub.status.busy": "2026-05-19T20:29:04.208212Z",
"iopub.status.idle": "2026-05-19T20:29:04.523968Z",
"shell.execute_reply": "2026-05-19T20:29:04.523172Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(pdf_over_pdf_Int[y]) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- using generic CPU library compiled with no vectorizations\n",
"[#1] INFO:Fitting -- Creation of NLL object took 580.042 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_pdf_over_pdf_Int[y]_pdfData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_63:3: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{pdf->generate(y, 1000)};\n",
"^\n"
]
}
],
"source": [
"RooPlot *frame1 = y.frame(Title(\"Compiled class MyPdfV3\"));\n",
"std::unique_ptr data{pdf->generate(y, 1000)};\n",
"pdf->fitTo(*data, PrintLevel(-1));\n",
"data->plotOn(frame1);\n",
"pdf->plotOn(frame1);"
]
},
{
"cell_type": "markdown",
"id": "6794ae05",
"metadata": {},
"source": [
"-----------------------------------------------------------------\n",
"Compiled version of example rf103\n",
"================================================================="
]
},
{
"cell_type": "markdown",
"id": "6f9d5150",
"metadata": {},
"source": [
"Declare observable x"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "64623950",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:04.525640Z",
"iopub.status.busy": "2026-05-19T20:29:04.525425Z",
"iopub.status.idle": "2026-05-19T20:29:04.735565Z",
"shell.execute_reply": "2026-05-19T20:29:04.734994Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -20, 20);"
]
},
{
"cell_type": "markdown",
"id": "ca5db3c1",
"metadata": {},
"source": [
"The RooClassFactory::makePdfInstance() function performs code writing, compiling, linking\n",
"and object instantiation in one go and can serve as a straight replacement of RooGenericPdf"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "d67a6bbc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:04.737643Z",
"iopub.status.busy": "2026-05-19T20:29:04.737496Z",
"iopub.status.idle": "2026-05-19T20:29:09.915751Z",
"shell.execute_reply": "2026-05-19T20:29:09.915103Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Info in : creating shared library /github/home/master/notebooks/RooGenPdfPdf_cxx.so\n"
]
}
],
"source": [
"RooRealVar alpha(\"alpha\", \"alpha\", 5, 0.1, 10);\n",
"RooAbsPdf *genpdf =\n",
" RooClassFactory::makePdfInstance(\"GenPdf\", \"(1+0.1*fabs(x)+sin(sqrt(fabs(x*alpha+0.1))))\", RooArgSet(x, alpha));"
]
},
{
"cell_type": "markdown",
"id": "ffcb3a31",
"metadata": {},
"source": [
"Generate a toy dataset from the interpreted pdf"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "e475d9e9",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:09.917204Z",
"iopub.status.busy": "2026-05-19T20:29:09.917089Z",
"iopub.status.idle": "2026-05-19T20:29:10.124700Z",
"shell.execute_reply": "2026-05-19T20:29:10.124208Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(GenPdf_Int[x]) using numeric integrator RooIntegrator1D to calculate Int(x)\n",
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(GenPdf_Int[x]) using numeric integrator RooIntegrator1D to calculate Int(x)\n"
]
}
],
"source": [
"std::unique_ptr data2{genpdf->generate(x, 50000)};"
]
},
{
"cell_type": "markdown",
"id": "b0842888",
"metadata": {},
"source": [
"Fit the interpreted pdf to the generated data"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "9cb82733",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:10.126724Z",
"iopub.status.busy": "2026-05-19T20:29:10.126579Z",
"iopub.status.idle": "2026-05-19T20:29:10.334256Z",
"shell.execute_reply": "2026-05-19T20:29:10.333944Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(GenPdf_over_GenPdf_Int[x]) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- Creation of NLL object took 627.844 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_GenPdf_over_GenPdf_Int[x]_GenPdfData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n",
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(GenPdf_Int[x]) using numeric integrator RooIntegrator1D to calculate Int(x)\n"
]
}
],
"source": [
"genpdf->fitTo(*data2, PrintLevel(-1));"
]
},
{
"cell_type": "markdown",
"id": "03c2fdc9",
"metadata": {},
"source": [
"Make a plot of the data and the pdf overlaid"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "1055080f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:10.336316Z",
"iopub.status.busy": "2026-05-19T20:29:10.336196Z",
"iopub.status.idle": "2026-05-19T20:29:10.543693Z",
"shell.execute_reply": "2026-05-19T20:29:10.543092Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(GenPdf_Int[x]) using numeric integrator RooIntegrator1D to calculate Int(x)\n"
]
}
],
"source": [
"RooPlot *frame2 = x.frame(Title(\"Compiled version of pdf of rf103\"));\n",
"data2->plotOn(frame2);\n",
"genpdf->plotOn(frame2);"
]
},
{
"cell_type": "markdown",
"id": "ff663f5f",
"metadata": {},
"source": [
"Draw all frames on a canvas"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "02d39a29",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:10.545507Z",
"iopub.status.busy": "2026-05-19T20:29:10.545393Z",
"iopub.status.idle": "2026-05-19T20:29:10.752513Z",
"shell.execute_reply": "2026-05-19T20:29:10.751945Z"
}
},
"outputs": [],
"source": [
"TCanvas *c = new TCanvas(\"rf104_classfactory\", \"rf104_classfactory\", 800, 400);\n",
"c->Divide(2);\n",
"c->cd(1);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame1->GetYaxis()->SetTitleOffset(1.4);\n",
"frame1->Draw();\n",
"c->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame2->GetYaxis()->SetTitleOffset(1.4);\n",
"frame2->Draw();"
]
},
{
"cell_type": "markdown",
"id": "3f46c620",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "8feaa722",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:29:10.754673Z",
"iopub.status.busy": "2026-05-19T20:29:10.754527Z",
"iopub.status.idle": "2026-05-19T20:29:10.980724Z",
"shell.execute_reply": "2026-05-19T20:29:10.980277Z"
}
},
"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
}