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

Last change on this file since 858 was 858, checked in by tbretz, 23 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 12.2 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(MWriteRootFile);
46
47// --------------------------------------------------------------------------
48//
49// Specify the name of the root file. You can also give an option ("UPDATE"
50// and "RECREATE" would make sense only) as well as the file title and
51// compression factor. To a more detaild description of the options see
52// TFile.
53//
54MWriteRootFile::MWriteRootFile(const char *fname,
55 const Option_t *opt,
56 const char *ftitle,
57 const Int_t comp,
58 const char *name,
59 const char *title)
60{
61 *fName = name ? name : "MWriteRootFile";
62 *fTitle = title ? title : "Task which writes a root-output file";
63
64 //
65 // Set the Arrays the owner of its entries. This means, that the
66 // destructor of the arrays will delete all its entries.
67 //
68 fBranches.SetOwner();
69 fTrees.SetOwner();
70
71 //
72 // Open the rootfile
73 //
74 fOut = new TFile(fname, opt, ftitle, comp);
75}
76
77// --------------------------------------------------------------------------
78//
79// Prints some statistics about the file to the screen. And closes the file
80// properly.
81//
82MWriteRootFile::~MWriteRootFile()
83{
84 //
85 // Print some statistics to the looging out.
86 //
87 Print();
88
89 //
90 // If the file is still open (no error) write the keys. This is necessary
91 // for appearance of the all trees and branches.
92 //
93 if (IsFileOpen())
94 fOut->Write();
95
96 //
97 // Delete the file. This'll also close the file (if open)
98 //
99 delete fOut;
100}
101
102// --------------------------------------------------------------------------
103//
104// Prints all trees with the actually number of written entries to log-out.
105//
106void MWriteRootFile::Print(Option_t *)
107{
108 *fLog << "File: " << GetFileName() << endl;
109 *fLog << "--------------------------------------------------" << endl;
110
111 MRootFileTree *entry;
112
113 //
114 // Loop over all tree entries
115 //
116 TObjArrayIter Next(&fTrees);
117 while ((entry=(MRootFileTree*)Next()))
118 {
119 //
120 // Print out the name and the number of actually written entries.
121 //
122 *fLog << entry->GetTree()->GetName() << ": \t";
123 *fLog << entry->GetNumEntries() << " entries." << endl;
124 }
125}
126
127// --------------------------------------------------------------------------
128//
129// Add a new Container to list of containers which should be written to the
130// file. Give the name of the container which will identify the container
131// in the parameterlist. tname is the name of the tree to which the
132// container should be written (Remark: one tree can hold more than one
133// container). The default is the same name as the container name.
134// You can slso specify a title for the tree. This is only
135// used the first time this tree in 'mentioned'. As default the title
136// is the name of the tree.
137//
138void MWriteRootFile::AddContainer(const char *cname, const char *tname, const char *ttitle)
139{
140 //
141 // create a new entry in the list of branches to write and
142 // add the entry to the list.
143 //
144 MRootFileBranch *entry = new MRootFileBranch(cname, tname, ttitle);
145 fBranches.AddLast(entry);
146}
147
148// --------------------------------------------------------------------------
149//
150// Add a new Container to list of containers which should be written to the
151// file. Give the pointer to the container. tname is the name of the tree to
152// which the container should be written (Remark: one tree can hold more than
153// one container). The default is the same name as the container name.
154// You can slso specify a title for the tree. This is only
155// used the first time this tree in 'mentioned'. As default the title
156// is the name of the tree.
157//
158void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname,
159 const char *ttitle)
160{
161 //
162 // create a new entry in the list of branches to write and
163 // add the entry to the list.
164 //
165 MRootFileBranch *entry = new MRootFileBranch(cont, tname, ttitle);
166 fBranches.AddLast(entry);
167}
168
169// --------------------------------------------------------------------------
170//
171// Add a new Container to list of containers which should be written to the
172// file. Give the pointer to the container. tname is the name of the tree to
173// which the container should be written (Remark: one tree can hold more than
174// one container). The default is the same name as the container name.
175// You can slso specify a title for the tree. This is only
176// used the first time this tree in 'mentioned'. As default the title
177// is the name of the tree.
178//
179Bool_t MWriteRootFile::GetContainer(MParList *pList)
180{
181 MRootFileBranch *entry;
182
183 //
184 //
185 // loop over all branches which are 'marked' as branches to get written.
186 TObjArrayIter Next(&fBranches);
187 while ((entry=(MRootFileBranch*)Next()))
188 {
189 //
190 // Get the pointer to the container. If the pointer is NULL it seems,
191 // that the user identified the container by name.
192 //
193 MParContainer *cont = entry->GetContainer();
194 if (!cont)
195 {
196 //
197 // Get the name and try to find a container with this name
198 // in the parameter list.
199 //
200 const char *cname = entry->GetContName();
201 cont = (MParContainer*)pList->FindObject(cname);
202 if (!cont)
203 {
204 //
205 // No corresponding container is found
206 //
207 *fLog << dbginf << "Cannot find parameter container '" << cname << "'." << endl;
208 return kFALSE;
209 }
210 //
211 // The container is found. Put the pointer into the entry.
212 //
213 entry->SetContainer(cont);
214 }
215
216 //
217 // Get container name, tree name and tree title of this entry.
218 //
219 const char *cname = cont->GetName();
220 const char *tname = entry->GetTreeName();
221 const char *ttitle = entry->GetTreeTitle();
222
223 //
224 // if the tree name is NULL this idetifies it to use the default:
225 // the container name.
226 //
227 if (!tname)
228 tname = cname;
229
230 //
231 // Check if the tree is already existing (part of the file)
232 //
233 TTree *tree = (TTree*)fOut->Get(tname);
234 if (!tree)
235 {
236 //
237 // if the tree doesn't exist create a new tree. Use the tree
238 // name as title if title is NULL
239 //
240 tree = new TTree(tname, ttitle ? ttitle : tname);
241
242 //
243 // Create a new entry in the list of trees, which are stored to
244 // the file. Add it to the list.
245 //
246 MRootFileTree *entry = new MRootFileTree(tree);
247 fTrees.AddLast(entry);
248
249 *fLog << "Created Tree " << tname << "." << endl;
250 }
251
252 //
253 // Now we have a valid tree. Search the list of trees for this tree
254 // (either it is already there, or we created and add it previously)
255 // Add a pointer to the entry in the tree list to this branch-entry
256 //
257 MRootFileTree *loop;
258 TObjArrayIter NextTree(&fTrees);
259 while ((loop=(MRootFileTree*)NextTree()))
260 {
261 if (loop->GetTree() == tree)
262 entry->SetTree(loop);
263 }
264
265 //
266 // Try to get the branch from the file.
267 // If the branch already exists the user specified one branch twice.
268 //
269 TBranch *branch = tree->GetBranch(cname);
270 if (branch)
271 {
272 *fLog << dbginf << "Branch '" << cname << "' is already existing." << endl;
273 return kFALSE;
274 }
275
276 //
277 // Create a new branch in the actual tree. The branch has the name
278 // container name. The type of the container is given by the
279 // ClassName entry in the container. The Address is the address of a
280 // pointer to the container (gotten from the branch entry). As
281 // Basket size we specify a (more or less) common default value.
282 // The containers should be written in Splitlevel=1
283 //
284 branch = tree->Branch(cname, cont->ClassName(), entry->GetAddress(), 32000, 1);
285
286 *fLog << "Created Branch " << cname << " of " << cont->ClassName() << "." << endl;
287
288 //
289 // If the branch couldn't be created we have a problem.
290 //
291 if (!branch)
292 {
293 *fLog << dbginf << "Unable to create branch '" << cname << "'." << endl;
294 return kFALSE;
295 }
296 }
297 return kTRUE;
298}
299
300// --------------------------------------------------------------------------
301//
302// Checks all given containers (branch entries) for the write flag.
303// If the write flag is set the corresponding Tree is marked to get filled.
304// All Trees which are marked to be filled are filled with the corresponding
305// branches.
306// Be carefull: If only one container (corresponding to a branch) of a tree
307// has the write flag, all containers in this tree are filled!
308//
309void MWriteRootFile::CheckAndWrite() const
310{
311 TObject *obj;
312
313 //
314 // Loop over all branch entries
315 //
316 TObjArrayIter NextBranch(&fBranches);
317 while ((obj=NextBranch()))
318 {
319 MRootFileBranch *entry = (MRootFileBranch*)obj;
320
321 //
322 // Check for the Write flag
323 //
324 if (!entry->GetContainer()->IsReadyToSave())
325 continue;
326
327 //
328 // If the write flag of the branch entry is set, set the write flag of
329 // the corresponding tree entry.
330 //
331 entry->GetTree()->SetWriteFlag();
332 }
333
334 //
335 // Loop over all tree entries
336 //
337 TObjArrayIter NextTree(&fTrees);
338 while ((obj=NextTree()))
339 {
340 MRootFileTree *entry = (MRootFileTree*)obj;
341
342 //
343 // Check the write flag of the tree
344 //
345 if (!entry->HasWriteFlag())
346 continue;
347
348 //
349 // If the write flag is set, fill the tree (with the corrasponding
350 // branches/containers), delete the write flag and increase the number
351 // of written/filled entries.
352 //
353 entry->GetTree()->Fill();
354 entry->DelWriteFlag();
355 (*entry)++;
356 }
357}
358
359// --------------------------------------------------------------------------
360//
361// return open state of the root file.
362//
363Bool_t MWriteRootFile::IsFileOpen() const
364{
365 return fOut->IsOpen();
366}
367
368// --------------------------------------------------------------------------
369//
370// return name of the root-file
371//
372const char *MWriteRootFile::GetFileName() const
373{
374 return fOut->GetName();
375}
376
Note: See TracBrowser for help on using the repository browser.