{
"cells": [
{
"cell_type": "markdown",
"id": "91e1b6cb",
"metadata": {},
"source": [
"# rf405_realtocatfuncs\n",
"Data and categories: demonstration of real-->discrete mapping functions\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:31 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "be6f3a71",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:49.076998Z",
"iopub.status.busy": "2026-05-19T20:31:49.076886Z",
"iopub.status.idle": "2026-05-19T20:31:49.091070Z",
"shell.execute_reply": "2026-05-19T20:31:49.090514Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"RooRealVar.h\"\n",
"#include \"RooDataSet.h\"\n",
"#include \"RooGaussian.h\"\n",
"#include \"RooCategory.h\"\n",
"#include \"RooThresholdCategory.h\"\n",
"#include \"RooBinningCategory.h\"\n",
"#include \"Roo1DTable.h\"\n",
"#include \"RooArgusBG.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TAxis.h\"\n",
"#include \"RooPlot.h\"\n",
"using namespace RooFit;"
]
},
{
"cell_type": "markdown",
"id": "482214da",
"metadata": {},
"source": [
"Define pdf in x, sample dataset in x\n",
"------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "52b7a0fd",
"metadata": {},
"source": [
"Define a dummy PDF in x"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b16e9f84",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:49.092390Z",
"iopub.status.busy": "2026-05-19T20:31:49.092275Z",
"iopub.status.idle": "2026-05-19T20:31:49.467873Z",
"shell.execute_reply": "2026-05-19T20:31:49.467152Z"
}
},
"outputs": [],
"source": [
"RooRealVar x(\"x\", \"x\", 0, 10);\n",
"RooArgusBG a(\"a\", \"argus(x)\", x, 10.0, -1.0);"
]
},
{
"cell_type": "markdown",
"id": "8a254d13",
"metadata": {},
"source": [
"Generate a dummy dataset"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d60d0ee9",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:49.469529Z",
"iopub.status.busy": "2026-05-19T20:31:49.469412Z",
"iopub.status.idle": "2026-05-19T20:31:49.678354Z",
"shell.execute_reply": "2026-05-19T20:31:49.677588Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_50: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{a.generate(x, 10000)};\n",
" ^\n"
]
}
],
"source": [
"std::unique_ptr data{a.generate(x, 10000)};"
]
},
{
"cell_type": "markdown",
"id": "0180f97e",
"metadata": {},
"source": [
"Create a threshold real->cat function\n",
"--------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "3082c848",
"metadata": {},
"source": [
"A RooThresholdCategory is a category function that maps regions in a real-valued\n",
"input observable observables to state names. At construction time a 'default'\n",
"state name must be specified to which all values of x are mapped that are not\n",
"otherwise assigned"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "23d4dbd3",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:49.679787Z",
"iopub.status.busy": "2026-05-19T20:31:49.679668Z",
"iopub.status.idle": "2026-05-19T20:31:49.885262Z",
"shell.execute_reply": "2026-05-19T20:31:49.884528Z"
}
},
"outputs": [],
"source": [
"RooThresholdCategory xRegion(\"xRegion\", \"region of x\", x, \"Background\");"
]
},
{
"cell_type": "markdown",
"id": "d30aa3db",
"metadata": {},
"source": [
"Specify thresholds and state assignments one-by-one.\n",
"Each statement specifies that all values _below_ the given value\n",
"(and above any lower specified threshold) are mapped to the\n",
"category state with the given name\n",
"\n",
"Background | SideBand | Signal | SideBand | Background\n",
"4.23 5.23 8.23 9.23"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "13ffaae4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:49.887217Z",
"iopub.status.busy": "2026-05-19T20:31:49.887097Z",
"iopub.status.idle": "2026-05-19T20:31:50.092441Z",
"shell.execute_reply": "2026-05-19T20:31:50.091789Z"
}
},
"outputs": [],
"source": [
"xRegion.addThreshold(4.23, \"Background\");\n",
"xRegion.addThreshold(5.23, \"SideBand\");\n",
"xRegion.addThreshold(8.23, \"Signal\");\n",
"xRegion.addThreshold(9.23, \"SideBand\");"
]
},
{
"cell_type": "markdown",
"id": "3c63fb34",
"metadata": {},
"source": [
"Use threshold function to plot data regions\n",
"-------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "558d711b",
"metadata": {},
"source": [
"Add values of threshold function to dataset so that it can be used as observable"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a52a17d0",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:50.095563Z",
"iopub.status.busy": "2026-05-19T20:31:50.095379Z",
"iopub.status.idle": "2026-05-19T20:31:50.307493Z",
"shell.execute_reply": "2026-05-19T20:31:50.306810Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_53:2:2: error: reference to 'data' is ambiguous\n",
" data->addColumn(xRegion);\n",
" ^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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": [
"data->addColumn(xRegion);"
]
},
{
"cell_type": "markdown",
"id": "78bcebfd",
"metadata": {},
"source": [
"Make plot of data in x"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "55c888d6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:50.309460Z",
"iopub.status.busy": "2026-05-19T20:31:50.309293Z",
"iopub.status.idle": "2026-05-19T20:31:50.519568Z",
"shell.execute_reply": "2026-05-19T20:31:50.518876Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_54:3:1: error: reference to 'data' is ambiguous\n",
"data->plotOn(xframe);\n",
"^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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(Title(\"Demo of threshold and binning mapping functions\"));\n",
"data->plotOn(xframe);"
]
},
{
"cell_type": "markdown",
"id": "ebb25b6a",
"metadata": {},
"source": [
"Use calculated category to select sideband data"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "05e4ec59",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:50.521144Z",
"iopub.status.busy": "2026-05-19T20:31:50.521023Z",
"iopub.status.idle": "2026-05-19T20:31:50.730545Z",
"shell.execute_reply": "2026-05-19T20:31:50.729515Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_55:2:2: error: reference to 'data' is ambiguous\n",
" data->plotOn(xframe, Cut(\"xRegion==xRegion::SideBand\"), MarkerColor(kRed), LineColor(kRed));\n",
" ^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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": [
"data->plotOn(xframe, Cut(\"xRegion==xRegion::SideBand\"), MarkerColor(kRed), LineColor(kRed));"
]
},
{
"cell_type": "markdown",
"id": "b9bae135",
"metadata": {},
"source": [
"Create a binning real->cat function\n",
"----------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "76858808",
"metadata": {},
"source": [
"A RooBinningCategory is a category function that maps bins of a (named) binning definition\n",
"in a real-valued input observable observables to state names. The state names are automatically\n",
"constructed from the variable name, the binning name and the bin number. If no binning name\n",
"is specified the default binning is mapped"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "c22f8001",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:50.740131Z",
"iopub.status.busy": "2026-05-19T20:31:50.740004Z",
"iopub.status.idle": "2026-05-19T20:31:50.946180Z",
"shell.execute_reply": "2026-05-19T20:31:50.944995Z"
}
},
"outputs": [],
"source": [
"x.setBins(10, \"coarse\");\n",
"RooBinningCategory xBins(\"xBins\", \"coarse bins in x\", x, \"coarse\");"
]
},
{
"cell_type": "markdown",
"id": "995c3665",
"metadata": {},
"source": [
"Use binning function for tabulation and plotting\n",
"-----------------------------------------------------------------------------------------------"
]
},
{
"cell_type": "markdown",
"id": "7d4dbcf4",
"metadata": {},
"source": [
"Print table of xBins state multiplicity. Note that xBins does not need to be an observable in data\n",
"it can be a function of observables in data as well"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "03bb9c21",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:50.947572Z",
"iopub.status.busy": "2026-05-19T20:31:50.947454Z",
"iopub.status.idle": "2026-05-19T20:31:51.154841Z",
"shell.execute_reply": "2026-05-19T20:31:51.154024Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_57:2:24: error: reference to 'data' is ambiguous\n",
" Roo1DTable *xbtable = data->table(xBins);\n",
" ^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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": [
"Roo1DTable *xbtable = data->table(xBins);\n",
"xbtable->Print(\"v\");"
]
},
{
"cell_type": "markdown",
"id": "8d144ac5",
"metadata": {},
"source": [
"Add values of xBins function to dataset so that it can be used as observable"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "2dd27b08",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:51.156319Z",
"iopub.status.busy": "2026-05-19T20:31:51.156182Z",
"iopub.status.idle": "2026-05-19T20:31:51.365337Z",
"shell.execute_reply": "2026-05-19T20:31:51.364773Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_58:2:35: error: reference to 'data' is ambiguous\n",
" RooCategory *xb = (RooCategory *)data->addColumn(xBins);\n",
" ^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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": [
"RooCategory *xb = (RooCategory *)data->addColumn(xBins);"
]
},
{
"cell_type": "markdown",
"id": "a443b772",
"metadata": {},
"source": [
"Define range \"alt\" as including bins 1,3,5,7,9"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "72243c39",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:51.366827Z",
"iopub.status.busy": "2026-05-19T20:31:51.366714Z",
"iopub.status.idle": "2026-05-19T20:31:51.572331Z",
"shell.execute_reply": "2026-05-19T20:31:51.571919Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_60:2:3: error: use of undeclared identifier 'xb'\n",
" (xb->setRange(\"alt\", \"x_coarse_bin1,x_coarse_bin3,x_coarse_bin5,x_coarse_bin7,x_coarse_bin9\"))\n",
" ^\n",
"Error in : Error evaluating expression (xb->setRange(\"alt\", \"x_coarse_bin1,x_coarse_bin3,x_coarse_bin5,x_coarse_bin7,x_coarse_bin9\"))\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"xb->setRange(\"alt\", \"x_coarse_bin1,x_coarse_bin3,x_coarse_bin5,x_coarse_bin7,x_coarse_bin9\");"
]
},
{
"cell_type": "markdown",
"id": "9910c89e",
"metadata": {},
"source": [
"Construct subset of data matching range \"alt\" but only for the first 5000 events and plot it on the frame"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "715fedfc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:51.573865Z",
"iopub.status.busy": "2026-05-19T20:31:51.573753Z",
"iopub.status.idle": "2026-05-19T20:31:51.783050Z",
"shell.execute_reply": "2026-05-19T20:31:51.782654Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_61:2:38: error: reference to 'data' is ambiguous\n",
" std::unique_ptr dataSel{data->reduce(CutRange(\"alt\"), EventRange(0, 5000))};\n",
" ^\n",
"input_line_50:2:30: note: candidate found by name lookup is 'data'\n",
" std::unique_ptr data{a.generate(x, 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",
"input_line_61:3:17: error: use of undeclared identifier 'xframe'\n",
"dataSel->plotOn(xframe, MarkerColor(kGreen), LineColor(kGreen));\n",
" ^\n",
"input_line_61:6:1: error: use of undeclared identifier 'xframe'\n",
"xframe->SetMinimum(0.01);\n",
"^\n",
"input_line_61:8:1: error: use of undeclared identifier 'xframe'\n",
"xframe->GetYaxis()->SetTitleOffset(1.4);\n",
"^\n",
"input_line_61:9:1: error: use of undeclared identifier 'xframe'\n",
"xframe->Draw();\n",
"^\n"
]
}
],
"source": [
"std::unique_ptr dataSel{data->reduce(CutRange(\"alt\"), EventRange(0, 5000))};\n",
"dataSel->plotOn(xframe, MarkerColor(kGreen), LineColor(kGreen));\n",
"\n",
"new TCanvas(\"rf405_realtocatfuncs\", \"rf405_realtocatfuncs\", 600, 600);\n",
"xframe->SetMinimum(0.01);\n",
"gPad->SetLeftMargin(0.15);\n",
"xframe->GetYaxis()->SetTitleOffset(1.4);\n",
"xframe->Draw();"
]
},
{
"cell_type": "markdown",
"id": "4b87bf21",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "032a81df",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:31:51.784527Z",
"iopub.status.busy": "2026-05-19T20:31:51.784418Z",
"iopub.status.idle": "2026-05-19T20:31:52.013489Z",
"shell.execute_reply": "2026-05-19T20:31:52.012985Z"
}
},
"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
}