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

Last change on this file since 972 was 967, 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(MRootFileBranch);
46ClassImp(MRootFileTree);
47
48ClassImp(MWriteRootFile);
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 *)
110{
111 *fLog << "File: " << GetFileName() << endl;
112 *fLog << "--------------------------------------------------" << endl;
113
114 MRootFileTree *entry;
115
116 //
117 // Loop over all tree entries
118 //
119 TObjArrayIter Next(&fTrees);
120 while ((entry=(MRootFileTree*)Next()))
121 {
122 //
123 // Print out the name and the number of actually written entries.
124 //
125 *fLog << entry->GetTree()->GetName() << ": \t";
126 *fLog << entry->GetNumEntries() << " entries." << endl;
127 }
128}
129
130// --------------------------------------------------------------------------
131//
132// Add a new Container to list of containers which should be written to the
133// file. Give the name of the container which will identify the container
134// in the parameterlist. tname is the name of the tree to which the
135// container should be written (Remark: one tree can hold more than one
136// container). The default is the same name as the container name.
137// You can slso specify a title for the tree. This is only
138// used the first time this tree in 'mentioned'. As default the title
139// is the name of the tree.
140//
141void MWriteRootFile::AddContainer(const char *cname, const char *tname, const char *ttitle)
142{
143 //
144 // create a new entry in the list of branches to write and
145 // add the entry to the list.
146 //
147 MRootFileBranch *entry = new MRootFileBranch(cname, tname, ttitle);
148 fBranches.AddLast(entry);
149}
150
151// --------------------------------------------------------------------------
152//
153// Add a new Container to list of containers which should be written to the
154// file. Give the pointer to the container. tname is the name of the tree to
155// which the container should be written (Remark: one tree can hold more than
156// one container). The default is the same name as the container name.
157// You can slso specify a title for the tree. This is only
158// used the first time this tree in 'mentioned'. As default the title
159// is the name of the tree.
160//
161void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname,
162 const char *ttitle)
163{
164 //
165 // create a new entry in the list of branches to write and
166 // add the entry to the list.
167 //
168 MRootFileBranch *entry = new MRootFileBranch(cont, tname, ttitle);
169 fBranches.AddLast(entry);
170}
171
172// --------------------------------------------------------------------------
173//
174// Add a new Container to list of containers which should be written to the
175// file. Give the pointer to the container. tname is the name of the tree to
176// which the container should be written (Remark: one tree can hold more than
177// one container). The default is the same name as the container name.
178// You can slso specify a title for the tree. This is only
179// used the first time this tree in 'mentioned'. As default the title
180// is the name of the tree.
181//
182Bool_t MWriteRootFile::GetContainer(MParList *pList)
183{
184 MRootFileBranch *entry;
185
186 //
187 //
188 // loop over all branches which are 'marked' as branches to get written.
189 TObjArrayIter Next(&fBranches);
190 while ((entry=(MRootFileBranch*)Next()))
191 {
192 //
193 // Get the pointer to the container. If the pointer is NULL it seems,
194 // that the user identified the container by name.
195 //
196 MParContainer *cont = entry->GetContainer();
197 if (!cont)
198 {
199 //
200 // Get the name and try to find a container with this name
201 // in the parameter list.
202 //
203 const char *cname = entry->GetContName();
204 cont = (MParContainer*)pList->FindObject(cname);
205 if (!cont)
206 {
207 //
208 // No corresponding container is found
209 //
210 *fLog << dbginf << "Cannot find parameter container '" << cname << "'." << endl;
211 return kFALSE;
212 }
213 //
214 // The container is found. Put the pointer into the entry.
215 //
216 entry->SetContainer(cont);
217 }
218
219 //
220 // Get container name, tree name and tree title of this entry.
221 //
222 const char *cname = cont->GetName();
223 const char *tname = entry->GetTreeName();
224 const char *ttitle = entry->GetTreeTitle();
225
226 //
227 // if the tree name is NULL this idetifies it to use the default:
228 // the container name.
229 //
230 if (!tname)
231 tname = cname;
232
233 //
234 // Check if the tree is already existing (part of the file)
235 //
236 TTree *tree = (TTree*)fOut->Get(tname);
237 if (!tree)
238 {
239 //
240 // if the tree doesn't exist create a new tree. Use the tree
241 // name as title if title is NULL
242 //
243 tree = new TTree(tname, ttitle ? ttitle : tname);
244
245 //
246 // Create a new entry in the list of trees, which are stored to
247 // the file. Add it to the list.
248 //
249 MRootFileTree *entry = new MRootFileTree(tree);
250 fTrees.AddLast(entry);
251
252 *fLog << "Created Tree " << tname << "." << endl;
253 }
254
255 //
256 // Now we have a valid tree. Search the list of trees for this tree
257 // (either it is already there, or we created and add it previously)
258 // Add a pointer to the entry in the tree list to this branch-entry
259 //
260 MRootFileTree *loop;
261 TObjArrayIter NextTree(&fTrees);
262 while ((loop=(MRootFileTree*)NextTree()))
263 {
264 if (loop->GetTree() == tree)
265 entry->SetTree(loop);
266 }
267
268 //
269 // Try to get the branch from the file.
270 // If the branch already exists the user specified one branch twice.
271 //
272 TBranch *branch = tree->GetBranch(cname);
273 if (branch)
274 {
275 *fLog << dbginf << "Branch '" << cname << "' is already existing." << endl;
276 return kFALSE;
277 }
278
279 //
280 // Create a new branch in the actual tree. The branch has the name
281 // container name. The type of the container is given by the
282 // ClassName entry in the container. The Address is the address of a
283 // pointer to the container (gotten from the branch entry). As
284 // Basket size we specify a (more or less) common default value.
285 // The containers should be written in Splitlevel=1
286 //
287 branch = tree->Branch(cname, cont->ClassName(), entry->GetAddress(), 32000, 1);
288
289 *fLog << "Created Branch " << cname << " of " << cont->ClassName() << "." << endl;
290
291 //
292 // If the branch couldn't be created we have a problem.
293 //
294 if (!branch)
295 {
296 *fLog << dbginf << "Unable to create branch '" << cname << "'." << endl;
297 return kFALSE;
298 }
299 }
300 return kTRUE;
301}
302
303// --------------------------------------------------------------------------
304//
305// Checks all given containers (branch entries) for the write flag.
306// If the write flag is set the corresponding Tree is marked to get filled.
307// All Trees which are marked to be filled are filled with the corresponding
308// branches.
309// Be carefull: If only one container (corresponding to a branch) of a tree
310// has the write flag, all containers in this tree are filled!
311//
312void MWriteRootFile::CheckAndWrite() const
313{
314 TObject *obj;
315
316 //
317 // Loop over all branch entries
318 //
319 TObjArrayIter NextBranch(&fBranches);
320 while ((obj=NextBranch()))
321 {
322 MRootFileBranch *entry = (MRootFileBranch*)obj;
323
324 //
325 // Check for the Write flag
326 //
327 if (!entry->GetContainer()->IsReadyToSave())
328 continue;
329
330 //
331 // If the write flag of the branch entry is set, set the write flag of
332 // the corresponding tree entry.
333 //
334 entry->GetTree()->SetWriteFlag();
335 }
336
337 //
338 // Loop over all tree entries
339 //
340 TObjArrayIter NextTree(&fTrees);
341 while ((obj=NextTree()))
342 {
343 MRootFileTree *entry = (MRootFileTree*)obj;
344
345 //
346 // Check the write flag of the tree
347 //
348 if (!entry->HasWriteFlag())
349 continue;
350
351 //
352 // If the write flag is set, fill the tree (with the corrasponding
353 // branches/containers), delete the write flag and increase the number
354 // of written/filled entries.
355 //
356 entry->GetTree()->Fill();
357 entry->DelWriteFlag();
358 (*entry)++;
359 }
360}
361
362// --------------------------------------------------------------------------
363//
364// return open state of the root file.
365//
366Bool_t MWriteRootFile::IsFileOpen() const
367{
368 return fOut->IsOpen();
369}
370
371// --------------------------------------------------------------------------
372//
373// return name of the root-file
374//
375const char *MWriteRootFile::GetFileName() const
376{
377 return fOut->GetName();
378}
379
Note: See TracBrowser for help on using the repository browser.