Pyroot: Access leaf of file written with splitlevel=1

Hi everyone,

I am currently trying to read a ROOT file where several branches were added to a top branch saved with a splitlevel=1 to the tree data as follows:

fdata = new TTree("data", "data Tree");
fTopBranch = new TList();

fMCInfo = new MCInfo;
fMCInfo->SetName("MC");
fTopBranch->Add(fMCInfo);

fdata->Branch(fTopBranch, fBufsize, 1)

There are some information stored in the MC branch () that I am trying to access with pyroot (not just to do histograms) but I don’t manage to do so.
I am however able to access them with c++ just fine with the following code:

TFile *file = new TFile(fname.c_str())
TTree *data = (TTree*)file->Get("data");

TBranch * McinfoBranch;
MCInfo* mcinfo = (MCInfo*)file->GetList()->FindObject("MC");
data->SetBranchAddress("MC", &mcinfo, &McinfoBranch);
double value = 0;
for(int i = 0; i < data->GetEntries(); i++){
    data->GetEntry(i);
    value = mcinfo->energy;
}

However, when I am doing something similar in python, or try a more regular approach, I end up not being able to access the energy for instance:

from ROOT import gROOT, addressof
import StructROOTfiles //Containing the structure of the MC branch
mc= ROOT.MC()

inFileName = "myfile.root"
infile = ROOT.TFile(inFileName)
data = infile.Get("data")
data.SetBranchStatus("*",0)
entries = data.GetEntries()
data.SetBranchStatus("MC",1)
data.SetBranchAddress("MC", cast['void*'](StructROOTfiles.addressof(mc, 'energy')))

for i in range(entries):
    data.GetEntry(i)
    print (mc.energy)

I get only zeroes out of this for all leaves (energy, vertex, …). Would you have an idea why?

The other approach I first tried was simply:

infile = ROOT.TFile(inFileName)

data = infile.Get("data")

nentries = data.GetEntries()

for i in range(nentries):
    data.GetEntry(i)
    ***option 1 ***
    energy = data.energy.GetValue()
    ***option 2 ***
   data.GetLeaf("energy").GetValue(0)

Option 1 gives me “‘TTree’ object has no attribute ‘energy’” while it is there and in pyroot I can access it with data.Scan(“energy”) for example so I don’t know why this is not working the same way…
Option 2 gives me “attempt to access a null-pointer”

The infile.ls is giving this:

  TFile**		/path/myrootfile.root	Root File
  TFile*		/path/myrootfile.root 	Root File
  KEY: TTree	data;1	        Root data Tree
  KEY: TTree	Secdata;1	Root Secondaries data Tree
  KEY: TTree	SKdata;1         SK data Tree

while data.GetBranch(“MC”).Print() is giving ne this:

*Br    2 :MC        : MCInfo                                                 *
*Entries :       10 : Total  Size=      78114 bytes  File Size  =       1398 *
*Baskets :        1 : Basket Size=    8388608 bytes  Compression=  55.53     *
*............................................................................*

If anyone has an idea on how to go around this and be able to extract the values of the root file in pyroot for splitlevel=1, that would be great!

Hi @Alheana ,

about option 1, the correct spelling would be something like:

for event in data:
   print(event.MC.energy)

This is a very slow way to loop over a tree in PyROOT, but it should work. You can do it in several steps, checking that event.MC works correctly at first, then trying to access the contents of the MC object.

For option 2 I’m not sure what cast['void*'](StructROOTfiles.addressof(mc, 'energy')) does. In principle what you want to pass there is the address of a C++ object of the appropriate type.

Depending on what you need to do exactly, option 3 could be using RDataFrame. I haven’t tried this code (I don’t have the input file) but this should give you an idea:

import ROOT

df = ROOT.RDataFrame("data", "/path/myrootfile.root")
df.Define("energy", "MC.energy").Display(["energy"]).Print()

I hope this helps!
Enrico

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