ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataUtil/src/TreeWriter.cc
(Generate patch)

Comparing UserCode/MitAna/DataUtil/src/TreeWriter.cc (file contents):
Revision 1.1 by loizides, Tue May 27 19:36:05 2008 UTC vs.
Revision 1.11 by loizides, Sat Sep 27 06:14:05 2008 UTC

# Line 1 | Line 1
1   // $Id$
2  
3   #include "MitAna/DataUtil/interface/TreeWriter.h"
4
4   #include <Riostream.h>
5   #include <TObject.h>
6   #include <TSystem.h>
7   #include <TProcessID.h>
8 + #include <TBranchRef.h>
9 + #include "MitAna/DataUtil/interface/Debug.h"
10  
11   using namespace mithep;
12  
13   ClassImp(mithep::TreeWriter)
14  
15   //__________________________________________________________________________________________________
16 < TreeWriter::TreeWriter(const char *tname, Bool_t doreset)
17 <  : TNamed(tname,Form("%s written by mithep::TreeWriter", tname)),
18 <    fBaseURL("."),
19 <    fPrefix("mithep"),
20 <    fFileNumber(0),
21 <    fCompressLevel(9),
22 <    fDefBrSize(64*1024),
23 <    fDefSL(99),
24 <    fMaxSize((Long64_t)(0.99 * TTree::GetMaxTreeSize())),
25 <    fkMinFreeSpace(1024*1024),
26 <    fkMinAvgSize(10*1024),
27 <    fEvtObjNum(-1),
28 <    fIsInit(kFALSE),
29 <    fDoObjNumReset(doreset),
30 <    fFile(0),
31 <    fTree(0)
16 > TreeWriter::TreeWriter(const char *tname, Bool_t doreset) :
17 >  TNamed(tname,Form("%s written by mithep::TreeWriter", tname)),
18 >  fBaseURL("."),
19 >  fPrefix("mithep"),
20 >  fFileNumber(0),
21 >  fCompressLevel(9),
22 >  fDefBrSize(64*1024),
23 >  fDefSL(99),
24 >  fMaxSize((Long64_t)(0.99 * TTree::GetMaxTreeSize())),
25 >  fkMinFreeSpace(1024*1024),
26 >  fkMinAvgSize(10*1024),
27 >  fEvtObjNum(-1),
28 >  fIsInit(kFALSE),
29 >  fDoObjNumReset(doreset),
30 >  fFile(0),
31 >  fTrees(0)
32   {
33    // Constructor.
34  
35 <  TDirectory::TContext context(0);
35 <  fTree = new TTree(GetName(), GetTitle());
36 <  fTree->SetDirectory(0);
35 >  fTrees.SetOwner();
36   }
37  
38   //__________________________________________________________________________________________________
# Line 41 | Line 40 | TreeWriter::~TreeWriter()
40   {
41    // Destructor.
42    
43 <  if(fIsInit) {
43 >  if (fIsInit) {
44      CloseFile();
45    }
46  
47    TDirectory::TContext context(0);
48 <  delete fTree;
48 >  fTrees.Clear();
49   }
50  
51   //__________________________________________________________________________________________________
52 < void TreeWriter::AddBranch(const char *name, const char *cname, void *obj, Int_t bsize, Int_t level)
52 > void TreeWriter::AddBranch(const char *name, const char *cname,
53 >                           void *obj, Int_t bsize, Int_t level)
54   {
55 <  // Add branch with name "name" into tree and set its address to object pointer
56 <  // for class name "cname" using a given buffer size and splitlevel.
55 >  // Add branch with name "name" into tree with name "tname" and set its address
56 >  // to object pointer for class name "cname" using a given buffer size and splitlevel.
57  
58 <  fTree->Bronch(name, cname, obj, bsize, level);
58 >  MyTree  *t = AddOrGetMyTree(GetName());
59 >  TBranch *b = t->Bronch(name, cname, obj, bsize, level);
60 >  b->SetCompressionLevel(GetCompressLevel());
61   }
62  
63 < //__________________________________________________________________________________________________
64 < void TreeWriter::AddBranch(const char *name, const char *cname, void *obj, Int_t bsize)
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 and set its address to object pointer
68 <  // for class name "cname" using a given buffer size and default splitlevel.
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 <  fTree->Bronch(name, cname, obj, bsize, fDefSL);
70 >  AddBranch(name, CName(obj), obj, bsize, level);
71   }
72  
73 < //__________________________________________________________________________________________________
74 < void TreeWriter::AddBranch(const char *name, const char *cname, void *obj)
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 and set its address to object pointer
78 <  // for class name "cname" using a given buffer size and default splitlevel.
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 <  fTree->Bronch(name, cname, obj, fDefBrSize, fDefSL);
80 >  MyTree  *t = AddOrGetMyTree(GetName());
81 >  TBranch *b = t->Bronch(name, cname, obj, bsize, fDefSL);
82 >  b->SetCompressionLevel(GetCompressLevel());
83   }
84  
85 < //__________________________________________________________________________________________________
85 > //--------------------------------------------------------------------------------------------------
86 > void TreeWriter::AddBranch(const char *name, void *obj, Int_t bsize)
87 > {
88 >  // Add branch with name "name" into tree with name "tname" and set its address
89 >  // to object pointer using a given buffer size and default splitlevel.
90 >
91 >  AddBranch(name, CName(obj), obj, bsize);
92 > }
93 >
94 > //--------------------------------------------------------------------------------------------------
95 > void TreeWriter::AddBranch(const char *name, const char *cname,
96 >                           void *obj)
97 > {
98 >  // Add branch with name "name" into tree with name "tname" and set its address
99 >  // to object pointer for class name "cname" using a default buffer size and splitlevel.
100 >
101 >  MyTree  *t = AddOrGetMyTree(GetName());
102 >  TBranch *b = t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
103 >  b->SetCompressionLevel(GetCompressLevel());
104 > }
105 >
106 > //--------------------------------------------------------------------------------------------------
107 > void TreeWriter::AddBranch(const char *name, void *obj)
108 > {
109 >  // Add branch with name "name" into tree with name "tname" and set its address
110 >  // to object pointer using a default buffer size and splitlevel.
111 >
112 >  AddBranch(name, CName(obj), obj);
113 > }
114 >
115 > //--------------------------------------------------------------------------------------------------
116 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
117 >                                 void *obj, Int_t bsize, Int_t level)
118 > {
119 >  // Add branch with name "name" into tree with name "tname" and set its address
120 >  // to object pointer for class name "cname" using a given buffer size and splitlevel.
121 >
122 >  MyTree  *t = AddOrGetMyTree(tname);
123 >  TBranch *b = t->Bronch(name, cname, obj, bsize, level);
124 >  b->SetCompressionLevel(GetCompressLevel());
125 > }
126 >
127 > //--------------------------------------------------------------------------------------------------
128 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj,
129 >                                 Int_t bsize, Int_t level)
130 > {
131 >  // Add branch with name "name" into tree with name "tname" and set its address
132 >  // to object pointer using a given buffer size and splitlevel.
133 >
134 >  AddBranchToTree(tname, name, CName(obj), obj, bsize, level);
135 > }
136 >
137 > //--------------------------------------------------------------------------------------------------
138 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
139 >                                 void *obj, Int_t bsize)
140 > {
141 >  // Add branch with name "name" into tree with name "tname" and set its address
142 >  // to object pointer for class name "cname" using a given buffer size and default splitlevel.
143 >
144 >  MyTree  *t = AddOrGetMyTree(tname);
145 >  TBranch *b = t->Bronch(name, cname, obj, bsize, fDefSL);
146 >  b->SetCompressionLevel(GetCompressLevel());
147 > }
148 >
149 > //--------------------------------------------------------------------------------------------------
150 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj,
151 >                                 Int_t bsize)
152 > {
153 >  // Add branch with name "name" into tree with name "tname" and set its address
154 >  // to object pointer using a given buffer size and default splitlevel.
155 >
156 >  AddBranchToTree(tname, name, CName(obj), obj, bsize);
157 > }
158 >
159 > //--------------------------------------------------------------------------------------------------
160 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, const char *cname,
161 >                                 void *obj)
162 > {
163 >  // Add branch with name "name" into tree with name "tname" and set its address
164 >  // to object pointer for class name "cname" using a default buffer size and splitlevel.
165 >
166 >  MyTree  *t = AddOrGetMyTree(tname);
167 >  TBranch *b = t->Bronch(name, cname, obj, fDefBrSize, fDefSL);
168 >  b->SetCompressionLevel(GetCompressLevel());
169 > }
170 >
171 > //--------------------------------------------------------------------------------------------------
172 > void TreeWriter::AddBranchToTree(const char *tname, const char *name, void *obj)
173 > {
174 >  // Add branch with name "name" into tree with name "tname" and set its address
175 >  // to object pointer for class name "cname" using a default buffer size and splitlevel.
176 >
177 >  AddBranchToTree(tname, name, CName(obj), obj);
178 > }
179 >
180 > //--------------------------------------------------------------------------------------------------
181 > MyTree *TreeWriter::AddOrGetMyTree(const char *tn)
182 > {
183 >  // Add new tree if not present in array of trees or return
184 >  // present tree.
185 >
186 >  MyTree *tree = dynamic_cast<MyTree*>(fTrees.FindObject(tn));
187 >  if (tree)
188 >    return tree;
189 >
190 >  TDirectory::TContext context(fFile);
191 >  tree = new MyTree(tn, tn);
192 >  tree->SetDirectory(fFile);
193 >  if (fDoObjNumReset)
194 >    tree->BranchRef();
195 >  fTrees.AddLast(tree);  
196 >  return tree;
197 > }
198 >
199 > //--------------------------------------------------------------------------------------------------
200   Bool_t TreeWriter::BeginEvent(Bool_t doreset)
201   {
202    // Prepare for the next event. If doreset or fDoObjNumReset is kTRUE
# Line 86 | Line 206 | Bool_t TreeWriter::BeginEvent(Bool_t dor
206      OpenFile();
207    }
208  
209 <  if(doreset || fDoObjNumReset) {
209 >  if (doreset || fDoObjNumReset) {
210      fEvtObjNum = TProcessID::GetObjectCount();
211    }
212  
213    return kTRUE;
214   }
215  
216 < //__________________________________________________________________________________________________
216 > //--------------------------------------------------------------------------------------------------
217   void TreeWriter::CloseFile()
218   {
219 <  // Write tree and close file.
219 >  // Write tree(s) and close file.
220  
221    if (!fIsInit) {
222      Fatal("CloseFile", "File was not opened, call OpenFile() first!");
# Line 106 | Line 226 | void TreeWriter::CloseFile()
226    TDirectory::TContext context(fFile); // cd fFile &&
227                                         // automatically restore gDirectory
228  
229 <  fTree->Write(fTree->GetName(),TObject::kOverwrite);
230 <  fTree->Reset();
231 <  fTree->SetDirectory(0);  
229 >  for (Int_t i=0;i<fTrees.GetEntries();++i) {
230 >    MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
231 >    mt->Write(mt->GetName(),TObject::kOverwrite);
232 >    // Backup and restore list of branch pointers from TRefTable (needed for autoloading)
233 >    if (mt->GetBranchRef()) {
234 >      TObjArray *parents = mt->GetBranchRef()->GetRefTable()->GetParents();
235 >      TObjArray parentsBak(*parents);
236 >      mt->Reset();
237 >      for (Int_t j=0; j<parentsBak.GetEntries(); ++j)
238 >        parents->Add(parentsBak.At(j));
239 >    }
240 >    else
241 >      mt->Reset();
242 >    mt->SetDirectory(0);  
243 >  }
244  
245    fFile->Close();
246    delete fFile;
# Line 118 | Line 250 | void TreeWriter::CloseFile()
250    fFileNumber++;  
251   }
252  
253 < //__________________________________________________________________________________________________
253 > //--------------------------------------------------------------------------------------------------
254 > const char *TreeWriter::CName(void *obj) const
255 > {
256 >  // Dereference void* pointer into TObject* pointer
257 >
258 >  TObject *tobj = dynamic_cast<TObject*>(*(TObject**)obj);
259 >  if (tobj==0) {
260 >    Fatal("ClassName", "Given void* ptr can not be dereferenced into TObject*");
261 >  }
262 >  return tobj->ClassName();
263 > }
264 >
265 > //--------------------------------------------------------------------------------------------------
266   Bool_t TreeWriter::EndEvent(Bool_t doreset)
267   {
268    // Store the event in the tree. If doreset or fDoObjNumReset is kTRUE
# Line 130 | Line 274 | Bool_t TreeWriter::EndEvent(Bool_t dores
274      return kFALSE;
275    }
276  
277 <  //TDirectory::TContext context(fFile);
278 <  Int_t r = fTree->Fill();
277 >  Int_t r = 0;
278 >  for (Int_t i=0;i<fTrees.GetEntries();++i) {
279 >    MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
280 >    if (mt->GetAutoFill()==0)
281 >      continue;
282 >    r += mt->Fill();
283 >  }
284  
285 <  if(IsFull())
285 >  if (IsFull())
286      CloseFile();
287  
288    if (doreset || fDoObjNumReset) {
289      if (fEvtObjNum<0) {
290        Error("EndEvent", "Object counter is zero. Did you call BeginEvent(kTRUE)?");
291      } else {
292 <      // Reset the TRef table. keep it from growing with each event (see doc)
292 >      // Reset the TRef table. Keep it from growing with each event (see doc)
293        TProcessID::SetObjectCount(fEvtObjNum);
294      }
295    }
# Line 148 | Line 297 | Bool_t TreeWriter::EndEvent(Bool_t dores
297    return (r >= 0);
298   }
299  
300 < //__________________________________________________________________________________________________
300 > //--------------------------------------------------------------------------------------------------
301 > Long64_t TreeWriter::GetEntries(const char *tn) const
302 > {
303 >  // Return entries of tree with given name. If no tree is given, return sum of entries
304 >  // of all trees.
305 >
306 >   if (fTrees.GetEntries()==0) return -1;
307 >
308 >   if (tn) {
309 >     const TTree *mt=GetTree(tn);
310 >     if (mt)
311 >       return mt->GetEntries();
312 >     else
313 >       return -1;
314 >   }
315 >
316 >   Long64_t ret = 0;
317 >   for (Int_t i=0;i<fTrees.GetEntries();++i) {
318 >      const MyTree *mt = static_cast<const MyTree*>(fTrees.At(i));
319 >      ret += mt->GetEntries();
320 >   }
321 >   return ret;
322 > }
323 >
324 > //--------------------------------------------------------------------------------------------------
325 > MyTree *mithep::TreeWriter::GetMyTree(const char *tn)
326 > {
327 >  // Return MyTree with given name from array.
328 >
329 >  if (fTrees.GetEntries()==0)
330 >    return 0;
331 >
332 >  TObject *obj = 0;
333 >  if (tn==0) {
334 >    obj = fTrees.At(0);
335 >  } else {
336 >    obj = fTrees.FindObject(tn);
337 >  }
338 >  
339 >  if (obj)  
340 >    return static_cast<MyTree*>(obj);
341 >  return 0;
342 > }  
343 >
344 > //--------------------------------------------------------------------------------------------------
345 > const TTree *mithep::TreeWriter::GetTree(const char *tn) const
346 > {
347 >  // Return TTree with given name from array.
348 >
349 >  if (fTrees.GetEntries()==0)
350 >    return 0;
351 >
352 >  TObject *obj = 0;
353 >  if (tn==0) {
354 >    obj = fTrees.At(0);
355 >  } else {
356 >    obj = fTrees.FindObject(tn);
357 >  }
358 >  
359 >  if (obj)  
360 >    return dynamic_cast<const TTree*>(obj);
361 >  return 0;
362 > }  
363 >
364 > //--------------------------------------------------------------------------------------------------
365 > TTree *mithep::TreeWriter::GetTree(const char *tn)
366 > {
367 >  // Return TTree with given name from array.
368 >
369 >  if (fTrees.GetEntries()==0)
370 >    return 0;
371 >
372 >  TObject *obj = 0;
373 >  if (tn==0) {
374 >    obj = fTrees.At(0);
375 >  } else {
376 >    obj = fTrees.FindObject(tn);
377 >  }
378 >  
379 >  if (obj)  
380 >    return dynamic_cast<TTree*>(obj);
381 >  return 0;
382 > }  
383 >
384 > //--------------------------------------------------------------------------------------------------
385   Bool_t TreeWriter::IsFull() const
386   {
387    // Check if the maximum file size has been reached.
388  
389    Long64_t entries = GetEntries();
157  
390    if (entries < 1) return kFALSE;
391    
392    Long64_t avgSize = GetFileSize() / entries;
# Line 165 | Line 397 | Bool_t TreeWriter::IsFull() const
397    return (GetFileSize() + avgSize + fkMinFreeSpace) > fMaxSize;
398   }
399  
400 < //__________________________________________________________________________________________________
400 > //--------------------------------------------------------------------------------------------------
401   void TreeWriter::OpenFile()
402   {
403    // Open the file and attach the tree.
# Line 187 | Line 419 | void TreeWriter::OpenFile()
419    }
420  
421    fFile->SetCompressionLevel(fCompressLevel);
422 <  fTree->SetDirectory(fFile);
422 >
423 >  for (Int_t i=0;i<fTrees.GetEntries();++i) {
424 >    MyTree *mt = static_cast<MyTree*>(fTrees.At(i));
425 >    mt->SetDirectory(fFile);
426 >  }
427 >
428    fIsInit = kTRUE;
429   }
430  
431 < //__________________________________________________________________________________________________
431 > //--------------------------------------------------------------------------------------------------
432   void TreeWriter::Print(Option_t *option) const
433   {
434    // Print the contents of the tree writer.
435  
436 <  if(option) {
436 >  if (option) {
437      cout << ClassName() << " with members " << endl;
438      cout << "   fBaseURL:       " << fBaseURL << endl;
439      cout << "   fPreFix:        " << fPrefix << endl;
# Line 213 | Line 450 | void TreeWriter::Print(Option_t *option)
450         << (GetEntries() == 1 ? " event" : " events") << endl;
451   }
452  
453 < //__________________________________________________________________________________________________
453 > //--------------------------------------------------------------------------------------------------
454 > void TreeWriter::SetAutoFill(const char *tn, Bool_t b)
455 > {
456 >  // Set auto-fill mode of tree with given name.
457 >
458 >  if (fTrees.GetEntries()==0)
459 >    return;
460 >
461 >  MyTree *mt = GetMyTree(tn);
462 >  if (!mt)
463 >    return;
464 >
465 >  mt->SetAutoFill(b);
466 > }
467 >
468 > //--------------------------------------------------------------------------------------------------
469 > void TreeWriter::SetMaxSize(Long64_t s)
470 > {
471 >  // Set maximum file size. Check if this exceeds the ROOT file size and if,
472 >  // print a warning and adjust it.
473 >
474 >  if (s>=(Long64_t)(0.99 * TTree::GetMaxTreeSize())) {
475 >    Long64_t news = (Long64_t)(s/0.99);
476 >    Warning("SetMaxSize", "Maximum tree size increased from %lld to %lld",
477 >            TTree::GetMaxTreeSize(), news);
478 >    TTree::SetMaxTreeSize(news);
479 >  }
480 >
481 >  fMaxSize=s;
482 > }
483 >
484 > //--------------------------------------------------------------------------------------------------
485   void TreeWriter::StoreObject(const TObject *obj)
486   {
487    // Store object next to tree in file. Used to store the

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines