Df 0 1 6_Vec Ops

This tutorial shows the potential of the VecOps approach for treating collections stored in datasets, a situation very common in HEP data analysis.

Author: Danilo Piparo
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Monday, July 06, 2020 at 11:35 AM.

In [1]:
using ROOT::RDataFrame;
using namespace ROOT::VecOps;

We re-create a set of points in a square. This is a technical detail, just to create a dataset to play with!

In [2]:
auto unifGen = [](double) { return gRandom->Uniform(-1.0, 1.0); };
auto vGen = [&](int len) {
   RVec<double> v(len);
   std::transform(v.begin(), v.end(), v.begin(), unifGen);
   return v;
};
RDataFrame d(1024);
auto d0 = d.Define("len", []() { return (int)gRandom->Uniform(0, 16); })
   .Define("x", vGen, {"len"})
   .Define("y", vGen, {"len"});
input_line_50:4:4: error: use of undeclared identifier 'RVec'
   RVec<double> v(len);
   ^
input_line_50:4:15: error: expected '(' for function-style cast or type construction
   RVec<double> v(len);
        ~~~~~~^
input_line_50:4:17: error: use of undeclared identifier 'v'
   RVec<double> v(len);
                ^
input_line_50:5:19: error: use of undeclared identifier 'v'
   std::transform(v.begin(), v.end(), v.begin(), unifGen);
                  ^
input_line_50:5:30: error: use of undeclared identifier 'v'
   std::transform(v.begin(), v.end(), v.begin(), unifGen);
                             ^
input_line_50:5:39: error: use of undeclared identifier 'v'
   std::transform(v.begin(), v.end(), v.begin(), unifGen);
                                      ^
input_line_50:6:11: error: use of undeclared identifier 'v'
   return v;
          ^
In module 'ROOTDataFrame':
/home/sftnight/build/workspace/root-makedoc-master/rootspi/rdoc/src/master.build/include/ROOT/RDF/RInterface.hxx:2367:7: error: static_assert failed "Error in `Define`: type returned by expression is not default-constructible"
      static_assert(std::is_default_constructible<typename TTraits::CallableTraits<F>::ret_type>::value,
      ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sftnight/build/workspace/root-makedoc-master/rootspi/rdoc/src/master.build/include/ROOT/RDF/RInterface.hxx:296:14: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager, void>::DefineImpl<(lambda at input_line_50:3:13), ROOT::Detail::RDF::CustomColExtraArgs::None, void, false, false>' requested here
      return DefineImpl<F, RDFDetail::CustomColExtraArgs::None>(name, std::move(expression), columns);
             ^
input_line_50:10:5: note: in instantiation of function template specialization 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager, void>::Define<(lambda at input_line_50:3:13), 0>' requested here
   .Define("x", vGen, {"len"})
    ^

Now we have in hands d, a rdataframe with two columns, x and y, which hold collections of coordinates. The size of these collections vary. Let's now define radii out of x and y. We'll do it treating the collections stored in the columns without looping on the individual elements.

In [3]:
auto d1 = d0.Define("r", "sqrt(x*x + y*y)");
input_line_51:2:2: error: Syntax error
 auto d1 = d0.Define("r", "sqrt(x*x + y*y)");
 ^
FunctionDecl 0x7f72a0e871f8 <input_line_51:1:1, line:4:1> line:1:6 __cling_Un1Qu322 'void (void *)'
|-ParmVarDecl 0x7f72a0e87148 <col:23, col:29> col:29 vpClingValue 'void *'
|-CompoundStmt 0x7f72a0e87568 <col:43, line:4:1>
| |-DeclStmt 0x7f72a0e87540 <line:2:2, col:45>
| | `-VarDecl 0x7f72a0e872d0 <col:2, col:44> col:7 d1 'auto' cinit
| |   `-CallExpr 0x7f72a0e87508 <col:12, col:44> '<dependent type>'
| |     |-CXXDependentScopeMemberExpr 0x7f72a0e87448 <col:12, col:15> '<dependent type>' lvalue .Define
| |     | `-DeclRefExpr 0x7f72a0e87400 <col:12> '<dependent type>' lvalue Var 0x7f72a0e87338 'd0' '<dependent type>'
| |     |-StringLiteral 0x7f72a0e874a0 <col:22> 'const char [2]' lvalue "r"
| |     `-StringLiteral 0x7f72a0e874d0 <col:27> 'const char [16]' lvalue "sqrt(x*x + y*y)"
| `-NullStmt 0x7f72a0e87558 <line:3:1>
`-AnnotateAttr 0x7f72a0e87398 <<invalid sloc>> R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP"
<<<NULL>>>

Now we want to plot 2 quarters of a ring with radii .5 and 1 Note how the cuts are performed on RVecs, comparing them with integers and among themselves

In [4]:
auto ring_h = d1.Define("rInFig", "r > .4 && r < .8 && x*y < 0")
                 .Define("yFig", "y[rInFig]")
                 .Define("xFig", "x[rInFig]")
                 .Histo2D({"fig", "Two quarters of a ring", 64, -1, 1, 64, -1, 1}, "xFig", "yFig");

auto cring = new TCanvas();
ring_h->DrawCopy("Colz");

return 0;
input_line_52:2:2: error: Syntax error
 auto ring_h = d1.Define("rInFig", "r > .4 && r < .8 && x*y < 0")
 ^
FunctionDecl 0x7f72a191d718 <input_line_52:1:1, line:12:1> line:1:6 __cling_Un1Qu323 'void (void *)'
|-ParmVarDecl 0x7f72a191d668 <col:23, col:29> col:29 vpClingValue 'void *'
|-CompoundStmt 0x7f72a1fcfed8 <col:43, line:12:1>
| |-DeclStmt 0x7f72a191df48 <line:2:2, line:5:99>
| | `-VarDecl 0x7f72a191d7f0 <line:2:2, line:5:98> line:2:7 used ring_h 'auto' cinit
| |   `-CallExpr 0x7f72a191df08 <col:16, line:5:98> '<dependent type>'
| |     |-CXXDependentScopeMemberExpr 0x7f72a191dc60 <line:2:16, line:5:19> '<dependent type>' lvalue .Histo2D
| |     | `-CallExpr 0x7f72a191dc28 <line:2:16, line:4:45> '<dependent type>'
| |     |   |-CXXDependentScopeMemberExpr 0x7f72a191db68 <line:2:16, line:4:19> '<dependent type>' lvalue .Define
| |     |   | `-CallExpr 0x7f72a191db30 <line:2:16, line:3:45> '<dependent type>'
| |     |   |   |-CXXDependentScopeMemberExpr 0x7f72a191da70 <line:2:16, line:3:19> '<dependent type>' lvalue .Define
| |     |   |   | `-CallExpr 0x7f72a191da38 <line:2:16, col:65> '<dependent type>'
| |     |   |   |   |-CXXDependentScopeMemberExpr 0x7f72a191d968 <col:16, col:19> '<dependent type>' lvalue .Define
| |     |   |   |   | `-DeclRefExpr 0x7f72a191d920 <col:16> '<dependent type>' lvalue Var 0x7f72a191d858 'd1' '<dependent type>'
| |     |   |   |   |-StringLiteral 0x7f72a191d9c0 <col:26> 'const char [7]' lvalue "rInFig"
| |     |   |   |   `-StringLiteral 0x7f72a191d9f0 <col:36> 'const char [28]' lvalue "r > .4 && r < .8 && x*y < 0"
| |     |   |   |-StringLiteral 0x7f72a191dac8 <line:3:26> 'const char [5]' lvalue "yFig"
| |     |   |   `-StringLiteral 0x7f72a191daf8 <col:34> 'const char [10]' lvalue "y[rInFig]"
| |     |   |-StringLiteral 0x7f72a191dbc0 <line:4:26> 'const char [5]' lvalue "xFig"
| |     |   `-StringLiteral 0x7f72a191dbf0 <col:34> 'const char [10]' lvalue "x[rInFig]"
| |     |-InitListExpr 0x7f72a191de28 <line:5:27, col:81> 'void'
| |     | |-StringLiteral 0x7f72a191dcb8 <col:28> 'const char [4]' lvalue "fig"
| |     | |-StringLiteral 0x7f72a191dce8 <col:35> 'const char [23]' lvalue "Two quarters of a ring"
| |     | |-IntegerLiteral 0x7f72a191dd28 <col:61> 'int' 64
| |     | |-UnaryOperator 0x7f72a191dd68 <col:65, col:66> 'int' prefix '-'
| |     | | `-IntegerLiteral 0x7f72a191dd48 <col:66> 'int' 1
| |     | |-IntegerLiteral 0x7f72a191dd88 <col:69> 'int' 1
| |     | |-IntegerLiteral 0x7f72a191dda8 <col:72> 'int' 64
| |     | |-UnaryOperator 0x7f72a191dde8 <col:76, col:77> 'int' prefix '-'
| |     | | `-IntegerLiteral 0x7f72a191ddc8 <col:77> 'int' 1
| |     | `-IntegerLiteral 0x7f72a191de08 <col:80> 'int' 1
| |     |-StringLiteral 0x7f72a191dea8 <col:84> 'const char [5]' lvalue "xFig"
| |     `-StringLiteral 0x7f72a191ded8 <col:92> 'const char [5]' lvalue "yFig"
| |-DeclStmt 0x7f72a1fcfd60 <line:7:1, col:27>
| | `-VarDecl 0x7f72a191df78 <col:1, col:26> col:6 cring 'class TCanvas *':'class TCanvas *' cinit
| |   `-CXXNewExpr 0x7f72a1fcfc68 <col:14, col:26> 'class TCanvas *' CXXMethod 0x6048ca8 'operator new' 'void *(size_t)'
| |     `-CXXConstructExpr 0x7f72a1fcf958 <col:18, col:26> 'class TCanvas' 'void (Bool_t)'
| |       `-CXXDefaultArgExpr 0x7f72a1fcf938 <<invalid sloc>> 'Bool_t':'_Bool'
| |-CallExpr 0x7f72a1fcfe48 <line:8:1, col:24> '<dependent type>'
| | |-CXXDependentScopeMemberExpr 0x7f72a1fcfdc0 <col:1, col:9> '<dependent type>' lvalue ->DrawCopy
| | | `-DeclRefExpr 0x7f72a1fcfd78 <col:1> 'auto' lvalue Var 0x7f72a191d7f0 'ring_h' 'auto'
| | `-StringLiteral 0x7f72a1fcfe18 <col:18> 'const char [5]' lvalue "Colz"
| |-ReturnStmt 0x7f72a1fcfeb0 <line:10:1, col:8>
| | `-ImplicitCastExpr 0x7f72a1fcfe98 <col:8> 'void' <ToVoid>
| |   `-IntegerLiteral 0x7f72a1fcfe78 <col:8> 'int' 0
| `-NullStmt 0x7f72a1fcfec8 <line:11:1>
`-AnnotateAttr 0x7f72a191d8b8 <<invalid sloc>> R"ATTRDUMP(__ResolveAtRuntime)ATTRDUMP"
<<<NULL>>>

Draw all canvases

In [5]:
gROOT->GetListOfCanvases()->Draw()