ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
Revision: 1.3
Committed: Thu Jun 5 07:55:55 2008 UTC (16 years, 11 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.2: +76 -5 lines
Log Message:
Also accept TObject pointers and figure out ClassName automatically.

File Contents

# Content
1 // $Id: TreeWriter.cc,v 1.2 2008/06/02 08:58:52 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 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) return tree;
183
184 TDirectory::TContext context(fFile);
185 tree = new MyTree(tn, tn);
186 tree->SetDirectory(fFile);
187 fTrees.AddLast(tree);
188 return tree;
189 }
190
191 //__________________________________________________________________________________________________
192 Bool_t TreeWriter::BeginEvent(Bool_t doreset)
193 {
194 // Prepare for the next event. If doreset or fDoObjNumReset is kTRUE
195 // store the current object number to be reset in FillEvent().
196
197 if (!fIsInit) {
198 OpenFile();
199 }
200
201 if (doreset || fDoObjNumReset) {
202 fEvtObjNum = TProcessID::GetObjectCount();
203 }
204
205 return kTRUE;
206 }
207
208 //__________________________________________________________________________________________________
209 void TreeWriter::CloseFile()
210 {
211 // Write tree(s) and close file.
212
213 if (!fIsInit) {
214 Fatal("CloseFile", "File was not opened, call OpenFile() first!");
215 return;
216 }
217
218 TDirectory::TContext context(fFile); // cd fFile &&
219 // automatically restore gDirectory
220
221 for (Int_t i=0;i<fTrees.GetEntries();++i) {
222 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
223 mt->Write(mt->GetName(),TObject::kOverwrite);
224 mt->Reset();
225 mt->SetDirectory(0);
226 }
227
228 fFile->Close();
229 delete fFile;
230 fFile = 0;
231
232 fIsInit = kFALSE;
233 fFileNumber++;
234 }
235
236 //__________________________________________________________________________________________________
237 const char *TreeWriter::CName(void *obj) const
238 {
239 // Dereference void* pointer into TObject* pointer
240
241 TObject *tobj = dynamic_cast<TObject*>(*(TObject**)obj);
242 if(tobj==0) {
243 Fatal("ClassName", "Given void* ptr can not be dereferenced into TObject*");
244 }
245 return tobj->ClassName();
246 }
247
248 //__________________________________________________________________________________________________
249 Bool_t TreeWriter::EndEvent(Bool_t doreset)
250 {
251 // Store the event in the tree. If doreset or fDoObjNumReset is kTRUE
252 // restore the stored object number at the time BeginEvent(kTRUE)
253 // was called.
254
255 if (!fIsInit) {
256 Fatal("EndEvent", "File is not open, did you call BeginEvent?");
257 return kFALSE;
258 }
259
260 Int_t r = 0;
261 for (Int_t i=0;i<fTrees.GetEntries();++i) {
262 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
263 if (mt->GetAutoFill()==0) continue;
264 r += mt->Fill();
265 }
266
267 if (IsFull())
268 CloseFile();
269
270 if (doreset || fDoObjNumReset) {
271 if (fEvtObjNum<0) {
272 Error("EndEvent", "Object counter is zero. Did you call BeginEvent(kTRUE)?");
273 } else {
274 // Reset the TRef table. keep it from growing with each event (see doc)
275 TProcessID::SetObjectCount(fEvtObjNum);
276 }
277 }
278
279 return (r >= 0);
280 }
281
282 //-------------------------------------------------------------------------------------------------
283 Long64_t TreeWriter::GetEntries(const char *tn) const
284 {
285 //
286
287 if (fTrees.GetEntries()==0) return -1;
288
289 if (tn) {
290 const TTree *mt=GetTree(tn);
291 if (mt) return mt->GetEntries();
292 else return -1;
293 }
294
295 Long64_t ret = 0;
296 for (Int_t i=0;i<fTrees.GetEntries();++i) {
297 const MyTree *mt = static_cast<const MyTree*>(fTrees.At(i));
298 ret += mt->GetEntries();
299 }
300 return ret;
301 }
302
303 //-------------------------------------------------------------------------------------------------
304 MyTree *mithep::TreeWriter::GetMyTree(const char *tn)
305 {
306 // Return MyTree with given name from array.
307
308 if (fTrees.GetEntries()==0)
309 return 0;
310
311 TObject *obj = 0;
312 if (tn==0) {
313 obj = fTrees.At(0);
314 } else {
315 obj = fTrees.FindObject(tn);
316 }
317
318 if (obj)
319 return static_cast<MyTree*>(obj);
320 return 0;
321 }
322
323 //-------------------------------------------------------------------------------------------------
324 const TTree *mithep::TreeWriter::GetTree(const char *tn) const
325 {
326 // Return TTree with given name from array.
327
328 if (fTrees.GetEntries()==0)
329 return 0;
330
331 TObject *obj = 0;
332 if (tn==0) {
333 obj = fTrees.At(0);
334 } else {
335 obj = fTrees.FindObject(tn);
336 }
337
338 if (obj)
339 return dynamic_cast<const TTree*>(obj);
340 return 0;
341 }
342
343 //-------------------------------------------------------------------------------------------------
344 TTree *mithep::TreeWriter::GetTree(const char *tn)
345 {
346 // Return TTree with given name from array.
347
348 if (fTrees.GetEntries()==0)
349 return 0;
350
351 TObject *obj = 0;
352 if (tn==0) {
353 obj = fTrees.At(0);
354 } else {
355 obj = fTrees.FindObject(tn);
356 }
357
358 if (obj)
359 return dynamic_cast<TTree*>(obj);
360 return 0;
361 }
362
363 //__________________________________________________________________________________________________
364 Bool_t TreeWriter::IsFull() const
365 {
366 // Check if the maximum file size has been reached.
367
368 Long64_t entries = GetEntries();
369 if (entries < 1) return kFALSE;
370
371 Long64_t avgSize = GetFileSize() / entries;
372
373 if (avgSize < fkMinAvgSize)
374 avgSize = fkMinAvgSize;
375
376 return (GetFileSize() + avgSize + fkMinFreeSpace) > fMaxSize;
377 }
378
379 //__________________________________________________________________________________________________
380 void TreeWriter::OpenFile()
381 {
382 // Open the file and attach the tree.
383
384 if (fIsInit) {
385 Fatal("OpenFile", "File is already open, call CloseFile first!");
386 return;
387 }
388
389 TDirectory::TContext context(0);
390
391 TString pathname=GetFullName();
392 gSystem->ExpandPathName(pathname);
393
394 fFile = TFile::Open(pathname, "RECREATE");
395 if (fFile == 0) {
396 Fatal("OpenFile", "Could not open file %s", pathname.Data());
397 return;
398 }
399
400 fFile->SetCompressionLevel(fCompressLevel);
401
402 for (Int_t i=0;i<fTrees.GetEntries();++i) {
403 MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
404 mt->SetDirectory(fFile);
405 }
406
407 fIsInit = kTRUE;
408 }
409
410 //__________________________________________________________________________________________________
411 void TreeWriter::Print(Option_t *option) const
412 {
413 // Print the contents of the tree writer.
414
415 if (option) {
416 cout << ClassName() << " with members " << endl;
417 cout << " fBaseURL: " << fBaseURL << endl;
418 cout << " fPreFix: " << fPrefix << endl;
419 cout << " fFileNumber: " << fFileNumber << endl;
420 cout << " fCompressLevel: " << fCompressLevel << endl;
421 cout << " fDefBrSize: " << fDefBrSize << endl;
422 cout << " fDefSL: " << fDefSL << endl;
423 cout << " fMaxSize: " << fMaxSize << endl;
424 cout << " fDoObjNumReset: " << fDoObjNumReset << endl;
425 return;
426 }
427
428 cout << ClassName() << ": " << GetEntries()
429 << (GetEntries() == 1 ? " event" : " events") << endl;
430 }
431
432 //-------------------------------------------------------------------------------------------------
433 void TreeWriter::SetAutoFill(const char *tn, Bool_t b)
434 {
435 // Set auto-fill mode of tree with given name.
436
437 if (fTrees.GetEntries()==0) return;
438
439 MyTree *mt = GetMyTree(tn);
440 if (!mt) return;
441
442 mt->SetAutoFill(b);
443 }
444
445 //__________________________________________________________________________________________________
446 void TreeWriter::StoreObject(const TObject *obj)
447 {
448 // Store object next to tree in file. Used to store the
449 // settings of how the tree was created.
450
451 if (!fIsInit) {
452 Fatal("StoreObject", "Tree is not created, call create first!");
453 return;
454 }
455
456 if (!obj) {
457 Fatal("StoreObject", "Ptr to TObject is null!");
458 return;
459 }
460
461 fFile->WriteTObject(obj,obj->GetName(),"WriteDelete");
462 }