Hi Rooters,
I would need to fill a TTree with stl:vector because I would like don’t fix their size. I created a class which contains the stl vectors.
[code]#ifndef BDSRoot_h
#define BDSRoot_h
#include
#include “TFile.h”
#include “TTree.h”
#include “TBrowser.h”
#include “TH2.h”
#include “TMath.h”
#include “TROOT.h”
#include “TRandom.h”
#include “TCanvas.h”
#include “TObject.h”
#include
using std::vector;
class BDSRoot : public TObject {
public:
Int_t Nsampler;
Int_t n_hits[200];
std::vector <Float_t> X[200];
std::vector <Float_t> Z[200];;
void Init()
{
for(Int_t i=0;i<200;i++)
{
X[i].clear();
Z[i].clear();
}
}
void GetPos(Int_t ksampler,Int_t nhit,Float_t x,Float_t z)
{
std::cout<<ksampler<<"\t"<<
nhit<<" x= "<<x<<std::endl;
X[ksampler].push_back(x);
Z[ksampler].push_back(z);
}
BDSRoot();
~BDSRoot();
ClassDef(BDSRoot,1)
};
#endif
[/code]
And the code which fills the Tree :
[code]#include “BDSRoot.hh”
#include “BDSSamplerSD.hh”
#include
extern G4String outputFilename;
BDSRoot *hevent=0;
BDSOutput::BDSOutput()
{
//time_t tm = time(NULL);
format = _ASCII; // default - write an ascii file
nSamplers = 0;
//of.open(“output.txt”);
//of<<"## BDSIM output created “<<ctime(&tm)<<” ####"<<G4endl;
}
BDSOutput::BDSOutput(int fmt)
{
format = fmt;
nSamplers = 0;
}
BDSOutput::~BDSOutput()
{
if(of != NULL)
of.close();
#ifdef USE_ROOT
if(format==_ROOT)
if(theRootOutputFile->IsOpen())
{
theRootOutputFile->Write();
theRootOutputFile->Close();
delete theRootOutputFile;
}
#endif
}
void BDSOutput::SetFormat(G4int val)
{
format = val;
time_t tm = time(NULL);
if( format == _ASCII)
{
G4String filename = outputFilename+".txt";
G4cout<<“output format ASCII, filename: “<<filename<<G4endl;
of.open(filename);
of<<”### BDSIM output created “<<ctime(&tm)<<” ####”<<G4endl;
of<<"# PT E[GeV] X[mum] Y[mum] Z[m] Xp[rad] Yp[rad] "<<G4endl;
}
if( format == _ROOT)
{
G4cout<<“output format ROOT”<<G4endl;
}
}
// output initialization (ROOT only)
void BDSOutput::Init(G4int FileNum)
{
if(format != _ROOT) return;
#ifdef USE_ROOT
// set up the root file
G4String filename = outputFilename + “_”
+ BDSGlobals->StringFromInt(FileNum) + “.root”;
G4cout<<"Setting up new file: "<<filename<<G4endl;
theRootOutputFile=new TFile(filename,“RECREATE”, “BDS output file”);
// TTree* SamplerTree = new TTree(“AllDetectors”, “Sampler output”);
TTree* SamplerTree = new TTree(“AllDetectors”, “Sampler output”);
gSystem->Load("/cern/BDSIM_last/rootlib/BDSRoot_cc.so");
G4cout<<"---------->>> DEFINITION DE hevent -------->>>"<<G4endl;
if(!hevent) hevent = new BDSRoot();
// BDSRoot *hevent = new BDSRoot();
int bufsize = 10000;
int split = 1;
SamplerTree->Branch(“hevent”,&hevent, bufsize,split);
hevent->Init();
Nsampler=nSamplers;
for(G4int i=0;i<nSamplers;i++)
{
G4String name=SampName[i];
names[name.c_str()]=i;
G4cout<<"i = "<<i<<" Name --> "<<name<<G4endl;
}
G4cout<<"----> Apres Declaration des Branches …"<<G4endl;
if(
BDSGlobals->GetStoreTrajectory() ||
BDSGlobals->GetStoreMuonTrajectories() ||
BDSGlobals->GetStoreNeutronTrajectories()
)
// create a tree with trajectories
{
//G4cout<<“BDSOutput::storing trajectories set”<<G4endl;
TTree* TrajTree = new TTree(“Trajectories”, “Trajectories”);
}
// build energy loss histogram
G4int nBins = G4int(zMax/m);
EnergyLossHisto = new TH1F(“ElossHisto”, “Energy Loss”,nBins,0.,zMax/m);
EnergyLossNtuple= new TNtuple(“ElossNtuple”, “Energy Loss”,“z:E”);
#endif
}
void BDSOutput::WriteHits(BDSSamplerHitsCollection *hc)
{
if( format == _ASCII) {
G4cout.precision(6);
for (G4int i=0; i<hc->entries(); i++)
{
of<<(*hc)[i]->GetPDGtype()
<<" "
<<(*hc)[i]->GetMom()/GeV
<<" "
<<(*hc)[i]->GetX()/micrometer
<<" "
<<(*hc)[i]->GetY()/micrometer
<<" "
<<(*hc)[i]->GetZ() / m
<<" "
<<(*hc)[i]->GetXPrime() / radian
<<" "
<<(*hc)[i]->GetYPrime() / radian
<<G4endl;
}
of<<G4endl;
//of<<"end of hits collection"<<G4endl;
}
if( format == _ROOT) {
#ifdef USE_ROOT
// ---- Initialize n_hits ------
for(G4int ks=0; ks<Nsampler;ks++)
{
n_hits[ks]=0;
}
G4String name;
TTree* sTree=(TTree*)gDirectory->Get("AllDetectors");
for (G4int i=0; i<hc->entries(); i++)
{
G4int ksampler = names[(*hc)[i]->GetName()];
name=(*hc)[i]->GetName();
G4cout<<ksampler<<" ICI : "<<i<<"\t"<<n_hits[ksampler]<<G4endl;
n_hits[ksampler]++;
hevent->GetPos(
ksampler,
n_hits[ksampler],
(*hc)[i]->GetX()/ micrometer,
(*hc)[i]->GetZ() / m);
G4cout<<i<<"before --> "<<ksampler<<"\t"<<
(*hc)[i]->GetX()/ micrometer<<
" name --> "<<name.c_str()<< G4endl;
Nsampler=nSamplers;
}
sTree->Fill();
G4cout<<" Nentries : "<<hc->entries()<<G4endl;
G4cout<<"------------------------------- "<<G4endl;
#endif
}
}
// write a trajectory to a root/ascii file
G4int BDSOutput::WriteTrajectory(TrajectoryVector* TrajVec)
{
G4cout<<“a trajectory stored…”<<G4endl;
G4int tID;
G4TrajectoryPoint* TrajPoint;
G4ThreeVector TrajPos;
#ifdef USE_ROOT
TTree* TrajTree;
G4String name = “Trajectories”;
TrajTree=(TTree*)gDirectory->Get(name);
if(TrajTree == NULL) { G4cerr<<“TrajTree=NULL”<<G4endl; return -1;}
#endif
if(TrajVec)
{
TrajectoryVector::iterator iT;
for(iT=TrajVec->begin();iT<TrajVec->end();iT++)
{
G4Trajectory* Traj=(G4Trajectory*)(*iT);
tID=Traj->GetTrackID();
// part = Traj->GetPDGEncoding();
for(G4int j=0; j<Traj->GetPointEntries(); j++)
{
TrajPoint=(G4TrajectoryPoint*)Traj->GetPoint(j);
TrajPos=TrajPoint->GetPosition();
// x = TrajPos.x() / m;
// y = TrajPos.y() / m;
// z = TrajPos.z() / m;
#ifdef USE_ROOT
if( format == _ROOT)
TrajTree->Fill();
#endif
//G4cout<<"TrajPos="<<TrajPos<<G4endl;
}
}
}
return 0;
}
// make energy loss histo
void BDSOutput::WriteEnergyLoss(BDSEnergyCounterHitsCollection* hc)
{
if( format == _ROOT) {
#ifdef USE_ROOT
G4int n_hit = hc->entries();
for (G4int i=0;i<n_hit;i++)
{
G4double Energy=(*hc)[i]->GetEnergy();
G4double EWeightZ=(*hc)[i]->
GetEnergyWeightedPosition()/Energy;
EnergyLossHisto->Fill(EWeightZ/m,Energy/GeV);
EnergyLossNtuple->Fill(EWeightZ/m,Energy/GeV);
}
#endif
}
if( format == _ASCII) {
G4int n_hit = hc->entries();
for (G4int i=0;i<n_hit;i++)
{
G4double Energy=(*hc)[i]->GetEnergy();
G4double EWeightZ=(*hc)[i]->
GetEnergyWeightedPosition()/Energy;
of<<EWeightZ/m<<" "<<Energy/GeV<<G4endl;
}
}
}
// write some comments to the output file
// only for ASCII output
void BDSOutput::Echo(G4String str)
{
if(format == _ASCII) of<<"#"<<str<<G4endl;
else // default
G4cout<<"#"<<str<<G4endl;
}
G4int BDSOutput::Commit(G4int FileNum)
{
#ifdef USE_ROOT
if(format==_ROOT)
if(theRootOutputFile->IsOpen())
{
theRootOutputFile->Write();
theRootOutputFile->Close();
delete theRootOutputFile;
}
#endif
Init(FileNum);
return 0;
}
[/code]
So it seems that using that method, the Tree is not properly filled
But, if I use instead Float_t X[200][10] it works fine …
And how can I also include a char *name[200] in my Tree ?
Thanks !
Cheers
Hayg