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
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