How to iterate over tree with dynamically generated branches

Hi all,

I am trying to iterate over a tree with branches, which are generated dynamically, i.e., I parse a text file and create branches for fields in this list matching a certain pattern. Thus I do not know which fields will show up in the beginning.

After filling and saving the tree, I would now create a few histograms for values I now are showing up.
However, I am stuck at how to address the branch values properly (CINT equivalent would be SetBranchAdress or so I suppose)

So My steps are

setting up the tree and adding branches

    logValues = {}
    rootFileName = "./plots/%s.root" % (baseFileName)
    rootFile = ROOT.TFile(rootFileName, "RECREATE")
    rootTree = ROOT.TTree("jobTree", "jobTree")

    for logField,accounting in logInfo.iteritems():
        logValues[logField] = array( 'f',[0])
        rootTree.Branch("%s" % logField,logValues[logField],"%s/F" % logField)

Then filling a branch after somewhat of text parsing

        logValues[logField][0] = float(jobSplit[accounting[0]])

which works fine and I can save a root-file with branches+values

Now I want to iterate over the tree and branches and fill values into a histogram (I could fill the histogram while filling the root file, but I would like to avoid that)

    canvas = ROOT.TCanvas("canvas","KIT Statistics")
    histo = ROOT.TH1D("histo",title,int(histoBinning),float(histoStart),float(histoEnd))
    nTreeEvents = tree.GetEntries()
    value = []
    branch = tree.GetBranch(branchName)      # <-- where branchName = one of the dynamcally generated 
    for event in range(nTreeEvents):
        tree.GetEntry(event)          # <-- ??
        ##branch.GetEntry(event)   # <-- ??
        histo.Fill(value)                  # <--  ??

which is where I am lost how to get the actual value for a given branch of a given event?

Has somebody an idea for me?

Cheers and many thanks,

The TTree object has an attribute for each of its branches (like if there is a branch foo). When you GetEntry(i) on the tree, these attributes are filled with the value from the tree.

So you can do:

import ROOT
f = ROOT.TFile("filename.root")
t = f.Get("treename")
nentries = t.GetEntries()
h_branchname = ROOT.TH1F("h_branchname","branchname",10,0,10)
for i in xrange(nentries):

You can also get the list of branches and create the histograms using python loops and dictionaries. The only trick you need is getattr(t,some_branch) to access the attribute without knowing the exact branch name.

Note that this is a big python loop, which will be immensely slower than compiled C++. For filling histograms and doing cuts (as long as it’s not too complex), I usually end up using TTree.Draw and the “>>” methods for filling histograms. For an example, see the function at line 101 here

I hope that helps.


Hi Jean-François,

thanks for the suggestions – I will give it a try.

Actually, I tried the >> redirection into a histogram but failed so far to get it working in Python as in cint :frowning:

The notation for complex TTree::Draw commands is difficult to get right. Using “>>htemp”, it creates or resets an existing histogram called “htemp”, but this name only exists in the ROOT memory management system, it is not yet a Python identifier (or even a C++ object). To get a usable handle for the histogram, you can use

If you create the histogram ahead of time (required for non-equal binning for example), you can use “>>+ htemp” to fill an existing histogram without resetting it. Again here “htemp” is the name of object in the ROOT memory system.

Look here: for the complicated syntax available for TTree::Draw. You can Ctrl+F for the strings “>>” and “>>+” to find the relevant sections. You can also check out my personal wiki with notes to myself, there are some posts about TTree::Draw: