source: trunk/MagicSoft/Mars/mbase/MReadTree.cc@ 770

Last change on this file since 770 was 768, checked in by tbretz, 24 years ago
*** empty log message ***
File size: 10.9 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 12/2000 (tbretz@uni-sw.gwdg.de)
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MReadTree //
28// //
29// This tasks opens all branches in a specified tree and creates the //
30// corresponding parameter containers if not already existing in the //
31// parameter list. //
32// //
33// The Process function reads one events from the tree. To go through the //
34// events of one tree make sure that the event number is increased from //
35// outside. It makes also possible to go back by decreasing the number. //
36// //
37/////////////////////////////////////////////////////////////////////////////
38
39#include "MReadTree.h"
40
41#include <fstream.h>
42
43#include <TFile.h>
44#include <TChain.h>
45#include <TArrayC.h>
46#include <TObjArray.h>
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51#include "MTime.h"
52#include "MParList.h"
53
54ClassImp(MReadTree)
55
56// --------------------------------------------------------------------------
57//
58// Default constructor. It creates an TChain instance which represents the
59// the Tree you want to read and adds the given file (if you gave one).
60// More files can be added using MReadTree::AddFile.
61// Also an empty veto list is created. This list is used if you want to
62// veto (disable or "don't enable") a branch in the tree.
63//
64MReadTree::MReadTree(const char *tname, const char *fname,
65 const char *name, const char *title) : fNumEntry(0)
66{
67 *fName = name ? name : "MReadTree";
68 *fTitle = title ? title : "Task to loop over all events in one single tree";
69
70 fVetoList = new TArrayC;
71 //
72 // open the input stream
73 //
74 fChain = new TChain(tname);
75
76 if (fname)
77 fChain->Add(fname);
78}
79
80// --------------------------------------------------------------------------
81//
82// Destructor. It deletes the TChain and veto list object
83//
84MReadTree::~MReadTree()
85{
86 delete fChain;
87 delete fVetoList;
88}
89
90// --------------------------------------------------------------------------
91//
92// If you want to read the given tree over several files you must add
93// the files here before PreProcess is called. Be carfull: This does
94// only work if the trees in the files containing the same branches yet.
95//
96/*Int_t*/ void MReadTree::AddFile(const char *fname)
97{
98 //
99 // FIXME! A check is missing whether the file already exists or not.
100 //
101 //
102 // returns the number of file which were added
103 //
104 /*return root >3.0*/ fChain->Add(fname);
105}
106
107// --------------------------------------------------------------------------
108//
109// The PreProcess loops (till now) over the branches in the given tree.
110// It checks if the corresponding containers (containers with the same
111// name than the branch name) are existing in the Parameter Container List.
112// If not, a container of objec type 'branch-name' is created (everything
113// after the last semicolon in the branch name is stripped). Only
114// branches which don't have a veto (see VetoBranch) are enabled If the
115// object isn't found in the root dictionary (a list of classes known by the
116// root environment) the branch is skipped and an error message is printed
117// out.
118//
119Bool_t MReadTree::PreProcess (MParList *pList)
120{
121 //
122 // get number of events in this tree
123 //
124 fNumEntries = (UInt_t)fChain->GetEntries();
125
126 if (!fNumEntries)
127 {
128 *fLog << dbginf << "No Entries found in chain (file/s)." << endl;
129 return kFALSE;
130 }
131
132 //
133 // output logging information
134 //
135 *fLog << fNumEntries << " Entries found in file(s)." << endl;
136
137 //
138 // Get all branches of this tree and
139 // create the Iterator to loop over all branches
140 //
141 TIter Next(fChain->GetListOfBranches());
142 TBranch *branch=NULL;
143
144 //
145 // loop over all tasks for processing
146 //
147 while ( (branch=(TBranch*)Next()) )
148 {
149 //
150 // Get Name of Branch
151 //
152 const char *name = branch->GetName();
153
154 //
155 // Check if enabeling the branch is allowed
156 //
157 if (HasVeto(name))
158 continue;
159
160 //
161 // check if object is existing in the list
162 //
163 MParContainer *pcont = pList->FindCreateObj(name);
164
165
166 if (!pcont)
167 {
168 //
169 // if class is not existing in the (root) environment
170 // we cannot proceed reading this branch
171 //
172 *fLog << "MReadTree::PreProcess - Warning: Class '" << name << "' not existing in dictionary. Branch skipped." << endl;
173 continue;
174 }
175
176 //
177 // here pcont is a pointer the to container in which the data from
178 // the actual branch should be stored - enable branch.
179 //
180 branch->SetAddress(&pcont);
181 }
182
183 return kTRUE;
184}
185
186// --------------------------------------------------------------------------
187//
188// The Process-function reads one event from the tree (this contains all
189// enabled branches) and increases the position in the file by one event.
190// (Remark: The position can also be set by some member functions
191// If the end of the file is reached the Eventloop is stopped.
192Bool_t MReadTree::Process()
193{
194 //
195 // check for end of file
196 //
197 if (fNumEntry>=fNumEntries)
198 return kFALSE;
199
200 //
201 // get entry
202 //
203 fChain->GetEntry(fNumEntry);
204
205 fNumEntry++;
206
207 return kTRUE;
208}
209
210// --------------------------------------------------------------------------
211//
212// Get the Event with the current EventNumber fNumEntry
213//
214Bool_t MReadTree::GetEvent()
215{
216 fChain->GetEntry(fNumEntry);
217
218 return kTRUE;
219}
220
221// --------------------------------------------------------------------------
222//
223// Decrease the number of the event which is read by Process() next
224// by one or more
225//
226Bool_t MReadTree::DecEventNum(UInt_t dec)
227{
228 //!
229 //! this function makes Process() read the event one (or more) before
230 //! the actual position (event) in the tree
231 //!
232 if (fNumEntry < dec/*+1*/)
233 {
234 *fLog << "MReadTree::SetPrevEvent: WARNING: " << fNumEntry/*-1*/ << "-" << dec << " out of Range." << endl;
235 return kFALSE;
236 }
237
238 fNumEntry -= dec/*+1*/;
239 return kTRUE;
240}
241
242// --------------------------------------------------------------------------
243//
244// Increase the number of the event which is read by Process() next
245// by one or more
246//
247Bool_t MReadTree::IncEventNum(UInt_t inc)
248{
249 //!
250 //! this function makes Process() read the next (or more) after
251 //! the actual position (event) in the tree
252 //! (Be careful: IncEventNum() or IncEventNum(1) does not chenge anything
253 //! in the standard behaviour of the task)
254 //!
255 if (fNumEntry+inc/*-1*/ >= fNumEntries)
256 {
257 *fLog << "MReadTree::SkipEvents: WARNING: " << fNumEntry/*-1*/ << "+" << inc << " out of Range." << endl;
258 return kFALSE;
259 }
260
261 fNumEntry += inc/*-1*/;
262 return kTRUE;
263}
264
265// --------------------------------------------------------------------------
266//
267// this function makes Process() read event number nr next
268//
269// Remark: You can use this function to set the event number from which
270// you want to start reading.
271//
272Bool_t MReadTree::SetEventNum(UInt_t nr)
273{
274 if (nr>=fNumEntries)
275 {
276 *fLog << "MReadTree::SetEventNum: WARNING: " << nr << " out of Range." << endl;
277 return kFALSE;
278 }
279
280 fNumEntry = nr;
281 return kTRUE;
282}
283
284// --------------------------------------------------------------------------
285//
286// This function checks if the Branch Name is part of the Veto List.
287// This means, that the preprocess doesn't enable the branch.
288//
289Bool_t MReadTree::HasVeto(const char *name) const
290{
291 const size_t nlen = strlen(name)+1;
292
293 char *pos = fVetoList->GetArray();
294 size_t len = fVetoList->GetSize();
295
296 //
297 // now we compare the 'strings' in the list word by word
298 // (string or word in this context means a zero terminated
299 // array of chars
300 //
301
302 for (;;)
303 {
304 //
305 // Search for the first byte of the name
306 //
307 char *c = (char*)memchr(pos, name[0], len);
308
309 //
310 // if we don't find the first byte, the list cannot contain 'name'
311 //
312 if (!c)
313 return kFALSE;
314
315 //
316 // calculate and check how many bytes remains in the list
317 //
318 len -= c-pos;
319
320 //
321 // if there are not enough bytes to match the query we are done
322 //
323 if (len<nlen)
324 return kFALSE;
325
326 //
327 // check if the next 'nlen' byte (including the trailing '\0'
328 // are matching
329 //
330 if (!memcmp(c, name, nlen))
331 return kTRUE;
332
333 //
334 // we didn't find the string, goto the next 'string'
335 //
336 pos = (char*)memchr(c, '\0', len);
337
338 //
339 // check if there is a 'next' string really
340 //
341 if (!pos)
342 return kFALSE;
343
344 //
345 // calculate the remaining length
346 //
347 len -= pos-c;
348
349 //
350 // if there are not enough bytes to match the query we are done
351 //
352 if (len<nlen)
353 return kFALSE;
354 }
355}
356
357
358// --------------------------------------------------------------------------
359//
360// If you don't want that a branch is enabled within the PreProcess you
361// can set a veto for enabeling the branch. (This means also the
362// corresponding object won't be created automatically)
363//
364// This functionality is for experienced users which don't want to
365// read in branches which are not processed in the program (for
366// speed reasons)
367//
368void MReadTree::VetoBranch(const char *name)
369{
370 //
371 // Add this file as the last entry of the list
372 // (including the trailing '\0')
373 //
374 const int sz = fVetoList->GetSize();
375 const int tsz = strlen(name)+1;
376
377 fVetoList->Set(sz+tsz);
378
379 memcpy(fVetoList->GetArray()+sz, name, tsz);
380}
Note: See TracBrowser for help on using the repository browser.