Error in <TTree::Branch> with a vector of vectors

Hi,

I have a class with a member whose type is a std::vector<std::vector > *ptr. I want to store this variable as a branch in my tree. I do this using the method

myTree->Branch("branchName","vector<vector<float> >", &MyBranchName );

In the header file I include

#include <vector>
#ifdef __MAKECINT__
#pragma link C++ class std::vector < std::vector<float> >+;   
#endif

The class compiles fine. I then create an executable for my main() program using the syntax

/afs/cern.ch/sw/lcg/external/gcc/4.3.2/x86_64/bin/g++ -Wall -g `root-config --cflags` -I. `root-config --libs` MyClass.o MainProgram.C -o MainProgram

and this creates the exe, as expected. When I try to run the exe, I get the runtime errors

Error in <TTree::Branch>: The class requested (vector<vector<float> >) for the branch "branchName" refer to an stl collection and do not have a compiled CollectionProxy.  Please generate the dictionary for this class (vector<vector<float> >)

Any reason why this is happening, even though I #include and link with the appropriate standard library?

For “std::vector<std::vector >” see [url]Storing 2D vector [--> vector<vector<...> >] into a TTree
For “std::vector<std::vectorstd::string >” see [url]Problem in getting the vector < vector <string> > branch

BTW. The “#pragma link C++” is irrelevant for the compiler when you compile your class’es source code. You would need to call “rootcint” in order to build the dictionary for your class. A separate additional source code file would be created which you would need to compile and add that additional object file to the linker command line.

A brutal fix …
… assuming that the class’es source code file is “MyClass.cxx”, execute: echo 'gROOT->LoadMacro("MyClass.cxx++"); gSystem->Exit(0);' | root -b -l -n … or … root -b -l -n <<EOF .L MyClass.cxx++ .q EOF This will (hopefully) create a “MyClass_cxx.so” shared library file (it should include the class’es dictionary and all “#pragma link C++” related ones as well). Add this “MyClass_cxx.so” shared library file (you can also rename it into something like a “libMyClass.so”, if you like) to the link command line instead of the “MyClass.o” file (no need to compile the “MyClass.cxx” file itself separately at all).

See also [url]Compile a macro without running? and [url]Peoblems with passing bash script arguments

Thanks. I got it to work by generating the dictionary using rootcint. Here’s the makefile I used

CC        = /afs/cern.ch/sw/lcg/external/gcc/4.3.2/x86_64/bin/g++
CCFLAGS   = -Wall -g
INCS      = `root-config --cflags` -I.
LIBS      = `root-config --libs` -lTreePlayer

SkimMain : SkimMain.C BranchBase.o MuonBranch.o TrigGlobalBranch.o Dict.o
        $(CC) $(CCFLAGS) $< BranchBase.o MuonBranch.o TrigGlobalBranch.o Dict.o -o $@ $(INCS) $(LIBS)

TrigGlobalBranch.o: TrigGlobalBranch.C TrigGlobalBranch.h BranchBase.o
        $(CC) $(CCFLAGS) -c $< $(INCS) $(LIBS)

MuonBranch.o: MuonBranch.C MuonBranch.h BranchBase.o
        $(CC) $(CCFLAGS) -c $< $(INCS) $(LIBS)

BranchBase.o : BranchBase.C BranchBase.h
        $(CC) $(CCFLAGS) -c $< $(INCS) $(LIBS)

Dict.o : Dict.cxx
        $(CC) $(CCFLAGS) -c $< $(INCS) $(LIBS)

Dict.cxx : BranchBase.h
        rootcint -f $@ -c $<+

clean :
        rm -f Dict.o Dict.cxx Dict.h TrigGlobalBranch.o MuonBranch.o BranchBase.o