]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/STEERBase/TTreeStream.cxx
Adding static methods to get the azimuthal angle and eta range for a given vzero...
[u/mrichter/AliRoot.git] / STEER / STEERBase / TTreeStream.cxx
CommitLineData
9edefa04 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
9996a03b 18//
19// marian.ivanov@cern.ch
20//
21// ------------------------------------------------------------------------------------------------
22// TTreeStream
23// Standard stream (cout) like input for the tree
24// Run and see TTreeStreamer::Test() - to see TTreeStreamer functionality
25// ------------------------------------------------------------------------------------------------
26//
27// -------------------------------------------------------------------------------------------------
28// TTreeSRedirector
29// Redirect file to different TTreeStreams
30// Run and see TTreeSRedirector::Test() as an example of TTreeSRedirectorer functionality
31//
32
9edefa04 33#include <TClass.h>
34#include <TFile.h>
e619a839 35#include <TDirectory.h>
9edefa04 36#include <TObjArray.h>
37#include <TTree.h>
7330f0e5 38#include "TTreeStream.h"
cd246117 39
40ClassImp(TTreeDataElement)
41ClassImp(TTreeStream)
42ClassImp(TTreeSRedirector)
43
cd246117 44
45
46void TTreeStream::Test()
47{
48 //
49 //
50 TFile *ftest = new TFile("teststreamer.root","recreate");
51 if (!ftest) ftest = new TFile("teststreamer.root","new");
52 //
53 //create to streems Tree1 and Tree2
54 TTreeStream stream1("Tree1");
55 TTreeStream stream2("Tree2");
56 //
57 Char_t ch='s';
58 Float_t f=3.;
59 Float_t f2=1;
60 TObject *po = new TObject;
61 TObject *po2 = new TObject;
62 for (Int_t i=0;i<100000;i++) {
63 f=i*100;
64 po->SetUniqueID(i);
65 po2->SetUniqueID(i*100);
66 ch=i%120;
67 //
68 // Stream the data
69 // The data layout of stream is defined during first invocation of streamer.
70 // Endl is the trigger which define the end of structure.
71 //
72 // The name of branch can be specified using strings with = at the the end
73 // if string is not specified automatic convention is u (sed B0, B1, ...Bn)
74 stream1<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
75 f = 1./(100.1+i);
76 f2 = -f;
77 //3.) just another example - we can fill the same tree with different objects
78 //
79 stream2<<f<<po<<"\n";
80 stream2<<f2<<po2<<"\n";
81 }
82 //
83 //4.) Close the streeamers (Write the streamed tree's to the file) and close the corresponding file.
84 //
85 stream1.Close();
86 stream2.Close();
87 ftest->Close();
88 delete ftest;
89 //
90 //5.) and now see results in file tteststreamer.root
91}
92
b857113b 93void TTreeSRedirector::Test2()
94{
95 //
96 //Example test function to show functionality of TTreeSRedirector
97 //
98 //
99 //1.)create the redirector associated with file (testredirector.root)
100 //
101 //
102 TFile* file = new TFile("test.root","recreate");
103 TTreeSRedirector *pmistream= new TTreeSRedirector();
104 TTreeSRedirector &mistream = *pmistream;
105 Char_t ch='s';
106 Float_t f=3.;
107 Float_t f2=1;
108 TObject *po = new TObject;
109 TObject *po2 = new TObject;
110 for (Int_t i=0;i<100000;i++) {
111 f=i*100;
112 po->SetUniqueID(i);
113 po2->SetUniqueID(i*100);
114 ch=i%120;
115 //
116 //2.) create the tree with identifier specified by first argument
117 // layout specified by sequence of arguments
118 // Tree identifier has to be specified as first argument !!!
119 // if the tree and layout was already defined the consistency if layout is checked
120 // if the data are consisten fill given tree
121 // the name of branch can be specified using strings with = at the the end
122 // if string is not specified use automatic convention B0, B1, ...Bn
123 mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
124 f = 1./(100.1+i);
125 f2 = -f;
126
127 //3.) just another example - we can fill the same tree with different objects
128 //
129 mistream<<"TreeK"<<f<<po<<"\n";
130 mistream<<"TreeK"<<f2<<po2<<"\n";
131 }
132 //
133 //4.) write the streamed tree's to the file and close the corresponding file in destructor
134 //
135 delete pmistream;
136 delete file;
137 //
138 //5.) and now see results in file testredirector.root
139}
cd246117 140
141void TTreeSRedirector::Test()
142{
143 //
144 //Example test function to show functionality of TTreeSRedirector
145 //
146 //
147 //1.)create the redirector associated with file (testredirector.root)
148 //
149 //
150 TTreeSRedirector *pmistream= new TTreeSRedirector("testredirector.root");
151 TTreeSRedirector &mistream = *pmistream;
152 Char_t ch='s';
153 Float_t f=3.;
154 Float_t f2=1;
155 TObject *po = new TObject;
156 TObject *po2 = new TObject;
157 for (Int_t i=0;i<100000;i++) {
158 f=i*100;
159 po->SetUniqueID(i);
160 po2->SetUniqueID(i*100);
161 ch=i%120;
162 //
163 //2.) create the tree with identifier specified by first argument
164 // layout specified by sequence of arguments
165 // Tree identifier has to be specified as first argument !!!
166 // if the tree and layout was already defined the consistency if layout is checked
167 // if the data are consisten fill given tree
168 // the name of branch can be specified using strings with = at the the end
169 // if string is not specified use automatic convention B0, B1, ...Bn
170 mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
171 f = 1./(100.1+i);
172 f2 = -f;
173
174 //3.) just another example - we can fill the same tree with different objects
175 //
176 mistream<<"TreeK"<<f<<po<<"\n";
177 mistream<<"TreeK"<<f2<<po2<<"\n";
178 }
179 //
180 //4.) write the streamed tree's to the file and close the corresponding file in destructor
181 //
182 delete pmistream;
183 //
184 //5.) and now see results in file testredirector.root
185}
186
187
d01710c6 188TTreeSRedirector::TTreeSRedirector(const char *fname,const char * option) :
b857113b 189 fDirectory(NULL),
190 fDirectoryOwner(kTRUE),
191 fDataLayouts(NULL)
90e48c0c 192{
cd246117 193 //
90e48c0c 194 // Constructor
cd246117 195 //
b857113b 196 TString name(fname);
197 if (!name.IsNull()){
198 fDirectory = new TFile(fname,option);
199 }
200 else
201 {
202 fDirectory = gDirectory;
203 fDirectoryOwner = kFALSE;
cd246117 204 }
cd246117 205}
206
90e48c0c 207TTreeSRedirector::~TTreeSRedirector()
208{
cd246117 209 //
90e48c0c 210 // Destructor
cd246117 211 //
212 Close(); //write the tree to the selected file
b857113b 213 if (fDirectoryOwner)
214 {
215 fDirectory->Close();
216 delete fDirectory;
217 }
cd246117 218}
df1e0cdc 219void TTreeSRedirector::StoreObject(TObject* object){
220 //
221 //
222 //
e619a839 223 TDirectory * backup = gDirectory;
b857113b 224 fDirectory->cd();
df1e0cdc 225 object->Write();
226 if (backup) backup->cd();
227}
228
b857113b 229void TTreeSRedirector::SetDirectory(TDirectory *sfile){
d01710c6 230 //
231 // Set the external file
232 // In case other file already attached old file is closed before
233 // Redirector will be the owner of file ?
b857113b 234 if (fDirectory && fDirectoryOwner) {
235 fDirectory->Close();
236 delete fDirectory;
d01710c6 237 }
b857113b 238 fDirectory=sfile;
d01710c6 239}
240
cd246117 241TTreeStream & TTreeSRedirector::operator<<(Int_t id)
242{
243 //
244 // return reference to the data layout with given identifier
245 // if not existing - creates new
246 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
247 TTreeStream *clayout=0;
248 Int_t entries = fDataLayouts->GetEntriesFast();
249 for (Int_t i=0;i<entries;i++){
250 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
251 if (!layout) continue;
252 if (layout->fId==id) {
253 clayout = layout;
254 break;
255 }
256 }
257 if (!clayout){
2c69896b 258 TDirectory * backup = gDirectory;
b857113b 259 fDirectory->cd();
cd246117 260 char chname[100];
cd507f9c 261 snprintf(chname,100,"Tree%d",id);
cd246117 262 clayout = new TTreeStream(chname);
263 clayout->fId=id;
264 fDataLayouts->AddAt(clayout,entries);
2c69896b 265 if (backup) backup->cd();
cd246117 266 }
267 return *clayout;
268}
269
b857113b 270void TTreeSRedirector::SetExternalTree(const char* name, TTree* externalTree)
271{
272 TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
273
274 if (!clayout){
275 TDirectory * backup = gDirectory;
276 fDirectory->cd();
277 clayout = new TTreeStream(name,externalTree);
278 clayout->fId=-1;
279 clayout->SetName(name);
280 Int_t entries = fDataLayouts->GetEntriesFast();
281 fDataLayouts->AddAt(clayout,entries);
282 if (backup) backup->cd();
283 }
284 //else
285 // AliError(Form("identifier %s already associated",name));
286}
287
cd246117 288
289TTreeStream & TTreeSRedirector::operator<<(const char* name)
290{
291 //
292 // return reference to the data layout with given identifier
293 // if not existing - creates new
294 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
2fca8fe0 295 TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
cd246117 296 Int_t entries = fDataLayouts->GetEntriesFast();
2fca8fe0 297
cd246117 298 if (!clayout){
2c69896b 299 TDirectory * backup = gDirectory;
b857113b 300 fDirectory->cd();
cd246117 301 clayout = new TTreeStream(name);
302 clayout->fId=-1;
303 clayout->SetName(name);
cd246117 304 fDataLayouts->AddAt(clayout,entries);
2c69896b 305 if (backup) backup->cd();
cd246117 306 }
307 return *clayout;
308}
309
310
311
312
313void TTreeSRedirector::Close(){
314 //
315 //
e619a839 316 TDirectory * backup = gDirectory;
b857113b 317 fDirectory->cd();
2fca8fe0 318 if (fDataLayouts){
319 Int_t entries = fDataLayouts->GetEntriesFast();
320 for (Int_t i=0;i<entries;i++){
321 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
322 if (layout){
323 if (layout->fTree) layout->fTree->Write(layout->GetName());
324 }
325 }
326 delete fDataLayouts;
327 fDataLayouts=0;
cd246117 328 }
d0742e95 329 if (backup) backup->cd();
cd246117 330}
331
cd246117 332//-------------------------------------------------------------
90e48c0c 333TTreeDataElement:: TTreeDataElement(Char_t type) :
fdf65bb5 334 TNamed(),
90e48c0c 335 fType(type),
336 fDType(0),
337 fClass(0),
338 fPointer(0)
339{
340 //
cd246117 341 //
342 //
cd246117 343}
90e48c0c 344
345TTreeDataElement:: TTreeDataElement(TDataType* type) :
fdf65bb5 346 TNamed(),
81e97e0d 347 fType(0),
90e48c0c 348 fDType(type),
349 fClass(0),
350 fPointer(0)
351{
352 //
cd246117 353 //
354 //
cd246117 355}
90e48c0c 356
357TTreeDataElement:: TTreeDataElement(TClass* cl) :
fdf65bb5 358 TNamed(),
81e97e0d 359 fType(0),
90e48c0c 360 fDType(0),
361 fClass(cl),
362 fPointer(0)
363{
364 //
cd246117 365 //
366 //
cd246117 367}
368
369//-------------------------------------------------------------------
b857113b 370TTreeStream::TTreeStream(const char *treename, TTree* externalTree):
90e48c0c 371 TNamed(treename,treename),
372 fElements(0),
373 fBranches(0),
b857113b 374 fTree(externalTree),
90e48c0c 375 fCurrentIndex(0),
fe12e09c 376 fId(0),
90e48c0c 377 fNextName(),
378 fNextNameCounter(),
379 fStatus(0)
380{
9996a03b 381 //
382 // Standard ctor
383 //
b857113b 384 if (!fTree) fTree = new TTree(treename, treename);
cd246117 385}
386
387TTreeStream::~TTreeStream()
388{
9996a03b 389 //
390 // Class dtor
391 //
cd246117 392 fElements->Delete();
393 fBranches->Clear();
394 delete fElements;
395 delete fBranches;
396}
397
398void TTreeStream::Close()
399{
9996a03b 400 //
401 // Flush data to disk and close
cd246117 402 //
403 fTree->Write();
404}
405
406Int_t TTreeStream::CheckIn(Char_t type, void *pointer)
407{
9996a03b 408 //
409 // Insert object of given type
410 //
78e18d24 411 if (!fElements) fElements = new TObjArray(10000);
412 if (fElements->GetSize()<=fCurrentIndex) fElements->Expand(fCurrentIndex*2);
cd246117 413 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
414 if (!element) {
415 element = new TTreeDataElement(type);
416 //
417 char name[1000];
418 if (fNextName.Length()>0){
419 if (fNextNameCounter==0){
cd507f9c 420 snprintf(name,1000,"%s",(const char*)fNextName);
cd246117 421 }
422 if (fNextNameCounter>0){
cd507f9c 423 snprintf(name,1000,"%s%d",(const char*)fNextName,fNextNameCounter);
cd246117 424 }
425 }
426 else{
cd507f9c 427 snprintf(name,1000,"B%d.",fCurrentIndex);
cd246117 428 }
429 element->SetName(name);
430 //
431 element->SetPointer(pointer);
432 fElements->AddAt(element,fCurrentIndex);
433 fCurrentIndex++;
434 return 0; //new element added
435 }
436 if (element->GetType()!=type){
437 fStatus++;
438 return 1; //mismatched data element
439 }
440 element->SetPointer(pointer);
441 fCurrentIndex++;
442 return 0;
443}
444
445Int_t TTreeStream::CheckIn(TObject *o){
446 //
9996a03b 447 // Insert TObject
cd246117 448 //
449 if (!o) return 0;
450 if (!fElements) fElements = new TObjArray(1000);
451 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
452 if (!element) {
453 element = new TTreeDataElement(o->IsA());
454 //
455 char name[1000];
456 if (fNextName.Length()>0){
457 if (fNextNameCounter==0){
cd507f9c 458 snprintf(name,1000,"%s",(const char*)fNextName);
cd246117 459 }
460 if (fNextNameCounter>0){
cd507f9c 461 snprintf(name,1000,"%s%d",(const char*)fNextName,fNextNameCounter);
cd246117 462 }
463 }
464 else{
cd507f9c 465 snprintf(name,1000,"B%d",fCurrentIndex);
cd246117 466 }
467 element->SetName(name);
468
469 element->SetPointer(o);
470 fElements->AddAt(element,fCurrentIndex);
471 fCurrentIndex++;
472 return 0; //new element added
473 }
474 if (element->fClass!=o->IsA()){
475 fStatus++;
476 return 1; //mismatched data element
477 }
478 element->SetPointer(o);
479 fCurrentIndex++;
480 return 0;
481}
482
483void TTreeStream::BuildTree(){
484 //
9996a03b 485 // Build the Tree
cd246117 486 //
bbc15444 487 if (fTree && fTree->GetEntries()>0) return;
488 if (!fTree) fTree = new TTree(GetName(),GetName());
cd246117 489 Int_t entries = fElements->GetEntriesFast();
490 fBranches = new TObjArray(entries);
491
492 for (Int_t i=0;i<entries;i++){
493 //
494 TTreeDataElement* element = (TTreeDataElement*)fElements->At(i);
495 char bname1[1000];
496 if (element->GetName()[0]==0){
cd507f9c 497 snprintf(bname1,1000,"B%d",i);
cd246117 498 }
499 else{
389410ea 500 snprintf(bname1,1000,"%s",element->GetName());
cd246117 501 }
502 if (element->fClass){
2fca8fe0 503 if (element->fClass->GetBaseClass("TClonesArray")){
3194e208 504 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
2fca8fe0 505 fBranches->AddAt(br,i);
506 }else
507 {
508 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
509 fBranches->AddAt(br,i);
510 }
cd246117 511 }
512 if (element->GetType()>0){
513 char bname2[1000];
cd507f9c 514 snprintf(bname2,1000,"B%d/%c",i,element->GetType());
cd246117 515 TBranch * br = fTree->Branch(bname1,element->fPointer,bname2);
516 fBranches->AddAt(br,i);
517 }
518 }
519}
520
521void TTreeStream::Fill(){
522 //
9996a03b 523 // Fill the tree
cd246117 524 //
525 if (fTree) {
526 Int_t entries=fElements->GetEntriesFast();
527 if (entries>fTree->GetNbranches()) BuildTree();
528 for (Int_t i=0;i<entries;i++){
529 TTreeDataElement* el = (TTreeDataElement*)fElements->At(i);
530 if (!el) continue;
531 if (!el->GetType()) continue;
532 TBranch * br = (TBranch*)fBranches->At(i);
533 if (br &&el){
534 if (el->GetType()) br->SetAddress(el->fPointer);
535 }
536 }
537 if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts
538 fStatus=0;
539 }
540}
541
9996a03b 542TTreeStream & TTreeStream::Endl()
543{
544 //
545 // Perform pseudo endl operation
546 //
cd246117 547 if (fTree->GetNbranches()==0) BuildTree();
548 Fill();
549 fStatus =0;
550 fCurrentIndex=0;
551 return *this;
552}
553
554
4f57cad7 555TTreeStream &TTreeStream::operator<<(const Char_t *name)
cd246117 556{
557 //
9996a03b 558 // Endl
cd246117 559 //
cd246117 560 if (name[0]=='\n'){
561 return Endl();
562 }
563 //
564 //if tree was already defined ignore
565 if (fTree->GetEntries()>0) return *this;
566 //check branch name if tree was not
567 //
568 Int_t last=0;
569 for (last=0;;last++){
570 if (name[last]==0) break;
571 }
572
573 if (last>0&&name[last-1]=='='){
574 fNextName = name;
575 fNextName[last-1]=0;
576 fNextNameCounter=0;
577 }
578 return *this;
579}
580