ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
Revision: 1.8
Committed: Tue Jul 1 14:36:52 2008 UTC (16 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.7: +3 -1 lines
Log Message:
Add branchref.

File Contents

# Content
1 // $Id: TreeWriter.cc,v 1.7 2008/06/26 16:45:27 loizides Exp $
2
3 #include "MitAna/DataUtil/interface/TreeWriter.h"
4
5 #include <Riostream.h>
6 #include <TObject.h>
7 #include <TSystem.h>
8 #include <TProcessID.h>
9
10 #include "MitAna/DataUtil/interface/Debug.h"
11
12 using namespace mithep;
13
14 ClassImp(mithep::TreeWriter)
15
16 //__________________________________________________________________________________________________
17 TreeWriter::TreeWriter(const char *tname, Bool_t doreset) :
18 TNamed(tname,Form("%s written by mithep::TreeWriter", tname)),
19 fBaseURL("."),
20 fPrefix("mithep"),
21 fFileNumber(0),
22 fCompressLevel(9),
23 fDefBrSize(64*1024),
24 fDefSL(99),
25 fMaxSize((Long64_t)(0.99 * TTree::GetMaxTreeSize())),
26 fkMinFreeSpace(1024*1024),
27 fkMinAvgSize(10*1024),
28 fEvtObjNum(-1),
29 fIsInit(kFALSE),
30 fDoObjNumReset(doreset),
31 fFile(0),
32 fTrees(0)
33 {
34 // Constructor.
35
36 fTrees.SetOwner();
37 }
38
39 //__________________________________________________________________________________________________
40 TreeWriter::~TreeWriter()
41 {
42 // Destructor.
43
44 if (fIsInit) {
45 CloseFile();
46 }
47
48 TDirectory::TContext context(0);
49 fTrees.Clear();
50 }
51
52 //__________________________________________________________________________________________________
53 void TreeWriter::AddBranch(const char *name, const char *cname,
54 void *obj, Int_t bsize, Int_t level)
55 {
56 // Add branch with name "name" into tree with name "tname" and set its address
57 // to object pointer for class name "cname" using a given buffer size and splitlevel.
58
59 MyTree *t = AddOrGetMyTree(GetName());
60 TBranch *b = t->Bronch(name, cname, obj, bsize, level);
61 b->SetCompressionLevel(GetCompressLevel());
62 }
63
64
65 //__________________________________________________________________________________________________
66 void TreeWriter::AddBranch(const char *name, void *obj, Int_t bsize, Int_t level)
67 {
68 // Add branch with name "name" into tree with name "tname" and set its address
69 // to object pointer using a given buffer size and splitlevel.
70
71 AddBranch(name, CName(obj), obj, bsize, level);
72 }
73
74 //__________________________________________________________________________________________________
75 void TreeWriter::AddBranch(const char *name, const char *cname,
76 void *obj, Int_t bsize)
77 {
78 // Add branch with name "name" into tree with name "tname" and set its address
79 // to object pointer for class name "cname" using a given buffer size and default splitlevel.
80
81 MyTree *t = AddOrGetMyTree(GetName());
82 TBranch *b = t->Bronch(name, cname, obj, bsize, fDefSL);
83 b->SetCompressionLevel(GetCompressLevel());
84 }
85
86 //__________________________________________________________________________________________________
87 void TreeWriter::AddBranch(const char *name, void *obj, Int_t bsize)
88 {
89 // Add branch with name "name" into tree with name "tname" and set its address
90 // to object pointer using a given buffer size and default splitlevel.
91
92 AddBranch(name, CName(obj), obj, bsize);
93 }
94
95 //__________________________________________________________________________________________________
96 void TreeWriter::AddBranch(const char *name, const char *cname,
97 void *obj)
98 {
99 // Add branch with name "name" into tree with name "tname" and set its address
100 // to object pointer for class name "cname" using a default buffer size and splitlevel.
101
102 MyTree *t = AddOrGetMyTree(GetName());
103 TBranch *b = t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
104 b->SetCompressionLevel(GetCompressLevel());
105 }
106
107 //__________________________________________________________________________________________________
108 void TreeWriter::AddBranch(const char *name, void *obj)
109 {
110 // Add branch with name "name" into tree with name "tname" and set its address
111 // to object pointer using a default buffer size and splitlevel.
112
113 AddBranch(name, CName(obj), obj);
114 }
115
116 //__________________________________________________________________________________________________
117 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
118 void *obj, Int_t bsize, Int_t level)
119 {
120 // Add branch with name "name" into tree with name "tname" and set its address
121 // to object pointer for class name "cname" using a given buffer size and splitlevel.
122
123 MyTree *t = AddOrGetMyTree(tname);
124 TBranch *b = t->Bronch(name, cname, obj, bsize, level);
125 b->SetCompressionLevel(GetCompressLevel());
126 }
127
128 //__________________________________________________________________________________________________
129 void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj,
130 Int_t bsize, Int_t level)
131 {
132 // Add branch with name "name" into tree with name "tname" and set its address
133 // to object pointer using a given buffer size and splitlevel.
134
135 AddBranchToTree(tname, name, CName(obj), obj, bsize, level);
136 }
137
138 //__________________________________________________________________________________________________
139 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
140 void *obj, Int_t bsize)
141 {
142 // Add branch with name "name" into tree with name "tname" and set its address
143 // to object pointer for class name "cname" using a given buffer size and default splitlevel.
144
145 MyTree *t = AddOrGetMyTree(tname);
146 TBranch *b = t->Bronch(name, cname, obj, bsize, fDefSL);
147 b->SetCompressionLevel(GetCompressLevel());
148 }
149
150 //__________________________________________________________________________________________________
151 void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj,
152 Int_t bsize)
153 {
154 // Add branch with name "name" into tree with name "tname" and set its address
155 // to object pointer using a given buffer size and default splitlevel.
156
157 AddBranchToTree(tname, name, CName(obj), obj, bsize);
158 }
159
160 //__________________________________________________________________________________________________
161 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
162 void *obj)
163 {
164 // Add branch with name "name" into tree with name "tname" and set its address
165 // to object pointer for class name "cname" using a default buffer size and splitlevel.
166
167 MyTree *t = AddOrGetMyTree(tname);
168 TBranch *b = t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
169 b->SetCompressionLevel(GetCompressLevel());
170 }
171
172 //__________________________________________________________________________________________________
173 void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj)
174 {
175 // Add branch with name "name" into tree with name "tname" and set its address
176 // to object pointer for class name "cname" using a default buffer size and splitlevel.
177
178 AddBranchToTree(tname, name, CName(obj), obj);
179 }
180
181 //__________________________________________________________________________________________________
182 MyTree *TreeWriter::AddOrGetMyTree(const char *tn)
183 {
184 // Add new tree if not present in array of trees or return
185 // present tree.
186
187 MyTree *tree = dynamic_cast<MyTree*>(fTrees.FindObject(tn));
188 if (tree)
189 return tree;
190
191 TDirectory::TContext context(fFile);
192 tree = new MyTree(tn, tn);
193 tree->SetDirectory(fFile);
194 if (fDoObjNumReset)
195 tree->BranchRef();
196 fTrees.AddLast(tree);
197 return tree;
198 }
199
200 //__________________________________________________________________________________________________
201 Bool_t TreeWriter::BeginEvent(Bool_t doreset)
202 {
203 // Prepare for the next event. If doreset or fDoObjNumReset is kTRUE
204 // store the current object number to be reset in FillEvent().
205
206 if (!fIsInit) {
207 OpenFile();
208 }
209
210 if (doreset || fDoObjNumReset) {
211 fEvtObjNum = TProcessID::GetObjectCount();
212 }
213
214 return kTRUE;
215 }
216
217 //__________________________________________________________________________________________________
218 void TreeWriter::CloseFile()
219 {
220 // Write tree(s) and close file.
221
222 if (!fIsInit) {
223 Fatal("CloseFile", "File was not opened, call OpenFile() first!");
224 return;
225 }
226
227 TDirectory::TContext context(fFile); // cd fFile &&
228 // automatically restore gDirectory
229
230 for (Int_t i=0;i<fTrees.GetEntries();++i) {
231 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
232 mt->Write(mt->GetName(),TObject::kOverwrite);
233 mt->Reset();
234 mt->SetDirectory(0);
235 }
236
237 fFile->Close();
238 delete fFile;
239 fFile = 0;
240
241 fIsInit = kFALSE;
242 fFileNumber++;
243 }
244
245 //__________________________________________________________________________________________________
246 const char *TreeWriter::CName(void *obj) const
247 {
248 // Dereference void* pointer into TObject* pointer
249
250 TObject *tobj = dynamic_cast<TObject*>(*(TObject**)obj);
251 if (tobj==0) {
252 Fatal("ClassName", "Given void* ptr can not be dereferenced into TObject*");
253 }
254 return tobj->ClassName();
255 }
256
257 //__________________________________________________________________________________________________
258 Bool_t TreeWriter::EndEvent(Bool_t doreset)
259 {
260 // Store the event in the tree. If doreset or fDoObjNumReset is kTRUE
261 // restore the stored object number at the time BeginEvent(kTRUE)
262 // was called.
263
264 if (!fIsInit) {
265 Fatal("EndEvent", "File is not open, did you call BeginEvent?");
266 return kFALSE;
267 }
268
269 Int_t r = 0;
270 for (Int_t i=0;i<fTrees.GetEntries();++i) {
271 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
272 if (mt->GetAutoFill()==0)
273 continue;
274 r += mt->Fill();
275 }
276
277 if (IsFull())
278 CloseFile();
279
280 if (doreset || fDoObjNumReset) {
281 if (fEvtObjNum<0) {
282 Error("EndEvent", "Object counter is zero. Did you call BeginEvent(kTRUE)?");
283 } else {
284 // Reset the TRef table. keep it from growing with each event (see doc)
285 TProcessID::SetObjectCount(fEvtObjNum);
286 }
287 }
288
289 return (r >= 0);
290 }
291
292 //-------------------------------------------------------------------------------------------------
293 Long64_t TreeWriter::GetEntries(const char *tn) const
294 {
295 // Return entries of tree with given name. If no tree is given, return sum of entries
296 // of all trees.
297
298 if (fTrees.GetEntries()==0) return -1;
299
300 if (tn) {
301 const TTree *mt=GetTree(tn);
302 if (mt)
303 return mt->GetEntries();
304 else
305 return -1;
306 }
307
308 Long64_t ret = 0;
309 for (Int_t i=0;i<fTrees.GetEntries();++i) {
310 const MyTree *mt = static_cast<const MyTree*>(fTrees.At(i));
311 ret += mt->GetEntries();
312 }
313 return ret;
314 }
315
316 //-------------------------------------------------------------------------------------------------
317 MyTree *mithep::TreeWriter::GetMyTree(const char *tn)
318 {
319 // Return MyTree with given name from array.
320
321 if (fTrees.GetEntries()==0)
322 return 0;
323
324 TObject *obj = 0;
325 if (tn==0) {
326 obj = fTrees.At(0);
327 } else {
328 obj = fTrees.FindObject(tn);
329 }
330
331 if (obj)
332 return static_cast<MyTree*>(obj);
333 return 0;
334 }
335
336 //-------------------------------------------------------------------------------------------------
337 const TTree *mithep::TreeWriter::GetTree(const char *tn) const
338 {
339 // Return TTree with given name from array.
340
341 if (fTrees.GetEntries()==0)
342 return 0;
343
344 TObject *obj = 0;
345 if (tn==0) {
346 obj = fTrees.At(0);
347 } else {
348 obj = fTrees.FindObject(tn);
349 }
350
351 if (obj)
352 return dynamic_cast<const TTree*>(obj);
353 return 0;
354 }
355
356 //-------------------------------------------------------------------------------------------------
357 TTree *mithep::TreeWriter::GetTree(const char *tn)
358 {
359 // Return TTree with given name from array.
360
361 if (fTrees.GetEntries()==0)
362 return 0;
363
364 TObject *obj = 0;
365 if (tn==0) {
366 obj = fTrees.At(0);
367 } else {
368 obj = fTrees.FindObject(tn);
369 }
370
371 if (obj)
372 return dynamic_cast<TTree*>(obj);
373 return 0;
374 }
375
376 //__________________________________________________________________________________________________
377 Bool_t TreeWriter::IsFull() const
378 {
379 // Check if the maximum file size has been reached.
380
381 Long64_t entries = GetEntries();
382 if (entries < 1) return kFALSE;
383
384 Long64_t avgSize = GetFileSize() / entries;
385
386 if (avgSize < fkMinAvgSize)
387 avgSize = fkMinAvgSize;
388
389 return (GetFileSize() + avgSize + fkMinFreeSpace) > fMaxSize;
390 }
391
392 //__________________________________________________________________________________________________
393 void TreeWriter::OpenFile()
394 {
395 // Open the file and attach the tree.
396
397 if (fIsInit) {
398 Fatal("OpenFile", "File is already open, call CloseFile first!");
399 return;
400 }
401
402 TDirectory::TContext context(0);
403
404 TString pathname=GetFullName();
405 gSystem->ExpandPathName(pathname);
406
407 fFile = TFile::Open(pathname, "RECREATE");
408 if (fFile == 0) {
409 Fatal("OpenFile", "Could not open file %s", pathname.Data());
410 return;
411 }
412
413 fFile->SetCompressionLevel(fCompressLevel);
414
415 for (Int_t i=0;i<fTrees.GetEntries();++i) {
416 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
417 mt->SetDirectory(fFile);
418 }
419
420 fIsInit = kTRUE;
421 }
422
423 //__________________________________________________________________________________________________
424 void TreeWriter::Print(Option_t *option) const
425 {
426 // Print the contents of the tree writer.
427
428 if (option) {
429 cout << ClassName() << " with members " << endl;
430 cout << " fBaseURL: " << fBaseURL << endl;
431 cout << " fPreFix: " << fPrefix << endl;
432 cout << " fFileNumber: " << fFileNumber << endl;
433 cout << " fCompressLevel: " << fCompressLevel << endl;
434 cout << " fDefBrSize: " << fDefBrSize << endl;
435 cout << " fDefSL: " << fDefSL << endl;
436 cout << " fMaxSize: " << fMaxSize << endl;
437 cout << " fDoObjNumReset: " << fDoObjNumReset << endl;
438 return;
439 }
440
441 cout << ClassName() << ": " << GetEntries()
442 << (GetEntries() == 1 ? " event" : " events") << endl;
443 }
444
445 //-------------------------------------------------------------------------------------------------
446 void TreeWriter::SetAutoFill(const char *tn, Bool_t b)
447 {
448 // Set auto-fill mode of tree with given name.
449
450 if (fTrees.GetEntries()==0)
451 return;
452
453 MyTree *mt = GetMyTree(tn);
454 if (!mt)
455 return;
456
457 mt->SetAutoFill(b);
458 }
459
460
461 //-------------------------------------------------------------------------------------------------
462 void TreeWriter::SetMaxSize(Long64_t s)
463 {
464 // Set maximum file size. Check if this exceeds the ROOT file size and if,
465 // print a warning and adjust it.
466
467 if (s>=(Long64_t)(0.99 * TTree::GetMaxTreeSize())) {
468 Long64_t news = (Long64_t)(s/0.99);
469 Warning("SetMaxSize", "Maximum tree size increased from %lld to %lld",
470 TTree::GetMaxTreeSize(), news);
471 TTree::SetMaxTreeSize(news);
472 }
473
474 fMaxSize=s;
475 }
476
477 //__________________________________________________________________________________________________
478 void TreeWriter::StoreObject(const TObject *obj)
479 {
480 // Store object next to tree in file. Used to store the
481 // settings of how the tree was created.
482
483 if (!fIsInit) {
484 Fatal("StoreObject", "Tree is not created, call create first!");
485 return;
486 }
487
488 if (!obj) {
489 Fatal("StoreObject", "Ptr to TObject is null!");
490 return;
491 }
492
493 fFile->WriteTObject(obj,obj->GetName(),"WriteDelete");
494 }