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

# User Rev Content
1 loizides 1.3 // $Id: TreeWriter.cc,v 1.2 2008/06/02 08:58:52 loizides Exp $
2 loizides 1.1
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 loizides 1.3 #include "MitAna/DataUtil/interface/Debug.h"
11    
12 loizides 1.1 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 loizides 1.2 fTrees(0)
33 loizides 1.1 {
34     // Constructor.
35    
36 loizides 1.2 fTrees.SetOwner();
37 loizides 1.1 }
38    
39     //__________________________________________________________________________________________________
40     TreeWriter::~TreeWriter()
41     {
42     // Destructor.
43    
44 loizides 1.2 if (fIsInit) {
45 loizides 1.1 CloseFile();
46     }
47    
48     TDirectory::TContext context(0);
49 loizides 1.2 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 loizides 1.1 }
62    
63 loizides 1.3
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 loizides 1.1 //__________________________________________________________________________________________________
74 loizides 1.2 void TreeWriter::AddBranch(const char *name, const char *cname,
75     void *obj, Int_t bsize)
76 loizides 1.1 {
77 loizides 1.2 // 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 loizides 1.1
80 loizides 1.2 MyTree *t = AddOrGetMyTree(GetName());
81     t->Bronch(name, cname, obj, bsize, fDefSL);
82 loizides 1.1 }
83    
84     //__________________________________________________________________________________________________
85 loizides 1.3 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 loizides 1.2 void TreeWriter::AddBranch(const char *name, const char *cname,
95     void *obj)
96 loizides 1.1 {
97 loizides 1.2 // Add branch with name "name" into tree with name "tname" and set its address
98 loizides 1.3 // to object pointer for class name "cname" using a default buffer size and splitlevel.
99 loizides 1.1
100 loizides 1.2 MyTree *t = AddOrGetMyTree(GetName());
101     t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
102 loizides 1.1 }
103    
104     //__________________________________________________________________________________________________
105 loizides 1.3 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 loizides 1.2 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
115     void *obj, Int_t bsize, Int_t level)
116 loizides 1.1 {
117 loizides 1.2 // 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 loizides 1.1
120 loizides 1.2 MyTree *t = AddOrGetMyTree(tname);
121     t->Bronch(name, cname, obj, bsize, level);
122     }
123    
124     //__________________________________________________________________________________________________
125 loizides 1.3 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 loizides 1.2 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
136 loizides 1.3 void *obj, Int_t bsize)
137 loizides 1.2 {
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 loizides 1.3 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 loizides 1.2 void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
157 loizides 1.3 void *obj)
158 loizides 1.2 {
159     // Add branch with name "name" into tree with name "tname" and set its address
160 loizides 1.3 // to object pointer for class name "cname" using a default buffer size and splitlevel.
161 loizides 1.2
162     MyTree *t = AddOrGetMyTree(tname);
163     t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
164     }
165    
166     //__________________________________________________________________________________________________
167 loizides 1.3 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 loizides 1.2 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 loizides 1.1 }
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 loizides 1.2 if (doreset || fDoObjNumReset) {
202 loizides 1.1 fEvtObjNum = TProcessID::GetObjectCount();
203     }
204    
205     return kTRUE;
206     }
207    
208     //__________________________________________________________________________________________________
209     void TreeWriter::CloseFile()
210     {
211 loizides 1.2 // Write tree(s) and close file.
212 loizides 1.1
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 loizides 1.2 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 loizides 1.1
228     fFile->Close();
229     delete fFile;
230     fFile = 0;
231    
232     fIsInit = kFALSE;
233     fFileNumber++;
234     }
235    
236     //__________________________________________________________________________________________________
237 loizides 1.3 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 loizides 1.1 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 loizides 1.2 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 loizides 1.1
267 loizides 1.2 if (IsFull())
268 loizides 1.1 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 loizides 1.2 //-------------------------------------------------------------------------------------------------
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 loizides 1.1 //__________________________________________________________________________________________________
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 loizides 1.2
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 loizides 1.1 fIsInit = kTRUE;
408     }
409    
410     //__________________________________________________________________________________________________
411     void TreeWriter::Print(Option_t *option) const
412     {
413     // Print the contents of the tree writer.
414    
415 loizides 1.2 if (option) {
416 loizides 1.1 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 loizides 1.2 //-------------------------------------------------------------------------------------------------
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 loizides 1.1 //__________________________________________________________________________________________________
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     }