Df 0 1 2_ Defines And Filters As Strings

Use just-in-time-compiled Filters and Defines for quick prototyping.

This tutorial illustrates how to save some typing when using RDataFrame by invoking functions that perform jit-compiling at runtime.

Author: Guilherme Amadio (CERN)
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Thursday, June 24, 2021 at 07:13 AM.

We will inefficiently calculate an approximation of pi by generating some data and doing very simple filtering and analysis on it

We start by creating an empty dataframe where we will insert 10 million random points in a square of side 2.0 (that is, with an inscribed circle of radius 1.0)

In [1]:
size_t npoints = 10000000;
ROOT::RDataFrame df(npoints);

Define what we want inside the dataframe. we do not need to define p as an array, but we do it here to demonstrate how to use jitting with RDataFrame

Note: although it's possible to use "for (auto&& x : p)" below, it will shadow the name of the data column "x", and may cause compilation failures if the local variable and the data column are of different types or the local x variable is declared in the global scope of the lambda function

In [2]:
auto pidf = df.Define("x", "gRandom->Uniform(-1.0, 1.0)")
              .Define("y", "gRandom->Uniform(-1.0, 1.0)")
              .Define("p", "std::array<double, 2> v{x, y}; return v;")
              .Define("r", "double r2 = 0.0; for (auto&& x : p) r2 += x*x; return sqrt(r2);");

Now we have a dataframe with columns x, y, p (which is a point based on x and y), and the radius r = sqrt(xx + yy). In order to approximate pi, we need to know how many of our data points fall inside the unit circle compared with the total number of points. The ratio of the areas is

 A_circle / A_square = pi r*r / l * l, where r = 1.0, and l = 2.0

Therefore, we can approximate pi with 4 times the number of points inside the unit circle over the total number of points in our dataframe:

In [3]:
auto incircle = *(pidf.Filter("r <= 1.0").Count());

double pi_approx = 4.0 * incircle / npoints;

std::cout << "pi is approximately equal to " << pi_approx << std::endl;
pi is approximately equal to 3.14146