source: trunk/MagicSoft/Mars/mbase/MWriteRootFile.cc@ 1003

Last change on this file since 1003 was 1003, checked in by tbretz, 24 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 11.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 06/2001 (tbretz@uni-sw.gwdg.de)
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MWriteRootFile //
28// //
29// This is a writer to store several containers to a root file. //
30// The containers are added with AddContainer. //
31// To understand how it works, see base class MWriteFile //
32// //
33/////////////////////////////////////////////////////////////////////////////
34
35#include "MWriteRootFile.h"
36
37#include <TFile.h>
38#include <TTree.h>
39
40#include "MLog.h"
41#include "MLogManip.h"
42
43#include "MParList.h"
44
45ClassImp(MRootFileBranch);
46ClassImp(MWriteRootFile);
47
48#define kFillTree BIT(1)
49
50// --------------------------------------------------------------------------
51//
52// Specify the name of the root file. You can also give an option ("UPDATE"
53// and "RECREATE" would make sense only) as well as the file title and
54// compression factor. To a more detaild description of the options see
55// TFile.
56//
57MWriteRootFile::MWriteRootFile(const char *fname,
58 const Option_t *opt,
59 const char *ftitle,
60 const Int_t comp,
61 const char *name,
62 const char *title)
63{
64 fName = name ? name : "MWriteRootFile";
65 fTitle = title ? title : "Task which writes a root-output file";
66
67 //
68 // Set the Arrays the owner of its entries. This means, that the
69 // destructor of the arrays will delete all its entries.
70 //
71 fBranches.SetOwner();
72 fTrees.SetOwner();
73
74 //
75 // Open the rootfile
76 //
77 fOut = new TFile(fname, opt, ftitle, comp);
78}
79
80// --------------------------------------------------------------------------
81//
82// Prints some statistics about the file to the screen. And closes the file
83// properly.
84//
85MWriteRootFile::~MWriteRootFile()
86{
87 //
88 // Print some statistics to the looging out.
89 //
90 Print();
91
92 //
93 // If the file is still open (no error) write the keys. This is necessary
94 // for appearance of the all trees and branches.
95 //
96 if (IsFileOpen())
97 fOut->Write();
98
99 //
100 // Delete the file. This'll also close the file (if open)
101 //
102 delete fOut;
103}
104
105// --------------------------------------------------------------------------
106//
107// Prints all trees with the actually number of written entries to log-out.
108//
109void MWriteRootFile::Print(Option_t *) const
110{
111 cout << "File: " << GetFileName() << endl;
112 cout << "--------------------------------------------------" << endl;
113
114 TTree *t;
115 TIter Next(&fTrees);
116 while ((t=(TTree*)Next()))
117 cout << t->GetName() << ": \t" << t->GetEntries() << " entries." << endl;
118}
119
120// --------------------------------------------------------------------------
121//
122// Add a new Container to list of containers which should be written to the
123// file. Give the name of the container which will identify the container
124// in the parameterlist. tname is the name of the tree to which the
125// container should be written (Remark: one tree can hold more than one
126// container). The default is the same name as the container name.
127// You can slso specify a title for the tree. This is only
128// used the first time this tree in 'mentioned'. As default the title
129// is the name of the tree.
130//
131void MWriteRootFile::AddContainer(const char *cname, const char *tname, const char *ttitle)
132{
133 //
134 // create a new entry in the list of branches to write and
135 // add the entry to the list.
136 //
137 MRootFileBranch *entry = new MRootFileBranch(cname, tname, ttitle);
138 fBranches.AddLast(entry);
139}
140
141// --------------------------------------------------------------------------
142//
143// Add a new Container to list of containers which should be written to the
144// file. Give the pointer to the container. tname is the name of the tree to
145// which the container should be written (Remark: one tree can hold more than
146// one container). The default is the same name as the container name.
147// You can slso specify a title for the tree. This is only
148// used the first time this tree in 'mentioned'. As default the title
149// is the name of the tree.
150//
151void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname,
152 const char *ttitle)
153{
154 //
155 // create a new entry in the list of branches to write and
156 // add the entry to the list.
157 //
158 MRootFileBranch *entry = new MRootFileBranch(cont, tname, ttitle);
159 fBranches.AddLast(entry);
160}
161
162// --------------------------------------------------------------------------
163//
164// Add a new Container to list of containers which should be written to the
165// file. Give the pointer to the container. tname is the name of the tree to
166// which the container should be written (Remark: one tree can hold more than
167// one container). The default is the same name as the container name.
168// You can slso specify a title for the tree. This is only
169// used the first time this tree in 'mentioned'. As default the title
170// is the name of the tree.
171//
172Bool_t MWriteRootFile::GetContainer(MParList *pList)
173{
174 MRootFileBranch *entry;
175
176 //
177 // loop over all branches which are 'marked' as branches to get written.
178 //
179 TIter Next(&fBranches);
180 while ((entry=(MRootFileBranch*)Next()))
181 {
182 //
183 // Get the pointer to the container. If the pointer is NULL it seems,
184 // that the user identified the container by name.
185 //
186 MParContainer *cont = entry->GetContainer();
187 if (!cont)
188 {
189 //
190 // Get the name and try to find a container with this name
191 // in the parameter list.
192 //
193 const char *cname = entry->GetContName();
194 cont = (MParContainer*)pList->FindObject(cname);
195 if (!cont)
196 {
197 //
198 // No corresponding container is found
199 //
200 *fLog << dbginf << "Cannot find parameter container '" << cname << "'." << endl;
201 return kFALSE;
202 }
203 //
204 // The container is found. Put the pointer into the entry.
205 //
206 entry->SetContainer(cont);
207 }
208
209 //
210 // Get container name, tree name and tree title of this entry.
211 //
212 const char *cname = cont->GetName();
213 const char *tname = entry->GetName();
214 const char *ttitle = entry->GetTitle();
215
216 //
217 // if the tree name is NULL this idetifies it to use the default:
218 // the container name.
219 //
220 if (tname[0] == '\0')
221 tname = cname;
222
223 //
224 // Check if the tree is already existing (part of the file)
225 //
226 TTree *tree = (TTree*)fOut->Get(tname);
227 if (!tree)
228 {
229 //
230 // if the tree doesn't exist create a new tree. Use the tree
231 // name as title if title is NULL.
232 // And add the tree to the list of trees
233 //
234 tree = new TTree(tname, ttitle ? ttitle : tname);
235 fTrees.AddLast(tree);
236
237 *fLog << "Created Tree " << tname << "." << endl;
238 }
239
240 //
241 // Now we have a valid tree. Search the list of trees for this tree
242 // (either it is already there, or we created and add it previously)
243 // Add a pointer to the entry in the tree list to this branch-entry
244 //
245 TObject *obj;
246 TIter NextTree(&fTrees);
247 while ((obj=NextTree()))
248 {
249 if (obj == tree)
250 entry->SetTree((TTree*)obj);
251 }
252
253 //
254 // Try to get the branch from the file.
255 // If the branch already exists the user specified one branch twice.
256 //
257 TBranch *branch = tree->GetBranch(cname);
258 if (branch)
259 {
260 *fLog << dbginf << "Branch '" << cname << "' is already existing." << endl;
261 return kFALSE;
262 }
263
264 //
265 // Create a new branch in the actual tree. The branch has the name
266 // container name. The type of the container is given by the
267 // ClassName entry in the container. The Address is the address of a
268 // pointer to the container (gotten from the branch entry). As
269 // Basket size we specify a (more or less) common default value.
270 // The containers should be written in Splitlevel=1
271 //
272 branch = tree->Branch(cname, cont->ClassName(), entry->GetAddress());
273
274 *fLog << "Created Branch " << cname << " of " << cont->ClassName() << "." << endl;
275
276 //
277 // If the branch couldn't be created we have a problem.
278 //
279 if (!branch)
280 {
281 *fLog << dbginf << "Unable to create branch '" << cname << "'." << endl;
282 return kFALSE;
283 }
284 }
285 return kTRUE;
286}
287
288// --------------------------------------------------------------------------
289//
290// Checks all given containers (branch entries) for the write flag.
291// If the write flag is set the corresponding Tree is marked to get filled.
292// All Trees which are marked to be filled are filled with the corresponding
293// branches.
294// Be carefull: If only one container (corresponding to a branch) of a tree
295// has the write flag, all containers in this tree are filled!
296//
297void MWriteRootFile::CheckAndWrite() const
298{
299 TObject *obj;
300
301 //
302 // Loop over all branch entries
303 //
304 TIter NextBranch(&fBranches);
305 while ((obj=NextBranch()))
306 {
307 MRootFileBranch *b = (MRootFileBranch*)obj;
308
309 //
310 // Check for the Write flag
311 //
312 if (!b->GetContainer()->IsReadyToSave())
313 continue;
314
315 //
316 // If the write flag of the branch entry is set, set the write flag of
317 // the corresponding tree entry.
318 //
319 b->GetTree()->SetBit(kFillTree);
320 }
321
322 //
323 // Loop over all tree entries
324 //
325 TIter NextTree(&fTrees);
326 while ((obj=NextTree()))
327 {
328 TTree *t = (TTree*)obj;
329
330 //
331 // Check the write flag of the tree
332 //
333 if (!t->TestBit(kFillTree))
334 continue;
335
336 //
337 // If the write flag is set, fill the tree (with the corresponding
338 // branches/containers), delete the write flag and increase the number
339 // of written/filled entries.
340 //
341 t->Fill();
342 t->ResetBit(kFillTree);
343 }
344}
345
346// --------------------------------------------------------------------------
347//
348// return open state of the root file.
349//
350Bool_t MWriteRootFile::IsFileOpen() const
351{
352 return fOut->IsOpen();
353}
354
355// --------------------------------------------------------------------------
356//
357// return name of the root-file
358//
359const char *MWriteRootFile::GetFileName() const
360{
361 return fOut->GetName();
362}
363
Note: See TracBrowser for help on using the repository browser.