Reading a TTree branch using PyROOT

Dear all,

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


I guess @pcanal and @etejedor can help you.

Hi Sadia,

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)

@etejedor : Nope, this gives the same error:

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’

Hi,

does the tree have a column called traj ?

Cheers,
Danilo

@Danilo: It is a branch.

Thanks,
Sadia

f = ROOT.TFile("../Ntuple/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root")
f.ls()
TFile**        ../Ntuples/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root
TFile*        ../Ntuples/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root
KEY: TTree    trajTree;1    Trajectory measurements in the Pixel detector.
KEY: TTree    eventTree;1    The event.
KEY: TTree    clustTree;1    Pixel clusters.
KEY: TTree    trajROCEfficiencyTree;1    ROC and module efficiencies.
>>> t = f.Get("trajTree")
>>> t.Print()
*............................................................................*
*Br    7 :traj      : validhit/I:missing:lx/F:ly:lz:glx:gly:glz:clust_near/I:*
*         | hit_near:pass_effcuts:alpha/F:beta:norm_charge:d_tr:dx_tr:dy_tr: *
*         | d_cl:dx_cl:dy_cl:dx_hit:dy_hit:onedge/I:lx_err/F:ly_err/F        *
*Entries : 42180482 : Total  Size= 4220749516 bytes  File Size  = 2508894561 *
*Baskets :    28411 : Basket Size=    2275840 bytes  Compression=   1.68     *
*............................................................................*

Hi Sadia,

What happens if you do:
print(t.GetBranch('traj').GetName())

Cheers,
Enric

Hi Enric,

This is what I get:

>>> 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'

Regards,
Sadia

Hi Sadia,

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?

Thank you,
Enric

Hi Enric,

Here is a small sample: https://www.dropbox.com/s/4fjopksw0rna8ww/Ntuple_75.root?dl=0

Once you download, then I like to delete it as it is still taking a lot of my space on dropbox.

I got in touch with uproot authors, and they also looked at the file. Their proposal for PyROOT is to directly call the leaf names.

for x in t:
    print x.glx     # instead of x.traj (glx is a leaf in traj)

However, then I am not sure if this branch belongs to branch clust or traj.

Thanks,
Sadia

1 Like

I doubt PyROOT can automatically make completely (and reliably) sense of the overall structure of your file.

see (with my Go-based tools):

$> root-dump Ntuple_75.root 
>>> file[Ntuple_75.root]
key[000]: trajTree;11 "Trajectory measurements in the Pixel detector." (TTree)
root-dump: error dumping file "/home/binet/Downloads/Ntuple_75.root": error dumping key "trajTree": rootio: Tree "trajTree" has no (count) branch named "federrs_size"

hum…

$> root-ls -t Ntuple_75.root 
=== [Ntuple_75.root] ===
version: 61009
TTree       trajTree                                                                                                                                                                                                                                                                                                            Trajectory measurements in the Pixel detector. (entries=1767676)
  event     "fill/I:run:ls:orb:bx:evt:nvtx:trig:nclu[7]:npix[7]:time/i:pileup/F:vtxndof:vtxchi2:vtxD0:vtxX:vtxY:vtxZ:vtxntrk/I:good:tmuon/F:tmuon_err:tecal:tecal_raw:tecal_err:field:wbc/I:delay:ntracks:ntrackFPix[3]:ntrackBPix[4]:ntrackFPixvalid[3]:ntrackBPixvalid[4]:trackSep/F:federrs_size/I:federrs[federrs_size][2]" TBranch
  mod_on    "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  mod       "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  clust     "x/F:y:lx:ly:glx:gly:glz:sizeX/I:sizeY:i:edge:badpix:tworoc:size:charge/F"                                                                                                                                                                                                                                          TBranch
  clust_adc "adc[size]/F"                                                                                                                                                                                                                                                                                                       TBranch
  clust_pix "pix[size][2]/F"                                                                                                                                                                                                                                                                                                    TBranch
  track     "pt/F:eta:phi:theta:p:d0:dz:fromVtxNtrk/I:strip:quality:i:pix:pixhit[2]:validpixhit[2]:fpix[3]:bpix[4]:validfpix[3]:validbpix[4]"                                                                                                                                                                                   TBranch
  traj      "validhit/I:missing:lx/F:ly:lz:glx:gly:glz:clust_near/I:hit_near:pass_effcuts:alpha/F:beta:norm_charge:d_tr:dx_tr:dy_tr:d_cl:dx_cl:dy_cl:dx_hit:dy_hit:onedge/I:lx_err/F:ly_err/F"                                                                                                                                  TBranch
TTree       trajTree                                                                                                                                                                                                                                                                                                            Trajectory measurements in the Pixel detector. (entries=1746040)
  event     "fill/I:run:ls:orb:bx:evt:nvtx:trig:nclu[7]:npix[7]:time/i:pileup/F:vtxndof:vtxchi2:vtxD0:vtxX:vtxY:vtxZ:vtxntrk/I:good:tmuon/F:tmuon_err:tecal:tecal_raw:tecal_err:field:wbc/I:delay:ntracks:ntrackFPix[3]:ntrackBPix[4]:ntrackFPixvalid[3]:ntrackBPixvalid[4]:trackSep/F:federrs_size/I:federrs[federrs_size][2]" TBranch
  mod_on    "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  mod       "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  clust     "x/F:y:lx:ly:glx:gly:glz:sizeX/I:sizeY:i:edge:badpix:tworoc:size:charge/F"                                                                                                                                                                                                                                          TBranch
  clust_adc "adc[size]/F"                                                                                                                                                                                                                                                                                                       TBranch
  clust_pix "pix[size][2]/F"                                                                                                                                                                                                                                                                                                    TBranch
  track     "pt/F:eta:phi:theta:p:d0:dz:fromVtxNtrk/I:strip:quality:i:pix:pixhit[2]:validpixhit[2]:fpix[3]:bpix[4]:validfpix[3]:validbpix[4]"                                                                                                                                                                                   TBranch
  traj      "validhit/I:missing:lx/F:ly:lz:glx:gly:glz:clust_near/I:hit_near:pass_effcuts:alpha/F:beta:norm_charge:d_tr:dx_tr:dy_tr:d_cl:dx_cl:dy_cl:dx_hit:dy_hit:onedge/I:lx_err/F:ly_err/F"                                                                                                                                  TBranch
TTree   eventTree                                                                                                                                                                                                                                                                                                           The event. (entries=367)
  event "fill/I:run:ls:orb:bx:evt:nvtx:trig:nclu[7]:npix[7]:time/i:pileup/F:vtxndof:vtxchi2:vtxD0:vtxX:vtxY:vtxZ:vtxntrk/I:good:tmuon/F:tmuon_err:tecal:tecal_raw:tecal_err:field:wbc/I:delay:ntracks:ntrackFPix[3]:ntrackBPix[4]:ntrackFPixvalid[3]:ntrackBPixvalid[4]:trackSep/F:federrs_size/I:federrs[federrs_size][2]" TBranch
TTree       clustTree                                                                                                                                                                                                                                                                                                           Pixel clusters. (entries=34573)
  event     "fill/I:run:ls:orb:bx:evt:nvtx:trig:nclu[7]:npix[7]:time/i:pileup/F:vtxndof:vtxchi2:vtxD0:vtxX:vtxY:vtxZ:vtxntrk/I:good:tmuon/F:tmuon_err:tecal:tecal_raw:tecal_err:field:wbc/I:delay:ntracks:ntrackFPix[3]:ntrackBPix[4]:ntrackFPixvalid[3]:ntrackBPixvalid[4]:trackSep/F:federrs_size/I:federrs[federrs_size][2]" TBranch
  mod_on    "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  mod       "det/I:shl:side:module:layer:sec:ladder:flipped:half:disk:blade:panel:ring:federr:rawid/i:fedid:channel:roc:module_coord/F:ladder_coord:disk_coord:disk_ring_coord:blade_panel_coord"                                                                                                                               TBranch
  clust     "x/F:y:lx:ly:glx:gly:glz:sizeX/I:sizeY:i:edge:badpix:tworoc:size:charge/F"                                                                                                                                                                                                                                          TBranch
  clust_adc "adc[size]/F"                                                                                                                                                                                                                                                                                                       TBranch
  clust_pix "pix[size][2]/F"                                                                                                                                                                                                                                                                                                    TBranch
TTree               trajROCEfficiencyTree                                       ROC and module efficiencies. (entries=0)
  trajROCEfficiency "ROCEfficiency/F:halfModuleEfficiency/F:moduleEfficiency/F" TBranch

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.

1 Like

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)

When extracting a histogram from TTree.Draw as

t.Draw( "traj/norm_charge >> hcharge", "traj/norm_charge > 0")

the “/” sign in “traj/norm_charge” was taken as mathematical operator for division, which I corrected as,

t.Draw( "traj.norm_charge >> hcharge", "traj.norm_charge > 0")

Therefore, it was very normal for me to thinking to extract a leaf of a branch as branch.leaf.

Best,
Sadia

1 Like

Hi @skhalil,

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.

Cheers,
Enric

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