Pyroot object not found in namespace dictionary

Hi,

I seem to be unable to check if an object is in a tfile before directly accessing it. In addition, if I try to use the namespace dictionary I do not get the valid object until a direct namespace call is performed. This doesn’t allow dynamic request for objects of different names and requires that I hard code the names of all objects I may want to get from the tfile. Any suggestions on a work around?

Thanks

$ python pyroot-dict.py 
Generating ROOT file.
Opening generated tfile.

Check if 'hist' is in namespace.
FAILED 'hist' not found in namespace.
Check if hist is accesible through namespace dictionary.
FAILED KeyError('hist')

Check if hist is accesible through direct namespace access.
SUCCESS Name: hist Title: Hist NbinsX: 100

Check if 'hist' is in namespace.
SUCCESS 'hist' found in namespace.
Check if hist is accesible through namespace dictionary.
SUCCESS Name: hist Title: Hist NbinsX: 100

The script for performing these tests:

import ROOT

def generate_tfile(file_name):
    tfile = ROOT.TFile(file_name, "CREATE")
    if tfile.IsOpen():
        hist = ROOT.TH1F("hist", "Hist", 100, -2, 2)
        hist.FillRandom("gaus")
        hist.Write()
        tfile.Close()

def check_namespace(arg, namespace):
    "Check if argument is `in` namespace."

    print("Check if '{}' is in namespace.".format(arg))
    if arg in tfile:
        print("SUCCESS '{}' found in namespace.".format(arg))
    else:
        print("FAILED '{}' not found in namespace.".format(arg))

def check_namespace_dict(arg, namespace):
    "Check if arg is in name sace dictionary by using `__dict__`."

    print("Check if hist is accesible through namespace dictionary.")
    try:
        hist = tfile.__dict__[arg]
        print("SUCCESS", hist)
    except Exception as e:
        print("FAILED", repr(e))

file_name = "test_file.root"
print("Generating ROOT file.")
generate_tfile(file_name)

print("Opening generated tfile.")
tfile = ROOT.TFile(file_name)

print("")
check_namespace('hist', tfile)
check_namespace_dict('hist', tfile)

print("")
print("Check if hist is accesible through direct namespace access.")
try:
    hist = tfile.hist
    print("SUCCESS", hist)
except Exception as e:
    print("FAILED", repr(e))

print("")
check_namespace('hist', tfile)
check_namespace_dict('hist', tfile)

ROOT Version: 6.14.04
Platform: Not Provided
Compiler: Not Provided


tfile.arg calls getattr. In the case of a TFile – getattr
seems to dynamically load the item you are looking for in the file.
Only at that point, it is also put in the __dict__

In stead of

if arg in tfile:

try

if hasattr( tfile, arg ) :

or getattr( tfile, arg ) and catch AttributeError, or just use root’s TFile::Get().

cheers,
aart

hasattr does indeed resolve the issue. Why doesn’t in perform this same action?

Thanks for the response.

The idea apparently is that the objects stored in the file look like attributes
of the TFile object.

In python in is not used to check for attributes. It checks if the requested
thing is in a (iterable) sequence (like a list).

>>> str.strip # okay, so str has an attribute 'strip'
<method 'strip' of 'str' objects>
>>> hasattr( str, 'strip')
True
>>> 'strip' in str # it just does not work like that in Python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'type' is not iterable

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.