Read array from TChain

Hi,

sorry if this is already answered somewhere but I couldn’t find it.

I have been following some of the posts in here to figure out how to read a TTree using pyroot since I just want to loop over all events really quickly to find a number. I have to read a branch which is a Foat_t[1], as it is declared when I make a MakeClass of the TTree. This is what I am doing:

from ROOT import *
import sys,glob

gROOT.ProcessLine(
        "struct var_t{\
        Float_t we[1];\
        }")

files = ["file1.root","file2.root"]
chain = TChain("Delphes")
for file in files:
    print "Adding file: "+file
    chain.Add(file)
entries = chain.GetEntries()
print "Number of events: "+str(entries)
var = var_t()
chain.SetBranchStatus("*",0)
chain.SetBranchStatus("Event.Weight",1)
chain.SetBranchAddress("Event.Weight",AddressOf(var,"we"))
wei = 0
for i in range(entries):
    chain.GetEntry(i)
    print "Weight: "+str(var.we[1])
    wei = wei + var.we[1]
print "Number of weigihted events: "+str(wei)

Although it seems to work in the sense that it does not crash, it doesn’t really work since all I get is the same silly number fo all events, something like 1.6*10^-13, so, the value I am reading is not the one it is suppose to load. How should I read that branch? In C++ I just do Event_Weight[0] but I am not sure that this is how this is supposed to be done in pyROOT.

Thanks a lot in advance!
Juanpe.

You’re trying to retrieve parts of a decomposed object (which was written with splitlevel >= 1).
I’d say this kind of games is reserved for “advanced users” only, so you’re asking for trouble.
You’ better have a look at an “analysis skeleton”: Header files for Trees

from ROOT import *
import sys, glob

gROOT.ProcessLine(
        "struct var_t {\
        Int_t Event_;\
        Float_t Weight[1];\
        };")

files = ["/afs/cern.ch/user/s/shilpi/public/B-4p-0-1-v1510_14TEV_50PileUp_101175088.root"]
# files = ["file1.root", "file2.root"]
chain = TChain("Delphes")
for file in files:
    print "Adding file: " + file
    chain.Add(file)
chain.SetMakeClass(1)
chain.SetBranchStatus("*", 0)

entries = chain.GetEntries()
print "Number of entries = " + str(entries)

var = var_t()
chain.SetBranchStatus("Event", 1)
chain.SetBranchAddress("Event", AddressOf(var, "Event_"))
chain.SetBranchStatus("Event.Weight", 1)
chain.SetBranchAddress("Event.Weight", AddressOf(var, "Weight"))

wei = 0
for i in range(entries):
    chain.GetEntry(i)
    if var.Event_ == 1:
        print "Weight = " + str(var.Weight[0])
        wei += var.Weight[0]
    elif var.Event_ > 1: # note: var.Event_ == 0 is o.k. ("do nothing")
        print "Fatal: Entry = " + str(i) + " -> Event_ = " + str(var.Event_)
        quit()
print "Sum of all weights = " + str(wei)

Hi Wile,

thanks for your answer. I have been doing data analysis for a couple of years but you are right, I have never used any TTree with split level different from 0. That is why I was asking how to read it. I know that this TTree has been created with TClonesArray corresponding to some C++ objects which I am not using and I am reading it like it was serialised (loading each leaf separatedly instead of loading the TClonesArray itself), which is what you are suggesting as far as I can tell. I see that I forgot the SetMakeClass and I didin’t know that I had to set the address for the header of the branch. When I read this in my analysis I have

so maybe this is why I haven’t thought about it.

Thanks a lot, it seems to be working now.
Juanpe.

It’s not any “header of the branch” that matters.
The “Event” branch is an “Int_t Event_” and it keeps the actual number of elements (different TTree entries can have different numbers, from 0 to “kMaxEvent = 1” in your case) in the “Event.Weight” branch which is a “Float_t Weight[Event_]” variable length array (and another variable length arrays related to another “Event.*” branches, as far as I can see). I assume you got the maximum number of elements “kMaxEvent” from the source code generated by the TTree::MakeClass (i.e. you got something like “const Int_t kMaxEvent = 1;” and then “Float_t Event_Weight[kMaxEvent]; //[Event_]”).

If you are familiar with the “Delphes” tree, could you maybe have a look at: Problem generating dictionary