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