Trees with vectors

Dear rooters,

I was not very successful in saving trees with vectors in my own program, so I started picking apart hvector.C example hoping to understand what I’m doing wrong. Instead, I found that I can;t run that one as a standalone program either.

I changed it in such away that only the write() routine and some other essential stuff is left:

//
// This tutorials demonstrate how to store and restore simple vectors
// in a TTree
//

#include <vector>


#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TFrame.h"
#include "TH1F.h"
#include "TBenchmark.h"
#include "TRandom.h"
#include "TSystem.h"

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

void write() 
{
  
   TFile *f = TFile::Open("hvector.root","RECREATE");
   
   if (!f) { return; }

   std::vector<float> vpx;
   std::vector<float> vpy;
   std::vector<float> vpz;
   std::vector<float> vrand;

   // Create a TTree
   TTree *t = new TTree("tvec","Tree with vectors");
   t->Branch("vpx",&vpx);
   t->Branch("vpy",&vpy);
   t->Branch("vpz",&vpz);
   t->Branch("vrand",&vrand);


   gRandom->SetSeed();
   for (Int_t i = 0; i < 25000; i++) {
      Int_t npx = (Int_t)(gRandom->Rndm(1)*15);

      vpx.clear();
      vpy.clear();
      vpz.clear();
      vrand.clear();

      for (Int_t j = 0; j < npx; ++j) {

         Float_t px,py,pz;
         gRandom->Rannor(px,py);
         pz = px*px + py*py;
         Float_t random = gRandom->Rndm(1);
 
         vpx.push_back(px);
         vpy.push_back(py);
         vpz.push_back(pz);
         vrand.push_back(random);

      }

      t->Fill();
   }
   f->Write();
   
   delete f;
}


//void hvector() 
int main()
{
  //  gBenchmark->Start("hvector");

   write();
   //   read();
   
   //   gBenchmark->Show("hvector");   
   
   return 0;
}

When I compile (this part is fine) and run it, I get the following output:
Error in TTree::Branch: The pointer specified for vpx is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpy is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpz is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vrand is not of a class or type known to ROOT

and the root file is empty. Could you, please, tell me what my blunder is. I am using root v5.20, gcc version 4.1.3

Best regards,
Slava

[quote=“Slava”]Dear rooters,

I was not very successful in saving trees with vectors in my own program, so I started picking apart hvector.C example hoping to understand what I’m doing wrong. Instead, I found that I can;t run that one as a standalone program either.

I changed it in such away that only the write() routine and some other essential stuff is left:

//
// This tutorials demonstrate how to store and restore simple vectors
// in a TTree
//

#include <vector>


#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TFrame.h"
#include "TH1F.h"
#include "TBenchmark.h"
#include "TRandom.h"
#include "TSystem.h"

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

void write() 
{
  
   TFile *f = TFile::Open("hvector.root","RECREATE");
   
   if (!f) { return; }

   std::vector<float> vpx;
   std::vector<float> vpy;
   std::vector<float> vpz;
   std::vector<float> vrand;

   // Create a TTree
   TTree *t = new TTree("tvec","Tree with vectors");
   t->Branch("vpx",&vpx);
   t->Branch("vpy",&vpy);
   t->Branch("vpz",&vpz);
   t->Branch("vrand",&vrand);


   gRandom->SetSeed();
   for (Int_t i = 0; i < 25000; i++) {
      Int_t npx = (Int_t)(gRandom->Rndm(1)*15);

      vpx.clear();
      vpy.clear();
      vpz.clear();
      vrand.clear();

      for (Int_t j = 0; j < npx; ++j) {

         Float_t px,py,pz;
         gRandom->Rannor(px,py);
         pz = px*px + py*py;
         Float_t random = gRandom->Rndm(1);
 
         vpx.push_back(px);
         vpy.push_back(py);
         vpz.push_back(pz);
         vrand.push_back(random);

      }

      t->Fill();
   }
   f->Write();
   
   delete f;
}


//void hvector() 
int main()
{
  //  gBenchmark->Start("hvector");

   write();
   //   read();
   
   //   gBenchmark->Show("hvector");   
   
   return 0;
}

When I compile (this part is fine) and run it, I get the following output:
Error in TTree::Branch: The pointer specified for vpx is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpy is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpz is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vrand is not of a class or type known to ROOT

and the root file is empty. Could you, please, tell me what my blunder is. I am using root v5.20, gcc version 4.1.3

Best regards,
Slava[/quote]
I think these:

std::vector<float> vpx; std::vector<float> vpy; std::vector<float> vpz; std::vector<float> vrand;
must be pointers.
Se also:
root.cern.ch/root/html/tutorials … ion.C.html

[quote]When I compile (this part is fine) and run it, I get the following output:
Error in TTree::Branch: The pointer specified for vpx is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpy is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpz is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vrand is not of a class or type known to ROOT
[/quote]As the message tries to hint, you are missing the dictionary for the class being used. In your case this is the class ‘vector’. You must either generate generate a dictionary with rootcint, compile and link the result, or you can use the provided dictionary for vector by adding the line#include "TROOT.h"[code]and add to your main function the line:[code]gROOT->ProcessLine("#include <vector>");.

Cheers,
Philippe.

[quote]I think these:
Code:

std::vector vpx;
std::vector vpy;
std::vector vpz;
std::vector vrand;

must be pointers. [/quote]In ROOT v5.20, this is not longer required :slight_smile:

Cheers,
Philippe.

[quote=“pcanal”][quote]When I compile (this part is fine) and run it, I get the following output:
Error in TTree::Branch: The pointer specified for vpx is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpy is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vpz is not of a class or type known to ROOT
Error in TTree::Branch: The pointer specified for vrand is not of a class or type known to ROOT
[/quote]As the message tries to hint, you are missing the dictionary for the class being used. In your case this is the class ‘vector’. You must either generate generate a dictionary with rootcint, compile and link the result, or you can use the provided dictionary for vector by adding the line#include "TROOT.h"[code]and add to your main function the line:[code]gROOT->ProcessLine("#include <vector>");.

Cheers,
Philippe.[/quote]

Thank you. That worked.

[quote=“pcanal”][quote]I think these:
Code:

std::vector vpx;
std::vector vpy;
std::vector vpz;
std::vector vrand;

must be pointers. [/quote]In ROOT v5.20, this is not longer required :slight_smile:

Cheers,
Philippe.[/quote]
good to know :wink: :slight_smile:

[quote=“pcanal”]
line:gROOT->ProcessLine("#include <vector>");.
Philippe.[/quote]

How this should be extended to use a vector<vector > ?
The include of vector.h through

should not change as a vector of vector is just a vector.

I tried adding a dictionary but this do not change the runtime error about the unknown kind of object to be added to the branch.

Hi,

You need to generate the dictionary for vector<vector > as either part of a rootcint dictionary or a script compiled by ACLiC.

Cheers,
Philippe.