{
"cells": [
{
"cell_type": "markdown",
"id": "dba839a0",
"metadata": {},
"source": [
"# vo003_LogicalOperations\n",
"In this tutorial we learn how the RVec class can be used to\n",
"express logical operations.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Danilo Piparo \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:27 PM."
]
},
{
"cell_type": "markdown",
"id": "72241520",
"metadata": {},
"source": [
"Logical operations on RVec instances are made to be very easy to use."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "39518f64",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:02.341977Z",
"iopub.status.busy": "2026-05-19T20:28:02.341866Z",
"iopub.status.idle": "2026-05-19T20:28:02.686888Z",
"shell.execute_reply": "2026-05-19T20:28:02.686141Z"
}
},
"outputs": [],
"source": [
"ROOT::RVecD v1{1., 2., 3.};\n",
"ROOT::RVecD v2{3., 2., 1.};"
]
},
{
"cell_type": "markdown",
"id": "718d6cb5",
"metadata": {},
"source": [
"Let's start with operations which act element by element. In this case\n",
"we expect a RVec which holds {1. > 3., 2. > 2., 3. > 1.}, i.e. {1, 0, 0}:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "51364301",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:02.689234Z",
"iopub.status.busy": "2026-05-19T20:28:02.689062Z",
"iopub.status.idle": "2026-05-19T20:28:02.896852Z",
"shell.execute_reply": "2026-05-19T20:28:02.896105Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{ 1, 2, 3 } > { 3, 2, 1 } = { 0, 0, 1 }\n"
]
}
],
"source": [
"auto v1_gr_v2 = v1 > v2;\n",
"std::cout << v1 << \" > \" << v2 << \" = \" << v1_gr_v2 << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "4abf8195",
"metadata": {},
"source": [
"Other logical operations are supported, of course:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5c582325",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:02.898311Z",
"iopub.status.busy": "2026-05-19T20:28:02.898193Z",
"iopub.status.idle": "2026-05-19T20:28:03.105693Z",
"shell.execute_reply": "2026-05-19T20:28:03.104971Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{ 1, 2, 3 } != { 3, 2, 1 } = { 1, 0, 1 }\n"
]
}
],
"source": [
"auto v1_noteq_v2 = v1 != v2;\n",
"std::cout << v1 << \" != \" << v2 << \" = \" << v1_noteq_v2 << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "64e5ebb3",
"metadata": {},
"source": [
"All returns true if all of the elements equate to true, return false otherwise.\n",
"Any returns true if any of the elements equates to true, return false otherwise."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "31b8d9e7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:03.107154Z",
"iopub.status.busy": "2026-05-19T20:28:03.107034Z",
"iopub.status.idle": "2026-05-19T20:28:03.315467Z",
"shell.execute_reply": "2026-05-19T20:28:03.314873Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_56:2:8: error: expected unqualified-id\n",
" (std::((*(ostream*)0x7fdc2f23a480)) << \"All( \" << ((*(ROOT::RVecD*)0x7fdc30dc3008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7fdc30dc3058)) << \" ) = \" << All(((*(RVec*)0x7fdbf438e040))) << std::endl)\n",
" ^\n",
"input_line_56:2:159: error: use of undeclared identifier 'RVec'\n",
" (std::((*(ostream*)0x7fdc2f23a480)) << \"All( \" << ((*(ROOT::RVecD*)0x7fdc30dc3008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7fdc30dc3058)) << \" ) = \" << All(((*(RVec*)0x7fdbf438e040))) << std::endl)\n",
" ^\n",
"input_line_56:2:169: error: expected expression\n",
" (std::((*(ostream*)0x7fdc2f23a480)) << \"All( \" << ((*(ROOT::RVecD*)0x7fdc30dc3008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7fdc30dc3058)) << \" ) = \" << All(((*(RVec*)0x7fdbf438e040))) << std::endl)\n",
" ^\n",
"Error in : Error evaluating expression (std::((*(ostream*)0x7fdc2f23a480)) << \"All( \" << ((*(ROOT::RVecD*)0x7fdc30dc3008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7fdc30dc3058)) << \" ) = \" << All(((*(RVec*)0x7fdbf438e040))) << std::endl)\n",
"Execution of your code was aborted.\n"
]
}
],
"source": [
"auto all_true = v1 > .5 * v2;\n",
"std::cout << std::boolalpha;\n",
"std::cout << \"All( \" << v1 << \" > .5 * \" << v2 << \" ) = \" << All(all_true) << std::endl;\n",
"std::cout << \"Any( \" << v1 << \" > \" << v2 << \" ) = \" << Any(v1_noteq_v2) << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "51efc6b1",
"metadata": {},
"source": [
"Selections on the RVec contents can be applied with the \"square brackets\" operator,\n",
"which is not only a way to access the content of the RVec.\n",
"This operation can change the size of the RVec."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "c672f882",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:03.317171Z",
"iopub.status.busy": "2026-05-19T20:28:03.317052Z",
"iopub.status.idle": "2026-05-19T20:28:03.524550Z",
"shell.execute_reply": "2026-05-19T20:28:03.523832Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"v = { 1, 2, 3, 4, 5 }. v[ v > 3. ] = { 4, 5 }\n"
]
}
],
"source": [
"ROOT::RVecD v{1., 2., 3., 4., 5.};\n",
"auto v_filtered = v[v > 3.];\n",
"std::cout << \"v = \" << v << \". v[ v > 3. ] = \" << v_filtered << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "5d1bf51e",
"metadata": {},
"source": [
"This filtering operation can be particularly useful when cleaning collections of\n",
"objects coming from HEP events. For example:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "1a62d820",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:03.526022Z",
"iopub.status.busy": "2026-05-19T20:28:03.525901Z",
"iopub.status.idle": "2026-05-19T20:28:03.754798Z",
"shell.execute_reply": "2026-05-19T20:28:03.738378Z"
}
},
"outputs": [],
"source": [
"ROOT::RVecD mu_pt{15., 12., 10.6, 2.3, 4., 3.};\n",
"ROOT::RVecD mu_eta{1.2, -0.2, 4.2, -5.3, 0.4, -2.};"
]
},
{
"cell_type": "markdown",
"id": "2943ae4d",
"metadata": {},
"source": [
"Suppose the pts of the muons with a pt greater than 10 and eta smaller than 2.1 are needed:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "70c25af4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:03.758528Z",
"iopub.status.busy": "2026-05-19T20:28:03.758384Z",
"iopub.status.idle": "2026-05-19T20:28:03.965895Z",
"shell.execute_reply": "2026-05-19T20:28:03.965198Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"mu_pt = { 15, 12, 10.6, 2.3, 4, 3 } mu_pt[ mu_pt > 10 && abs(mu_eta) < 2.1] = { 15, 12 }\n"
]
}
],
"source": [
"auto good_mu_pt = mu_pt[mu_pt > 10 && abs(mu_eta) < 2.1];\n",
"std::cout << \"mu_pt = \" << mu_pt << \" mu_pt[ mu_pt > 10 && abs(mu_eta) < 2.1] = \" << good_mu_pt << std::endl;"
]
},
{
"cell_type": "markdown",
"id": "5a9b5efe",
"metadata": {},
"source": [
"Advanced logical operations with masking can be performed with the Where helper."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "99b16a2a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:28:03.967300Z",
"iopub.status.busy": "2026-05-19T20:28:03.967183Z",
"iopub.status.idle": "2026-05-19T20:28:04.174564Z",
"shell.execute_reply": "2026-05-19T20:28:04.173957Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_60:2:22: error: cannot deduce 'auto' from unknown expression\n",
" auto masked_mu_pt = Where(abs(mu_eta) < 2., mu_pt, -999.);\n",
" ^\n"
]
}
],
"source": [
"auto masked_mu_pt = Where(abs(mu_eta) < 2., mu_pt, -999.);\n",
"std::cout << \"mu_pt if abs(mu_eta) < 2 else -999 = \" << masked_mu_pt << std::endl;"
]
}
],
"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
}