{ "cells": [ { "cell_type": "markdown", "id": "38870db7", "metadata": {}, "source": [ "# rf211_paramconv\n", "Addition and convolution: working with a pdf with a convolution operator in terms of a parameter\n", "\n", "This tutorial requires FFT3 to be enabled.\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:30 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "f3aa4793", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:18.090314Z", "iopub.status.busy": "2026-05-19T20:30:18.090192Z", "iopub.status.idle": "2026-05-19T20:30:18.103457Z", "shell.execute_reply": "2026-05-19T20:30:18.102922Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \"RooRealVar.h\"\n", "#include \"RooDataHist.h\"\n", "#include \"RooGaussian.h\"\n", "#include \"RooGenericPdf.h\"\n", "#include \"RooFormulaVar.h\"\n", "#include \"RooFFTConvPdf.h\"\n", "#include \"RooPlot.h\"\n", "#include \"TCanvas.h\"\n", "#include \"TAxis.h\"\n", "#include \"TH2.h\"\n", "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "2e4f3c73", "metadata": {}, "source": [ "Setup component pdfs\n", "---------------------------------------" ] }, { "cell_type": "markdown", "id": "4966c049", "metadata": {}, "source": [ "Gaussian g(x ; mean,sigma)" ] }, { "cell_type": "code", "execution_count": 2, "id": "1d98c8b4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:18.105177Z", "iopub.status.busy": "2026-05-19T20:30:18.105064Z", "iopub.status.idle": "2026-05-19T20:30:18.464942Z", "shell.execute_reply": "2026-05-19T20:30:18.464251Z" } }, "outputs": [], "source": [ "RooRealVar x(\"x\", \"x\", -10, 10);\n", "RooRealVar mean(\"mean\", \"mean\", -3, 3);\n", "RooRealVar sigma(\"sigma\", \"sigma\", 0.5, 0.1, 10);\n", "RooGaussian modelx(\"gx\", \"gx\", x, mean, sigma);" ] }, { "cell_type": "markdown", "id": "c289c2bc", "metadata": {}, "source": [ "Block function in mean" ] }, { "cell_type": "code", "execution_count": 3, "id": "765eb025", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:18.467618Z", "iopub.status.busy": "2026-05-19T20:30:18.467484Z", "iopub.status.idle": "2026-05-19T20:30:18.675419Z", "shell.execute_reply": "2026-05-19T20:30:18.674701Z" } }, "outputs": [], "source": [ "RooRealVar a(\"a\", \"a\", 2, 1, 10);\n", "RooGenericPdf model_mean(\"model_mean\", \"abs(mean)= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x565197864250 with pdf gx_CONV_model_mean_CACHE_Obs[mean,x]_NORM_mean for nset (mean) with code 0\n" ] } ], "source": [ "RooAbsPdf *projModel = model.createProjection(mean);" ] }, { "cell_type": "markdown", "id": "5e108b44", "metadata": {}, "source": [ "Generate 1000 toy events" ] }, { "cell_type": "code", "execution_count": 7, "id": "16b91400", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:19.306639Z", "iopub.status.busy": "2026-05-19T20:30:19.306501Z", "iopub.status.idle": "2026-05-19T20:30:19.514853Z", "shell.execute_reply": "2026-05-19T20:30:19.514255Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:NumericIntegration -- RooRealIntegral::init(gx_Int[mean,x]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_mean_Int[mean]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#0] WARNING:Eval -- The FFT convolution 'model' will run with 50 bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x7f6de98eec30 with pdf gx_CONV_model_mean_CACHE_Obs[x,mean]_NORM_x_mean for nset (x,mean) with code 1\n" ] } ], "source": [ "std::unique_ptr d{projModel->generateBinned(x, 1000)};" ] }, { "cell_type": "markdown", "id": "73b810c3", "metadata": {}, "source": [ "Fit pdf to toy data" ] }, { "cell_type": "code", "execution_count": 8, "id": "545335db", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:19.516381Z", "iopub.status.busy": "2026-05-19T20:30:19.516270Z", "iopub.status.idle": "2026-05-19T20:30:20.812543Z", "shell.execute_reply": "2026-05-19T20:30:20.812067Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:NumericIntegration -- RooRealIntegral::init(gx_Int[mean,x]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_mean_Int[mean]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#0] WARNING:Eval -- The FFT convolution 'model' will run with 50 bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x7f6de9d596d0 with pdf gx_CONV_model_mean_CACHE_Obs[x,mean]_NORM_x_mean for nset (x,mean) with code 1\n", "[#1] INFO:Fitting -- RooAbsPdf::fitTo(model_Int[mean]_Norm[mean,x]_wrapped_pdf) 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 32.6568 ms\n", "[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_Int[mean]_Norm[mean,x]_wrapped_pdf_genData) Summation contains a RooNLLVar, using its error level\n", "[#0] WARNING:Minimization -- RooAbsMinimizerFcn::synchronize: WARNING: no initial error estimate available for a: using 0.5\n", "[#0] WARNING:Minimization -- RooAbsMinimizerFcn::synchronize: WARNING: no initial error estimate available for sigma: using 0.2\n", "[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n", "sigma=0.5, [#1] INFO:NumericIntegration -- RooRealIntegral::init(model_mean_Int[mean]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#0] WARNING:Eval -- The FFT convolution 'model' will run with 50 bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x7f6dea18a2a0 with pdf gx_CONV_model_mean_CACHE_Obs[mean] for nset () with code 2\n", "\n", "prevFCN = 2171.275755 a=2.017, \n", "prevFCN = 2171.275755 a=1.983, \n", "prevFCN = 2171.275755 a=2.172, \n", "prevFCN = 2171.861215 a=1.84, \n", "prevFCN = 2174.775121 a=2.017, \n", "prevFCN = 2171.275755 a=1.983, \n", "prevFCN = 2171.275755 a=2, sigma=0.5067, \n", "prevFCN = 2171.291807 sigma=0.4934, \n", "prevFCN = 2171.265264 sigma=0.5029, \n", "prevFCN = 2171.281998 sigma=0.4971, \n", "prevFCN = 2171.270547 sigma=0.4843, \n", "prevFCN = 2171.259881 a=2.172, \n", "prevFCN = 2171.692149 a=1.84, \n", "prevFCN = 2175.249474 a=2.017, \n", "prevFCN = 2171.259881 a=1.983, \n", "prevFCN = 2171.259881 a=2.172, \n", "prevFCN = 2171.692149 a=1.84, \n", "prevFCN = 2175.249474 a=2, sigma=0.4871, \n", "prevFCN = 2171.26042 sigma=0.4815, \n", "prevFCN = 2171.260367 a=2.003, sigma=0.4688, \n", "prevFCN = 2171.275519 a=2.001, sigma=0.479, \n", "prevFCN = 2171.261603 a=2, sigma=0.482, \n", "prevFCN = 2171.260187 a=2, sigma=0.4832, \n", "prevFCN = 2171.259943 a=2, sigma=0.4838, \n", "prevFCN = 2171.259893 a=2, sigma=0.484, \n", "prevFCN = 2171.259883 a=2, sigma=0.4841, \n", "prevFCN = 2171.259881 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.017, \n", "prevFCN = 2171.25988 a=1.983, \n", "prevFCN = 2171.25988 a=2.172, \n", "prevFCN = 2171.691427 a=1.84, \n", "prevFCN = 2175.251788 a=2.017, \n", "prevFCN = 2171.25988 a=1.983, \n", "prevFCN = 2171.25988 a=2, sigma=0.487, \n", "prevFCN = 2171.260398 sigma=0.4814, \n", "prevFCN = 2171.260398 sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.017, \n", "prevFCN = 2171.25988 a=1.983, \n", "prevFCN = 2171.25988 a=2.172, \n", "prevFCN = 2171.691427 a=1.84, \n", "prevFCN = 2175.251788 a=2.083, \n", "prevFCN = 2171.25988 a=1.92, \n", "prevFCN = 2172.379556 a=2, sigma=0.487, \n", "prevFCN = 2171.260398 sigma=0.4814, \n", "prevFCN = 2171.260398 a=2.002, sigma=0.4842, \n", "prevFCN = 2171.25988 a=1.998, \n", "prevFCN = 2171.25988 a=2, sigma=0.4848, \n", "prevFCN = 2171.259901 sigma=0.4836, \n", "prevFCN = 2171.259901 sigma=0.4843, \n", "prevFCN = 2171.259881 sigma=0.4841, \n", "prevFCN = 2171.259881 a=2.083, sigma=0.487, \n", "prevFCN = 2171.260398 a=2.041, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.02, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.01, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.005, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.003, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.001, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.001, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.083, \n", "prevFCN = 2171.25988 a=1.92, \n", "prevFCN = 2172.379556 a=2, sigma=0.4843, \n", "prevFCN = 2171.259881 sigma=0.4841, \n", "prevFCN = 2171.259881 a=2.002, sigma=0.4842, \n", "prevFCN = 2171.25988 a=1.998, \n", "prevFCN = 2171.25988 a=2, sigma=0.4842, \n", "prevFCN = 2171.25988 sigma=0.4842, \n", "prevFCN = 2171.25988 a=2.083, sigma=0.4843, \n", "prevFCN = 2171.259881 a=2, sigma=0.4842, " ] } ], "source": [ "projModel->fitTo(*d, Verbose(), PrintLevel(-1));" ] }, { "cell_type": "markdown", "id": "f72cd6e1", "metadata": {}, "source": [ "Plot data and fitted pdf" ] }, { "cell_type": "code", "execution_count": 9, "id": "82f20e8b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:20.813901Z", "iopub.status.busy": "2026-05-19T20:30:20.813789Z", "iopub.status.idle": "2026-05-19T20:30:21.022100Z", "shell.execute_reply": "2026-05-19T20:30:21.021664Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:NumericIntegration -- RooRealIntegral::init(gx_Int[mean,x]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_mean_Int[mean]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#0] WARNING:Eval -- The FFT convolution 'model' will run with 50 bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x7f6dea19d020 with pdf gx_CONV_model_mean_CACHE_Obs[x,mean]_NORM_x_mean for nset (x,mean) with code 1\n" ] } ], "source": [ "RooPlot *frame = x.frame(Bins(25));\n", "d->plotOn(frame);\n", "projModel->plotOn(frame);" ] }, { "cell_type": "markdown", "id": "b0b89323", "metadata": {}, "source": [ "Make 2d histogram of model(x;mean)" ] }, { "cell_type": "code", "execution_count": 10, "id": "42245cf5", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:21.023661Z", "iopub.status.busy": "2026-05-19T20:30:21.023535Z", "iopub.status.idle": "2026-05-19T20:30:21.231488Z", "shell.execute_reply": "2026-05-19T20:30:21.231048Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:NumericIntegration -- RooRealIntegral::init(gx_Int[mean,x]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_mean_Int[mean]) using numeric integrator RooIntegrator1D to calculate Int(mean)\n", "[#0] WARNING:Eval -- The FFT convolution 'model' will run with 50 bins. A decent accuracy for difficult convolutions is typically only reached with n >= 1000. Suggest to increase the number of bins of the observable 'mean'.\n", "[#1] INFO:Caching -- RooAbsCachedPdf::getCache(model) creating new cache 0x7f6dea621bb0 with pdf gx_CONV_model_mean_CACHE_Obs[x,mean]_NORM_x for nset (x) with code 3\n" ] } ], "source": [ "TH1 *hh = model.createHistogram(\"hh\", x, Binning(50), YVar(mean, Binning(50)), ConditionalObservables(mean));\n", "hh->SetTitle(\"histogram of model(x|mean)\");\n", "hh->SetLineColor(kBlue);" ] }, { "cell_type": "markdown", "id": "79008943", "metadata": {}, "source": [ "Draw frame on canvas" ] }, { "cell_type": "code", "execution_count": 11, "id": "f18a14f6", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:21.232836Z", "iopub.status.busy": "2026-05-19T20:30:21.232730Z", "iopub.status.idle": "2026-05-19T20:30:21.437733Z", "shell.execute_reply": "2026-05-19T20:30:21.437177Z" } }, "outputs": [], "source": [ "TCanvas *c = new TCanvas(\"rf211_paramconv\", \"rf211_paramconv\", 800, 400);\n", "c->Divide(2);\n", "c->cd(1);\n", "gPad->SetLeftMargin(0.15);\n", "frame->GetYaxis()->SetTitleOffset(1.4);\n", "frame->Draw();\n", "c->cd(2);\n", "gPad->SetLeftMargin(0.20);\n", "hh->GetZaxis()->SetTitleOffset(2.5);\n", "hh->Draw(\"surf\");" ] }, { "cell_type": "markdown", "id": "2a861f20", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 12, "id": "d17d572c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:30:21.439538Z", "iopub.status.busy": "2026-05-19T20:30:21.439427Z", "iopub.status.idle": "2026-05-19T20:30:21.646746Z", "shell.execute_reply": "2026-05-19T20:30:21.646260Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "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 }