Creation of a ROOT Tree
//*CMZ : 1.00/07 04/04/97 10.13.50 by Rene Brun
//*-- Author : Valery Fine(fine@vxcern.cern.ch) 19/01/97
//______________________________________________________________________________
// A simple example with a ROOT tree
// =================================
//
// This program creates :
// - a ROOT file
// - a tree
// Additional arguments can be passed to the program to control the flow
// of execution. (see comments describing the arguments in the code).
// Event nevent comp split fill
// All arguments are optional: Default is
// Event 400 1 1 1
//
// In this example, the tree consists of one single "super branch"
// The statement ***tree->Branch("event", event, 64000,split);*** below
// will parse the structure described in Event.h and will make
// a new branch for each data member of the class if split is set to 1.
// - 5 branches corresponding to the basic types fNtrack,fNseg,fNvertex
// ,fFlag and fTemperature.
// - 3 branches corresponding to the members of the subobject EventHeader.
// - one branch for each data member of the class Track of TClonesArray.
// - one branch for the object fH (histogram of class TH1F).
//
// if split = 0 only one single branch is created and the complete event
// is serialized in one single buffer.
// if comp = 0 no compression at all.
// if comp = 1 event is compressed.
// if comp = 2 same as 1. In addition branches with floats in the TClonesArray
// are also compressed.
// The 4th argument fill can be set to 0 if one wants to time
// the percentage of time spent in creating the event structure and
// not write the event in the file.
// In this example, one loops over nevent events.
// The branch "event" is created at the first event.
// The branch address is set for all other events.
// For each event, the event header is filled and ntrack tracks
// are generated and added to the TClonesArray list.
// For each event the event histogram is saved as well as the list
// of all tracks.
//
// The number of events can be given as the first argument to the program.
// By default 400 events are generated.
// The compression option can be activated/deactivated via the second argument.
//
// ---Running/Linking instructions----
// This program consists of the following files and procedures.
// - Event.h event class description
// - Event.C event class implementation
// - MainEvent.C the main program to demo this class might be used (this file)
// - EventCint.C the CINT dictionary for the event and Track classes
// this file is automatically generated by rootcint (see Makefile),
// when the class definition in Event.h is modified.
//
// ---Analyzing the Event.root file with the interactive root
// example of a simple session
// Root > TFile f("Event.root")
// Root > T.Draw("fNtrack") //histogram the number of tracks per event
// Root > T.Draw("fPx") //histogram fPx for all tracks in all events
// Root > T.Draw("fXfirst:fYfirst","fNtrack>600")
// //scatter-plot for x versus y of first point of each track
// Root > T.Draw("fH.GetRMS()") //histogram of the RMS of the event histogram
//
// Look also in the same directory at the following macros:
// - eventa.C an example how to read the tree
// - eventb.C how to read events conditionally
//
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#include <stdlib.h>
#include "TROOT.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"
#include "Event.h"
//______________________________________________________________________________
main(int argc, char **argv)
{
TROOT simple("simple","Example of creation of a tree");
Int_t nevent = 400; // by default create 400 events
Int_t comp = 1; // by default file is compressed
Int_t split = 1; // by default, split Event in sub branches
Int_t write = 1; // by default the tree is filled
Int_t hfill = 0; // by default histograms are not filled
Int_t read = 0;
Int_t arg4 = 1;
Int_t arg5 = 600; //default number of tracks per event
if (argc > 1) nevent = atoi(argv[1]);
if (argc > 2) comp = atoi(argv[2]);
if (argc > 3) split = atoi(argv[3]);
if (argc > 4) arg4 = atoi(argv[4]);
if (argc > 5) arg5 = atoi(argv[5]);
if (arg4 == 0) { write = 0; hfill = 0;}
if (arg4 == 1) { write = 1; hfill = 0;}
if (arg4 == 10) { write = 0; hfill = 1;}
if (arg4 == 11) { write = 1; hfill = 1;}
if (arg4 == 20) { write = 0; read = 1;} //read sequential
if (arg4 == 25) { write = 0; read = 2;} //read random
TFile *hfile;
Event *event;
TTree *tree;
TBranch *b = 0;
// Fill event, header and tracks with some random numbers
// Create a timer object to benchmark this loop
TStopwatch timer;
timer.Start();
Int_t nb = 0;
Int_t ev;
Int_t bufsize;
Double_t told = 0;
Double_t tnew = 0;
Int_t printev = 100;
if (arg5 < 100) printev = 1000;
if (arg5 < 10) printev = 10000;
// Read case
if (read) {
hfile = new TFile("Event.root");
tree = (TTree*)hfile->Get("T");
TBranch *branch = tree->GetBranch("event");
event = new Event();
branch->SetAddress(&event);
Int_t nentries = (Int_t)tree->GetEntries();
nevent = TMath::Max(nevent,nentries);
if (read == 1) { //read sequential
for (ev = 0; ev < nevent; ev++) {
if (ev%printev == 0) cout<<"event="<<ev<<endl;
nb += tree->GetEvent(ev); //read complete event in memory
}
} else { //read random
Int_t evrandom;
for (ev = 0; ev < nevent; ev++) {
if (ev%printev == 0) cout<<"event="<<ev<<endl;
evrandom = nevent*gRandom->Rndm(1);
nb += tree->GetEvent(evrandom); //read complete event in memory
}
}
} else {
// Write case
// Create a new ROOT binary machine independent file.
// Note that this file may contain any kind of ROOT objects, histograms,
// pictures, graphics objects, detector geometries, tracks, events, etc..
// This file is now becoming the current directory.
hfile = new TFile("Event.root","RECREATE","TTree benchmark ROOT file");
hfile->SetCompressionLevel(comp);
// Create histogram to show write_time in function of time
Float_t curtime = -0.5;
Int_t ntime = nevent/printev;
TH1F *htime = new TH1F("htime","Real-Time to write versus time",ntime,0,ntime);
// Create one event
event = new Event();
if (hfill) event->Hcreate();
// Create a ROOT Tree and one superbranch
TTree *tree = new TTree("T","An example of a ROOT tree");
tree->SetAutoSave(1000000000); // autosave when 1 Gbyte written
bufsize = 256000;
if (split) bufsize /= 4;
TBranch *b = tree->Branch("event", "Event", &event, bufsize,split);
for (ev = 0; ev < nevent; ev++) {
if (ev%printev == 0) {
tnew = timer.RealTime();
printf("event:%d, rtime=%f s\n",ev,tnew-told);
htime->Fill(curtime,tnew-told);
curtime += 1;
told=tnew;
timer.Continue();
}
Float_t sigmat, sigmas;
gRandom->Rannor(sigmat,sigmas);
Int_t ntrack = Int_t(arg5 +arg5*sigmat/120.);
Float_t random = gRandom->Rndm(1);
event->SetHeader(ev, 200, 960312, random);
event->SetNseg(Int_t(10*ntrack+20*sigmas));
event->SetNvertex(1);
event->SetFlag(UInt_t(random+0.5));
event->SetTemperature(random+20.);
// Create and Fill the Track objects
for (Int_t t = 0; t < ntrack; t++) event->AddTrack(random);
if (write) nb += tree->Fill(); //fill the tree
if (hfill) event->Hfill(); //fill histograms
event->GetTracks()->Clear();
}
if (write) { hfile->Write(); tree->Print();}
}
// Stop timer and print results
timer.Stop();
Float_t mbytes = 0.000001*nb;
Double_t rtime = timer.RealTime();
Double_t ctime = timer.CpuTime();
printf("\n%d events and %d bytes processed.\n",nevent,nb);
printf("RealTime=%f seconds, CpuTime=%f seconds\n",rtime,ctime);
if (read) {
printf("You read %f Mbytes/Realtime seconds\n",mbytes/rtime);
printf("You read %f Mbytes/Cputime seconds\n",mbytes/ctime);
} else {
printf("compression level=%d, split=%d, arg4=%d\n",comp,split,arg4);
printf("You write %f Mbytes/Realtime seconds\n",mbytes/rtime);
printf("You write %f Mbytes/Cputime seconds\n",mbytes/ctime);
//printf("file compression factor = %f\n",hfile.GetCompressionFactor());
}
hfile->Close();
return 0;
}
//*CMZ : 1.00/00 14/02/97 11.04.07 by Rene Brun
//*-- Author : Rene Brun 19/08/96
//______________________________________________________________________________
// Event and Track classes
// =======================
//
// The Event class is a naive/simple example of an event structure.
// public:
// Int_t fNtrack;
// Int_t fNseg;
// Int_t fNvertex;
// UInt_t fFlag;
// Float_t fTemperature;
// EventHeader fEvtHdr;
// TClonesArray *fTracks;
// TH1F *fH;
//
// The EventHeader class has 3 data members (integers):
// public:
// Int_t fEvtNum;
// Int_t fRun;
// Int_t fDate;
//
//
// The Event data member fTracks is a pointer to a TClonesArray.
// It is an array of a variable number of tracks per event.
// Each element of the array is an object of class Track with the members:
// private:
// Float_t fPx; //X component of the momentum
// Float_t fPy; //Y component of the momentum
// Float_t fPz; //Z component of the momentum
// Float_t fRandom; //A random track quantity
// Float_t fMass2; //The mass square of this particle
// Float_t fBx; //X intercept at the vertex
// Float_t fBy; //Y intercept at the vertex
// Float_t fMeanCharge; //Mean charge deposition of all hits of this track
// Float_t fXfirst; //X coordinate of the first point
// Float_t fXlast; //X coordinate of the last point
// Float_t fYfirst; //Y coordinate of the first point
// Float_t fYlast; //Y coordinate of the last point
// Float_t fZfirst; //Z coordinate of the first point
// Float_t fZlast; //Z coordinate of the last point
// Float_t fCharge; //Charge of this track
// Int_t fNpoint; //Number of points for this track
// Short_t fValid; //Validity criterion
//
// An example of a batch program to use the Event/Track classes is given
// in this directory: MainEvent.
// Look also in the same directory at the following macros:
// - eventa.C an example how to read the tree
// - eventb.C how to read events conditionally
//
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#include "TRandom.h"
#include "Event.h"
ClassImp(EventHeader)
ClassImp(Event)
ClassImp(Track)
TClonesArray *gTracks;
TH1F *gHist;
TH1F *hNtrack,*hNseg, *hTemperature;
TH1F *hPx, *hPy, *hPz, *hRandom, *hMass2, *hBx, *hBy;
TH1F *hMeanCharge,*hXfirst,*hXlast,*hYfirst,*hYlast;
TH1F *hZfirst,*hZlast,*hCharge,*hNpoint,*hValid;
//______________________________________________________________________________
Event::Event()
{
// Create one Event object
// When the constructor is invoked for the first time, the global
// variable gTracks is NULL. The TClonesArray gTracks is created.
// The histogram fH is created.
//
fNtrack = 0;
if (!gTracks) gTracks = new TClonesArray("Track", 1000);
fTracks = gTracks;
fH = 0;
}
//______________________________________________________________________________
Event::~Event()
{
Clear();
}
//______________________________________________________________________________
void Event::AddTrack(Float_t random)
{
// Add a new track to the list of tracks for this event.
// To avoid calling the very time consuming operator new for each track,
// the standard but not well know C++ operator "new with placement" is called.
// if tracks[i] is NULL, a new Track object will be created
// otherwise the previous Track[i] will be overwritten.
TClonesArray &tracks = *fTracks;
new(tracks[fNtrack++]) Track(random);
}
//______________________________________________________________________________
void Event::Clear()
{
fTracks->Clear();
delete fH;
fH = 0;
}
//______________________________________________________________________________
void Event::Hcreate()
{
// Create histograms
hNtrack = new TH1F("hNtrack", "Ntrack",100,575,625);
hNseg = new TH1F("hNseg", "Nseg",100,5800,6200);
hTemperature = new TH1F("hTemperature","Temperature",100,19.5,20.5);
hPx = new TH1F("hPx", "Px",100,-4,4);
hPy = new TH1F("hPy", "Py",100,-4,4);
hPz = new TH1F("hPz", "Pz",100,0,5);
hRandom = new TH1F("hRandom", "Random",100,0,1000);
hMass2 = new TH1F("hMass2", "Mass2",100,0,12);
hBx = new TH1F("hBx", "Bx",100,-0.5,0.5);
hBy = new TH1F("hBy", "By",100,-0.5,0.5);
hMeanCharge = new TH1F("hMeanCharge","MeanCharge",100,0,0.01);
hXfirst = new TH1F("hXfirst", "Xfirst",100,-40,40);
hXlast = new TH1F("hXlast", "Xlast",100,-40,40);
hYfirst = new TH1F("hYfirst", "Yfirst",100,-40,40);
hYlast = new TH1F("hYlast", "Ylast",100,-40,40);
hZfirst = new TH1F("hZfirst", "Zfirst",100,0,80);
hZlast = new TH1F("hZlast", "Zlast",100,0,250);
hCharge = new TH1F("hCharge", "Charge",100,-1.5,1.5);
hNpoint = new TH1F("hNpoint", "Npoint",100,50,80);
hValid = new TH1F("hValid", "Valid",100,0,1.2);
}
//______________________________________________________________________________
void Event::Hfill()
{
// Fill histograms
hNtrack->Fill(fNtrack);
hNseg->Fill(fNseg);
hTemperature->Fill(fTemperature);
for (Int_t itrack=0;itrack<fNtrack;itrack++) {
Track *track = (Track*)fTracks->UncheckedAt(itrack);
hPx->Fill(track->GetPx());
hPy->Fill(track->GetPy());
hPz->Fill(track->GetPz());
hRandom->Fill(track->GetRandom());
hMass2->Fill(track->GetMass2());
hBx->Fill(track->GetBx());
hBy->Fill(track->GetBy());
hMeanCharge->Fill(track->GetMeanCharge());
hXfirst->Fill(track->GetXfirst());
hXlast->Fill(track->GetXlast());
hYfirst->Fill(track->GetYfirst());
hYlast->Fill(track->GetYlast());
hZfirst->Fill(track->GetZfirst());
hZlast->Fill(track->GetZlast());
hCharge->Fill(track->GetCharge());
hNpoint->Fill(track->GetNpoint());
hValid->Fill(track->GetValid());
}
}
//______________________________________________________________________________
void Event::SetHeader(Int_t i, Int_t run, Int_t date, Float_t random)
{
fNtrack = 0;
fEvtHdr.Set(i, run, date);
if (!gHist) gHist = new TH1F("hstat","Event Histogram",100,0,1);
fH = gHist;
fH->Fill(random);
}
//______________________________________________________________________________
Track::Track(Float_t random) :TObject()
{
//*-*-*-*-*-*-*-*-*-*-*Track normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =======================
// Note that in this example, data members do not have any physical meaning
Float_t a,b,sigmat,sigmas,px,py,pz;
gRandom->Rannor(px,py);
fPx = px;
fPy = py;
fPz = TMath::Sqrt(px*px+py*py);
fRandom = 1000*random;
if (fRandom < 10) fMass2 = 0.08;
else if (fRandom < 100) fMass2 = 0.8;
else if (fRandom < 500) fMass2 = 4.5;
else if (fRandom < 900) fMass2 = 8.9;
else fMass2 = 9.8;
gRandom->Rannor(a,b);
fBx = 0.1*a;
fBy = 0.1*b;
fMeanCharge = 0.01*gRandom->Rndm(1);
gRandom->Rannor(a,b);
fXfirst = a*10;
fXlast = b*10;
gRandom->Rannor(a,b);
fYfirst = a*12;
fYlast = b*16;
gRandom->Rannor(a,b);
fZfirst = 50 + 5*a;
fZlast = 200 + 10*b;
fCharge = Float_t(Int_t(3*gRandom->Rndm(1)) - 1);
fNpoint = Int_t(60+10*gRandom->Rndm(1));
fValid = Int_t(0.6+gRandom->Rndm(1));
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.