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 Tuesday, March 19, 2024 at 07:22 PM.
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*)0x7f0026087480)) << "All( " << ((*(ROOT::RVecD*)0x7f0008275000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7f0008275050)) << " ) = " << All(((*(RVec<int>*)0x7f00080d4000))) << std::endl) ^ input_line_55:2:159: error: use of undeclared identifier 'RVec' (std::((*(ostream*)0x7f0026087480)) << "All( " << ((*(ROOT::RVecD*)0x7f0008275000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7f0008275050)) << " ) = " << All(((*(RVec<int>*)0x7f00080d4000))) << std::endl) ^ input_line_55:2:169: error: expected expression (std::((*(ostream*)0x7f0026087480)) << "All( " << ((*(ROOT::RVecD*)0x7f0008275000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7f0008275050)) << " ) = " << All(((*(RVec<int>*)0x7f00080d4000))) << std::endl) ^ Error in <HandleInterpreterException>: Error evaluating expression (std::((*(ostream*)0x7f0026087480)) << "All( " << ((*(ROOT::RVecD*)0x7f0008275000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7f0008275050)) << " ) = " << All(((*(RVec<int>*)0x7f00080d4000))) << 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 0x7effed64a0e0 <input_line_59:1:1, line:5:1> line:1:6 __cling_Un1Qu327 'void (void *)' |-ParmVarDecl 0x7effed64a028 <col:23, col:29> col:29 vpClingValue 'void *' |-CompoundStmt 0x7effed6529b0 <col:43, line:5:1> | |-DeclStmt 0x7effed64f898 <line:2:2, col:59> | | `-VarDecl 0x7effed64a1f8 <col:2, col:58> col:7 used masked_mu_pt 'auto' cinit | | `-ExprWithCleanups 0x7effed64f880 <col:22, col:58> '<dependent type>' | | `-CallExpr 0x7effed64f848 <col:22, col:58> '<dependent type>' | | |-DeclRefExpr 0x7effed64a450 <col:22> '<dependent type>' lvalue Var 0x7effed64a378 'Where' '<dependent type>' | | |-CXXBindTemporaryExpr 0x7effed64f7d0 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' (CXXTemporary 0x7effed64f7d0) | | | `-CXXOperatorCallExpr 0x7effed64f790 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' '<' adl | | | |-ImplicitCastExpr 0x7effed64f778 <col:40> 'auto (*)(const RVec<double> &, const double &) -> RVec<int>' <FunctionToPointerDecay> | | | | `-DeclRefExpr 0x7effed64f758 <col:40> 'auto (const RVec<double> &, const double &) -> RVec<int>' lvalue Function 0x7effed5fd7f0 'operator<' 'auto (const RVec<double> &, const double &) -> RVec<int>' | | | |-MaterializeTemporaryExpr 0x7effed64f710 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' lvalue | | | | `-ImplicitCastExpr 0x7effed64f6f8 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' <NoOp> | | | | `-CXXBindTemporaryExpr 0x7effed64a8f8 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' (CXXTemporary 0x7effed64a8f8) | | | | `-CallExpr 0x7effed64a8b0 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' adl | | | | |-ImplicitCastExpr 0x7effed64a898 <col:28> 'RVec<PromoteType<double> > (*)(const RVec<double> &)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7effed64a870 <col:28> 'RVec<PromoteType<double> > (const RVec<double> &)' lvalue Function 0x7effed5faa40 'abs' 'RVec<PromoteType<double> > (const RVec<double> &)' (FunctionTemplate 0x7effed5f9a80 'abs') | | | | `-ImplicitCastExpr 0x7effed64a8d8 <col:32> 'const RVec<double>':'const ROOT::VecOps::RVec<double>' lvalue <NoOp> | | | | `-DeclRefExpr 0x7effed64a518 <col:32> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7effed4f87e8 'mu_eta' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | | `-MaterializeTemporaryExpr 0x7effed64f740 <col:42> 'const double' lvalue | | | `-ImplicitCastExpr 0x7effed64f728 <col:42> 'const double' <NoOp> | | | `-FloatingLiteral 0x7effed64a918 <col:42> 'double' 2.000000e+00 | | |-DeclRefExpr 0x7effed64f7f0 <col:46> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7effed4f8460 'mu_pt' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | `-UnaryOperator 0x7effed64f830 <col:53, col:54> 'double' prefix '-' | | `-FloatingLiteral 0x7effed64f810 <col:54> 'double' 9.990000e+02 | |-CXXOperatorCallExpr 0x7effed652970 <line:3:1, col:78> '<dependent type>' '<<' | | |-UnresolvedLookupExpr 0x7effed652630 <col:70> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x5158e58 0x5109898 0x51091f8 0x5156418 0x51566a0 0x5156930 0x5156bc0 0x5156e50 0x51570e0 0x5157370 0x5157600 0x5157890 0x5157b20 0x5157db0 0x5158040 0x51582d0 0x5158560 0x5158828 0x6646c68 0x66492d8 0x6650578 0x6651468 0x665e8e8 0x665ec08 0x6671098 0x6672198 0x66734d8 0x66748a8 0x6675be8 0x6676f28 0x6678fd0 0x68d24f8 0x68d3ed8 0x6ab6ce8 0x563ace0 0x565b8c8 0x5a8bed8 0x5b35b70 0x5b84828 0x5b84ec8 0x5b85568 0x5b85bf8 0x5b86200 0x5b86810 0x5b8da80 0x5b87590 0x5b87ba0 0x5b881e0 0x5b8c668 0x5bd6720 0x588ed60 0x5cfeaa8 0x5da2bf8 0x5df9528 0x5dfa5c8 0x5dfb648 0x5dfcbb8 0x5dfdcc8 0x5dfed48 0x5e00c60 0x5e01d40 0x5ef5718 0x5f2ed28 0x5f01da8 0x5f02d08 0x5f03c68 0x5f04de8 0x5f51f68 0x5f054d8 0x5f67e28 0x5f06438 0x5f07398 0x5f082f8 0x5f0f568 0x5f389a8 0x5f3afd0 0x5f3d6a8 0x5f48468 0x5f4b138 0x5f4e928 0x5f5bb28 0x5f5e680 0x5f629a8 0x5f65368 0x5f74f58 0x5f79cc8 0x5f7e968 0x63d0530 0x6100438 0x61010d0 0x6101b38 0x6102598 0x6103088 0x61a4bb0 0x61a5610 0x61a6010 | | |-CXXOperatorCallExpr 0x7effed652590 <col:1, col:57> '<dependent type>' '<<' | | | |-UnresolvedLookupExpr 0x7effed652250 <col:54> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x5158e58 0x5109898 0x51091f8 0x5156418 0x51566a0 0x5156930 0x5156bc0 0x5156e50 0x51570e0 0x5157370 0x5157600 0x5157890 0x5157b20 0x5157db0 0x5158040 0x51582d0 0x5158560 0x5158828 0x6646c68 0x66492d8 0x6650578 0x6651468 0x665e8e8 0x665ec08 0x6671098 0x6672198 0x66734d8 0x66748a8 0x6675be8 0x6676f28 0x6678fd0 0x68d24f8 0x68d3ed8 0x6ab6ce8 0x563ace0 0x565b8c8 0x5a8bed8 0x5b35b70 0x5b84828 0x5b84ec8 0x5b85568 0x5b85bf8 0x5b86200 0x5b86810 0x5b8da80 0x5b87590 0x5b87ba0 0x5b881e0 0x5b8c668 0x5bd6720 0x588ed60 0x5cfeaa8 0x5da2bf8 0x5df9528 0x5dfa5c8 0x5dfb648 0x5dfcbb8 0x5dfdcc8 0x5dfed48 0x5e00c60 0x5e01d40 0x5ef5718 0x5f2ed28 0x5f01da8 0x5f02d08 0x5f03c68 0x5f04de8 0x5f51f68 0x5f054d8 0x5f67e28 0x5f06438 0x5f07398 0x5f082f8 0x5f0f568 0x5f389a8 0x5f3afd0 0x5f3d6a8 0x5f48468 0x5f4b138 0x5f4e928 0x5f5bb28 0x5f5e680 0x5f629a8 0x5f65368 0x5f74f58 0x5f79cc8 0x5f7e968 0x63d0530 0x6100438 0x61010d0 0x6101b38 0x6102598 0x6103088 0x61a4bb0 0x61a5610 0x61a6010 | | | |-CXXOperatorCallExpr 0x7effed6521d8 <col:1, col:14> 'basic_ostream<char, char_traits<char> >':'std::basic_ostream<char>' lvalue '<<' | | | | |-ImplicitCastExpr 0x7effed6521c0 <col:11> 'basic_ostream<char, char_traits<char> > &(*)(basic_ostream<char, char_traits<char> > &, const char *)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7effed6521a0 <col:11> 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' lvalue Function 0x7effece946e8 'operator<<' 'basic_ostream<char, char_traits<char> > &(basic_ostream<char, char_traits<char> > &, const char *)' | | | | |-DeclRefExpr 0x7effed64f900 <col:1, col:6> 'ostream':'std::basic_ostream<char>' lvalue Var 0x5e1a2a8 'cout' 'ostream':'std::basic_ostream<char>' | | | | `-ImplicitCastExpr 0x7effed652188 <col:14> 'const char *' <ArrayToPointerDecay> | | | | `-StringLiteral 0x7effed64f9a8 <col:14> 'const char[38]' lvalue "mu_pt if abs(mu_eta) < 2 else -999 = " | | | `-DeclRefExpr 0x7effed652210 <col:57> 'auto' lvalue Var 0x7effed64a1f8 'masked_mu_pt' 'auto' | | `-UnresolvedLookupExpr 0x7effed6525e8 <col:73, col:78> '<overloaded function type>' lvalue (no ADL) = 'endl' 0x5b88820 | `-NullStmt 0x7effed6529a8 <line:4:1> |-AnnotateAttr 0x7effed64a2d0 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" `-AnnotateAttr 0x7effed64a3e0 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" <<<NULL>>>