Can not write std::vector<TVector3> to a TTree

Dear experts

I want to write std::vector<TVector3> to a TTree, but I can not find it in the output ROOT file.

  1. I have already generated the dictionary and linked it in CMakeLists.txt
  2. The code is like:
std::vector<TVector3> fv;
std::vector<double> fd;
TFile* f_out = new TFile("some.root", "RECREATE");
TTree* t_out = new TTree("t", "t");
t_out->Branch("v", &fv);
t_out->Branch("d", &fd);
for(some_loop){
    fv = v;
    fd = d;
    t_out->Fill();
}
t_out->Write();
f_out->Close();

But in the output file I only get the value d, why?

Hi,

thanks for the interesting post.
I tried a slightly modified version of your code with 6.32.02, fresh from last Tuesday:

// Quick check: generate dictionary at runtime
gInterpreter->GenerateDictionary("vector<TVector3>", "vector;TVector3.h");

std::vector<TVector3> fv;
std::vector<double> fd;
TFile* f_out = new TFile("some.root", "RECREATE");
TTree* t_out = new TTree("t", "t");

t_out->Branch("v", &fv);
t_out->Branch("d", &fd);

for(auto i : {1.,2.,3.}){
    fd.emplace_back(i);
    fv.emplace_back(i,i*2,i*3);
    t_out->Fill();
}

t_out->Write();
f_out->Close();

It seems to work (pardon my quick workaround for making explicit the creation of the dictionary). This is what I have in the file:

~> rootls -lt some.root:t
TTree  Jun 20 14:39 2024 t;1 "t" 
  v  "v"  355
  d  "d"  163
  Cluster INCLUSIVE ranges:
   - # 0: [0, 2]
  The total number of clusters is 1

Are you sure the library that contains the dictionary is loaded when you write out your data?
One way to check this is to ask ROOT if the vector class has a dictionary:

TClass::GetClass("vector<TVector3>")->HasDictionary()

and to see the list of loaded libraries:

gSystem->GetLibraries()

For example, try to compare at the prompt the output of the 2 commands before and after running

gInterpreter->GenerateDictionary("vector<TVector3>", "vector;TVector3.h");

I hope this helps starting your debugging session.

Cheers,
D

I just Tried your method and it works fine!
Now I’m wondering where I did wrong in my dictionary gen process…here is what I did:
1.Make a vector_of_TVector3_LinkDef.h and write:

#ifdef __CINT__
#pragma link C++ class std::vector<TVector3>+;
#endif
  1. use rootcling -f vector_of_TVector3_Dict.cxx path_to_root_include/TVector3.h vector_of_TVector3_LinkDef.h
  2. Add Dict source file in CMakeLists.txt:
    add_library(lib other_source_files Dict.cxx)
  3. Compile and run it
    Any suggestion?

Hi,

Could you check whether the library is loaded at runtime as suggested above?

Cheers,
Danilo

It gives this:

Error in <TTree::Branch>: The class requested (vector<TVector3>) for the branch "trkPos" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<TVector3>) to avoid to write corrupted data.

seems dictionary is not loaded…why? I have already add the dictionary file in CMakeList.txt add_library(lib other_source_files Dict.cxx) and target_link_libraries(main PUBLIC lib)

Hi,

Could you perhaps find out if the dictionary is actually compiled (and the pcm created), if yes, in which library the dictionary is compiled and whether the library is loaded at runtime?

Best,
D