Reading tree into python leaf by leaf

Hello All

Fairly new to ROOT
I want to be able to read individual leaves from a ROOT file so that I can work on the data myself in Python.

The ROOT file is organised as:
tree is called cbmsim
that contains three branches, the one of interest is called MCTrack
MCTrack contains lots of leaves, but I am interested in the one called MCTrack.fPdgCode for now.

ROOT file: https://drive.google.com/file/d/1KMMOgZhx-wILtaAZoFf6EGf1osVZxyaZ/view?usp=sharing

I currently have a script

import ROOT
f =ROOT.TFile.Open("DEC_12pythia8_Geant4_1_0.5_ID_0.root");
for event in f.cbmsim:
	for track in event.MCTrack:
		#here I want to say... if MCTrack.fPdgCode == 13 -> do other stuff
        #I want to save the values in leaves to python variable

How can I within these loops save the value stored in each leaf to a python variable so that I can play with it.

I have tried things like:

if track.fPdgCode == 13:
    do_other_stuff()

but get errors like,

Traceback (most recent call last):
  File "root_test.py", line 10, in <module>
    if track.fPdgCode == 13:
AttributeError: 'TObject' object has no attribute 'fPdgCode'

It may add to the complication that the leaves I refer to in the file are actually TBranchElements or that the objects are called MCTrack.fPdgCode not just fPdgCode.

Any ideas?

Thanks a lot

When I open the file, ROOT complains about missing dictionaries. You could try loading the library with them beforehand using

ROOT.gSystem.Load(‘libraryname.so’)

It seems the leaf names are confusing to PyROOT. You can access the field by doing so:

import ROOT
f = ROOT.TFile.Open("DEC_12pythia8_Geant4_1_0.5_ID_0.root");
print(f.cbmsim.__getattr__('MCTrack.fPdgCode'))

Your loop then becomes

for events in f.cbmsim:
    for e in events:
        do_stuff(e.__getattr__('MCTrack.fPdgCode'))

PyRoot normally handles this for you, but when the branch name contains a period (’.’), python get confused. A look up of x.y.z normally resolves to ‘find attribute z on y; which in turn is an attribute on x’. To get the, in this case correct, lookup of ‘find attribute y.z on x’ we need to use the __getattr__ function.

Cheers,
Kim

Hi thanks so much for help! Definitely getting closer!

When you say ‘do_stuff’ how would I print the value of the object, for example.

I tried

for events in f.cbmsim:
    for e in events:
        value = (e.__getattr__('MCTrack.fPdgCode'))
        print(value)

but this just prints information on the object itself not the value:
<ROOT.ShipMCTrack object at 0x102252bb0>
(and actually every time it prints the same memory address 0x102252bb0 - potentially worrying)

I tried

for events in f.cbmsim:
    for e in events:
        e.__getattr__('MCTrack.fPdgCode').PrintValue()

but get AttributeError: ‘ShipMCTrack’ object has no attribute ‘PrintValue’

I don’t know anything about dictionaries but this is where I am worried problem may be related to, on opening the root file getting this… TClass::Init:0: RuntimeWarning: no dictionary for class ShipMCTrack is available

Thanks a lot

I think you have to get the class definition for ShipMCTrack from somewhere or someone and load this into ROOT. Then you can do print(dir(e.__getattr__('MCTrack.fPdgCode').PrintValue())) to see what methods are available on the object.

Cheers,
Kim

Ok cheers, ill look into this, thanks a lot for your help!

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