Problems with 3-dimensional STL vectors

I trying to get a 3 dimensional STL vector to work using python, but get the following error message:
AttributeError: type object ‘ROOT’ has no attribute ‘vector<std::vector<std::vector > >’

The following code snippet shows how this error is produced. The 2 dimensional STL vector is fine, and commenting out vec3 works, so it seems to be an issue with instantiating the class on the python side (as there’s no issue with the ProcessLine). But have I got the correct syntax for vec3? It seems like it should just be an extension of the syntax for vec2, as I have attempted, but it fails to work.

[code]# simple root macro to test vectors in PyROOT

from ROOT import *

gROOT.ProcessLine("#ifdef CINT
#pragma link C++ class std::vector<std::vector >+;
#pragma link C++ class std::vector<std::vector<std::vector > >+;

vec1 = std.vector(‘double’)()
vec2 = std.vector(‘std::vector’)()
vec3 = std.vector(‘std::vector<std::vector >’)()[/code]

I’ve also tried to keep the class definition on the C side by using the following structure:


#ifdef CINT
#pragma link C++ class std::vector<std::vector >+;
#pragma link C++ class std::vector<std::vector<std::vector > >+;

struct myStruct
std::vector vec1;
std::vector<std::vector > vec2;
std::vector<std::vector<std::vector > > vec3;

Then using this with python, ie:

[code]from ROOT import *

gROOT.ProcessLine(".L vecs.C+")

from ROOT import myStruct



But the final line causes a segmentation fault. If I comment out this line, it works fine, and I can also manipulate the other vectors, ie, with resize(). Any suggestions would be greatly appreciated. Oh, and I am using root v5r28p00fn00 and python 2.4.3 if that helps.

Callum (121 Bytes)
vecs.C (365 Bytes) (450 Bytes)


there appears to be an infinite loop in GetClass():#27538 0xb610adfc in TClass::GetClass(char const*, bool, bool) () from /home/wlav/rootdev/root/lib/ #27539 0xb6069fcb in TROOT::LoadClass(char const*, bool) const () from /home/wlav/rootdev/root/lib/
and after a while it runs out of memory. The problem is that the code ends up with an incomplete class first, then loads vector, removes the class, then the above happens. Can also be reproduced in root.exe, as the following crashes:root [0] gROOT->LoadMacro("vecs.C+") (Int_t)0 root [1] TClass::GetClass("vector<vector<vector<double> > >") (class TClass*)0x852e238 root [2] TClass::RemoveClass(TClass::GetClass("vector<vector<vector<double> > >")) root [3] TClass::GetClass("vector<vector<vector<double> > >")
I don’t know what it is about this particular class that makes the above a problem. I’ll have a look.



it’s one of those issues with std:: (CINT doesn’t honor it, and in between stripping/adding to get the right set, something goes wrong although I haven’t found in detail what). To work around, drop the “#pragma link C++ class std::vector<std::vector >+;” as one such is already available in CINT’s dlls and so no new dictionary is needed. Then, for the 3-dim vector, drop all the “std::” in the name. That is, all you need is:#ifdef __CINT__ #pragma link C++ class vector<vector<vector<double> > >+; #endif
After that, both the given examples work for me.


Hi Wim,

Thanks for the quick responses! Your solution does indeed solve the problem for me too.




As a side note:gROOT.ProcessLine("#ifdef __CINT__ \ #pragma link C++ class std::vector<std::vector<double> >+;\ #pragma link C++ class std::vector<std::vector<std::vector<double> > >+;\ #endif")does not (will not) generate any dictionary and is simply ignored.
Instead you can use:gInterpreter->GenerateDictionary("std::vector<std::vector<double> >","vector"); gInterpreter->GenerateDictionary(" std::vector<std::vector<std::vector<double> > >","vector");