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

# User Rev Content
1 loizides 1.5 // $Id: TreeWriter.cc,v 1.4 2008/06/09 11:47:03 paus 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     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 paus 1.4 if (tree)
183     return tree;
184 loizides 1.2
185     TDirectory::TContext context(fFile);
186     tree = new MyTree(tn, tn);
187     tree->SetDirectory(fFile);
188     fTrees.AddLast(tree);
189     return tree;
190 loizides 1.1 }
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 loizides 1.2 if (doreset || fDoObjNumReset) {
203 loizides 1.1 fEvtObjNum = TProcessID::GetObjectCount();
204     }
205    
206     return kTRUE;
207     }
208    
209     //__________________________________________________________________________________________________
210     void TreeWriter::CloseFile()
211     {
212 loizides 1.2 // Write tree(s) and close file.
213 loizides 1.1
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 loizides 1.2 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 loizides 1.1
229     fFile->Close();
230     delete fFile;
231     fFile = 0;
232    
233     fIsInit = kFALSE;
234     fFileNumber++;
235     }
236    
237     //__________________________________________________________________________________________________
238 loizides 1.3 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 paus 1.4 if (tobj==0) {
244 loizides 1.3 Fatal("ClassName", "Given void* ptr can not be dereferenced into TObject*");
245     }
246     return tobj->ClassName();
247     }
248    
249     //__________________________________________________________________________________________________
250 loizides 1.1 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 loizides 1.2 Int_t r = 0;
262     for (Int_t i=0;i<fTrees.GetEntries();++i) {
263     MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
264 paus 1.4 if (mt->GetAutoFill()==0)
265     continue;
266 loizides 1.2 r += mt->Fill();
267     }
268 loizides 1.1
269 loizides 1.2 if (IsFull())
270 loizides 1.1 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 loizides 1.2 //-------------------------------------------------------------------------------------------------
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 paus 1.4 if (mt)
294     return mt->GetEntries();
295     else
296     return -1;
297 loizides 1.2 }
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 loizides 1.1 //__________________________________________________________________________________________________
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 loizides 1.2
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 loizides 1.1 fIsInit = kTRUE;
412     }
413    
414     //__________________________________________________________________________________________________
415     void TreeWriter::Print(Option_t *option) const
416     {
417     // Print the contents of the tree writer.
418    
419 loizides 1.2 if (option) {
420 loizides 1.1 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 loizides 1.2 //-------------------------------------------------------------------------------------------------
437     void TreeWriter::SetAutoFill(const char *tn, Bool_t b)
438     {
439     // Set auto-fill mode of tree with given name.
440    
441 paus 1.4 if (fTrees.GetEntries()==0)
442     return;
443 loizides 1.2
444     MyTree *mt = GetMyTree(tn);
445 paus 1.4 if (!mt)
446     return;
447 loizides 1.2
448     mt->SetAutoFill(b);
449     }
450    
451 loizides 1.5
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 loizides 1.1 //__________________________________________________________________________________________________
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     }