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