Branching std::vector<double> in TTree on compiled cod

Hello everybody. Please don’t flame me if this in answered somewhere else, but I have been searching and trying for a few days now with no luck.

So let me give you the facts:

I am using Root 5.18 on ubuntu 8.04. I try to stick with the recommended stable release because I need to produce portable code.

I am developing something in C++ that uses the ROOT libraries for display, histogramming and output (TNtuples and now trying TTree).

So, I have a loop in the code that loops through a requested number of events.
Each event, produces many things, one of which is a vector of doubles: std::vector vec;

I want to make everything as simple as possible, so for other things I have 2-3 ntuples of variables that I fill per event.

I now want to create a TTree, independently of the other ntuples (i dont care about creating beautifully structured or efficient root files for the time being), that will hold (per event) the above vector.

As i see it, most likely, a leaf will be created for each event (Right or Wrong??)

For that, i do:

//Statistics.h
...
TTree *zTree;
...
//Statistics.cxx
...
zTree = new TTree("anDistr","Tree to hold the Zijk");
...
//and later at some point, code to write on the rootfile
//Reconstruction.cxx
	std::vector<double> *vec = trigger.getZijk();
	statistics->zTree->Branch("vec","vector<double>",&vec);

So. When i compile, everything is fine. TO be honest, I tried multiple ways to use Branch(), to find the way that works.

When I run, i get the error

[quote]Error in TTree::Branch: The class requested (vector) for the branch “vec” refer to an stl collection and do not have a compiled CollectionProxy. Please generate the dictionary for this class (vector)
[/quote]

I then created a dictionary like:

//loader.C
#include <vector>

#ifdef __MAKECINT__
#pragma link C++ class vector<double>+;
#endif 

I compile it with ACLiC, and the .so file is created. I get the warning about already linked class and I ignore it. Actualy, the warning gave me the idea to use the full stl name in Branch() instead of the template “vector” -> “vector<double,allocator >” with no luck.

And since I don’t do anything with the so file, the same errors appear: need for a dictionary, no TTree in the rootfile.

Do i have to link the .so somehow? And will this make my code less portable?
Please remember that I am referring to C++ compiled code.
Finally, if someone has a better way to solve my problem (storing a set of doubles PER event), please help.

Once again sorry for the long post.

Hi,

The dictionary for vector is precompiled. You simply need to use the following command to insure that it is loaded:gROOT->ProcessLine("#include <vector>");

Cheers,
Philippe.

Sorry maybe you misunderstood me. I am not using the interpreter; I am compiling code using g++.

My main class has something like (this is executed per event):

[code] std::vector *vec = new std::vector;//trigger.getZijk();
char branchName[20];
sprintf(branchName,“Zvector_%d”,i);
statistics->zTree->Branch(branchName,“vector”,&vec);
trigger.analyzeSet(generator->mc_hits);
std::vector tangents = trigger.getTangentLines();
for (std::vector::iterator it = tangents.begin();it<tangents.end();it++) {

       disp.DrawLine(*it,5,2);
   vec->push_back(it->x0);


    }

[/code]

SInce my last post, I understood that you can include just a Linkdef.h file like #include <vector> #ifdef __MAKECINT__ #pragma link C++ class vector<double>+; #endif in your main class.

I did it and It compiles, but on runtime I get the error:

[quote]Starting Event ----1----
Error in TTree::Branch: The class requested (vector) for the branch “Zvector_1” refer to an stl collection and do not have a compiled CollectionProxy. Please generate the dictionary for this class (vector)
[/quote]

Did I not understand correctly? I know that dictionary and own class declaration and use is somewhere documented, but for this simple thing a simple answer will help me a lot. Do I have to link the .so file somehow?

Since we are at it, in the zTree->Branch(branchName,“vector”,&vec); method, if I skip the &vec and use vec (no reference, not the address of the pointer). I get NO error about dictionaries in runtime, I do get hte tree in my root file, I do get the leaves but I think they are empty.

Any ideas?

[quote]I compile it with ACLiC, and the .so file is created. I get the warning about already linked class and I ignore it[/quote]This warning does meant that the dictionary for vector is not being generated (and hence not loaded in your executable.

Whether using the interpreter or in compiled code add the linegROOT->ProcessLine("#include <vector>");to your main function. (In compiled code you will also need to add #include “TROOT.h” at the beginning of your file.

Cheers,
Philippe.

Ps. Note that in the upcoming 5.20 release, the loading of the dictionary vector (and all the other pre-generated dictionaries) will automatic (via the ROOT library autoloader).

Thank you very much for the reply on a Sunday morning! It seems I was missing basic concepts. Anyway, the whole dictionary and personal classes thing looks interesting. I would like to look deeper into it some other time.

The include indeed works and the dictionary is loaded, the Tree is written , the leaves are there, but I still cannot get full leaves. I try to get the vectors (manually, using an object via MakeClass…) but the vectors are size 0.

So if you could answer this last thing while I am working on it: Do you see anything strange on the above code concerning the filling of the tree? After working on the same thing for a while, everything looks ok to me, even if I am missing something trivial :stuck_out_tongue:.

Cheers,

Nik

Found it :stuck_out_tongue: forgot to tree->Fill() :stuck_out_tongue:

Thanks for the help!

Cheers,

Nik