{
"cells": [
{
"cell_type": "markdown",
"id": "4ca66aca",
"metadata": {},
"source": [
"# rf303_conditional\n",
"Multidimensional models: use of tailored pdf as conditional pdfs.s\n",
"\n",
"`pdf = gauss(x,f(y),sx | y )` 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": "92762d11",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:35.525676Z",
"iopub.status.busy": "2026-05-19T20:30:35.525546Z",
"iopub.status.idle": "2026-05-19T20:30:35.539301Z",
"shell.execute_reply": "2026-05-19T20:30:35.538722Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooDataHist.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooPolyVar.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"TRandom.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"TH1.h\"\n",
"\n",
"using namespace RooFit;\n",
"\n",
"RooDataSet *makeFakeDataXY();"
]
},
{
"cell_type": "markdown",
"id": "ca5ec743",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "62ade1ec",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:35.540852Z",
"iopub.status.busy": "2026-05-19T20:30:35.540735Z",
"iopub.status.idle": "2026-05-19T20:30:35.564457Z",
"shell.execute_reply": "2026-05-19T20:30:35.563908Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"RooDataSet *makeFakeDataXY()\n",
"{\n",
" TRandom3 trnd{};\n",
"\n",
" RooRealVar x(\"x\", \"x\", -10, 10);\n",
" RooRealVar y(\"y\", \"y\", -10, 10);\n",
" RooArgSet coord(x, y);\n",
"\n",
" RooDataSet *d = new RooDataSet(\"d\", \"d\", RooArgSet(x, y));\n",
"\n",
" for (int i = 0; i < 10000; i++) {\n",
" double tmpy = trnd.Gaus(0, 10);\n",
" double tmpx = trnd.Gaus(0.5 * tmpy, 1);\n",
" if (fabs(tmpy) < 10 && fabs(tmpx) < 10) {\n",
" x.setVal(tmpx);\n",
" y.setVal(tmpy);\n",
" d->add(coord);\n",
" }\n",
" }\n",
"\n",
" return d;\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "43353c2f",
"metadata": {},
"source": [
"Setup composed model gauss(x,m(y),s)\n",
"-----------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "1beb39d2",
"metadata": {},
"source": [
"Create observables"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c784f733",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:35.566033Z",
"iopub.status.busy": "2026-05-19T20:30:35.565912Z",
"iopub.status.idle": "2026-05-19T20:30:35.774109Z",
"shell.execute_reply": "2026-05-19T20:30:35.773511Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", -10, 10);\n",
"RooRealVar y(\"y\", \"y\", -10, 10);"
]
},
{
"cell_type": "markdown",
"id": "6d647e33",
"metadata": {},
"source": [
"Create function f(y) = a0 + a1*y"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "eb2a6023",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:35.776136Z",
"iopub.status.busy": "2026-05-19T20:30:35.776013Z",
"iopub.status.idle": "2026-05-19T20:30:35.983878Z",
"shell.execute_reply": "2026-05-19T20:30:35.983247Z"
}
},
"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": "a2f1faf6",
"metadata": {},
"source": [
"Create gauss(x,f(y),s)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1e253392",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:35.985984Z",
"iopub.status.busy": "2026-05-19T20:30:35.985858Z",
"iopub.status.idle": "2026-05-19T20:30:36.193785Z",
"shell.execute_reply": "2026-05-19T20:30:36.193102Z"
}
},
"outputs": [],
"source": [
"RooRealVar sigma(\"sigma\", \"width of gaussian\", 0.5, 0.1, 2.0);\n",
"RooGaussian model(\"model\", \"Gaussian with shifting mean\", x, fy, sigma);"
]
},
{
"cell_type": "markdown",
"id": "88135db1",
"metadata": {},
"source": [
"Obtain fake external experimental dataset with values for x and y"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "b8708367",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:36.195591Z",
"iopub.status.busy": "2026-05-19T20:30:36.195471Z",
"iopub.status.idle": "2026-05-19T20:30:36.403348Z",
"shell.execute_reply": "2026-05-19T20:30:36.402681Z"
}
},
"outputs": [],
"source": [
"RooDataSet *expDataXY = makeFakeDataXY();"
]
},
{
"cell_type": "markdown",
"id": "25eac4e7",
"metadata": {},
"source": [
"Generate data from conditional p.d.f model(x|y)\n",
"---------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "4c8a32d3",
"metadata": {},
"source": [
"Make subset of experimental data with only y values"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "0daf2f0b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:36.405386Z",
"iopub.status.busy": "2026-05-19T20:30:36.405260Z",
"iopub.status.idle": "2026-05-19T20:30:36.613331Z",
"shell.execute_reply": "2026-05-19T20:30:36.612676Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr expAbsDataY{expDataXY->reduce(y)};\n",
"RooDataSet *expDataY = static_cast(expAbsDataY.get());"
]
},
{
"cell_type": "markdown",
"id": "30b42164",
"metadata": {},
"source": [
"Generate 10000 events in x obtained from _conditional_ model(x|y) with y values taken from experimental data"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "98277fe8",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:36.615383Z",
"iopub.status.busy": "2026-05-19T20:30:36.615255Z",
"iopub.status.idle": "2026-05-19T20:30:36.825069Z",
"shell.execute_reply": "2026-05-19T20:30:36.824319Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"RooDataSet::modelData[x,y] = 6850 entries\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_55: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, ProtoData(*expDataY))};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{model.generate(x, ProtoData(*expDataY))};\n",
"data->Print();"
]
},
{
"cell_type": "markdown",
"id": "1627abf8",
"metadata": {},
"source": [
"Fit conditional p.d.f model(x|y) to data\n",
"---------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "c3b48811",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:36.826817Z",
"iopub.status.busy": "2026-05-19T20:30:36.826690Z",
"iopub.status.idle": "2026-05-19T20:30:37.156271Z",
"shell.execute_reply": "2026-05-19T20:30:37.155735Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(model_over_model_Int[x]) 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 826.903 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_over_model_Int[x]_d) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n"
]
}
],
"source": [
"model.fitTo(*expDataXY, ConditionalObservables(y), PrintLevel(-1));"
]
},
{
"cell_type": "markdown",
"id": "b35facd3",
"metadata": {},
"source": [
"Project conditional p.d.f on x and y dimensions\n",
"---------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "0375fc69",
"metadata": {},
"source": [
"Plot x distribution of data and projection of model on x = 1/Ndata sum(data(y_i)) model(x;y_i)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "64385daf",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:37.158042Z",
"iopub.status.busy": "2026-05-19T20:30:37.157923Z",
"iopub.status.idle": "2026-05-19T20:30:37.366252Z",
"shell.execute_reply": "2026-05-19T20:30:37.365300Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x averages using data variables (y)\n"
]
}
],
"source": [
"RooPlot *xframe = x.frame();\n",
"expDataXY->plotOn(xframe);\n",
"model.plotOn(xframe, ProjWData(*expDataY));"
]
},
{
"cell_type": "markdown",
"id": "0be1820f",
"metadata": {},
"source": [
"Speed up (and approximate) projection by using binned clone of data for projection"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "a35f51e5",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:37.367712Z",
"iopub.status.busy": "2026-05-19T20:30:37.367574Z",
"iopub.status.idle": "2026-05-19T20:30:37.575722Z",
"shell.execute_reply": "2026-05-19T20:30:37.574917Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x averages using data variables (y)\n"
]
}
],
"source": [
"std::unique_ptr binnedDataY{expDataY->binnedClone()};\n",
"model.plotOn(xframe, ProjWData(*binnedDataY), LineColor(kCyan), LineStyle(kDotted));"
]
},
{
"cell_type": "markdown",
"id": "3ba74eac",
"metadata": {},
"source": [
"Show effect of projection with too coarse binning"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "0e3de4cd",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:37.577482Z",
"iopub.status.busy": "2026-05-19T20:30:37.577358Z",
"iopub.status.idle": "2026-05-19T20:30:37.786101Z",
"shell.execute_reply": "2026-05-19T20:30:37.785412Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x averages using data variables (y)\n"
]
}
],
"source": [
"((RooRealVar *)expDataY->get()->find(\"y\"))->setBins(5);\n",
"std::unique_ptr binnedDataY2{expDataY->binnedClone()};\n",
"model.plotOn(xframe, ProjWData(*binnedDataY2), LineColor(kRed));"
]
},
{
"cell_type": "markdown",
"id": "0e8e7d1a",
"metadata": {},
"source": [
"Make canvas and draw RooPlots"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "a6ec4dc5",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:37.788333Z",
"iopub.status.busy": "2026-05-19T20:30:37.788204Z",
"iopub.status.idle": "2026-05-19T20:30:37.996446Z",
"shell.execute_reply": "2026-05-19T20:30:37.995711Z"
}
},
"outputs": [],
"source": [
"new TCanvas(\"rf303_conditional\", \"rf303_conditional\", 600, 460);\n",
"gPad->SetLeftMargin(0.15);\n",
"xframe->GetYaxis()->SetTitleOffset(1.2);\n",
"xframe->Draw();"
]
},
{
"cell_type": "markdown",
"id": "0d49e208",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "c4eccf4c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:37.998295Z",
"iopub.status.busy": "2026-05-19T20:30:37.998167Z",
"iopub.status.idle": "2026-05-19T20:30:38.228472Z",
"shell.execute_reply": "2026-05-19T20:30:38.227858Z"
}
},
"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
}