How to get value of RResultPtr outside a loop?


ROOT Version:_ 6.24/02
Platform:Linux/Fedora 34
Compiler:
gcc version 11.3.1 20220421


I have the following lines in my code. I want to access the elements of vectorPtr outside the for loop.

  ROOT::RDataFrame df(treename, filename);
  std::vector<ROOT::RDF::RResultPtr<TH1D>> histos;
  for (const std::string &col : df.GetColumnNames()) {
    auto h = df.Filter(isPositive, {col}).Histo1D(TH1D(col.c_str(),col.c_str(),8192.,0,8192),col.c_str());
    histos.push_back(h);
    auto vectorPtr = df.Take<double>(col);
  }

How can I access the elements of vectorPtr outside the for loop? I need those for further analysis. I tried to define vectorPtr before/outside the for loop as:

std::vector<ROOT::RDF::RResultPtr<double>> vectorPtr;

and inside the for loop:

vectorPtr = df.Take<double>(col);

which gives the the following error:

/./GetValue.cxx:39:15: error: no viable overloaded '='
    vectorPtr = df.Take<double>(col);
    ~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~

Please note that I don’t want to trigger event loop at this stage.

Hi,

Yes, that’s expected. The method RDataFrame::Take is indeed templated with the type of the return collection. By default, that is a std::vector. Therefore, the code would look like this:

  // Define a dummy RDF for this example
  ROOT::RDataFrame df(8);
  auto df2cols = df.Define("a",[](){return 1;}).Define("b",[](){return 2;});
  using vint = std::vector<int>;
  std::vector<ROOT::RDF::RResultPtr<vint>> contents;

  for (const auto &col : df2cols.GetColumnNames()) {
    contents.emplace_back(df2cols.Take<int>(col));
  }

  // Just print the content
  for (auto i : ROOT::TSeqI(8)) {
    std::cout << contents[0]->at(i) << " " << contents[1]->at(i) << std::endl;
  }

I hope this helps.

Cheers,
D

1 Like

Dear @Danilo,
New year’s greetings! Thank you for the solution.

I have one more question, the answer to that will lead me to the
completion of my first data analysis code using RDataFrame.

I have a ROOT Tree which contains, say 3 branches: x, y, z.
x & y are variable size arrays of type ULong64_t and
z is a simple variable of type Int_t.

I want to generate the following two types of histograms.

  1. If the value of z is greater than 1 then I want to find the difference
    (which can be positive or negative) between elements of y.
    And if the absolute difference is say, between 50 and 100, then I want to generate
    2-dimentional histogram of the corresponding elements of x.

  2. Also, if the value of z is greater than 1 then for given values of elements of x
    (say “eX1” and “eX2”, which the user can pass as arguments to the code);
    I want to find the difference (which can be positive or negative) between corresponding
    elements of y. In this case, I want to generate 1-dimentional histogram of the difference.

These two tasks will require two different codes.
How can this be achieved? Can you suggest me recipes?

Best regards,

Ajay

Hi Ajay,

You can easily achieve all this with Defines (that we have already used in this thread), Filters, Histo1D and Histo2D.
Pre-packed examples can be found in the DataFrame tutorials. For a good start you can have a look to this one.

Cheers,
D

Dear @Danilo,

As suggested by you, I worked on the 1. above to generate a 2D histogram.
However, there is a problem with multithreading as mentioned in my new post.

For your reference, I am attaching a sample ROOT file here and the code is
attached (2.4 KB).

I am running the code at the ROOT prompt as: .x rdf_his2D.cxx+

Any help is highly appreciated.

Regards,

Ajay

Dear @Danilo,

As suggested by you, I worked on the 1. above to generate a 2D histogram.
However, there is a problem with multithreading as mentioned in my new post.

For your reference, I am attaching a sample ROOT file here and the code (2.4 KB).

I am running the code at the ROOT prompt as: .x rdf_his2D.cxx+

Any help is highly appreciated.

Regards,

Ajay

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.