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