{
"cells": [
{
"cell_type": "markdown",
"id": "83bfd53c",
"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 Monday, December 22, 2025 at 04:28 AM."
]
},
{
"cell_type": "markdown",
"id": "085f3d1c",
"metadata": {},
"source": [
"Logical operations on RVec instances are made to be very easy to use."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e135b53c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:55.800811Z",
"iopub.status.busy": "2025-12-22T03:28:55.800553Z",
"iopub.status.idle": "2025-12-22T03:28:56.133116Z",
"shell.execute_reply": "2025-12-22T03:28:56.132452Z"
}
},
"outputs": [],
"source": [
"ROOT::RVecD v1{1., 2., 3.};\n",
"ROOT::RVecD v2{3., 2., 1.};"
]
},
{
"cell_type": "markdown",
"id": "2ced9a22",
"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": "2938d6f7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:56.142780Z",
"iopub.status.busy": "2025-12-22T03:28:56.142521Z",
"iopub.status.idle": "2025-12-22T03:28:56.352861Z",
"shell.execute_reply": "2025-12-22T03:28:56.352343Z"
}
},
"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": "f1f8742a",
"metadata": {},
"source": [
"Other logical operations are supported, of course:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a133e699",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:56.358541Z",
"iopub.status.busy": "2025-12-22T03:28:56.358374Z",
"iopub.status.idle": "2025-12-22T03:28:56.570701Z",
"shell.execute_reply": "2025-12-22T03:28:56.570147Z"
}
},
"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": "e5f29588",
"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": "5f7c999d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:56.581435Z",
"iopub.status.busy": "2025-12-22T03:28:56.581158Z",
"iopub.status.idle": "2025-12-22T03:28:56.806682Z",
"shell.execute_reply": "2025-12-22T03:28:56.806109Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_60:2:8: error: expected unqualified-id\n",
" (std::((*(ostream*)0x7f9274ea0480)) << \"All( \" << ((*(ROOT::RVecD*)0x7f925034a008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7f925034a058)) << \" ) = \" << All(((*(RVec*)0x7f9238874040))) << std::endl)\n",
" ^\n",
"input_line_60:2:159: error: use of undeclared identifier 'RVec'\n",
" (std::((*(ostream*)0x7f9274ea0480)) << \"All( \" << ((*(ROOT::RVecD*)0x7f925034a008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7f925034a058)) << \" ) = \" << All(((*(RVec*)0x7f9238874040))) << std::endl)\n",
" ^\n",
"input_line_60:2:169: error: expected expression\n",
" (std::((*(ostream*)0x7f9274ea0480)) << \"All( \" << ((*(ROOT::RVecD*)0x7f925034a008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7f925034a058)) << \" ) = \" << All(((*(RVec*)0x7f9238874040))) << std::endl)\n",
" ^\n",
"Error in : Error evaluating expression (std::((*(ostream*)0x7f9274ea0480)) << \"All( \" << ((*(ROOT::RVecD*)0x7f925034a008)) << \" > .5 * \" << ((*(ROOT::RVecD*)0x7f925034a058)) << \" ) = \" << All(((*(RVec*)0x7f9238874040))) << 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": "2b9e0b61",
"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": "c7373a2b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:56.808993Z",
"iopub.status.busy": "2025-12-22T03:28:56.808815Z",
"iopub.status.idle": "2025-12-22T03:28:57.021500Z",
"shell.execute_reply": "2025-12-22T03:28:57.021107Z"
}
},
"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": "dcaf5901",
"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": "19679782",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:57.023376Z",
"iopub.status.busy": "2025-12-22T03:28:57.023244Z",
"iopub.status.idle": "2025-12-22T03:28:57.231421Z",
"shell.execute_reply": "2025-12-22T03:28:57.230841Z"
}
},
"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": "b33a50ce",
"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": "f529466d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:57.233592Z",
"iopub.status.busy": "2025-12-22T03:28:57.233429Z",
"iopub.status.idle": "2025-12-22T03:28:57.480350Z",
"shell.execute_reply": "2025-12-22T03:28:57.468116Z"
}
},
"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": "079da89d",
"metadata": {},
"source": [
"Advanced logical operations with masking can be performed with the Where helper."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "32e83f73",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2025-12-22T03:28:57.491955Z",
"iopub.status.busy": "2025-12-22T03:28:57.491736Z",
"iopub.status.idle": "2025-12-22T03:28:57.703704Z",
"shell.execute_reply": "2025-12-22T03:28:57.702909Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"input_line_64: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
}