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