Hi Rooters,
I am trying to create a tree with several branches containing objects of
the same class (e.g. Event), but the data in the tree seem to be
completely corrupted. Here is what I would like to do (I attach the full
modified MainEvent.cxx at the end).
// Create two Event objects
Event *event1 = new Event();
Event *event2 = new Event();
// Create two branches
TBranch *branch1 = tree->Branch("event1", "Event", &event1,
bufsize,split);
TBranch *branch2 = tree->Branch("event2", "Event", &event2,
bufsize,split);
// Fill the tree
event1->SetType(1);
event2->SetType(2);
...
// Create and fill track objects
event1->AddTrack(random1);
event2->AddTrack(random2);
The tree is filled, but when I look at it, the Track data are screwed
up. I also tried to add a dot to the branch name, but it didn't improve
things.
What am I missing?
Best regards,
Bernhard
// @(#)root/test:$Name: $:$Id: MainEvent.cxx,v 1.17 2001/07/09 20:38:07 brun Exp $
// Author: Rene Brun 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 split = -2 the event is split using the old TBranchObject mechanism
// if split = -1 the event is streamed using the old TBranchObject mechanism
// if split > 0 the event is split ising the new TBranchElement mechanism.
//
// 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 "TNetFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"
#include "TStopwatch.h"
#include "Event.h"
//______________________________________________________________________________
int main(int argc, char **argv)
{
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
Int_t netf = 0;
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; read = 1;}
if (arg4 == 1) { write = 1; hfill = 0;}
if (arg4 == 2) { write = 0; 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
if (arg4 >= 30) { netf = 1; } //use TNetFile
if (arg4 == 30) { write = 0; read = 1;} //netfile + read sequential
if (arg4 == 35) { write = 0; read = 2;} //netfile + read random
if (arg4 == 36) { write = 1; } //netfile + write sequential
Int_t branchStyle = 1; //new style by default
if (split < 0) {branchStyle = 0; split = 1-split;}
TFile *hfile;
TTree *tree;
Event *event1 = 0;
Event *event2 = 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;
Track::Class()->IgnoreTObjectStreamer();
// Read case
if (read) {
if (netf) {
hfile = new TNetFile("root://localhost/root/test/EventNet.root");
hfile->UseCache(10);
} else
hfile = new TFile("Event.root");
tree = (TTree*)hfile->Get("T");
TBranch *branch1 = tree->GetBranch("event1.");
branch1->SetAddress(&event1);
TBranch *branch2 = tree->GetBranch("event2.");
branch2->SetAddress(&event2);
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) {
tnew = timer.RealTime();
printf("event:%d, rtime=%f s\n",ev,tnew-told);
told=tnew;
timer.Continue();
}
nb += tree->GetEntry(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 = Int_t(nevent*gRandom->Rndm(1));
nb += tree->GetEntry(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.
if (netf) {
hfile = new TNetFile("root://localhost/root/test/EventNet.root","RECREATE","TTree benchmark ROOT file");
hfile->UseCache(10);
} else
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);
HistogramManager *hm = 0;
if (hfill) {
TDirectory *hdir = new TDirectory("histograms", "all histograms");
hm = new HistogramManager(hdir);
}
// 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 = 64000;
if (split) bufsize /= 4;
event1 = new Event();
event2 = new Event();
TTree::SetBranchStyle(branchStyle);
TBranch *branch1 = tree->Branch("event1.", "Event", &event1, bufsize,split);
branch1->SetAutoDelete(kFALSE);
TBranch *branch2 = tree->Branch("event2.", "Event", &event2, bufsize,split);
branch2->SetAutoDelete(kFALSE);
char etype[20];
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);
sprintf(etype,"type%d",ev%5);
event1->SetType(etype);
event1->SetHeader(ev, 200, 960312, random);
event1->SetNseg(Int_t(10*ntrack+20*sigmas));
event1->SetNvertex(Int_t(1+20*gRandom->Rndm()));
event1->SetFlag(UInt_t(random+0.5));
event1->SetTemperature(random+20.);
for(UChar_t m = 0; m < 10; m++) {
event1->SetMeasure(m, Int_t(gRandom->Gaus(m,m+1)));
}
for(UChar_t i0 = 0; i0 < 4; i0++) {
for(UChar_t i1 = 0; i1 < 4; i1++) {
event1->SetMatrix(i0,i1,gRandom->Gaus(i0*i1,1));
}
}
// Create and Fill the Track objects
for (Int_t t = 0; t < ntrack; t++) event1->AddTrack(random);
gRandom->Rannor(sigmat,sigmas);
ntrack = Int_t(arg5 +arg5*sigmat/20.);
random = gRandom->Rndm(1);
sprintf(etype,"type%d",ev%5);
event2->SetType(etype);
event2->SetHeader(ev, 200, 960312, random);
event2->SetNseg(Int_t(10*ntrack+20*sigmas));
event2->SetNvertex(Int_t(1+20*gRandom->Rndm()));
event2->SetFlag(UInt_t(random+0.5));
event2->SetTemperature(random+20.);
for(UChar_t m = 0; m < 10; m++) {
event2->SetMeasure(m, Int_t(gRandom->Gaus(m,m+1)));
}
for(UChar_t i0 = 0; i0 < 4; i0++) {
for(UChar_t i1 = 0; i1 < 4; i1++) {
event2->SetMatrix(i0,i1,gRandom->Gaus(i0*i1,1));
}
}
// Create and Fill the Track objects
for (Int_t t = 0; t < ntrack; t++) event2->AddTrack(random);
if (write) nb += tree->Fill(); //fill the tree
if (hm) hm->Hfill(event1); //fill histograms
event1->Clear();
event2->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;
}
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:05 MET