The FissionFragment_N_E_LabRef is not correctly filled and is not correctly read. When I do “MakeSelector(“mycode”)” on the tree I generate, the branch is either not supported (with the new root versions) or read as a char (if I write “=legacy”).
UPDATE : I’ve modified the branch declaration from simuTree->Branch ("FissionFragment_N_E_LabRef" , FF_n_E_labRef, "FissionFragment_N_E_LabRef[2][FF_multi_n]/D");
to simuTree->Branch ("FissionFragment_N_E_LabRef" , FF_n_E_labRef, "FissionFragment_N_E_LabRef[2][fMAX_EvapNeutrons]/D");
The MakeSelector(“mycode”,“=legacy”) now reads correctly the type of variable, namely a double.
For you to fully understand what I try to do:
I read a txt file and fill a tree from it → This step seems to be right. Right before filling the TTree with Fill() the values that are stored in the FF_n_E_labRef[2][fMAX_EvapNeutrons], variable are correct (I’ve a cout before filling)
I’ve made a MakeSelector(“xx”,“=legacy”) on the generated tree → the values that are read are wrong (I only added a GetEntry(entry) in the loop and a cout. It seems that for each line of the FissionFragment_N_E_LabRef[2][fMAX_EvapNeutrons] matrix, I can only read 2 values rather than fMAX_EvapNeutrons values
I don’t know if it helps
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