How to access single array instance with TDataFrame

Dear experts,

I’m trying to read a TTree through the new TDataFrame interface (using the ROOT prompt).
The basic functionality are working but I’ve not been able to plot only a specific entry from an array stored inside a Branch.
I’m assuming the syntax is the same as in TTree::Draw (i.e. “myarray[0]” to access the first entry, etc…) but it’s not working neither with TDataFrame::Histo1D nor TDataFrame::Fill.
The error I get in both case is:

ROOT::Experimental::TDataFrame df(“eb”, “history_EB_Run2016_v2.root”)
auto h = df.Histo1D(“lc[0]”)

Error in TRint::HandleTermInput(): std::runtime_error caught: Column “lc[0]” is not in a file and has not been defined.

Of course TTree::Draw(“lc[0]”) works properly on the same tree.

I also tried to Define a new column as:
df.Define(“lc_0”,(float lc[2]){return lc[0];},{“lc”})

but plotting “lc_0” resulted in a crash.

What should I do to read the array entry?

Thank you,

Simone

PS: I’m running ROOT 6.10/02 compiled with gcc 7.1.1

Hi Simone,

the argument of the Histo1D method you are invoking is the name of the column: no accessors are accepted there.
The way in which you can obtain the first element of the array is “functional”: a new, different column needs to be created and then plotted.
For example:

auto h = tdf.Define("lc_0", [](std::array_view<int> lc){return lc[0]}, {"lc"}).Histo1D("lc_0");
h->Draw();

We are aware of the burden the definition the full blown lambda imposes to users :sweat_smile:. This is the reason why starting from ROOT 6.12 (expected in November) the line above could be squeezed into this one:

auto h = tdf.Define("lc_0", "lc[0]").Histo1D("lc_0");
h->Draw();

The technical reason behind this is that one needs to be able to detect that lc is an array and not a simple pointer. By the way, if you like bleeding edge stuff, the functionality is available in the ROOT master already.

Cheers,
D

1 Like

Hi Danilo,

thank you for the prompt reply.

simone

Hi Danilo,

I installed ROOT from the master branch and both your solutions works.
Anyway I found a strange behaviour of the Define command:

dft.Define("newvar", "expr").Histo1D("newvar") 

works, but the splitting the Define call and the Histo1D call in two subsequent commands does not, the error is:

Error in <TRint::HandleTermInput()>: std::runtime_error caught: Unknown column: newvar

Furthermore trying to call again the Define(…).Histo1D(…) with same variable also gives an error:

Error in <TRint::HandleTermInput()>: std::runtime_error caught: Redefinition of column "newvar"

which makes sense but also means that it’s impossible to draw two histograms with the same new column as variable.

I understand that this is work in progress so I thank you in advance for any further help.

simone

PS: since the issue is unrelated to the single array instance access (the error appears also with simpler definitions) should I open a new topic?

Hi Simone,

I am not sure I get the problem correctly, but it’s not true that you cannot draw multiple hisos hanging from the same Define: it’s an objective by design! :slight_smile:

The TDataFrame is not a chain but rather a graph of nodes.

So the computation setup would be like this:

[...]
auto dft_d = dft.Define("newvar", "expr");
auto h1 = dft_d.Histo1D("newvar");
// inventing an hypothetical weight column
auto h1 = dft_d.Histo1D("newvar","newvarweight");
// new we hang an hypothetical filter to the Define node and a histo to it
auto dft_df = dft_d.Filter("newvar > 2");
auto h3 = dft_df.Histo1D("newvar");

Cheers,
D

PS
TDF is rather sturdy and not work in progress. The Experimental namespace signal that (minimal) interface changes might occour. It’s a bit like std::experimental :slight_smile:

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