]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/TTreeStream.cxx
- The part of JETAN dealing with ESD data has been separated from the one using MC...
[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}
df1e0cdc 147void TTreeSRedirector::StoreObject(TObject* object){
148 //
149 //
150 //
151 TFile * backup = gFile;
152 fFile->cd();
153 object->Write();
154 if (backup) backup->cd();
155}
156
157
cd246117 158
159TTreeStream & TTreeSRedirector::operator<<(Int_t id)
160{
161 //
162 // return reference to the data layout with given identifier
163 // if not existing - creates new
164 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
165 TTreeStream *clayout=0;
166 Int_t entries = fDataLayouts->GetEntriesFast();
167 for (Int_t i=0;i<entries;i++){
168 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
169 if (!layout) continue;
170 if (layout->fId==id) {
171 clayout = layout;
172 break;
173 }
174 }
175 if (!clayout){
2fca8fe0 176 fFile->cd();
cd246117 177 char chname[100];
178 sprintf(chname,"Tree%d",id);
179 clayout = new TTreeStream(chname);
180 clayout->fId=id;
181 fDataLayouts->AddAt(clayout,entries);
182 }
183 return *clayout;
184}
185
186
187TTreeStream & TTreeSRedirector::operator<<(const char* name)
188{
189 //
190 // return reference to the data layout with given identifier
191 // if not existing - creates new
192 if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
2fca8fe0 193 TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
cd246117 194 Int_t entries = fDataLayouts->GetEntriesFast();
2fca8fe0 195
cd246117 196 if (!clayout){
2fca8fe0 197 fFile->cd();
cd246117 198 clayout = new TTreeStream(name);
199 clayout->fId=-1;
200 clayout->SetName(name);
cd246117 201 fDataLayouts->AddAt(clayout,entries);
202 }
203 return *clayout;
204}
205
206
207
208
209void TTreeSRedirector::Close(){
210 //
211 //
2fca8fe0 212 TFile * backup = gFile;
213 fFile->cd();
214 if (fDataLayouts){
215 Int_t entries = fDataLayouts->GetEntriesFast();
216 for (Int_t i=0;i<entries;i++){
217 TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
218 if (layout){
219 if (layout->fTree) layout->fTree->Write(layout->GetName());
220 }
221 }
222 delete fDataLayouts;
223 fDataLayouts=0;
cd246117 224 }
d0742e95 225 if (backup) backup->cd();
cd246117 226}
227
228
229
230//-------------------------------------------------------------
90e48c0c 231TTreeDataElement:: TTreeDataElement(Char_t type) :
fdf65bb5 232 TNamed(),
90e48c0c 233 fType(type),
234 fDType(0),
235 fClass(0),
236 fPointer(0)
237{
238 //
cd246117 239 //
240 //
cd246117 241}
90e48c0c 242
243TTreeDataElement:: TTreeDataElement(TDataType* type) :
fdf65bb5 244 TNamed(),
81e97e0d 245 fType(0),
90e48c0c 246 fDType(type),
247 fClass(0),
248 fPointer(0)
249{
250 //
cd246117 251 //
252 //
cd246117 253}
90e48c0c 254
255TTreeDataElement:: TTreeDataElement(TClass* cl) :
fdf65bb5 256 TNamed(),
81e97e0d 257 fType(0),
90e48c0c 258 fDType(0),
259 fClass(cl),
260 fPointer(0)
261{
262 //
cd246117 263 //
264 //
cd246117 265}
266
267//-------------------------------------------------------------------
90e48c0c 268TTreeStream::TTreeStream(const char *treename):
269 TNamed(treename,treename),
270 fElements(0),
271 fBranches(0),
272 fTree(new TTree(treename, treename)),
273 fCurrentIndex(0),
fe12e09c 274 fId(0),
90e48c0c 275 fNextName(),
276 fNextNameCounter(),
277 fStatus(0)
278{
9996a03b 279 //
280 // Standard ctor
281 //
cd246117 282}
283
284TTreeStream::~TTreeStream()
285{
9996a03b 286 //
287 // Class dtor
288 //
cd246117 289 fElements->Delete();
290 fBranches->Clear();
291 delete fElements;
292 delete fBranches;
293}
294
295void TTreeStream::Close()
296{
9996a03b 297 //
298 // Flush data to disk and close
cd246117 299 //
300 fTree->Write();
301}
302
303Int_t TTreeStream::CheckIn(Char_t type, void *pointer)
304{
9996a03b 305 //
306 // Insert object of given type
307 //
cd246117 308 if (!fElements) fElements = new TObjArray(1000);
309 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
310 if (!element) {
311 element = new TTreeDataElement(type);
312 //
313 char name[1000];
314 if (fNextName.Length()>0){
315 if (fNextNameCounter==0){
316 sprintf(name,"%s",(const char*)fNextName);
317 }
318 if (fNextNameCounter>0){
319 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
320 }
321 }
322 else{
323 sprintf(name,"B%d.",fCurrentIndex);
324 }
325 element->SetName(name);
326 //
327 element->SetPointer(pointer);
328 fElements->AddAt(element,fCurrentIndex);
329 fCurrentIndex++;
330 return 0; //new element added
331 }
332 if (element->GetType()!=type){
333 fStatus++;
334 return 1; //mismatched data element
335 }
336 element->SetPointer(pointer);
337 fCurrentIndex++;
338 return 0;
339}
340
341Int_t TTreeStream::CheckIn(TObject *o){
342 //
9996a03b 343 // Insert TObject
cd246117 344 //
345 if (!o) return 0;
346 if (!fElements) fElements = new TObjArray(1000);
347 TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
348 if (!element) {
349 element = new TTreeDataElement(o->IsA());
350 //
351 char name[1000];
352 if (fNextName.Length()>0){
353 if (fNextNameCounter==0){
354 sprintf(name,"%s",(const char*)fNextName);
355 }
356 if (fNextNameCounter>0){
357 sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter);
358 }
359 }
360 else{
361 sprintf(name,"B%d",fCurrentIndex);
362 }
363 element->SetName(name);
364
365 element->SetPointer(o);
366 fElements->AddAt(element,fCurrentIndex);
367 fCurrentIndex++;
368 return 0; //new element added
369 }
370 if (element->fClass!=o->IsA()){
371 fStatus++;
372 return 1; //mismatched data element
373 }
374 element->SetPointer(o);
375 fCurrentIndex++;
376 return 0;
377}
378
379void TTreeStream::BuildTree(){
380 //
9996a03b 381 // Build the Tree
cd246117 382 //
383 if (fTree->GetEntries()>0) return;
384 fTree = new TTree(GetName(),GetName());
385 Int_t entries = fElements->GetEntriesFast();
386 fBranches = new TObjArray(entries);
387
388 for (Int_t i=0;i<entries;i++){
389 //
390 TTreeDataElement* element = (TTreeDataElement*)fElements->At(i);
391 char bname1[1000];
392 if (element->GetName()[0]==0){
393 sprintf(bname1,"B%d",i);
394 }
395 else{
396 sprintf(bname1,element->GetName());
397 }
398 if (element->fClass){
2fca8fe0 399 if (element->fClass->GetBaseClass("TClonesArray")){
3194e208 400 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
2fca8fe0 401 fBranches->AddAt(br,i);
402 }else
403 {
404 TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
405 fBranches->AddAt(br,i);
406 }
cd246117 407 }
408 if (element->GetType()>0){
409 char bname2[1000];
410 sprintf(bname2,"B%d/%c",i,element->GetType());
411 TBranch * br = fTree->Branch(bname1,element->fPointer,bname2);
412 fBranches->AddAt(br,i);
413 }
414 }
415}
416
417void TTreeStream::Fill(){
418 //
9996a03b 419 // Fill the tree
cd246117 420 //
421 if (fTree) {
422 Int_t entries=fElements->GetEntriesFast();
423 if (entries>fTree->GetNbranches()) BuildTree();
424 for (Int_t i=0;i<entries;i++){
425 TTreeDataElement* el = (TTreeDataElement*)fElements->At(i);
426 if (!el) continue;
427 if (!el->GetType()) continue;
428 TBranch * br = (TBranch*)fBranches->At(i);
429 if (br &&el){
430 if (el->GetType()) br->SetAddress(el->fPointer);
431 }
432 }
433 if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts
434 fStatus=0;
435 }
436}
437
9996a03b 438TTreeStream & TTreeStream::Endl()
439{
440 //
441 // Perform pseudo endl operation
442 //
cd246117 443 if (fTree->GetNbranches()==0) BuildTree();
444 Fill();
445 fStatus =0;
446 fCurrentIndex=0;
447 return *this;
448}
449
450
451TTreeStream &TTreeStream::operator<<(Char_t *name)
452{
453 //
9996a03b 454 // Endl
cd246117 455 //
cd246117 456 if (name[0]=='\n'){
457 return Endl();
458 }
459 //
460 //if tree was already defined ignore
461 if (fTree->GetEntries()>0) return *this;
462 //check branch name if tree was not
463 //
464 Int_t last=0;
465 for (last=0;;last++){
466 if (name[last]==0) break;
467 }
468
469 if (last>0&&name[last-1]=='='){
470 fNextName = name;
471 fNextName[last-1]=0;
472 fNextNameCounter=0;
473 }
474 return *this;
475}
476