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?
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.
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]
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?
phew! 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.
I symlimk’ed all the missing .dll’s to the corresponding .so’s and everything works perfectly . 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).