Accessing Reflex information about objects in PyRoot

Hello,

I'm trying to get information on objects stored in a Root file that have been generated with Reflex dictionaries (I have access to the .so libraries as well).  I am hoping, for example, to be able to [i]crawl[/i] through an object and figure out which are the "accessor" functions ([i]e.g.,[/i] pt()).

Any suggestions as where to start? 

Thanks,
     Charles

Hi Charles,

you should be able to load libCintex, then the library containing the Reflex dictionary of your class, and then open the file containing the objects you want to look at (order is important here). Then you can access the data using its functions.

If this is not the answer you wanted to hear then you’ll have to be a bit more rpecise on what you want to do and what doesn’t work :slight_smile:

Cheers, Axel.

Charles,

you can load and enable Cintex through “import PyCintex” (part of ROOT). If the .so’s are described in rootmap files, the dictionaries will be loaded automatically when accessing objects. If not, then there is PyCintex.loadDict() to load the dictionaries explicitly.

Otherwise, yes, a more detailed recipe would be handy.

Cheers,
Wim

Hi Axel and Wim,

It was (ahem) not a very well phrased question. I was looking for a way of crawling over an object so I could print out all of the values for a given instance.

It’s probably easiest to show what I wanted by showing what I ended up figuring out (using ‘dir()’ and ‘getattr()’)

Thanks,
Charles

def getObjectList (baseObj, base):
    """Get a list of interesting things from this object"""
    #print "In", base
    match = lastClassRegex.search (base)
    lastClass = ''
    if match:
        lastClass = match.group (1)
    retval = []
    todoDict = {}
    for objName in dir(baseObj):
        skip = False
        for regex in memberReList:            
            if regex.search (objName):
                skip = True
                break
        if skip: continue
        # is this simple?
        obj = getattr (baseObj, objName)
        foundSimple = False
        for possible in simpleClassList:
            if isinstance (obj, possible):
                retval.append( ("%s.%s" % (base, objName), possible.__name__) )
                foundSimple = True
        if foundSimple: continue
        if isinstance (obj, ROOT.MethodProxy):
            try:
                value = obj()
            except:
                continue
            knownType = False
            for possible in simpleClassList:
                if isinstance (value, possible):
                    retval.append( ("%s.%s()" % (base, objName),
                                    possible.__name__) )
                    knownType = True
                    break
            if knownType:
                continue
            # if we're here, then we don't know what we've got
            className = value.__class__.__name__
            if className == lastClass:
                # don't fall into a recursive trap
                continue
            skipType = False
            for regex in typeReList:
                if regex.search (className):
                    # print "skipping type '%s'" % name
                    skipType = True
                    break
            if not skipType:
                name = "%s.%s()" % (base, className)
                todoDict[name] = value
                #retval.append( ("%s.%s()" % (base, objName), className) )
    for name, obj in sorted (todoDict.iteritems()):
        retval.extend( getObjectList (obj, name) )
    return retval

# setup lists of things to avoid by default. 
memberSkipList = [r'^__', r'p4$', r'vertex$', r'^set', r'^begin$', r'^end$',
            r'^clone$', r'^IsA']
memberReList = []
for skip in memberSkipList:
    memberReList.append( re.compile (skip, re.IGNORECASE) )

lastClassRegex = re.compile (r'([^\.]+)\(\)$')

# list of types to avoid.
typeSkipList = [r'edm::Ref', r'edm::Ptr', r'vector']
typeReList = []
for skip in typeSkipList:
    typeReList.append( re.compile (skip) )

# list of 'known' classes
simpleClassList = [int, float, str, long]

mylist = getObjectList (muon, "muon")
pprint.pprint (mylist)

Charles,

sorry, but I’m still confused … is it a technical question of working with Cintex, or a functional question of getting more details of the underlying C++ signature?

If the latter, the C++ signatures are available in the doc string of the method proxies. In ROOT SVN HEAD, method-proxies are behaving more like python-functions (for PyPy) and such information is becoming a little more structured.

Another alternative is to use the Relax library (Reflex of Reflex). This allows you to load the Reflex library and look at the details using the dictionary and Reflex API only, not needing any instantiations of classes or objects.

Cheers,
Wim

Hi,

just call TClass::Dump(obj). Look at its source if you want to reproduce what it does yourself.

Axel.