ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
Revision: 1.5
Committed: Tue Jun 17 08:22:41 2008 UTC (16 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.4: +34 -17 lines
Log Message:
Adjust max tree size if requested max size is larger.

File Contents

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