Reading a tree with std::vector<float>

Hi,

I have a tree with a branch called “type” containing std::vector and a branch called “ed” containing std::vector and I would like to read it in python. However, using

[code]from ROOT import TFile, TTree

file = TFile(‘tree.root’)
tree = file.Get(‘t1’)

tree.GetEntry(0)

for j in tree.type:
print j,
print

for j in tree.ed:
print j,
print
[/code]
the vector of strings prints fine but the printing of the vector of floats fails with

Traceback (most recent call last): File "test.py", line 12, in ? for j in tree.ed: TypeError: iteration over non-sequence
A simple print of tree.ed gives

<ROOT.vector<float> object at 0x9b26a58>
The type seems ok, any idea what I am doing wrong?

Thanks,
Guillaume

Guillaume,

vectors are special in that stub classes can be created without the methods being available. Could you verify the contents of the class member of your vector of floats dir(.class)? Does it have a getitem method?

Otherwise, please post the version of ROOT and python that you’re using, as well as the script that you used to produce the tree. Thanks.

Cheers,
Wim

Hi Wim,

thanks for the quick reply. Here are the attributes of the vector’s class:

>>> dir(tree.ed.__class__) ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
No getitem

I am using ROOT 5.12.00 with python2.4 on linux. The tree is actually the output of a Geant4 simulation so it is created with something like:

[code]TTree *t1 = new TTree(“t1”, “”);

vector *ed = new vector;
t1->Branch(“ed”, “vector”, &ed);

/* fill vector */

t1->Fill();
[/code]
I am sure that the tree is properly written since I can read and print all branches with a C++ ROOT script.

Thanks for your help,
Guillaume

Guillaume,

try as I may, I can not reproduce it. My first reaction was that the cintdlls weren’t build (look for cint/stl/vector.dll), as that library contains vector. If I make that library go awol, I can exactly reproduce your error. But you say that reading works with a ROOT macro, so that can’t be the case, as the macro would fail the same way (the fact that writing worked doesn’t say much, as the code you showed looks like a compiled library, not a macro).

I tried 5.12.00, p2.4, and usage, reading, and writing of std.vector(float) works fine from python AFAICS.

Just the same, however, can you check whether $ROOTSYS/cint/stl/vector.dll exists on your system?

Cheers,
Wim

For reference, my test code:

[code]from ROOT import *

f = TFile( ‘test.root’, ‘recreate’ )
t = TTree( ‘t1’, ‘’ )

v = std.vector(float)()
t.Branch( ‘ed’, ‘vector’, v )

for i in range(10):
v.push_back( i )

t.Fill()
f.Write()[/code]

[code]from ROOT import *

f = TFile( ‘test.root’ )

for event in t1:
for i in event.ed:
print i
[/code]

Hi Wim,

looks like vector.dll might be responsible because when I look in /usr/lib/root/cint/stl/ (the ROOT components are installed in various directories in my case, ./configure --prefix=/usr) vector.dll is just a broken link to vector.dll.5. Here is the output of “ls -l /usr/lib/root/cint/stl/vector*”:

-rw-r--r-- 1 root root 37 2006-09-30 18:27 /usr/lib/root/cint/stl/vector lrwxrwxrwx 1 root root 12 2006-09-30 18:27 /usr/lib/root/cint/stl/vector.dll -> vector.dll.5 -rw-r--r-- 1 root root 41 2006-09-30 18:27 /usr/lib/root/cint/stl/vector.h lrwxrwxrwx 1 root root 15 2006-09-30 18:27 /usr/lib/root/cint/stl/vector.so.5 -> vector.dll.5.12 -rwxr-xr-x 1 root root 1.7M 2006-09-30 18:27 /usr/lib/root/cint/stl/vector.so.5.12
Maybe creating the links vector.dll.5 -> vector.so.5 and vector.dll.5.12 -> vector.so.5.12 would solve my problems. Is ROOT.py dynamically linking with vector.dll or the so library? Is it suppose to be the same thing in linux?

Thanks,
Guillaume

Guillaume,

phew! :slight_smile: If that’s the case then we may just get to the bottom of this.

What happens is slightly more convoluted: PyROOT requests CINT to load the dll, when a std::vector<> class is requested. Yes, please try fixing the link (if you do not have root access, you can put the link somewhere else in LD_LIBRARY_PATH). And yes, it is supposed to be called .dll on linux as well (for historical reasons). Let me know if that doesn’t solve it, even as I’m out of ideas.

Cheers,
Wim

Hi Wim,

I symlimk’ed all the missing .dll’s to the corresponding .so’s and everything works perfectly :smiley: . Thanks a lot for your help.

It seems that when you pass --enable-soversion --enable-shared to ./configure, the names of the cint dlls are not linked correctly (at least this is what happens to me if I look into cint/stl/ after make && make cintdlls).

Thanks again,

Guillaume