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