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 Wednesday, April 17, 2024 at 11:24 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*)0x7fa8bc0b7480)) << "All( " << ((*(ROOT::RVecD*)0x7fa89c9c5000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7fa89c9c5050)) << " ) = " << All(((*(RVec<int>*)0x7fa89c051000))) << std::endl) ^ input_line_55:2:159: error: use of undeclared identifier 'RVec' (std::((*(ostream*)0x7fa8bc0b7480)) << "All( " << ((*(ROOT::RVecD*)0x7fa89c9c5000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7fa89c9c5050)) << " ) = " << All(((*(RVec<int>*)0x7fa89c051000))) << std::endl) ^ input_line_55:2:169: error: expected expression (std::((*(ostream*)0x7fa8bc0b7480)) << "All( " << ((*(ROOT::RVecD*)0x7fa89c9c5000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7fa89c9c5050)) << " ) = " << All(((*(RVec<int>*)0x7fa89c051000))) << std::endl) ^ Error in <HandleInterpreterException>: Error evaluating expression (std::((*(ostream*)0x7fa8bc0b7480)) << "All( " << ((*(ROOT::RVecD*)0x7fa89c9c5000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7fa89c9c5050)) << " ) = " << All(((*(RVec<int>*)0x7fa89c051000))) << 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 0x7fa88d60ee50 <input_line_59:1:1, line:5:1> line:1:6 __cling_Un1Qu327 'void (void *)' |-ParmVarDecl 0x7fa88d60ed98 <col:23, col:29> col:29 vpClingValue 'void *' |-CompoundStmt 0x7fa88d617720 <col:43, line:5:1> | |-DeclStmt 0x7fa88d614608 <line:2:2, col:59> | | `-VarDecl 0x7fa88d60ef68 <col:2, col:58> col:7 used masked_mu_pt 'auto' cinit | | `-ExprWithCleanups 0x7fa88d6145f0 <col:22, col:58> '<dependent type>' | | `-CallExpr 0x7fa88d6145b8 <col:22, col:58> '<dependent type>' | | |-DeclRefExpr 0x7fa88d60f1c0 <col:22> '<dependent type>' lvalue Var 0x7fa88d60f0e8 'Where' '<dependent type>' | | |-CXXBindTemporaryExpr 0x7fa88d614540 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' (CXXTemporary 0x7fa88d614540) | | | `-CXXOperatorCallExpr 0x7fa88d614500 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' '<' adl | | | |-ImplicitCastExpr 0x7fa88d6144e8 <col:40> 'auto (*)(const RVec<double> &, const double &) -> RVec<int>' <FunctionToPointerDecay> | | | | `-DeclRefExpr 0x7fa88d6144c8 <col:40> 'auto (const RVec<double> &, const double &) -> RVec<int>' lvalue Function 0x7fa88d5c2560 'operator<' 'auto (const RVec<double> &, const double &) -> RVec<int>' | | | |-MaterializeTemporaryExpr 0x7fa88d614480 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' lvalue | | | | `-ImplicitCastExpr 0x7fa88d614468 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' <NoOp> | | | | `-CXXBindTemporaryExpr 0x7fa88d60f668 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' (CXXTemporary 0x7fa88d60f668) | | | | `-CallExpr 0x7fa88d60f620 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' adl | | | | |-ImplicitCastExpr 0x7fa88d60f608 <col:28> 'RVec<PromoteType<double> > (*)(const RVec<double> &)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7fa88d60f5e0 <col:28> 'RVec<PromoteType<double> > (const RVec<double> &)' lvalue Function 0x7fa88d5bf7b0 'abs' 'RVec<PromoteType<double> > (const RVec<double> &)' (FunctionTemplate 0x7fa88d5be7f0 'abs') | | | | `-ImplicitCastExpr 0x7fa88d60f648 <col:32> 'const RVec<double>':'const ROOT::VecOps::RVec<double>' lvalue <NoOp> | | | | `-DeclRefExpr 0x7fa88d60f288 <col:32> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7fa88d4d8bb8 'mu_eta' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | | `-MaterializeTemporaryExpr 0x7fa88d6144b0 <col:42> 'const double' lvalue | | | `-ImplicitCastExpr 0x7fa88d614498 <col:42> 'const double' <NoOp> | | | `-FloatingLiteral 0x7fa88d60f688 <col:42> 'double' 2.000000e+00 | | |-DeclRefExpr 0x7fa88d614560 <col:46> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7fa88d4d8830 'mu_pt' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | `-UnaryOperator 0x7fa88d6145a0 <col:53, col:54> 'double' prefix '-' | | `-FloatingLiteral 0x7fa88d614580 <col:54> 'double' 9.990000e+02 | |-CXXOperatorCallExpr 0x7fa88d6176e0 <line:3:1, col:78> '<dependent type>' '<<' | | |-UnresolvedLookupExpr 0x7fa88d6173a0 <col:70> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x6bc1018 0x565a508 0x5659e68 0x6bbe5d8 0x6bbe860 0x6bbeaf0 0x6bbed80 0x6bbf010 0x6bbf2a0 0x6bbf530 0x6bbf7c0 0x6bbfa50 0x6bbfce0 0x6bbff70 0x6bc0200 0x6bc0490 0x6bc0720 0x6bc09e8 0x6bc4508 0x6bc6b78 0x6bcde18 0x6bced08 0x6bdc1c8 0x6bdc4e8 0x6be6938 0x6be7a38 0x6be8d78 0x6bea148 0x6beb488 0x6bec7c8 0x6bee870 0x6e35ec8 0x6e378a8 0x7012368 0x5bb28b0 0x5bcbcc8 0x5ffbbd8 0x60a59c0 0x60ef618 0x60efcb8 0x60f0358 0x60f09e8 0x60f0ff0 0x60f1600 0x60f8870 0x60f2380 0x60f2990 0x60f2fd0 0x60f7458 0x61462f0 0x5dedb50 0x626a9b8 0x630e978 0x6369208 0x636a2a8 0x636b328 0x636c898 0x636d9a8 0x636ea28 0x6370940 0x6371a20 0x6465b68 0x649af98 0x64721f8 0x6473158 0x64740b8 0x6475028 0x64be1f8 0x6475718 0x64d4138 0x6476678 0x64775d8 0x6478538 0x647f7a8 0x64a4c08 0x64a7230 0x64a9908 0x64b46f8 0x64b73c8 0x64babb8 0x64c7e38 0x64ca990 0x64cecb8 0x64d1678 0x64e1248 0x64e5fb8 0x64eac58 0x6930f80 0x6668018 0x6668cb0 0x6669718 0x666a178 0x666ac68 0x671cde0 0x671d840 0x671e240 | | |-CXXOperatorCallExpr 0x7fa88d617300 <col:1, col:57> '<dependent type>' '<<' | | | |-UnresolvedLookupExpr 0x7fa88d616fc0 <col:54> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x6bc1018 0x565a508 0x5659e68 0x6bbe5d8 0x6bbe860 0x6bbeaf0 0x6bbed80 0x6bbf010 0x6bbf2a0 0x6bbf530 0x6bbf7c0 0x6bbfa50 0x6bbfce0 0x6bbff70 0x6bc0200 0x6bc0490 0x6bc0720 0x6bc09e8 0x6bc4508 0x6bc6b78 0x6bcde18 0x6bced08 0x6bdc1c8 0x6bdc4e8 0x6be6938 0x6be7a38 0x6be8d78 0x6bea148 0x6beb488 0x6bec7c8 0x6bee870 0x6e35ec8 0x6e378a8 0x7012368 0x5bb28b0 0x5bcbcc8 0x5ffbbd8 0x60a59c0 0x60ef618 0x60efcb8 0x60f0358 0x60f09e8 0x60f0ff0 0x60f1600 0x60f8870 0x60f2380 0x60f2990 0x60f2fd0 0x60f7458 0x61462f0 0x5dedb50 0x626a9b8 0x630e978 0x6369208 0x636a2a8 0x636b328 0x636c898 0x636d9a8 0x636ea28 0x6370940 0x6371a20 0x6465b68 0x649af98 0x64721f8 0x6473158 0x64740b8 0x6475028 0x64be1f8 0x6475718 0x64d4138 0x6476678 0x64775d8 0x6478538 0x647f7a8 0x64a4c08 0x64a7230 0x64a9908 0x64b46f8 0x64b73c8 0x64babb8 0x64c7e38 0x64ca990 0x64cecb8 0x64d1678 0x64e1248 0x64e5fb8 0x64eac58 0x6930f80 0x6668018 0x6668cb0 0x6669718 0x666a178 0x666ac68 0x671cde0 0x671d840 0x671e240 | | | |-CXXOperatorCallExpr 0x7fa88d616f48 <col:1, col:14> 'basic_ostream<char, char_traits<char> >':'std::basic_ostream<char>' lvalue '<<' | | | | |-ImplicitCastExpr 0x7fa88d616f30 <col:11> 'basic_ostream<char, char_traits<char> > &(*)(basic_ostream<char, char_traits<char> > &, const char *)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7fa88d616f10 <col:11> 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' lvalue Function 0x7fa88ce8ac28 'operator<<' 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' | | | | |-DeclRefExpr 0x7fa88d614670 <col:1, col:6> 'ostream':'std::basic_ostream<char>' lvalue Var 0x6389fc8 'cout' 'ostream':'std::basic_ostream<char>' | | | | `-ImplicitCastExpr 0x7fa88d616ef8 <col:14> 'const char *' <ArrayToPointerDecay> | | | | `-StringLiteral 0x7fa88d614718 <col:14> 'const char[38]' lvalue "mu_pt if abs(mu_eta) < 2 else -999 = " | | | `-DeclRefExpr 0x7fa88d616f80 <col:57> 'auto' lvalue Var 0x7fa88d60ef68 'masked_mu_pt' 'auto' | | `-UnresolvedLookupExpr 0x7fa88d617358 <col:73, col:78> '<overloaded function type>' lvalue (no ADL) = 'endl' 0x60f3610 | `-NullStmt 0x7fa88d617718 <line:4:1> |-AnnotateAttr 0x7fa88d60f040 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" `-AnnotateAttr 0x7fa88d60f150 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" <<<NULL>>>