{
"cells": [
{
"cell_type": "markdown",
"id": "edbc0965",
"metadata": {},
"source": [
"# rf307_fullpereventerrors\n",
"Multidimensional models: full pdf with per-event errors\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": "33820a6e",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:50.953598Z",
"iopub.status.busy": "2026-05-19T20:30:50.953490Z",
"iopub.status.idle": "2026-05-19T20:30:50.967139Z",
"shell.execute_reply": "2026-05-19T20:30:50.966611Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooGaussModel.h\"\n",
"#include \"RooDecay.h\"\n",
"#include \"RooLandau.h\"\n",
"#include \"RooProdPdf.h\"\n",
"#include \"RooHistPdf.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": "3bcd632c",
"metadata": {},
"source": [
"B-physics pdf with per-event Gaussian resolution\n",
"----------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "541709f1",
"metadata": {},
"source": [
"Observables"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "805105d4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:50.968380Z",
"iopub.status.busy": "2026-05-19T20:30:50.968268Z",
"iopub.status.idle": "2026-05-19T20:30:51.180752Z",
"shell.execute_reply": "2026-05-19T20:30:51.180072Z"
}
},
"outputs": [],
"source": [
"RooRealVar dt(\"dt\", \"dt\", -10, 10);\n",
"RooRealVar dterr(\"dterr\", \"per-event error on dt\", 0.01, 10);"
]
},
{
"cell_type": "markdown",
"id": "1a9f3ba3",
"metadata": {},
"source": [
"Build a gaussian resolution model scaled by the per-event error = gauss(dt,bias,sigma*dterr)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c12d9b51",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:51.182262Z",
"iopub.status.busy": "2026-05-19T20:30:51.182149Z",
"iopub.status.idle": "2026-05-19T20:30:51.390131Z",
"shell.execute_reply": "2026-05-19T20:30:51.389478Z"
}
},
"outputs": [],
"source": [
"RooRealVar bias(\"bias\", \"bias\", 0, -10, 10);\n",
"RooRealVar sigma(\"sigma\", \"per-event error scale factor\", 1, 0.1, 10);\n",
"RooGaussModel gm(\"gm1\", \"gauss model scaled bt per-event error\", dt, bias, sigma, dterr);"
]
},
{
"cell_type": "markdown",
"id": "77a01626",
"metadata": {},
"source": [
"Construct decay(dt) (x) gauss1(dt|dterr)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "889aa929",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:51.402237Z",
"iopub.status.busy": "2026-05-19T20:30:51.402109Z",
"iopub.status.idle": "2026-05-19T20:30:51.609877Z",
"shell.execute_reply": "2026-05-19T20:30:51.609343Z"
}
},
"outputs": [],
"source": [
"RooRealVar tau(\"tau\", \"tau\", 1.548);\n",
"RooDecay decay_gm(\"decay_gm\", \"decay\", dt, tau, gm, RooDecay::DoubleSided);"
]
},
{
"cell_type": "markdown",
"id": "48a6e797",
"metadata": {},
"source": [
"Construct empirical pdf for per-event error\n",
"-----------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "07cc49e7",
"metadata": {},
"source": [
"Use landau pdf to get empirical distribution with long tail"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "4aae85c4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:51.611665Z",
"iopub.status.busy": "2026-05-19T20:30:51.611523Z",
"iopub.status.idle": "2026-05-19T20:30:51.819317Z",
"shell.execute_reply": "2026-05-19T20:30:51.818864Z"
}
},
"outputs": [],
"source": [
"RooLandau pdfDtErr(\"pdfDtErr\", \"pdfDtErr\", dterr, 1.0, 0.25);\n",
"std::unique_ptr expDataDterr{pdfDtErr.generate(dterr, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "23c45417",
"metadata": {},
"source": [
"Construct a histogram pdf to describe the shape of the dtErr distribution"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "e54e90b2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:51.821150Z",
"iopub.status.busy": "2026-05-19T20:30:51.821039Z",
"iopub.status.idle": "2026-05-19T20:30:52.028708Z",
"shell.execute_reply": "2026-05-19T20:30:52.028226Z"
}
},
"outputs": [],
"source": [
"std::unique_ptr expHistDterr{expDataDterr->binnedClone()};\n",
"RooHistPdf pdfErr(\"pdfErr\", \"pdfErr\", dterr, *expHistDterr);"
]
},
{
"cell_type": "markdown",
"id": "956ec076",
"metadata": {},
"source": [
"Construct conditional product decay_dm(dt|dterr)*pdf(dter\n",
"r )\n",
"----------------------------------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "2169ff09",
"metadata": {},
"source": [
"Construct production of conditional decay_dm(dt|dterr) with empirical pdfErr(dterr)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "4ad12c83",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:52.030525Z",
"iopub.status.busy": "2026-05-19T20:30:52.030414Z",
"iopub.status.idle": "2026-05-19T20:30:52.238045Z",
"shell.execute_reply": "2026-05-19T20:30:52.237537Z"
}
},
"outputs": [],
"source": [
"RooProdPdf model(\"model\", \"model\", pdfErr, Conditional(decay_gm, dt));"
]
},
{
"cell_type": "markdown",
"id": "d33edc7c",
"metadata": {},
"source": [
"(Alternatively you could also use the landau shape pdfDtErr)\n",
"RooProdPdf model(\"model\",\"model\",pdfDtErr,Conditional(decay_gm,dt)) ;"
]
},
{
"cell_type": "markdown",
"id": "8fb2602c",
"metadata": {},
"source": [
"Sample, fit and plot product model\n",
"------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "4f3dab29",
"metadata": {},
"source": [
"Specify external dataset with dterr values to use model_dm as conditional pdf"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "46f5be9b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:52.239920Z",
"iopub.status.busy": "2026-05-19T20:30:52.239801Z",
"iopub.status.idle": "2026-05-19T20:30:52.447706Z",
"shell.execute_reply": "2026-05-19T20:30:52.447232Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_61: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({dt, dterr}, 10000)};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{model.generate({dt, dterr}, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "d0cf6b17",
"metadata": {},
"source": [
"Fit conditional decay_dm(dt|dterr)\n",
"---------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "f13148fd",
"metadata": {},
"source": [
"Specify dterr as conditional observable"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "07f357e7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:52.448925Z",
"iopub.status.busy": "2026-05-19T20:30:52.448805Z",
"iopub.status.idle": "2026-05-19T20:30:52.657251Z",
"shell.execute_reply": "2026-05-19T20:30:52.656843Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_65:2:15: error: reference to 'data' is ambiguous\n",
" model.fitTo(*data, PrintLevel(-1));\n",
" ^\n",
"input_line_61:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({dt, dterr}, 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": [
"model.fitTo(*data, PrintLevel(-1));"
]
},
{
"cell_type": "markdown",
"id": "4142227a",
"metadata": {},
"source": [
"Plot conditional decay_dm(dt|dterr)\n",
"---------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "80d62ad3",
"metadata": {},
"source": [
"Make two-dimensional plot of conditional pdf in (dt,dterr)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "fc522087",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:52.658712Z",
"iopub.status.busy": "2026-05-19T20:30:52.658582Z",
"iopub.status.idle": "2026-05-19T20:30:52.866219Z",
"shell.execute_reply": "2026-05-19T20:30:52.865720Z"
}
},
"outputs": [],
"source": [
"TH1 *hh_model = model.createHistogram(\"hh_model\", dt, Binning(50), YVar(dterr, Binning(50)));\n",
"hh_model->SetLineColor(kBlue);"
]
},
{
"cell_type": "markdown",
"id": "685ef7a8",
"metadata": {},
"source": [
"Make projection of data an dt"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "f70ea206",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:52.867803Z",
"iopub.status.busy": "2026-05-19T20:30:52.867675Z",
"iopub.status.idle": "2026-05-19T20:30:53.076039Z",
"shell.execute_reply": "2026-05-19T20:30:53.075655Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_67:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame);\n",
"^\n",
"input_line_61:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model.generate({dt, dterr}, 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 *frame = dt.frame(Title(\"Projection of model(dt|dterr) on dt\"));\n",
"data->plotOn(frame);\n",
"model.plotOn(frame);"
]
},
{
"cell_type": "markdown",
"id": "801cf671",
"metadata": {},
"source": [
"Draw all frames on canvas"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "acb38e40",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:53.077454Z",
"iopub.status.busy": "2026-05-19T20:30:53.077344Z",
"iopub.status.idle": "2026-05-19T20:30:53.285294Z",
"shell.execute_reply": "2026-05-19T20:30:53.284808Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_69:2:3: error: use of undeclared identifier 'frame'\n",
" (frame->GetYaxis()->SetTitleOffset(1.6000000000000001))\n",
" ^\n",
"Error in : Error evaluating expression (frame->GetYaxis()->SetTitleOffset(1.6000000000000001))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"TCanvas *c = new TCanvas(\"rf307_fullpereventerrors\", \"rf307_fullperventerrors\", 800, 400);\n",
"c->Divide(2);\n",
"c->cd(1);\n",
"gPad->SetLeftMargin(0.20);\n",
"hh_model->GetZaxis()->SetTitleOffset(2.5);\n",
"hh_model->Draw(\"surf\");\n",
"c->cd(2);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame->GetYaxis()->SetTitleOffset(1.6);\n",
"frame->Draw();"
]
},
{
"cell_type": "markdown",
"id": "544e8690",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "403a64fa",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:30:53.286684Z",
"iopub.status.busy": "2026-05-19T20:30:53.286556Z",
"iopub.status.idle": "2026-05-19T20:30:53.494050Z",
"shell.execute_reply": "2026-05-19T20:30:53.493535Z"
}
},
"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
}