ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
Revision: 1.7
Committed: Thu Jun 26 16:45:27 2008 UTC (16 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.6: +19 -13 lines
Log Message:
Enable compression. Although still not all branches seem to be compressed

File Contents

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