ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
Revision: 1.8
Committed: Tue Jul 1 14:36:52 2008 UTC (16 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.7: +3 -1 lines
Log Message:
Add branchref.

File Contents

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