In this tutorial we learn how the RVec class can be used to express logical operations.
Author: Danilo Piparo
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Monday, May 13, 2024 at 11:42 AM.
Logical operations on RVec instances are made to be very easy to use.
ROOT::RVecD v1{1., 2., 3.};
ROOT::RVecD v2{3., 2., 1.};
Let's start with operations which act element by element. In this case we expect a RVec which holds {1. > 3., 2. > 2., 3. > 1.}, i.e. {1, 0, 0}:
auto v1_gr_v2 = v1 > v2;
std::cout << v1 << " > " << v2 << " = " << v1_gr_v2 << std::endl;
{ 1, 2, 3 } > { 3, 2, 1 } = { 0, 0, 1 }
Other logical operations are supported, of course:
auto v1_noteq_v2 = v1 != v2;
std::cout << v1 << " != " << v2 << " = " << v1_noteq_v2 << std::endl;
{ 1, 2, 3 } != { 3, 2, 1 } = { 1, 0, 1 }
All returns true if all of the elements equate to true, return false otherwise. Any returns true if any of the elements equates to true, return false otherwise.
auto all_true = v1 > .5 * v2;
std::cout << std::boolalpha;
std::cout << "All( " << v1 << " > .5 * " << v2 << " ) = " << All(all_true) << std::endl;
std::cout << "Any( " << v1 << " > " << v2 << " ) = " << Any(v1_noteq_v2) << std::endl;
input_line_55:2:8: error: expected unqualified-id (std::((*(ostream*)0x7ff0cab44480)) << "All( " << ((*(ROOT::RVecD*)0x7ff0af8b9000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7ff0af8b9050)) << " ) = " << All(((*(RVec<int>*)0x7ff0ac1c5000))) << std::endl) ^ input_line_55:2:159: error: use of undeclared identifier 'RVec' (std::((*(ostream*)0x7ff0cab44480)) << "All( " << ((*(ROOT::RVecD*)0x7ff0af8b9000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7ff0af8b9050)) << " ) = " << All(((*(RVec<int>*)0x7ff0ac1c5000))) << std::endl) ^ input_line_55:2:169: error: expected expression (std::((*(ostream*)0x7ff0cab44480)) << "All( " << ((*(ROOT::RVecD*)0x7ff0af8b9000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7ff0af8b9050)) << " ) = " << All(((*(RVec<int>*)0x7ff0ac1c5000))) << std::endl) ^ Error in <HandleInterpreterException>: Error evaluating expression (std::((*(ostream*)0x7ff0cab44480)) << "All( " << ((*(ROOT::RVecD*)0x7ff0af8b9000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7ff0af8b9050)) << " ) = " << All(((*(RVec<int>*)0x7ff0ac1c5000))) << std::endl) Execution of your code was aborted.
Selections on the RVec contents can be applied with the "square brackets" operator, which is not only a way to access the content of the RVec. This operation can change the size of the RVec.
ROOT::RVecD v{1., 2., 3., 4., 5.};
auto v_filtered = v[v > 3.];
std::cout << "v = " << v << ". v[ v > 3. ] = " << v_filtered << std::endl;
v = { 1, 2, 3, 4, 5 }. v[ v > 3. ] = { 4, 5 }
This filtering operation can be particularly useful when cleaning collections of objects coming from HEP events. For example:
ROOT::RVecD mu_pt{15., 12., 10.6, 2.3, 4., 3.};
ROOT::RVecD mu_eta{1.2, -0.2, 4.2, -5.3, 0.4, -2.};
Suppose the pts of the muons with a pt greater than 10 and eta smaller than 2.1 are needed:
auto good_mu_pt = mu_pt[mu_pt > 10 && abs(mu_eta) < 2.1];
std::cout << "mu_pt = " << mu_pt << " mu_pt[ mu_pt > 10 && abs(mu_eta) < 2.1] = " << good_mu_pt << std::endl;
mu_pt = { 15, 12, 10.6, 2.3, 4, 3 } mu_pt[ mu_pt > 10 && abs(mu_eta) < 2.1] = { 15, 12 }
Advanced logical operations with masking can be performed with the Where helper.
auto masked_mu_pt = Where(abs(mu_eta) < 2., mu_pt, -999.);
std::cout << "mu_pt if abs(mu_eta) < 2 else -999 = " << masked_mu_pt << std::endl;
input_line_59:2:2: error: Syntax error auto masked_mu_pt = Where(abs(mu_eta) < 2., mu_pt, -999.); ^ FunctionDecl 0x7ff095632b50 <input_line_59:1:1, line:5:1> line:1:6 __cling_Un1Qu327 'void (void *)' |-ParmVarDecl 0x7ff095632a98 <col:23, col:29> col:29 vpClingValue 'void *' |-CompoundStmt 0x7ff09563b1e0 <col:43, line:5:1> | |-DeclStmt 0x7ff095638308 <line:2:2, col:59> | | `-VarDecl 0x7ff095632c68 <col:2, col:58> col:7 used masked_mu_pt 'auto' cinit | | `-ExprWithCleanups 0x7ff0956382f0 <col:22, col:58> '<dependent type>' | | `-CallExpr 0x7ff0956382b8 <col:22, col:58> '<dependent type>' | | |-DeclRefExpr 0x7ff095632ec0 <col:22> '<dependent type>' lvalue Var 0x7ff095632de8 'Where' '<dependent type>' | | |-CXXBindTemporaryExpr 0x7ff095638240 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' (CXXTemporary 0x7ff095638240) | | | `-CXXOperatorCallExpr 0x7ff095638200 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' '<' adl | | | |-ImplicitCastExpr 0x7ff0956381e8 <col:40> 'auto (*)(const RVec<double> &, const double &) -> RVec<int>' <FunctionToPointerDecay> | | | | `-DeclRefExpr 0x7ff0956381c8 <col:40> 'auto (const RVec<double> &, const double &) -> RVec<int>' lvalue Function 0x7ff0955e6300 'operator<' 'auto (const RVec<double> &, const double &) -> RVec<int>' | | | |-MaterializeTemporaryExpr 0x7ff095638180 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' lvalue | | | | `-ImplicitCastExpr 0x7ff095638168 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' <NoOp> | | | | `-CXXBindTemporaryExpr 0x7ff095633368 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' (CXXTemporary 0x7ff095633368) | | | | `-CallExpr 0x7ff095633320 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' adl | | | | |-ImplicitCastExpr 0x7ff095633308 <col:28> 'RVec<PromoteType<double> > (*)(const RVec<double> &)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7ff0956332e0 <col:28> 'RVec<PromoteType<double> > (const RVec<double> &)' lvalue Function 0x7ff0955e3550 'abs' 'RVec<PromoteType<double> > (const RVec<double> &)' (FunctionTemplate 0x7ff0955e2590 'abs') | | | | `-ImplicitCastExpr 0x7ff095633348 <col:32> 'const RVec<double>':'const ROOT::VecOps::RVec<double>' lvalue <NoOp> | | | | `-DeclRefExpr 0x7ff095632f88 <col:32> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7ff0954e4588 'mu_eta' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | | `-MaterializeTemporaryExpr 0x7ff0956381b0 <col:42> 'const double' lvalue | | | `-ImplicitCastExpr 0x7ff095638198 <col:42> 'const double' <NoOp> | | | `-FloatingLiteral 0x7ff095633388 <col:42> 'double' 2.000000e+00 | | |-DeclRefExpr 0x7ff095638260 <col:46> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7ff0954e4200 'mu_pt' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | `-UnaryOperator 0x7ff0956382a0 <col:53, col:54> 'double' prefix '-' | | `-FloatingLiteral 0x7ff095638280 <col:54> 'double' 9.990000e+02 | |-CXXOperatorCallExpr 0x7ff09563b1a0 <line:3:1, col:78> '<dependent type>' '<<' | | |-UnresolvedLookupExpr 0x7ff09563ae60 <col:70> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x4fa9158 0x4f51ab8 0x4f51418 0x4fa6718 0x4fa69a0 0x4fa6c30 0x4fa6ec0 0x4fa7150 0x4fa73e0 0x4fa7670 0x4fa7900 0x4fa7b90 0x4fa7e20 0x4fa80b0 0x4fa8340 0x4fa85d0 0x4fa8860 0x4fa8b28 0x6495458 0x6497ac8 0x649ed68 0x649fc58 0x64ad0d8 0x64ad3f8 0x64ba3e8 0x64bb4e8 0x64bc828 0x64bdbf8 0x64bef38 0x64c0278 0x64c2320 0x671ceb8 0x671e898 0x68fd408 0x54a22e0 0x54bb308 0x58eb228 0x5998db0 0x59e0098 0x59e0738 0x59e0dd8 0x59e1468 0x59e1a70 0x59e2080 0x59e92f0 0x59e2e00 0x59e3410 0x59e3a50 0x59e7ed8 0x5a31d50 0x56dd5a0 0x5b59278 0x5bfe318 0x5c58d58 0x5c59df8 0x5c5ae78 0x5c5c3e8 0x5c5d4f8 0x5c5e578 0x5c60490 0x5c61570 0x5d594e8 0x5d8a6c8 0x5d65b78 0x5d66ad8 0x5d67a38 0x5d689a8 0x5dadf88 0x5d69098 0x5dc3bb8 0x5d69ff8 0x5d6af58 0x5d6beb8 0x5d73128 0x5d94578 0x5d96ba0 0x5d99278 0x5da4488 0x5da7158 0x5daa948 0x5db78b8 0x5dba410 0x5dbe738 0x5dc10f8 0x5dd0cb8 0x5dd5a28 0x5dda6c8 0x622d0d0 0x5f59898 0x5f5a530 0x5f5af98 0x5f5b9f8 0x5f5c4e8 0x6000720 0x6001180 0x6001b80 | | |-CXXOperatorCallExpr 0x7ff09563adc0 <col:1, col:57> '<dependent type>' '<<' | | | |-UnresolvedLookupExpr 0x7ff09563aa80 <col:54> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x4fa9158 0x4f51ab8 0x4f51418 0x4fa6718 0x4fa69a0 0x4fa6c30 0x4fa6ec0 0x4fa7150 0x4fa73e0 0x4fa7670 0x4fa7900 0x4fa7b90 0x4fa7e20 0x4fa80b0 0x4fa8340 0x4fa85d0 0x4fa8860 0x4fa8b28 0x6495458 0x6497ac8 0x649ed68 0x649fc58 0x64ad0d8 0x64ad3f8 0x64ba3e8 0x64bb4e8 0x64bc828 0x64bdbf8 0x64bef38 0x64c0278 0x64c2320 0x671ceb8 0x671e898 0x68fd408 0x54a22e0 0x54bb308 0x58eb228 0x5998db0 0x59e0098 0x59e0738 0x59e0dd8 0x59e1468 0x59e1a70 0x59e2080 0x59e92f0 0x59e2e00 0x59e3410 0x59e3a50 0x59e7ed8 0x5a31d50 0x56dd5a0 0x5b59278 0x5bfe318 0x5c58d58 0x5c59df8 0x5c5ae78 0x5c5c3e8 0x5c5d4f8 0x5c5e578 0x5c60490 0x5c61570 0x5d594e8 0x5d8a6c8 0x5d65b78 0x5d66ad8 0x5d67a38 0x5d689a8 0x5dadf88 0x5d69098 0x5dc3bb8 0x5d69ff8 0x5d6af58 0x5d6beb8 0x5d73128 0x5d94578 0x5d96ba0 0x5d99278 0x5da4488 0x5da7158 0x5daa948 0x5db78b8 0x5dba410 0x5dbe738 0x5dc10f8 0x5dd0cb8 0x5dd5a28 0x5dda6c8 0x622d0d0 0x5f59898 0x5f5a530 0x5f5af98 0x5f5b9f8 0x5f5c4e8 0x6000720 0x6001180 0x6001b80 | | | |-CXXOperatorCallExpr 0x7ff09563aa08 <col:1, col:14> 'basic_ostream<char, char_traits<char> >':'std::basic_ostream<char>' lvalue '<<' | | | | |-ImplicitCastExpr 0x7ff09563a9f0 <col:11> 'basic_ostream<char, char_traits<char> > &(*)(basic_ostream<char, char_traits<char> > &, const char *)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7ff09563a9d0 <col:11> 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' lvalue Function 0x7ff094ea3b18 'operator<<' 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' | | | | |-DeclRefExpr 0x7ff095638370 <col:1, col:6> 'ostream':'std::basic_ostream<char>' lvalue Var 0x5c79ad8 'cout' 'ostream':'std::basic_ostream<char>' | | | | `-ImplicitCastExpr 0x7ff09563a9b8 <col:14> 'const char *' <ArrayToPointerDecay> | | | | `-StringLiteral 0x7ff095638418 <col:14> 'const char[38]' lvalue "mu_pt if abs(mu_eta) < 2 else -999 = " | | | `-DeclRefExpr 0x7ff09563aa40 <col:57> 'auto' lvalue Var 0x7ff095632c68 'masked_mu_pt' 'auto' | | `-UnresolvedLookupExpr 0x7ff09563ae18 <col:73, col:78> '<overloaded function type>' lvalue (no ADL) = 'endl' 0x59e4090 | `-NullStmt 0x7ff09563b1d8 <line:4:1> |-AnnotateAttr 0x7ff095632d40 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" `-AnnotateAttr 0x7ff095632e50 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" <<<NULL>>>