Reading a TTree branch using PyROOT

5.1k Views Asked by At

I like to read the content of a branch in TTree using PyROOT. I look for a possible solution to my problem here: Reading a TTree in root using PyRoot. However, the answer doesn't help me, because probabaly PyROOT doesn't know the structure of a branch. Please see the bottom output snippet, and suggest a solution.

Thanks, Sadia

>>> import ROOT
>>> 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()
    ******************************************************************************
    *Tree    :trajTree  : Trajectory measurements in the Pixel detector.         *
    *Entries : 42180482 : Total =     31858466801 bytes  File  Size = 8076610485 *
    *        :          : Tree compression factor =   3.94                              *
    ******************************************************************************
    *............................................................................*
    *Br    5 :clust_pix : pix[size][2]/F                                         *
    *Entries : 42180482 : Total  Size= 1597865089 bytes  File Size  =  569202378 *
    *Baskets :    12058 : Basket Size=    2175488 bytes  Compression=   2.81     *
    *............................................................................*
    *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     *
    *............................................................................*

>>> t.clust_pix
<read-write buffer ptr 0x7fba04428200, size 514 at 0x115e5ecf0>

>>> t.traj
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TTree' object has no attribute 'traj'

>>> t.traj.beta
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TTree' object has no attribute 'traj'
1

There are 1 best solutions below

2
On

Self answering with a help of a colleague: I define the structure of the branch and then set its address.

The structure data file is structDef.py

from ROOT import gROOT, AddressOf
gROOT.ProcessLine(
"struct Traj {\
  Int_t           validhit;\
  Float_t         missing;\
  Float_t         lx;\
  Float_t         ly;\
  Float_t         lz;\
  Float_t         glx;\
  Float_t         gly;\
  Float_t         glz;\
  Int_t           clust_near;\
  Float_t         hit_near;\
  Float_t         pass_effcuts;\
  Float_t         alpha;\
  Float_t         beta;\
  Float_t         norm_charge;\
  Float_t         d_tr;\
  Float_t         dx_tr;\
  Float_t         dy_tr;\
  Float_t         d_cl;\
  Float_t         dx_cl;\
  Float_t         dy_cl;\
  Float_t         dx_hit;\
  Float_t         dy_hit;\
  Int_t           onedge;\
  Float_t         lx_err;\
  Float_t         ly_err;\
  };"
); 

Then in my main code, I set the branch address.

#!/usr/bin/env python
from ROOT import TFile, TTree
import structDef
from ROOT import Traj
traj = Traj()

f = TFile.Open('../Ntuples/v0406_default_1012p2_101X_dataRun2_Express_v7_Fill6573_Ntuple.root')
t1 = f.Get("trajTree")
t1.SetBranchAddress("traj", structDef.AddressOf(traj, 'validhit'))

for iev in xrange(t1.GetEntries()):
    t1.GetEntry(iev)
    print traj.norm_charge 

If any one has a better solution, then I really appreciate your help as I do see warnings, despite that it works for me.

input_line_20:2:9: error: redefinition of 'Traj'
 struct Traj {      Int_t           validhit;      Float_t         missing;      Float_t         lx;      Float_t         ly;      Float_t         lz;      Float_t         glx;      Float_...
    ^
input_line_19:2:9: note: previous definition is here
 struct Traj {      Int_t           validhit;      Float_t         missing;      Float_t         lx;      Float_t         ly;      Float_t         lz;      Float_t         glx;      Float_...
    ^
17.0971317291

I like python, but this additional layer makes my macro complicated. Moreover, I like to take tips as how to loop over all entries in a tree in python efficiently just like in C++. May be its more a question of ROOT vs PyROOT. Currently, my macro takes double the time, if something is written in C++.