]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/TTreeStream.cxx
Changes suggested by Effective C++ (F.Carminati)
[u/mrichter/AliRoot.git] / STEER / TTreeStream.cxx
CommitLineData
cd246117 1#include "TObjArray.h"
2#include "TFile.h"
3#include "TTree.h"
4#include "TBrowser.h"
5#include "TTreeStream.h"
6
7
8ClassImp(TTreeDataElement)
9ClassImp(TTreeStream)
10ClassImp(TTreeSRedirector)
11
12/*
13 marian.ivanov@cern.ch
14 //
15 ------------------------------------------------------------------------------------------------
16 TTreeStream
17 Standard stream (cout) like input for the tree
18 Run and see TTreeStreamer::Test() - to see TTreeStreamer functionality
19 ------------------------------------------------------------------------------------------------
20 //
21 -------------------------------------------------------------------------------------------------
22 TTreeSRedirector
23 Redirect file to different TTreeStreams
24 Run and see TTreeSRedirector::Test() as an example of TTreeSRedirectorer functionality
25 //
26*/
27
28
29void TTreeStream::Test()
30{
31 //
32 //
33 TFile *ftest = new TFile("teststreamer.root","recreate");
34 if (!ftest) ftest = new TFile("teststreamer.root","new");
35 //
36 //create to streems Tree1 and Tree2
37 TTreeStream stream1("Tree1");
38 TTreeStream stream2("Tree2");
39 //
40 Char_t ch='s';
41 Float_t f=3.;
42 Float_t f2=1;
43 TObject *po = new TObject;
44 TObject *po2 = new TObject;
45 for (Int_t i=0;i<100000;i++) {
46 f=i*100;
47 po->SetUniqueID(i);
48 po2->SetUniqueID(i*100);
49 ch=i%120;
50 //
51 // Stream the data
52 // The data layout of stream is defined during first invocation of streamer.
53 // Endl is the trigger which define the end of structure.
54 //
55 // The name of branch can be specified using strings with = at the the end
56 // if string is not specified automatic convention is u (sed B0, B1, ...Bn)
57 stream1<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
58 f = 1./(100.1+i);
59 f2 = -f;
60 //3.) just another example - we can fill the same tree with different objects
61 //
62 stream2<<f<<po<<"\n";
63 stream2<<f2<<po2<<"\n";
64 }
65 //
66 //4.) Close the streeamers (Write the streamed tree's to the file) and close the corresponding file.
67 //
68 stream1.Close();
69 stream2.Close();
70 ftest->Close();
71 delete ftest;
72 //
73 //5.) and now see results in file tteststreamer.root
74}
75
76
77
78void TTreeSRedirector::Test()
79{
80 //
81 //Example test function to show functionality of TTreeSRedirector
82 //
83 //
84 //1.)create the redirector associated with file (testredirector.root)
85 //
86 //
87 TTreeSRedirector *pmistream= new TTreeSRedirector("testredirector.root");
88 TTreeSRedirector &mistream = *pmistream;
89 Char_t ch='s';
90 Float_t f=3.;
91 Float_t f2=1;
92 TObject *po = new TObject;
93 TObject *po2 = new TObject;
94 for (Int_t i=0;i<100000;i++) {
95 f=i*100;
96 po->SetUniqueID(i);
97 po2->SetUniqueID(i*100);
98 ch=i%120;
99 //
100 //2.) create the tree with identifier specified by first argument
101 // layout specified by sequence of arguments
102 // Tree identifier has to be specified as first argument !!!
103 // if the tree and layout was already defined the consistency if layout is checked
104 // if the data are consisten fill given tree
105 // the name of branch can be specified using strings with = at the the end
106 // if string is not specified use automatic convention B0, B1, ...Bn
107 mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
108 f = 1./(100.1+i);
109 f2 = -f;
110
111 //3.) just another example - we can fill the same tree with different objects
112 //
113 mistream<<"TreeK"<<f<<po<<"\n";
114 mistream<<"TreeK"<<f2<<po2<<"\n";
115 }
116 //
117 //4.) write the streamed tree's to the file and close the corresponding file in destructor
118 //
119 delete pmistream;
120 //
121 //5.) and now see results in file testredirector.root
122}
123
124
90e48c0c 125TTreeSRedirector::TTreeSRedirector(const char *fname) :
126 fFile(new TFile(fname,"recreate")),
127 fDataLayouts(0)
128{
cd246117 129 //
90e48c0c 130 // Constructor
cd246117 131 //
cd246117 132 if (!fFile){
133 fFile = new TFile(fname,"new");
134 }
cd246117 135}
136
90e48c0c 137TTreeSRedirector::~TTreeSRedirector()
138{
cd246117 139 //
90e48c0c 140 // Destructor
cd246117 141 //
142 Close(); //write the tree to the selected file
143 fFile->Close();
144 delete fFile;
145}
146
147TTreeStream & TTreeSRedirector::operator<<(Int_t id)
148{
149 //
150 // return reference to the data layout with given identifier
151 // if not existing - creates new
152 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
153 TTreeStream *clayout=0;
154 Int_t entries = fDataLayouts->GetEntriesFast();
155 for (Int_t i=0;i<entries;i++){
156 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
157 if (!layout) continue;
158 if (layout->fId==id) {
159 clayout = layout;
160 break;
161 }
162 }
163 if (!clayout){
2fca8fe0 164 fFile->cd();
cd246117 165 char chname[100];
166 sprintf(chname,"Tree%d",id);
167 clayout = new TTreeStream(chname);
168 clayout->fId=id;
169 fDataLayouts->AddAt(clayout,entries);
170 }
171 return *clayout;
172}
173
174
175TTreeStream & TTreeSRedirector::operator<<(const char* name)
176{
177 //
178 // return reference to the data layout with given identifier
179 // if not existing - creates new
180 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
2fca8fe0 181 TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
cd246117 182 Int_t entries = fDataLayouts->GetEntriesFast();
2fca8fe0 183
cd246117 184 if (!clayout){
2fca8fe0 185 fFile->cd();
cd246117 186 clayout = new TTreeStream(name);
187 clayout->fId=-1;
188 clayout->SetName(name);
cd246117 189 fDataLayouts->AddAt(clayout,entries);
190 }
191 return *clayout;
192}
193
194
195
196
197void TTreeSRedirector::Close(){
198 //
199 //
2fca8fe0 200 TFile * backup = gFile;
201 fFile->cd();
202 if (fDataLayouts){
203 Int_t entries = fDataLayouts->GetEntriesFast();
204 for (Int_t i=0;i<entries;i++){
205 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
206 if (layout){
207 if (layout->fTree) layout->fTree->Write(layout->GetName());
208 }
209 }
210 delete fDataLayouts;
211 fDataLayouts=0;
cd246117 212 }
2fca8fe0 213 backup->cd();
cd246117 214}
215
216
217
218//-------------------------------------------------------------
90e48c0c 219TTreeDataElement:: TTreeDataElement(Char_t type) :
220 fName(),
221 fType(type),
222 fDType(0),
223 fClass(0),
224 fPointer(0)
225{
226 //
cd246117 227 //
228 //
cd246117 229}
90e48c0c 230
231TTreeDataElement:: TTreeDataElement(TDataType* type) :
232 fName(),
233 fType(' '),
234 fDType(type),
235 fClass(0),
236 fPointer(0)
237{
238 //
cd246117 239 //
240 //
cd246117 241}
90e48c0c 242
243TTreeDataElement:: TTreeDataElement(TClass* cl) :
244 fName(),
245 fType(' '),
246 fDType(0),
247 fClass(cl),
248 fPointer(0)
249{
250 //
cd246117 251 //
252 //
cd246117 253}
254
255//-------------------------------------------------------------------
90e48c0c 256TTreeStream::TTreeStream(const char *treename):
257 TNamed(treename,treename),
258 fElements(0),
259 fBranches(0),
260 fTree(new TTree(treename, treename)),
261 fCurrentIndex(0),
262 fNextName(),
263 fNextNameCounter(),
264 fStatus(0)
265{
cd246117 266}
267
268TTreeStream::~TTreeStream()
269{
270 fElements->Delete();
271 fBranches->Clear();
272 delete fElements;
273 delete fBranches;
274}
275
276void TTreeStream::Close()
277{
278 //
279 fTree->Write();
280}
281
282Int_t TTreeStream::CheckIn(Char_t type, void *pointer)
283{
284 if (!fElements) fElements = new TObjArray(1000);
285 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
286 if (!element) {
287 element = new TTreeDataElement(type);
288 //
289 char name[1000];
290 if (fNextName.Length()>0){
291 if (fNextNameCounter==0){
292 sprintf(name,"%s",(const char*)fNextName);
293 }
294 if (fNextNameCounter>0){
295 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
296 }
297 }
298 else{
299 sprintf(name,"B%d.",fCurrentIndex);
300 }
301 element->SetName(name);
302 //
303 element->SetPointer(pointer);
304 fElements->AddAt(element,fCurrentIndex);
305 fCurrentIndex++;
306 return 0; //new element added
307 }
308 if (element->GetType()!=type){
309 fStatus++;
310 return 1; //mismatched data element
311 }
312 element->SetPointer(pointer);
313 fCurrentIndex++;
314 return 0;
315}
316
317Int_t TTreeStream::CheckIn(TObject *o){
318 //
319 //
320 if (!o) return 0;
321 if (!fElements) fElements = new TObjArray(1000);
322 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
323 if (!element) {
324 element = new TTreeDataElement(o->IsA());
325 //
326 char name[1000];
327 if (fNextName.Length()>0){
328 if (fNextNameCounter==0){
329 sprintf(name,"%s",(const char*)fNextName);
330 }
331 if (fNextNameCounter>0){
332 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
333 }
334 }
335 else{
336 sprintf(name,"B%d",fCurrentIndex);
337 }
338 element->SetName(name);
339
340 element->SetPointer(o);
341 fElements->AddAt(element,fCurrentIndex);
342 fCurrentIndex++;
343 return 0; //new element added
344 }
345 if (element->fClass!=o->IsA()){
346 fStatus++;
347 return 1; //mismatched data element
348 }
349 element->SetPointer(o);
350 fCurrentIndex++;
351 return 0;
352}
353
354void TTreeStream::BuildTree(){
355 //
356 //
357 if (fTree->GetEntries()>0) return;
358 fTree = new TTree(GetName(),GetName());
359 Int_t entries = fElements->GetEntriesFast();
360 fBranches = new TObjArray(entries);
361
362 for (Int_t i=0;i<entries;i++){
363 //
364 TTreeDataElement* element = (TTreeDataElement*)fElements->At(i);
365 char bname1[1000];
366 if (element->GetName()[0]==0){
367 sprintf(bname1,"B%d",i);
368 }
369 else{
370 sprintf(bname1,element->GetName());
371 }
372 if (element->fClass){
2fca8fe0 373 if (element->fClass->GetBaseClass("TClonesArray")){
374 TBranch * br = fTree->Branch(bname1,&(element->fPointer));
375 fBranches->AddAt(br,i);
376 }else
377 {
378 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
379 fBranches->AddAt(br,i);
380 }
cd246117 381 }
382 if (element->GetType()>0){
383 char bname2[1000];
384 sprintf(bname2,"B%d/%c",i,element->GetType());
385 TBranch * br = fTree->Branch(bname1,element->fPointer,bname2);
386 fBranches->AddAt(br,i);
387 }
388 }
389}
390
391void TTreeStream::Fill(){
392 //
393 //
394 if (fTree) {
395 Int_t entries=fElements->GetEntriesFast();
396 if (entries>fTree->GetNbranches()) BuildTree();
397 for (Int_t i=0;i<entries;i++){
398 TTreeDataElement* el = (TTreeDataElement*)fElements->At(i);
399 if (!el) continue;
400 if (!el->GetType()) continue;
401 TBranch * br = (TBranch*)fBranches->At(i);
402 if (br &&el){
403 if (el->GetType()) br->SetAddress(el->fPointer);
404 }
405 }
406 if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts
407 fStatus=0;
408 }
409}
410
411TTreeStream & TTreeStream::Endl(){
412 if (fTree->GetNbranches()==0) BuildTree();
413 Fill();
414 fStatus =0;
415 fCurrentIndex=0;
416 return *this;
417}
418
419
420TTreeStream &TTreeStream::operator<<(Char_t *name)
421{
422 //
423 //
424 //
425 //Endl
426 if (name[0]=='\n'){
427 return Endl();
428 }
429 //
430 //if tree was already defined ignore
431 if (fTree->GetEntries()>0) return *this;
432 //check branch name if tree was not
433 //
434 Int_t last=0;
435 for (last=0;;last++){
436 if (name[last]==0) break;
437 }
438
439 if (last>0&&name[last-1]=='='){
440 fNextName = name;
441 fNextName[last-1]=0;
442 fNextNameCounter=0;
443 }
444 return *this;
445}
446