{
"cells": [
{
"cell_type": "markdown",
"id": "4b9f44cd",
"metadata": {},
"source": [
"# rf301_composition\n",
"Multidimensional models: multi-dimensional pdfs through composition\n",
"e.g. substituting a pdf parameter with a function that depends on other observables\n",
"\n",
" `pdf = gauss(x,f(y),s)` with `f(y) = a0 + a1*y`\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": "fa391b03",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:28.987239Z",
"iopub.status.busy": "2026-05-19T20:30:28.987125Z",
"iopub.status.idle": "2026-05-19T20:30:29.000525Z",
"shell.execute_reply": "2026-05-19T20:30:29.000081Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooPolyVar.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"TH1.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "51093e00",
"metadata": {},
"source": [
"Setup composed model gauss(x,m(y),s)\n",
"-----------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "3dee9da8",
"metadata": {},
"source": [
"Create observables"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "86bcd0e2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:29.002122Z",
"iopub.status.busy": "2026-05-19T20:30:29.002005Z",
"iopub.status.idle": "2026-05-19T20:30:29.317900Z",
"shell.execute_reply": "2026-05-19T20:30:29.317432Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -5, 5);\n",
"RooRealVar y(\"y\", \"y\", -5, 5);"
]
},
{
"cell_type": "markdown",
"id": "12dcc6be",
"metadata": {},
"source": [
"Create function f(y) = a0 + a1*y"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8fb3b0b6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:29.338511Z",
"iopub.status.busy": "2026-05-19T20:30:29.338365Z",
"iopub.status.idle": "2026-05-19T20:30:29.546181Z",
"shell.execute_reply": "2026-05-19T20:30:29.545633Z"
}
},
"outputs": [],
"source": [
"RooRealVar a0(\"a0\", \"a0\", -0.5, -5, 5);\n",
"RooRealVar a1(\"a1\", \"a1\", -0.5, -1, 1);\n",
"RooPolyVar fy(\"fy\", \"fy\", y, RooArgSet(a0, a1));"
]
},
{
"cell_type": "markdown",
"id": "f152d32a",
"metadata": {},
"source": [
"Create gauss(x,f(y),s)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "0ef552f7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:29.548243Z",
"iopub.status.busy": "2026-05-19T20:30:29.548116Z",
"iopub.status.idle": "2026-05-19T20:30:29.756334Z",
"shell.execute_reply": "2026-05-19T20:30:29.755521Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#0] WARNING:InputArguments -- The parameter 'sigma' with range [-inf, inf] of the RooGaussian 'model' exceeds the safe range of (0, inf). Advise to limit its range.\n"
]
}
],
"source": [
"RooRealVar sigma(\"sigma\", \"width of gaussian\", 0.5);\n",
"RooGaussian model(\"model\", \"Gaussian with shifting mean\", x, fy, sigma);"
]
},
{
"cell_type": "markdown",
"id": "a069de2e",
"metadata": {},
"source": [
"Sample data, plot data and pdf on x and y\n",
"---------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "23291c01",
"metadata": {},
"source": [
"Generate 10000 events in x and y from model"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d9ced66f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:29.758094Z",
"iopub.status.busy": "2026-05-19T20:30:29.757971Z",
"iopub.status.idle": "2026-05-19T20:30:29.967737Z",
"shell.execute_reply": "2026-05-19T20:30:29.966940Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_Int[x,y]) using numeric integrator RooIntegrator1D to calculate Int(y)\n",
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_Int[x,y]) using numeric integrator RooIntegrator1D to calculate Int(y)\n",
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_Int[x,y]) using numeric integrator RooIntegrator1D to calculate Int(y)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_52: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{model.generate({x, y}, 10000)};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{model.generate({x, y}, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "dbc3dfff",
"metadata": {},
"source": [
"Plot x distribution of data and projection of model on x = Int(dy) model(x,y)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "44616d69",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:29.969586Z",
"iopub.status.busy": "2026-05-19T20:30:29.969468Z",
"iopub.status.idle": "2026-05-19T20:30:30.179057Z",
"shell.execute_reply": "2026-05-19T20:30:30.177622Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_53:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(xframe);\n",
"^\n",
"input_line_52:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, y}, 10000)};\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\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: candidate found by name lookup is 'std::data'\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: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"RooPlot *xframe = x.frame();\n",
"data->plotOn(xframe);\n",
"model.plotOn(xframe);"
]
},
{
"cell_type": "markdown",
"id": "9449b2fd",
"metadata": {},
"source": [
"Plot x distribution of data and projection of model on y = Int(dx) model(x,y)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "3b9343d1",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:30.200382Z",
"iopub.status.busy": "2026-05-19T20:30:30.200239Z",
"iopub.status.idle": "2026-05-19T20:30:30.410107Z",
"shell.execute_reply": "2026-05-19T20:30:30.409549Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_54:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(yframe);\n",
"^\n",
"input_line_52:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({x, y}, 10000)};\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:344:5: note: candidate found by name lookup is 'std::data'\n",
" data(initializer_list<_Tp> __il) noexcept\n",
" ^\n",
"/usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/bits/range_access.h:312:5: note: candidate found by name lookup is 'std::data'\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: candidate found by name lookup is 'std::data'\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: candidate found by name lookup is 'std::data'\n",
" data(_Tp (&__array)[_Nm]) noexcept\n",
" ^\n"
]
}
],
"source": [
"RooPlot *yframe = y.frame();\n",
"data->plotOn(yframe);\n",
"model.plotOn(yframe);"
]
},
{
"cell_type": "markdown",
"id": "cb3d6ad9",
"metadata": {},
"source": [
"Make two-dimensional plot in x vs y"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "4f99f537",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:30.412167Z",
"iopub.status.busy": "2026-05-19T20:30:30.412044Z",
"iopub.status.idle": "2026-05-19T20:30:30.620875Z",
"shell.execute_reply": "2026-05-19T20:30:30.620253Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:NumericIntegration -- RooRealIntegral::init(model_Int[x,y]) using numeric integrator RooIntegrator1D to calculate Int(y)\n"
]
}
],
"source": [
"TH1 *hh_model = model.createHistogram(\"hh_model\", x, Binning(50), YVar(y, Binning(50)));\n",
"hh_model->SetLineColor(kBlue);"
]
},
{
"cell_type": "markdown",
"id": "9760d32e",
"metadata": {},
"source": [
"Make canvas and draw RooPlots"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "2d82f558",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:30.622460Z",
"iopub.status.busy": "2026-05-19T20:30:30.622342Z",
"iopub.status.idle": "2026-05-19T20:30:30.828524Z",
"shell.execute_reply": "2026-05-19T20:30:30.828105Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_57:2:3: error: use of undeclared identifier 'xframe'\n",
" (xframe->GetYaxis()->SetTitleOffset(1.3999999999999999))\n",
" ^\n",
"Error in : Error evaluating expression (xframe->GetYaxis()->SetTitleOffset(1.3999999999999999))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"TCanvas *c = new TCanvas(\"rf301_composition\", \"rf301_composition\", 1200, 400);\n",
"c->Divide(3);\n",
"c->cd(1);\n",
"gPad->SetLeftMargin(0.15);\n",
"xframe->GetYaxis()->SetTitleOffset(1.4);\n",
"xframe->Draw();\n",
"c->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"yframe->GetYaxis()->SetTitleOffset(1.4);\n",
"yframe->Draw();\n",
"c->cd(3);\n",
"gPad->SetLeftMargin(0.20);\n",
"hh_model->GetZaxis()->SetTitleOffset(2.5);\n",
"hh_model->Draw(\"surf\");"
]
},
{
"cell_type": "markdown",
"id": "ca913d26",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "77a0fba2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:30.849300Z",
"iopub.status.busy": "2026-05-19T20:30:30.849153Z",
"iopub.status.idle": "2026-05-19T20:30:31.057350Z",
"shell.execute_reply": "2026-05-19T20:30:31.056314Z"
}
},
"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
}