In first approximation, and especially for your current usecase, you can think of a TTree
as a table.
Branches are columns of the table, entries are rows.
When creating/writing a TTree
, every call to TTree::Branch
will create a new column, and every call to TTree::Fill
will add a new row. The values that are used to fill each column for each row are read from the addresses that are associated to the columns by the TTree::Branch
call.
For example:
float value = 0.f;
tree->Branch("value", &value);
tree->Fill();
value = 8.f;
tree->Fill();
creates a column with name "value"
which will have two rows, one with value 0 and one with value 8.
That’s why RDataFrame’s Take
returns a vector: typically you have more than one value per branch. If you have only one value, you can retrieve it as the first and only element of the vector.
As to why the values that you read back are wrong, I don’t know, there is a problem somewhere in your code. Maybe it’s the extra "Value/F"
argument to TTree::Branch
that makes it trickier to retrieve the correct values later.
Here is a working snippet that creates a TTree called "file_info"
in a file "f.root"
, writes one entry of branch "RUNID"
and then reads it back with raw TTree
, TTreeReader
and RDataFrame
.
#include <TTree.h>
#include <TFile.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <ROOT/RDataFrame.hxx>
#include <vector>
#include <cassert>
void write_tree()
{
TFile f("f.root", "recreate");
TTree t("file_info", "file_info");
float value = 42.f;
t.Branch("RUNID", &value);
t.Fill();
f.Write();
f.Close();
}
float read_value_with_tree()
{
TFile f("f.root");
TTree *t = nullptr;
f.GetObject("file_info", t);
float value;
t->SetBranchAddress("RUNID", &value);
t->GetEntry(0);
return value;
}
float read_value_with_treereader()
{
TFile f("f.root");
TTreeReader r("file_info", &f);
TTreeReaderValue<float> v(r, "RUNID");
r.SetEntry(0); // should check ret value to be sure reading succeded
return *v;
}
float read_value_with_rdf()
{
ROOT::RDataFrame df("file_info", "f.root");
const std::vector<float> all_v = df.Take<float>("RUNID").GetValue();
return all_v[0];
}
int main()
{
write_tree();
assert(read_value_with_tree() == 42.f);
assert(read_value_with_treereader() == 42.f);
assert(read_value_with_rdf() == 42.f);
return 0;
}