{
"cells": [
{
"cell_type": "markdown",
"id": "da98b36a",
"metadata": {},
"source": [
"# rf510_wsnamedsets\n",
"Organization and simultaneous fits: working with named parameter sets and parameter\n",
"snapshots in workspaces\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:32 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "b3f25a80",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:32.476762Z",
"iopub.status.busy": "2026-05-19T20:32:32.476639Z",
"iopub.status.idle": "2026-05-19T20:32:32.491286Z",
"shell.execute_reply": "2026-05-19T20:32:32.490788Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooChebychev.h\"\n",
"#include \"RooAddPdf.h\"\n",
"#include \"RooWorkspace.h\"\n",
"#include \"RooPlot.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"TFile.h\"\n",
"#include \"TH1.h\"\n",
"\n",
"using namespace RooFit;\n",
"\n",
"void fillWorkspace(RooWorkspace &w);"
]
},
{
"cell_type": "markdown",
"id": "1714f882",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "98608349",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:32.493042Z",
"iopub.status.busy": "2026-05-19T20:32:32.492926Z",
"iopub.status.idle": "2026-05-19T20:32:32.555624Z",
"shell.execute_reply": "2026-05-19T20:32:32.555031Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void fillWorkspace(RooWorkspace &w)\n",
"{\n",
" // C r e a t e m o d e l\n",
" // -----------------------\n",
"\n",
" // Declare observable x\n",
" RooRealVar x(\"x\", \"x\", 0, 10);\n",
"\n",
" // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters\n",
" RooRealVar mean(\"mean\", \"mean of gaussians\", 5, 0, 10);\n",
" RooRealVar sigma1(\"sigma1\", \"width of gaussians\", 0.5);\n",
" RooRealVar sigma2(\"sigma2\", \"width of gaussians\", 1);\n",
"\n",
" RooGaussian sig1(\"sig1\", \"Signal component 1\", x, mean, sigma1);\n",
" RooGaussian sig2(\"sig2\", \"Signal component 2\", x, mean, sigma2);\n",
"\n",
" // Build Chebychev polynomial pdf\n",
" RooRealVar a0(\"a0\", \"a0\", 0.5, 0., 1.);\n",
" RooRealVar a1(\"a1\", \"a1\", 0.2, 0., 1.);\n",
" RooChebychev bkg(\"bkg\", \"Background\", x, RooArgSet(a0, a1));\n",
"\n",
" // Sum the signal components into a composite signal pdf\n",
" RooRealVar sig1frac(\"sig1frac\", \"fraction of component 1 in signal\", 0.8, 0., 1.);\n",
" RooAddPdf sig(\"sig\", \"Signal\", RooArgList(sig1, sig2), sig1frac);\n",
"\n",
" // Sum the composite signal and background\n",
" RooRealVar bkgfrac(\"bkgfrac\", \"fraction of background\", 0.5, 0., 1.);\n",
" RooAddPdf model(\"model\", \"g1+g2+a\", RooArgList(bkg, sig), bkgfrac);\n",
"\n",
" // Import model into pdf\n",
" w.import(model);\n",
"\n",
" // E n c o d e d e f i n i t i o n o f p a r a m e t e r s i n w o r k s p a c e\n",
" // ---------------------------------------------------------------------------------------\n",
"\n",
" // Define named sets \"parameters\" and \"observables\", which list which variables should be considered\n",
" // parameters and observables by the users convention\n",
" //\n",
" // Variables appearing in sets _must_ live in the workspace already, or the autoImport flag\n",
" // of defineSet must be set to import them on the fly. Named sets contain only references\n",
" // to the original variables, therefore the value of observables in named sets already\n",
" // reflect their 'current' value\n",
" std::unique_ptr params{model.getParameters(x)};\n",
" w.defineSet(\"parameters\", *params);\n",
" w.defineSet(\"observables\", x);\n",
"\n",
" // E n c o d e r e f e r e n c e v a l u e f o r p a r a m e t e r s i n w o r k s p a c e\n",
" // ---------------------------------------------------------------------------------------------------\n",
"\n",
" // Define a parameter 'snapshot' in the pdf\n",
" // Unlike a named set, a parameter snapshot stores an independent set of values for\n",
" // a given set of variables in the workspace. The values can be stored and reloaded\n",
" // into the workspace variable objects using the loadSnapshot() and saveSnapshot()\n",
" // methods. A snapshot saves the value of each variable, any errors that are stored\n",
" // with it as well as the 'Constant' flag that is used in fits to determine if a\n",
" // parameter is kept fixed or not.\n",
"\n",
" // Do a dummy fit to a (supposedly) reference dataset here and store the results\n",
" // of that fit into a snapshot\n",
" std::unique_ptr refData{model.generate(x, 10000)};\n",
" model.fitTo(*refData, PrintLevel(-1));\n",
"\n",
" // The true flag imports the values of the objects in (*params) into the workspace\n",
" // If not set, the present values of the workspace parameters objects are stored\n",
" w.saveSnapshot(\"reference_fit\", *params, true);\n",
"\n",
" // Make another fit with the signal component forced to zero\n",
" // and save those parameters too\n",
"\n",
" bkgfrac.setVal(1);\n",
" bkgfrac.setConstant(true);\n",
" bkgfrac.removeError();\n",
" model.fitTo(*refData, PrintLevel(-1));\n",
"\n",
" w.saveSnapshot(\"reference_fit_bkgonly\", *params, true);\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "81948562",
"metadata": {},
"source": [
"Create model and dataset\n",
"-----------------------------------------------"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "240bd80a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:32.557588Z",
"iopub.status.busy": "2026-05-19T20:32:32.557462Z",
"iopub.status.idle": "2026-05-19T20:32:33.071472Z",
"shell.execute_reply": "2026-05-19T20:32:33.071153Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[#0] WARNING:InputArguments -- The parameter 'sigma1' with range [-inf, inf] of the RooGaussian 'sig1' exceeds the safe range of (0, inf). Advise to limit its range.\n",
"[#0] WARNING:InputArguments -- The parameter 'sigma2' with range [-inf, inf] of the RooGaussian 'sig2' exceeds the safe range of (0, inf). Advise to limit its range.\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::model\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooChebychev::bkg\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::x\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::a0\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::a1\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::bkgfrac\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooAddPdf::sig\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooGaussian::sig1\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::mean\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::sigma1\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::sig1frac\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooGaussian::sig2\n",
"[#1] INFO:ObjectHandling -- RooWorkspace::import(w) importing RooRealVar::sigma2\n",
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(model) 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 934.644 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_modelData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n",
"[#1] INFO:Fitting -- RooAbsPdf::fitTo(model) fixing normalization set for coefficient determination to observables in data\n",
"[#1] INFO:Fitting -- Creation of NLL object took 181.441 μs\n",
"[#1] INFO:Fitting -- RooAddition::defaultErrorLevel(nll_model_modelData) Summation contains a RooNLLVar, using its error level\n",
"[#1] INFO:Minimization -- [fitFCN] No discrete parameters, performing continuous minimization only\n",
"[#0] ERROR:Minimization -- RooMinimizer::calculateHessErrors() Error when calculating Hessian\n"
]
}
],
"source": [
"RooWorkspace *w = new RooWorkspace(\"w\");\n",
"fillWorkspace(*w);"
]
},
{
"cell_type": "markdown",
"id": "53f444f6",
"metadata": {},
"source": [
"Exploit convention encoded in named set \"parameters\" and \"observables\"\n",
"to use workspace contents w/o need for introspected"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "63193497",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:33.080632Z",
"iopub.status.busy": "2026-05-19T20:32:33.080486Z",
"iopub.status.idle": "2026-05-19T20:32:33.285879Z",
"shell.execute_reply": "2026-05-19T20:32:33.285210Z"
}
},
"outputs": [],
"source": [
"RooAbsPdf *model = w->pdf(\"model\");"
]
},
{
"cell_type": "markdown",
"id": "aaf2c837",
"metadata": {},
"source": [
"Generate data from pdf in given observables"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "f48e5dff",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:33.288025Z",
"iopub.status.busy": "2026-05-19T20:32:33.287903Z",
"iopub.status.idle": "2026-05-19T20:32:33.496454Z",
"shell.execute_reply": "2026-05-19T20:32:33.495842Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_71: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(*w->set(\"observables\"), 1000)};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{model->generate(*w->set(\"observables\"), 1000)};"
]
},
{
"cell_type": "markdown",
"id": "738a3125",
"metadata": {},
"source": [
"Fit model to data"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "3946b05b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:33.497912Z",
"iopub.status.busy": "2026-05-19T20:32:33.497786Z",
"iopub.status.idle": "2026-05-19T20:32:33.706840Z",
"shell.execute_reply": "2026-05-19T20:32:33.706459Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_72:2:16: error: reference to 'data' is ambiguous\n",
" model->fitTo(*data, PrintLevel(-1));\n",
" ^\n",
"input_line_71:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model->generate(*w->set(\"observables\"), 1000)};\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": "5ee413f0",
"metadata": {},
"source": [
"Plot fitted model and data on frame of first (only) observable"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "821f6c60",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:33.708870Z",
"iopub.status.busy": "2026-05-19T20:32:33.708751Z",
"iopub.status.idle": "2026-05-19T20:32:33.917833Z",
"shell.execute_reply": "2026-05-19T20:32:33.917348Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_73:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(frame);\n",
"^\n",
"input_line_71:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{model->generate(*w->set(\"observables\"), 1000)};\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 = ((RooRealVar *)w->set(\"observables\")->first())->frame();\n",
"data->plotOn(frame);\n",
"model->plotOn(frame);"
]
},
{
"cell_type": "markdown",
"id": "60df2e03",
"metadata": {},
"source": [
"Overlay plot with model with reference parameters as stored in snapshots"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "b6d74037",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:33.919454Z",
"iopub.status.busy": "2026-05-19T20:32:33.919330Z",
"iopub.status.idle": "2026-05-19T20:32:34.128327Z",
"shell.execute_reply": "2026-05-19T20:32:34.127837Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_74:3:32: error: cannot take the address of an rvalue of type 'EColor'\n",
"model->plotOn(frame, LineColor(kRed));\n",
" ^~~~\n",
"Error while creating dynamic expression for:\n",
" model->plotOn(frame, LineColor(kRed))\n",
"input_line_74:5:32: error: cannot take the address of an rvalue of type 'EColor'\n",
"model->plotOn(frame, LineColor(kRed), LineStyle(kDashed));\n",
" ^~~~\n",
"Error while creating dynamic expression for:\n",
" model->plotOn(frame, LineColor(kRed), LineStyle(kDashed))\n"
]
}
],
"source": [
"w->loadSnapshot(\"reference_fit\");\n",
"model->plotOn(frame, LineColor(kRed));\n",
"w->loadSnapshot(\"reference_fit_bkgonly\");\n",
"model->plotOn(frame, LineColor(kRed), LineStyle(kDashed));"
]
},
{
"cell_type": "markdown",
"id": "49878346",
"metadata": {},
"source": [
"Draw the frame on the canvas"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "3249ccd2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:34.130009Z",
"iopub.status.busy": "2026-05-19T20:32:34.129894Z",
"iopub.status.idle": "2026-05-19T20:32:34.477011Z",
"shell.execute_reply": "2026-05-19T20:32:34.476587Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"IncrementalExecutor::executeFunction: symbol '_ZN5cling7runtime8internal9EvaluateTIvEET_PNS1_15DynamicExprInfoEPN5clang11DeclContextE' unresolved while linking [cling interface function]!\n",
"You are probably missing the definition of void cling::runtime::internal::EvaluateT(cling::runtime::internal::DynamicExprInfo*, clang::DeclContext*)\n",
"Maybe you need to load the corresponding shared library?\n"
]
}
],
"source": [
"new TCanvas(\"rf510_wsnamedsets\", \"rf503_wsnamedsets\", 600, 600);\n",
"gPad->SetLeftMargin(0.15);\n",
"frame->GetYaxis()->SetTitleOffset(1.4);\n",
"frame->Draw();"
]
},
{
"cell_type": "markdown",
"id": "306ffb9c",
"metadata": {},
"source": [
"Print workspace contents"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "c5b2108f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:34.478680Z",
"iopub.status.busy": "2026-05-19T20:32:34.478546Z",
"iopub.status.idle": "2026-05-19T20:32:34.687104Z",
"shell.execute_reply": "2026-05-19T20:32:34.686727Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"RooWorkspace(w) w contents\n",
"\n",
"variables\n",
"---------\n",
"(a0,a1,bkgfrac,mean,sig1frac,sigma1,sigma2,x)\n",
"\n",
"p.d.f.s\n",
"-------\n",
"RooChebychev::bkg[ x=x coefList=(a0,a1) ] = 0.8\n",
"RooAddPdf::model[ bkgfrac * bkg + [%] * sig ] = 0.9/1\n",
"RooAddPdf::sig[ sig1frac * sig1 + [%] * sig2 ] = 1/1\n",
"RooGaussian::sig1[ x=x mean=mean sigma=sigma1 ] = 1\n",
"RooGaussian::sig2[ x=x mean=mean sigma=sigma2 ] = 1\n",
"\n",
"parameter snapshots\n",
"-------------------\n",
"reference_fit = (a0=0.500613 +/- 0.023199,a1=0.160315 +/- 0.0373121,bkgfrac=0.504699 +/- 0.0113933,mean=5.01883 +/- 0.0101222,sigma1=0.5[C],sig1frac=0.8179 +/- 0.0374037,sigma2=1[C])\n",
"reference_fit_bkgonly = (a0=0.474264 +/- 0,a1=6.8252e-12 +/- 0,bkgfrac=1[C],mean=5.01883 +/- 0,sigma1=0.5[C],sig1frac=0.8179 +/- 0,sigma2=1[C])\n",
"\n",
"named sets\n",
"----------\n",
"observables:(x)\n",
"parameters:(a0,a1,bkgfrac,mean,sig1frac,sigma1,sigma2)\n",
"\n"
]
}
],
"source": [
"w->Print();"
]
},
{
"cell_type": "markdown",
"id": "3cb62ec4",
"metadata": {},
"source": [
"Workspace will remain in memory after macro finishes"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "079640dc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:34.688805Z",
"iopub.status.busy": "2026-05-19T20:32:34.688689Z",
"iopub.status.idle": "2026-05-19T20:32:34.896468Z",
"shell.execute_reply": "2026-05-19T20:32:34.896010Z"
}
},
"outputs": [],
"source": [
"gDirectory->Add(w);"
]
},
{
"cell_type": "markdown",
"id": "4985df86",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d6514c74",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:32:34.898788Z",
"iopub.status.busy": "2026-05-19T20:32:34.898672Z",
"iopub.status.idle": "2026-05-19T20:32:35.129810Z",
"shell.execute_reply": "2026-05-19T20:32:35.129213Z"
}
},
"outputs": [],
"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
}