Write with uproot, read with c++ size-agnostic

Hi,

I’d like to write a tree with uproot like this:

# write.py
# use uproot
import uproot
import numpy as np

root_file = uproot.recreate("testfile.root")
branch = { "br1":np.arange(10).reshape(-1,10),
           "br2":np.arange(10,20).reshape(-1,10) }
root_file["tree"] = branch

which I can easily read with pyroot like this:

# read1.py
# use PyROOT
import ROOT

f = ROOT.TFile.Open("testfile.root")
tree = f.tree
for entry in tree:
    for x,y in zip(entry.br1,entry.br2):
        print(x,y)

but if I use the C++ version, I need to specify the size of the array or of the STL vector

// read3.C
// use C++
void read3()
{
  TFile* f = TFile::Open("testfile.root","READ");
  TTree* t = (TTree*) f->Get("tree");

  vector<Long64_t> v1; // <-- I need to know that it's "10"
                       // vector<Long64_t> v1(10)
  vector<Long64_t> v2; 

  t->SetBranchAddress("br1", v1.data());
  t->SetBranchAddress("br2", v2.data());
  
  Long64_t nentries = t->GetEntriesFast();
  for( Long64_t entry=0; entry<nentries; ++entry)
    {
      t->GetEntry(entry);
      for(auto& i: v1) cout<<i<<endl;
      for(auto& i: v2) cout<<i<<endl;
      cout<<" size of v1: "<<v1.size()<<endl;
    }
}

Is there a way to declare a “size agnostic” leaf?

Thank you in advance for your help.

Uproot writes static length arrays and typically ROOT “assumes” that you know how long they are and you declare variables that you want to read those arrays into as e.g. Long64_t myarr[10].

I am not sure how to declare a “size-agnostic leaf”, but you can just ask what the static size is to the tree itself:

vector<Lont64_t> v1(t->GetLeaf("br1")->GetLenStatic());

and the vector will have the appropriate size.

Alternatively you can use RDataFrame instead of TTree to read (and also write, potentially) this data so you don’t have to deal with these details at all.

I hope this helps!
Enrico

Great! Thanks!

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