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 28, 2023 at 10:03 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 expext 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::((*(std::ostream*)0x7fec15a69480)) << "All( " << ((*(ROOT::RVecD*)0x7febf9f3a000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7febf9f3a050)) << " ) = " << All(((*(class ROOT::VecOps::RVec<int>*)0x7febf8013000))) << std::endl) ^ Error in <HandleInterpreterException>: Error evaluating expression (std::((*(std::ostream*)0x7fec15a69480)) << "All( " << ((*(ROOT::RVecD*)0x7febf9f3a000)) << " > .5 * " << ((*(ROOT::RVecD*)0x7febf9f3a050)) << " ) = " << All(((*(class ROOT::VecOps::RVec<int>*)0x7febf8013000))) << 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 particularely 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 0x7febe72d3d80 <input_line_59:1:1, line:5:1> line:1:6 __cling_Un1Qu327 'void (void *)' |-ParmVarDecl 0x7febe72d3cc8 <col:23, col:29> col:29 vpClingValue 'void *' |-CompoundStmt 0x7febe72db5a8 <col:43, line:5:1> | |-DeclStmt 0x7febe72d9340 <line:2:2, col:59> | | `-VarDecl 0x7febe72d3e88 <col:2, col:58> col:7 used masked_mu_pt 'auto' cinit | | `-ExprWithCleanups 0x7febe72d9328 <col:22, col:58> '<dependent type>' | | `-CallExpr 0x7febe72d92f0 <col:22, col:58> '<dependent type>' | | |-DeclRefExpr 0x7febe72d40c0 <col:22> '<dependent type>' lvalue Var 0x7febe72d3ff8 'Where' '<dependent type>' | | |-CXXBindTemporaryExpr 0x7febe72d9278 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' (CXXTemporary 0x7febe72d9278) | | | `-CXXOperatorCallExpr 0x7febe72d9238 <col:28, col:42> 'RVec<int>':'ROOT::VecOps::RVec<int>' '<' adl | | | |-ImplicitCastExpr 0x7febe72d9220 <col:40> 'auto (*)(const RVec<double> &, const double &) -> RVec<int>' <FunctionToPointerDecay> | | | | `-DeclRefExpr 0x7febe72d9200 <col:40> 'auto (const RVec<double> &, const double &) -> RVec<int>' lvalue Function 0x7febe71d31a8 'operator<' 'auto (const RVec<double> &, const double &) -> RVec<int>' | | | |-MaterializeTemporaryExpr 0x7febe72d91b8 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' lvalue | | | | `-ImplicitCastExpr 0x7febe72d91a0 <col:28, col:38> 'const RVec<PromoteType<double> >':'const ROOT::VecOps::RVec<double>' <NoOp> | | | | `-CXXBindTemporaryExpr 0x7febe72d4540 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' (CXXTemporary 0x7febe72d4540) | | | | `-CallExpr 0x7febe72d44f8 <col:28, col:38> 'RVec<PromoteType<double> >':'ROOT::VecOps::RVec<double>' adl | | | | |-ImplicitCastExpr 0x7febe72d44e0 <col:28> 'RVec<PromoteType<double> > (*)(const RVec<double> &)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7febe72d44b8 <col:28> 'RVec<PromoteType<double> > (const RVec<double> &)' lvalue Function 0x7febe71b48b0 'abs' 'RVec<PromoteType<double> > (const RVec<double> &)' (FunctionTemplate 0x7febe71b39a0 'abs') | | | | `-ImplicitCastExpr 0x7febe72d4520 <col:32> 'const RVec<double>':'const ROOT::VecOps::RVec<double>' lvalue <NoOp> | | | | `-DeclRefExpr 0x7febe72d4188 <col:32> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7febe71ad388 'mu_eta' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | | `-MaterializeTemporaryExpr 0x7febe72d91e8 <col:42> 'const double' lvalue | | | `-ImplicitCastExpr 0x7febe72d91d0 <col:42> 'const double' <NoOp> | | | `-FloatingLiteral 0x7febe72d4560 <col:42> 'double' 2.000000e+00 | | |-DeclRefExpr 0x7febe72d9298 <col:46> 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' lvalue Var 0x7febe71ad000 'mu_pt' 'ROOT::RVecD':'ROOT::VecOps::RVec<double>' | | `-UnaryOperator 0x7febe72d92d8 <col:53, col:54> 'double' prefix '-' | | `-FloatingLiteral 0x7febe72d92b8 <col:54> 'double' 9.990000e+02 | |-CXXOperatorCallExpr 0x7febe72db568 <line:3:1, col:78> '<dependent type>' '<<' | | |-UnresolvedLookupExpr 0x7febe72db220 <col:70> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x419bb10 0x527d678 0x527d0a0 0x4199300 0x4199570 0x41997e0 0x4199a50 0x4199cc0 0x4199f30 0x419a1a0 0x419a410 0x419a680 0x419a8f0 0x419ab60 0x419add0 0x419b040 0x419b2b0 0x419b550 0x419ed40 0x41a11c0 0x41a8088 0x41a8db8 0x41c8b30 0x41c8e40 0x41d2638 0x41d3598 0x41d4728 0x41d5948 0x41d6ad8 0x41d7c68 0x41d9b30 0x550cb38 0x550f948 0x3c47e00 0x3c48308 0x44fd800 0x451b200 0x4934430 0x49cfbb0 0x4a1ef48 0x4a1f588 0x4a1fbc8 0x4a20200 0x4a207a8 0x4a20d58 0x4a27a80 0x4a21a10 0x4a21fb8 0x4a22598 0x4a26750 0x4a66d78 0x4b5e1a0 0x4b71108 0x4c0acd8 0x4c63478 0x4c68028 0x4c68f78 0x4c6a3a8 0x4c6b358 0x4c6c2a8 0x4c6e048 0x4c6f018 0x4d3d0b8 0x4d6e078 0x4d49268 0x4d4a160 0x4d4b060 0x4d4d5b0 0x4d95eb0 0x4d4dc90 0x4dab700 0x4d4eb90 0x4d4fa90 0x4d50990 0x4d57570 0x4d78a88 0x4d7b040 0x4d7d648 0x4d8c7b0 0x4d8f330 0x4d929c0 0x4d9f820 0x4da22e0 0x4da6450 0x4da8d40 0x4db8730 0x4dbd2f0 0x4dc1de0 0x511aae8 0x4f27710 0x4f282b0 0x4f28c70 0x4f29630 0x4f2a050 0x4fc7ba8 0x4fc8548 0x4fc8eb8 | | |-CXXOperatorCallExpr 0x7febe72db180 <col:1, col:57> '<dependent type>' '<<' | | | |-UnresolvedLookupExpr 0x7febe72dae38 <col:54> '<overloaded function type>' lvalue (ADL) = 'operator<<' 0x419bb10 0x527d678 0x527d0a0 0x4199300 0x4199570 0x41997e0 0x4199a50 0x4199cc0 0x4199f30 0x419a1a0 0x419a410 0x419a680 0x419a8f0 0x419ab60 0x419add0 0x419b040 0x419b2b0 0x419b550 0x419ed40 0x41a11c0 0x41a8088 0x41a8db8 0x41c8b30 0x41c8e40 0x41d2638 0x41d3598 0x41d4728 0x41d5948 0x41d6ad8 0x41d7c68 0x41d9b30 0x550cb38 0x550f948 0x3c47e00 0x3c48308 0x44fd800 0x451b200 0x4934430 0x49cfbb0 0x4a1ef48 0x4a1f588 0x4a1fbc8 0x4a20200 0x4a207a8 0x4a20d58 0x4a27a80 0x4a21a10 0x4a21fb8 0x4a22598 0x4a26750 0x4a66d78 0x4b5e1a0 0x4b71108 0x4c0acd8 0x4c63478 0x4c68028 0x4c68f78 0x4c6a3a8 0x4c6b358 0x4c6c2a8 0x4c6e048 0x4c6f018 0x4d3d0b8 0x4d6e078 0x4d49268 0x4d4a160 0x4d4b060 0x4d4d5b0 0x4d95eb0 0x4d4dc90 0x4dab700 0x4d4eb90 0x4d4fa90 0x4d50990 0x4d57570 0x4d78a88 0x4d7b040 0x4d7d648 0x4d8c7b0 0x4d8f330 0x4d929c0 0x4d9f820 0x4da22e0 0x4da6450 0x4da8d40 0x4db8730 0x4dbd2f0 0x4dc1de0 0x511aae8 0x4f27710 0x4f282b0 0x4f28c70 0x4f29630 0x4f2a050 0x4fc7ba8 0x4fc8548 0x4fc8eb8 | | | |-CXXOperatorCallExpr 0x7febe72dadc0 <col:1, col:14> 'basic_ostream<char, std::char_traits<char> >':'std::basic_ostream<char>' lvalue '<<' | | | | |-ImplicitCastExpr 0x7febe72dada8 <col:11> 'basic_ostream<char, std::char_traits<char> > &(*)(basic_ostream<char, std::char_traits<char> > &, const char *)' <FunctionToPointerDecay> | | | | | `-DeclRefExpr 0x7febe72dad88 <col:11> 'basic_ostream<char, std::char_traits<char> > &(basic_ostream<char, std::char_traits<char> > &, const char *)' lvalue Function 0x7febe6bddf20 'operator<<' 'basic_ostream<char, std::char_traits<char> > &(basic_ostream<char, std::char_traits<char> > &, const char *)' | | | | |-DeclRefExpr 0x7febe72d93a8 <col:1, col:6> 'std::ostream':'std::basic_ostream<char>' lvalue Var 0x4c750e0 'cout' 'std::ostream':'std::basic_ostream<char>' | | | | `-ImplicitCastExpr 0x7febe72dad70 <col:14> 'const char *' <ArrayToPointerDecay> | | | | `-StringLiteral 0x7febe72d9418 <col:14> 'const char [38]' lvalue "mu_pt if abs(mu_eta) < 2 else -999 = " | | | `-DeclRefExpr 0x7febe72dadf8 <col:57> 'auto' lvalue Var 0x7febe72d3e88 'masked_mu_pt' 'auto' | | `-UnresolvedLookupExpr 0x7febe72db1d8 <col:73, col:78> '<overloaded function type>' lvalue (no ADL) = 'endl' 0x4a22b78 | `-NullStmt 0x7febe72db5a0 <line:4:1> |-AnnotateAttr 0x7febe72d3f60 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" `-AnnotateAttr 0x7febe72d4060 <<invalid sloc>> Implicit R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP" <<<NULL>>>