{
"cells": [
{
"cell_type": "markdown",
"id": "93e90920",
"metadata": {},
"source": [
"# df020_helpers\n",
"Show usage of RDataFrame's helper tools, contained in ROOT/RDFHelpers.hxx.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Enrico Guiraud (CERN) \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:09 PM."
]
},
{
"cell_type": "markdown",
"id": "5bd41e08",
"metadata": {},
"source": [
"First of all, we create a dataframe with 3 entries and define two simple columns"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e6f3e3a9",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:53.391929Z",
"iopub.status.busy": "2026-05-19T20:09:53.391809Z",
"iopub.status.idle": "2026-05-19T20:09:54.091199Z",
"shell.execute_reply": "2026-05-19T20:09:54.090704Z"
}
},
"outputs": [],
"source": [
"const auto nEntries = 3;\n",
"ROOT::RDataFrame _df(nEntries);\n",
"auto df = _df.Define(\"one\", [] { return 1; }).Define(\"two\", [] { return 2; });"
]
},
{
"cell_type": "markdown",
"id": "b1a28bb4",
"metadata": {},
"source": [
"*** Not ***\n",
"This helper takes a callable `f` (which must return a `bool`) and produces a new callable which takes the same\n",
"arguments as `f` but returns its negated result. `Not` is useful to invert the check performed by a given Filter.\n",
"Here we define a simple lambda that checks whether a value is equal to 1, and invert it with Not:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "e6641860",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:54.094209Z",
"iopub.status.busy": "2026-05-19T20:09:54.094094Z",
"iopub.status.idle": "2026-05-19T20:09:54.307053Z",
"shell.execute_reply": "2026-05-19T20:09:54.305694Z"
}
},
"outputs": [],
"source": [
"auto isOne = [] (int a) { return a == 1; };\n",
"auto isNotOne = ROOT::RDF::Not(isOne);"
]
},
{
"cell_type": "markdown",
"id": "2fad3426",
"metadata": {},
"source": [
"Both `isOne` and `isNotOne` are callables that we can use in `Filters`:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4add284f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:54.326443Z",
"iopub.status.busy": "2026-05-19T20:09:54.326302Z",
"iopub.status.idle": "2026-05-19T20:09:55.678210Z",
"shell.execute_reply": "2026-05-19T20:09:55.677668Z"
}
},
"outputs": [],
"source": [
"auto c1 = df.Filter(isOne, {\"one\"}).Count();\n",
"auto c2 = df.Filter(isNotOne, {\"two\"}).Count();"
]
},
{
"cell_type": "markdown",
"id": "db6b5714",
"metadata": {},
"source": [
"Both counts are equal to the total number of entries, as both Filters always pass."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "68613f8c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:55.694260Z",
"iopub.status.busy": "2026-05-19T20:09:55.694107Z",
"iopub.status.idle": "2026-05-19T20:09:55.897367Z",
"shell.execute_reply": "2026-05-19T20:09:55.896840Z"
}
},
"outputs": [],
"source": [
"R__ASSERT(*c1 == nEntries);\n",
"R__ASSERT(*c2 == nEntries);"
]
},
{
"cell_type": "markdown",
"id": "4e8eabc4",
"metadata": {},
"source": [
"*** PassAsVec ***\n",
"Consider the following function, which checks if a vector consists of two elements equal to 1 and 2:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "61f00e52",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:55.907697Z",
"iopub.status.busy": "2026-05-19T20:09:55.907540Z",
"iopub.status.idle": "2026-05-19T20:09:56.124797Z",
"shell.execute_reply": "2026-05-19T20:09:56.114635Z"
}
},
"outputs": [],
"source": [
"auto checkOneTwo = [] (const std::vector &v) { return v.size() == 2 && v[0] == 1 && v[1] == 2; };"
]
},
{
"cell_type": "markdown",
"id": "4ea3adc4",
"metadata": {},
"source": [
"The following line, although it looks reasonable, would _not_ run correctly:\n",
"df.Filter(checkOneTwo, {\"one\", \"two\"});\n",
"The reason is that `Filter(..., {\"one\", \"two\"})` expects a callable that takes exactly two integers, while\n",
"`checkOneTwo` actually takes a vector of integers (i.e. it does not have the right signature).\n",
"PassAsVec helps passing down the single values \"one\", \"two\" to `checkOneTwo` as a collection: it takes a callable\n",
"`f` that expects a collection as argument and returns a new callable that takes single arguments instead, passes\n",
"them down to `f` and returns what `f` returns.\n",
"PassAsVec requires that number of arguments and their type is specified as template argument.\n",
"Here's an example usage (remember, PassAsVec(f) returns a new callable!):"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "69318e7b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:56.142485Z",
"iopub.status.busy": "2026-05-19T20:09:56.142343Z",
"iopub.status.idle": "2026-05-19T20:09:56.840918Z",
"shell.execute_reply": "2026-05-19T20:09:56.829655Z"
}
},
"outputs": [],
"source": [
"auto c3 = df.Filter(ROOT::RDF::PassAsVec<2, int>(checkOneTwo), {\"one\", \"two\"}).Count();\n",
"R__ASSERT(*c3 == nEntries);"
]
},
{
"cell_type": "markdown",
"id": "cba16b90",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "846d6237",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:09:56.852057Z",
"iopub.status.busy": "2026-05-19T20:09:56.851907Z",
"iopub.status.idle": "2026-05-19T20:09:57.055406Z",
"shell.execute_reply": "2026-05-19T20:09:57.054811Z"
}
},
"outputs": [],
"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
}