]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/TTreeStream.cxx
Classes for CTP time parameters added (Plamen)
[u/mrichter/AliRoot.git] / STEER / 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>
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
93
94
95void TTreeSRedirector::Test()
96{
97 //
98 //Example test function to show functionality of TTreeSRedirector
99 //
100 //
101 //1.)create the redirector associated with file (testredirector.root)
102 //
103 //
104 TTreeSRedirector *pmistream= new TTreeSRedirector("testredirector.root");
105 TTreeSRedirector &mistream = *pmistream;
106 Char_t ch='s';
107 Float_t f=3.;
108 Float_t f2=1;
109 TObject *po = new TObject;
110 TObject *po2 = new TObject;
111 for (Int_t i=0;i<100000;i++) {
112 f=i*100;
113 po->SetUniqueID(i);
114 po2->SetUniqueID(i*100);
115 ch=i%120;
116 //
117 //2.) create the tree with identifier specified by first argument
118 // layout specified by sequence of arguments
119 // Tree identifier has to be specified as first argument !!!
120 // if the tree and layout was already defined the consistency if layout is checked
121 // if the data are consisten fill given tree
122 // the name of branch can be specified using strings with = at the the end
123 // if string is not specified use automatic convention B0, B1, ...Bn
124 mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
125 f = 1./(100.1+i);
126 f2 = -f;
127
128 //3.) just another example - we can fill the same tree with different objects
129 //
130 mistream<<"TreeK"<<f<<po<<"\n";
131 mistream<<"TreeK"<<f2<<po2<<"\n";
132 }
133 //
134 //4.) write the streamed tree's to the file and close the corresponding file in destructor
135 //
136 delete pmistream;
137 //
138 //5.) and now see results in file testredirector.root
139}
140
141
90e48c0c 142TTreeSRedirector::TTreeSRedirector(const char *fname) :
143 fFile(new TFile(fname,"recreate")),
144 fDataLayouts(0)
145{
cd246117 146 //
90e48c0c 147 // Constructor
cd246117 148 //
cd246117 149 if (!fFile){
150 fFile = new TFile(fname,"new");
151 }
cd246117 152}
153
90e48c0c 154TTreeSRedirector::~TTreeSRedirector()
155{
cd246117 156 //
90e48c0c 157 // Destructor
cd246117 158 //
159 Close(); //write the tree to the selected file
160 fFile->Close();
161 delete fFile;
162}
df1e0cdc 163void TTreeSRedirector::StoreObject(TObject* object){
164 //
165 //
166 //
e619a839 167 TDirectory * backup = gDirectory;
df1e0cdc 168 fFile->cd();
169 object->Write();
170 if (backup) backup->cd();
171}
172
173
cd246117 174
175TTreeStream & TTreeSRedirector::operator<<(Int_t id)
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);
181 TTreeStream *clayout=0;
182 Int_t entries = fDataLayouts->GetEntriesFast();
183 for (Int_t i=0;i<entries;i++){
184 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
185 if (!layout) continue;
186 if (layout->fId==id) {
187 clayout = layout;
188 break;
189 }
190 }
191 if (!clayout){
2c69896b 192 TDirectory * backup = gDirectory;
2fca8fe0 193 fFile->cd();
cd246117 194 char chname[100];
195 sprintf(chname,"Tree%d",id);
196 clayout = new TTreeStream(chname);
197 clayout->fId=id;
198 fDataLayouts->AddAt(clayout,entries);
2c69896b 199 if (backup) backup->cd();
cd246117 200 }
201 return *clayout;
202}
203
204
205TTreeStream & TTreeSRedirector::operator<<(const char* name)
206{
207 //
208 // return reference to the data layout with given identifier
209 // if not existing - creates new
210 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
2fca8fe0 211 TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
cd246117 212 Int_t entries = fDataLayouts->GetEntriesFast();
2fca8fe0 213
cd246117 214 if (!clayout){
2c69896b 215 TDirectory * backup = gDirectory;
2fca8fe0 216 fFile->cd();
cd246117 217 clayout = new TTreeStream(name);
218 clayout->fId=-1;
219 clayout->SetName(name);
cd246117 220 fDataLayouts->AddAt(clayout,entries);
2c69896b 221 if (backup) backup->cd();
cd246117 222 }
223 return *clayout;
224}
225
226
227
228
229void TTreeSRedirector::Close(){
230 //
231 //
e619a839 232 TDirectory * backup = gDirectory;
2fca8fe0 233 fFile->cd();
234 if (fDataLayouts){
235 Int_t entries = fDataLayouts->GetEntriesFast();
236 for (Int_t i=0;i<entries;i++){
237 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
238 if (layout){
239 if (layout->fTree) layout->fTree->Write(layout->GetName());
240 }
241 }
242 delete fDataLayouts;
243 fDataLayouts=0;
cd246117 244 }
d0742e95 245 if (backup) backup->cd();
cd246117 246}
247
248
249
250//-------------------------------------------------------------
90e48c0c 251TTreeDataElement:: TTreeDataElement(Char_t type) :
fdf65bb5 252 TNamed(),
90e48c0c 253 fType(type),
254 fDType(0),
255 fClass(0),
256 fPointer(0)
257{
258 //
cd246117 259 //
260 //
cd246117 261}
90e48c0c 262
263TTreeDataElement:: TTreeDataElement(TDataType* type) :
fdf65bb5 264 TNamed(),
81e97e0d 265 fType(0),
90e48c0c 266 fDType(type),
267 fClass(0),
268 fPointer(0)
269{
270 //
cd246117 271 //
272 //
cd246117 273}
90e48c0c 274
275TTreeDataElement:: TTreeDataElement(TClass* cl) :
fdf65bb5 276 TNamed(),
81e97e0d 277 fType(0),
90e48c0c 278 fDType(0),
279 fClass(cl),
280 fPointer(0)
281{
282 //
cd246117 283 //
284 //
cd246117 285}
286
287//-------------------------------------------------------------------
90e48c0c 288TTreeStream::TTreeStream(const char *treename):
289 TNamed(treename,treename),
290 fElements(0),
291 fBranches(0),
292 fTree(new TTree(treename, treename)),
293 fCurrentIndex(0),
fe12e09c 294 fId(0),
90e48c0c 295 fNextName(),
296 fNextNameCounter(),
297 fStatus(0)
298{
9996a03b 299 //
300 // Standard ctor
301 //
cd246117 302}
303
304TTreeStream::~TTreeStream()
305{
9996a03b 306 //
307 // Class dtor
308 //
cd246117 309 fElements->Delete();
310 fBranches->Clear();
311 delete fElements;
312 delete fBranches;
313}
314
315void TTreeStream::Close()
316{
9996a03b 317 //
318 // Flush data to disk and close
cd246117 319 //
320 fTree->Write();
321}
322
323Int_t TTreeStream::CheckIn(Char_t type, void *pointer)
324{
9996a03b 325 //
326 // Insert object of given type
327 //
78e18d24 328 if (!fElements) fElements = new TObjArray(10000);
329 if (fElements->GetSize()<=fCurrentIndex) fElements->Expand(fCurrentIndex*2);
cd246117 330 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
331 if (!element) {
332 element = new TTreeDataElement(type);
333 //
334 char name[1000];
335 if (fNextName.Length()>0){
336 if (fNextNameCounter==0){
337 sprintf(name,"%s",(const char*)fNextName);
338 }
339 if (fNextNameCounter>0){
340 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
341 }
342 }
343 else{
344 sprintf(name,"B%d.",fCurrentIndex);
345 }
346 element->SetName(name);
347 //
348 element->SetPointer(pointer);
349 fElements->AddAt(element,fCurrentIndex);
350 fCurrentIndex++;
351 return 0; //new element added
352 }
353 if (element->GetType()!=type){
354 fStatus++;
355 return 1; //mismatched data element
356 }
357 element->SetPointer(pointer);
358 fCurrentIndex++;
359 return 0;
360}
361
362Int_t TTreeStream::CheckIn(TObject *o){
363 //
9996a03b 364 // Insert TObject
cd246117 365 //
366 if (!o) return 0;
367 if (!fElements) fElements = new TObjArray(1000);
368 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
369 if (!element) {
370 element = new TTreeDataElement(o->IsA());
371 //
372 char name[1000];
373 if (fNextName.Length()>0){
374 if (fNextNameCounter==0){
375 sprintf(name,"%s",(const char*)fNextName);
376 }
377 if (fNextNameCounter>0){
378 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
379 }
380 }
381 else{
382 sprintf(name,"B%d",fCurrentIndex);
383 }
384 element->SetName(name);
385
386 element->SetPointer(o);
387 fElements->AddAt(element,fCurrentIndex);
388 fCurrentIndex++;
389 return 0; //new element added
390 }
391 if (element->fClass!=o->IsA()){
392 fStatus++;
393 return 1; //mismatched data element
394 }
395 element->SetPointer(o);
396 fCurrentIndex++;
397 return 0;
398}
399
400void TTreeStream::BuildTree(){
401 //
9996a03b 402 // Build the Tree
cd246117 403 //
bbc15444 404 if (fTree && fTree->GetEntries()>0) return;
405 if (!fTree) fTree = new TTree(GetName(),GetName());
cd246117 406 Int_t entries = fElements->GetEntriesFast();
407 fBranches = new TObjArray(entries);
408
409 for (Int_t i=0;i<entries;i++){
410 //
411 TTreeDataElement* element = (TTreeDataElement*)fElements->At(i);
412 char bname1[1000];
413 if (element->GetName()[0]==0){
414 sprintf(bname1,"B%d",i);
415 }
416 else{
417 sprintf(bname1,element->GetName());
418 }
419 if (element->fClass){
2fca8fe0 420 if (element->fClass->GetBaseClass("TClonesArray")){
3194e208 421 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
2fca8fe0 422 fBranches->AddAt(br,i);
423 }else
424 {
425 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
426 fBranches->AddAt(br,i);
427 }
cd246117 428 }
429 if (element->GetType()>0){
430 char bname2[1000];
431 sprintf(bname2,"B%d/%c",i,element->GetType());
432 TBranch * br = fTree->Branch(bname1,element->fPointer,bname2);
433 fBranches->AddAt(br,i);
434 }
435 }
436}
437
438void TTreeStream::Fill(){
439 //
9996a03b 440 // Fill the tree
cd246117 441 //
442 if (fTree) {
443 Int_t entries=fElements->GetEntriesFast();
444 if (entries>fTree->GetNbranches()) BuildTree();
445 for (Int_t i=0;i<entries;i++){
446 TTreeDataElement* el = (TTreeDataElement*)fElements->At(i);
447 if (!el) continue;
448 if (!el->GetType()) continue;
449 TBranch * br = (TBranch*)fBranches->At(i);
450 if (br &&el){
451 if (el->GetType()) br->SetAddress(el->fPointer);
452 }
453 }
454 if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts
455 fStatus=0;
456 }
457}
458
9996a03b 459TTreeStream & TTreeStream::Endl()
460{
461 //
462 // Perform pseudo endl operation
463 //
cd246117 464 if (fTree->GetNbranches()==0) BuildTree();
465 Fill();
466 fStatus =0;
467 fCurrentIndex=0;
468 return *this;
469}
470
471
4f57cad7 472TTreeStream &TTreeStream::operator<<(const Char_t *name)
cd246117 473{
474 //
9996a03b 475 // Endl
cd246117 476 //
cd246117 477 if (name[0]=='\n'){
478 return Endl();
479 }
480 //
481 //if tree was already defined ignore
482 if (fTree->GetEntries()>0) return *this;
483 //check branch name if tree was not
484 //
485 Int_t last=0;
486 for (last=0;;last++){
487 if (name[last]==0) break;
488 }
489
490 if (last>0&&name[last-1]=='='){
491 fNextName = name;
492 fNextName[last-1]=0;
493 fNextNameCounter=0;
494 }
495 return *this;
496}
497