Filling a TTree Branch with a variable lenght array

Hello,

I think I’ve managed to fill my tree with a variable length array.
I’ve got a major suggestion reading this post and did the same :

except that I want to write 10 events, so I loop over them (jj)

int essaie()
{
int nParticles;
vector<int> nTracks;
vector<vector<double>> trackPosition;

TFile file("test.root", "RECREATE");
TTree* tree=new TTree("test", "test");
tree->Branch("nParticles", &nParticles, "nParticles/I");
tree->Branch("nTracks", &nTracks);
tree->Branch("trackPosition", &trackPosition);

for(int jj=0; jj<10; jj++)
{
    //Assume 2 particles
    nParticles = 2;
    //1st has 2 traks
    nTracks.push_back(2+jj);
    //2nd has 3 tracks
    nTracks.push_back(3+jj);
    
    //Fill positions of each track for 1st particle
    vector<double> temp1;
    for (size_t i = 0; i < 2; i++) temp1.push_back((i+1+jj)*10);
    trackPosition.push_back(temp1);
    
    //Fill positions of each track for 2st particle
    vector<double> temp2;
    for (size_t i = 0; i < 3; i++) temp2.push_back((i+1+jj)*100);
    trackPosition.push_back(temp2);
    
    tree->Fill();
}
file.Write();
return 0;

The output tree is correctly filled (I can see the different values with StartViewer() for instance.
Now my problem is : how do I read the generated tree?
Below is what I did by generating the codes with MakeSelector(“mycode”,“=legacy”) :

The header :

  #ifndef monessai_h
  #define monessai_h

  #include <Riostream.h>
  #include <TROOT.h>
  #include <TChain.h>
  #include <TFile.h>
  #include <TSelector.h>

  // Header file for the classes stored in the TTree if any.
  #include "vector"
  #include "vector"

  class monessai : public TSelector {
  public :
     TTree          *fChain;   //!pointer to the analyzed TTree or TChain

  // Fixed size dimensions of array or collections stored in the TTree if any.
  
     // Declaration of leaf types
     Int_t           nParticles;
     vector<int>     *nTracks;
     vector<vector<double> > *trackPosition;

     // List of branches
     TBranch        *b_nParticles;   //!
     TBranch        *b_nTracks;   //!
     TBranch        *b_trackPosition;   //!

     monessai(TTree * /*tree*/ =0) : fChain(0) { }
     virtual ~monessai() { }
     virtual Int_t   Version() const { return 2; }
     virtual void    Begin(TTree *tree);
     virtual void    SlaveBegin(TTree *tree);
     virtual void    Init(TTree *tree);
     virtual Bool_t  Notify();
     virtual Bool_t  Process(Long64_t entry);
     virtual Int_t   GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
     virtual void    SetOption(const char *option) { fOption = option; }
     virtual void    SetObject(TObject *obj) { fObject = obj; }
     virtual void    SetInputList(TList *input) { fInput = input; }
     virtual TList  *GetOutputList() const { return fOutput; }
     virtual void    SlaveTerminate();
     virtual void    Terminate();
  
     ClassDef(monessai,0);
  };
  #endif

  #ifdef monessai_cxx
  void monessai::Init(TTree *tree)
  {
     // The Init() function is called when the selector needs to initialize
     // a new tree or chain. Typically here the branch addresses and branch
     // pointers of the tree will be set.
     // It is normally not necessary to make changes to the generated
     // code, but the routine can be extended by the user if needed.
     // Init() will be called many times when running on PROOF
     // (once per file to be processed).

     // Set object pointer
     nTracks = 0;
     trackPosition = 0;
     // Set branch addresses and branch pointers
     if (!tree) return;
     fChain = tree;
     fChain->SetMakeClass(1);

     fChain->SetBranchAddress("nParticles", &nParticles, &b_nParticles);
     fChain->SetBranchAddress("nTracks", &nTracks, &b_nTracks);
     fChain->SetBranchAddress("trackPosition", &trackPosition, &b_trackPosition);
  }
  
  Bool_t monessai::Notify()
  {   return kTRUE; }

  #endif // #ifdef monessai_cxx

And the code .C

  #define monessai_cxx
  #include "monessai.h"
  #include <TH2.h>
  #include <TStyle.h>

  void monessai::Begin(TTree * /*tree*/)
  { TString option = GetOption();}

  void monessai::SlaveBegin(TTree * /*tree*/)
  {  TString option = GetOption();}

  Bool_t monessai::Process(Long64_t entry)
  {
      GetEntry(entry);
      cout<<nParticles<<endl;
      for(int i=0; i<nParticles; i++)
      {
      cout<<"ntracks size : "<<nTracks->at(i)<<endl;
       for(int j=0; j<nTracks->at(i); j++)
       cout<<trackPosition->at(i).at(j) <<endl;
      }
  return kTRUE;
  }

  void monessai::SlaveTerminate()
  {}

  void monessai::Terminate()
  {}

However the output looks like I’m always reading only the first event :frowning:

  2
  ntracks size : 2
  10
  20
  ntracks size : 3
  100
  200
  300
  2
  ntracks size : 2
  10
  20
  ntracks size : 3
  100
  200
  300
  2
  .....

and so on, for 10 times as I’ve 10 entries in the Tree.

Do you have any idea on where I’m wrong?
Thank you in advance for your help
Cheers
Paola