Loop over all objects in a ROOT file

I just found this thread and thought I’d post an alternative, I think neater solution. All the intelligence is in the ~7 line getall function. I’ve not checked whether it’s particularly memory efficient since it runs perfectly fast for my current need, which is to just list ROOT all file contents… but being a generator it at least doesn’t try to put all the objects in memory at the same time!

import ROOT

def getall(d, basepath="/"):
    "Generator function to recurse into a ROOT file/dir and yield (path, obj) pairs"
    for key in d.GetListOfKeys():
        kname = key.GetName()
        if key.IsFolder():
            # TODO: -> "yield from" in Py3
            for i in getall(d.Get(kname), basepath+kname+"/"):
                yield i
        else:
            yield basepath+kname, d.Get(kname)


# Demo
ROOT.gROOT.SetBatch(True)
f = ROOT.TFile("mydata.root")
for k, o in getall(f):
    print o.ClassName(), k

# Output
# TH1D /Nominal/Vertex/RawLeadPt0
# TH2D /Nominal/Vertex/RawSumPt_leadPt_To0
# ...
# TH1D /Nominal/Vertex/RawSumPt_DeltaPhi_lexc0
# TH2D /Nominal/Vertex/RawSumPt_Ramp_TrMin_TrMax0
# ...
# TH1D /Up_Material/Vertex/RawLeadPt0
# TH2D /Up_Material/Vertex/RawSumPt_leadPt_To0
# ...

I’ve expanded this into a “rootls” script at pastebin.com/GebcyHY9 (cf. YODA’s yodals).