[ROOT] Getting TDirectory entries with pyROOT

From: Topher Cawlfield (cawlfiel@uiuc.edu)
Date: Wed Jun 30 2004 - 19:39:14 MEST


Hi,

I'm using pyROOT, writing a script that will take a directory and histogram 
name, and extract the histogram if it's there.  This should be trivially 
easy, but I'm having a hard time verifying that a given histogram really 
exists!   (Disclaimer: I'm using root v4.00_04)

I can think of two or three solutions to the problem, but I can't get any of 
them to work.  The obvious thing is to use the TDirectory.Get(...) method.  
This returns a null object if it can't find it.  But pyroot handles this by 
returning a TObject, which looks fine except that the python interpreter 
crashes when I try to call any method on it:  (in this example tdir is a 
TDirectory object.  The directory does contain "h400", but not "h401".  Yes, 
it's from a root file made by h2root.)

>>> this = tdir.Get("h400")
>>> print this
<__main__.TH1F instance at 0x41ec496c>
>>> that = tdir.Get("h401")
>>> print that     # <-- should be "None"
<__main__.TObject instance at 0x41ec49ac>
>>> this.GetName()
'h400'
>>> that.GetName()
python: pyroot/src/MethodHolder.cxx:538: virtual PyObject* 
PyROOT::MethodHolder::operator()(PyObject*, PyObject*): Assertion `obj != 0' 
failed.
Aborted

It doesn't even throw an exception that I could trap!  I see now that in one 
case I get a TObject (which is a null pointer to a TObject?), and in the 
other I get a TH1F.  So maybe there's a way I can ask python what the object 
is.  Perhaps this is the way!

>>> isinstance(this, ROOT.TObject)
False
>>> isinstance(that, ROOT.TObject)
True

Okay, maybe I just answered my own question.  But I hope there's a less ugly 
way to check for null TObject pointers in pyROOT.

Another thing that doesn't quite work is to get a directory listing.  The 
following code works to find all the subdirectories in a root file, but it 
does so by loading each directory into memory via ReadObj, which I have to do 
before I can call GetName().  I don't want to do that with histograms, 
because I don't want to load them all into memory.  How does the ls() method 
find the object names?  I'd expect there to be a TKey method that provides a 
stored object's name and title.

import ROOT
f = ROOT.TFile("pass1/hists/hist_132123.root", "READ")
dirlist = f.GetListOfKeys()
iter = dirlist.MakeIterator()
key = iter.Next()
dirs = {}
td = None
while key:
    if key.GetClassName() == 'TDirectory':
        td = key.ReadObj()
        dirName = td.GetName()
        print "found directory", dirName
        dirs[dirName] = td
    key = iter.Next()

So my two questions at this point are:
  How do I gracefully check for a null TObject pointer in pyroot?
  How can I get the name (and title) of an object in a file without reading 
the whole thing into memory?  ls() and TBrowser do this, so I know it's 
possible.

Thanks,
   Topher Cawlfield



This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:08 MET