I first posted my question to a wrong egroup (roottalk@cern.ch), then I wrote my question to stackover with a followup solution. I am directed to write by the roottalk forum to get a better feedback. Therefore, please let me know if there exist a better solution to my issue.
Thanks,
Sadia
Please provide the following information:
ROOT Version: 6.06/08:
Platform: OS 10.11.6
compiler:
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
The issue in your initial code is that you are trying to access the traj branch on the TTree, and instead you should do it on the event.
This code should also work:
f = TFile.Open('../Ntuples/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root')
t = f.trajTree
for iev in t:
print(iev.traj.norm_charge)
from ROOT import TFile, TTree
f = TFile.Open(‘…/Ntuple/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root’)
t = f.trajTree
for iev in t: print(iev.traj.norm_charge)
…
Traceback (most recent call last):
File “<stdin>”, line 1, in
AttributeError: ‘TTree’ object has no attribute ‘traj’
>>> print (t.GetBranch('traj').GetName())
traj
>>> for iev in t: print (t.GetBranch('traj').norm_charge)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TBranch' object has no attribute 'norm_charge'
If you find the branch with t.GetBranch but you cannot access it with iev.traj then this might be a bug. I would like to check what is especial about that branch, since I understand you can access other branches with the iev.mybranch syntax.
Would it be possible for you to share the ntuple file you are using?
ie: you have some hardcoded array sizes that are actually names of leaves, e.g.federrs_size of the federrs leaf from the event branch in the trajTree.
IIRC (but I may be mistaken here) PyROOT will do something like my Go tools (or rather, my Go tools do something along the lines of what PyROOT did at some point) which boils down to:
>>> import ROOT
>>> f = ROOT.TFile.Open("Ntuple_75.root")
>>> t = f.trajTree
>>> t.GetEntry(0)
716
>>> t.traj
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TTree' object has no attribute 'traj'
>>> t.GetBranch("traj")
<ROOT.TBranch object ("traj") at 0x55ad77cfab20>
>>> t.GetBranch("federrs_size")
<ROOT.TBranch object at 0x(nil)>
most probably, federrs_size (or size) is queried against the TTree to get the actual branch count but as it is stored as a leaf, PyROOT might assume it’s an error which is then converted into an AttributeError.
This all works fine, just not in a way that is natural to python:
import ROOT
f = ROOT.TFile.Open("Ntuple_75.root")
t = f.trajTree
for x in t:
print('traj.glx: ', getattr(x, 'traj/glx'))
print('clust.glx:', getattr(x, 'clust/glx'))
And yeah, for sure that could be automated to something cleaner, e.g. by having TTreeGetAttr return a TBranch when appropriate and having a TBranchGetAttr extracting the value of the leaf. I just never got around to do that, but there are no technical limitations per se.
This is great, thanks a lot to all of you for looking into the problem. I have definitely learned a lot.
f = TFile.Open("Ntuple_75.root")
t = f.Get("trajTree")
for iev in xrange(t.GetEntries()):
t.GetEntry(iev)
normCharge = getattr(t, 'traj/norm_charge')
print (normCharge)
branch.leaf indeed feels more natural, as @wlav pointed out we are just missing an extra hook that allows that syntax. I’m adding it to the list of new pythonizations we would like to have for PyROOT.