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

Last change on this file since 757 was 757, checked in by tbretz, 24 years ago
*** empty log message ***
File size: 9.6 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// --------------------------------------------------------------------------
57MReadTree::MReadTree(const char *tname, const char *fname,
58 const char *name, const char *title)
59{
60 *fName = name ? name : "MReadTree";
61 *fTitle = title ? title : "Task to loop over all events in one single tree";
62
63 fVetoList = new TArrayC;
64 //
65 // open the input stream
66 //
67 fChain = new TChain(tname);
68
69 if (fname)
70 fChain->Add(fname);
71}
72
73// --------------------------------------------------------------------------
74MReadTree::~MReadTree()
75{
76 delete fChain;
77 delete fVetoList;
78}
79
80// --------------------------------------------------------------------------
81/*Int_t*/ void MReadTree::AddFile(const char *fname)
82{
83 //
84 // FIXME! A check is missing whether the file already exists or not.
85 //
86 //
87 // returns the number of file which were added
88 //
89 /*return root >3.0*/ fChain->Add(fname);
90}
91
92// --------------------------------------------------------------------------
93//
94// open file and check if file is really open
95//
96Bool_t MReadTree::PreProcess (MParList *pList)
97{
98 //
99 // get number of events in this tree
100 //
101 fNumEntries = (UInt_t)fChain->GetEntries();
102
103 if (!fNumEntries)
104 {
105 *fLog << dbginf << "No Entries found in chain (file/s)." << endl;
106 return kFALSE;
107 }
108
109 //
110 // set pointer to first event
111 //
112 fNumEntry = 0;
113
114 //
115 // output logging information
116 //
117 *fLog << fNumEntries << " Entries found in file(s)." << endl;
118
119 //
120 // Get all branches of this tree and
121 // create the Iterator to loop over all branches
122 //
123 TIter Next(fChain->GetListOfBranches());
124 TBranch *branch=NULL;
125
126 //
127 // loop over all tasks for processing
128 //
129 while ( (branch=(TBranch*)Next()) )
130 {
131 //
132 // Get Name of Branch
133 //
134 const char *name = branch->GetName();
135
136 //
137 // Check if enabeling the branch is allowed
138 //
139 if (HasVeto(name))
140 continue;
141
142 //
143 // check if object is existing in the list
144 //
145 MParContainer *pcont = pList->FindCreateObj(name);
146
147
148 if (!pcont)
149 {
150 //
151 // if class is not existing in the (root) environment
152 // we cannot proceed reading this branch
153 //
154 *fLog << "MReadTree::PreProcess - Warning: Class '" << name << "' not existing in dictionary. Branch skipped." << endl;
155 continue;
156 }
157
158 //
159 // here pcont is a pointer the to container in which the data from
160 // the actual branch should be stored - enable branch.
161 //
162 branch->SetAddress(&pcont);
163 }
164
165 return kTRUE;
166}
167
168// --------------------------------------------------------------------------
169Bool_t MReadTree::Process()
170{
171 //
172 // check for end of file
173 //
174 if (fNumEntry==fNumEntries)
175 return kFALSE;
176
177 //
178 // get entry
179 //
180 fChain->GetEntry(fNumEntry );
181
182 fNumEntry ++ ;
183
184 return kTRUE;
185}
186
187// --------------------------------------------------------------------------
188//
189// Close File
190//
191Bool_t MReadTree::PostProcess()
192{
193 //fFile->Close();
194
195 return kTRUE;
196}
197
198// --------------------------------------------------------------------------
199//
200// Get the Event with the current EventNumber fNumEntry
201//
202Bool_t MReadTree::GetEvent()
203{
204 fChain->GetEntry(fNumEntry);
205
206 return kTRUE;
207}
208
209// --------------------------------------------------------------------------
210//
211// Decrease the number of the event which is read by Process() next
212// by one or more
213//
214Bool_t MReadTree::DecEventNum(UInt_t dec)
215{
216 //!
217 //! this function makes Process() read the event one (or more) before
218 //! the actual position (event) in the tree
219 //!
220 if (fNumEntry < dec/*+1*/)
221 {
222 *fLog << "MReadTree::SetPrevEvent: WARNING: " << fNumEntry/*-1*/ << "-" << dec << " out of Range." << endl;
223 return kFALSE;
224 }
225
226 fNumEntry -= dec/*+1*/;
227 return kTRUE;
228}
229
230// --------------------------------------------------------------------------
231//
232// Increase the number of the event which is read by Process() next
233// by one or more
234//
235Bool_t MReadTree::IncEventNum(UInt_t inc)
236{
237 //!
238 //! this function makes Process() read the next (or more) after
239 //! the actual position (event) in the tree
240 //! (Be careful: IncEventNum() or IncEventNum(1) does not chenge anything
241 //! in the standard behaviour of the task)
242 //!
243 if (fNumEntry+inc/*-1*/ >= fNumEntries)
244 {
245 *fLog << "MReadTree::SkipEvents: WARNING: " << fNumEntry/*-1*/ << "+" << inc << " out of Range." << endl;
246 return kFALSE;
247 }
248
249 fNumEntry += inc/*-1*/;
250 return kTRUE;
251}
252
253// --------------------------------------------------------------------------
254//
255// this function makes Process() read event number nr next
256//
257Bool_t MReadTree::SetEventNum(UInt_t nr)
258{
259 if (nr>=fNumEntries)
260 {
261 *fLog << "MReadTree::SetEventNum: WARNING: " << nr << " out of Range." << endl;
262 return kFALSE;
263 }
264
265 fNumEntry = nr;
266 return kTRUE;
267}
268
269// --------------------------------------------------------------------------
270//
271// This function checks if the Branch Name is part of the Veto List.
272// This means, that the preprocess doesn't enable the branch.
273//
274Bool_t MReadTree::HasVeto(const char *name) const
275{
276 const size_t nlen = strlen(name)+1;
277
278 char *pos = fVetoList->GetArray();
279 size_t len = fVetoList->GetSize();
280
281 //
282 // now we compare the 'strings' in the list word by word
283 // (string or word in this context means a zero terminated
284 // array of chars
285 //
286
287 for (;;)
288 {
289 //
290 // Search for the first byte of the name
291 //
292 char *c = (char*)memchr(pos, name[0], len);
293
294 //
295 // if we don't find the first byte, the list cannot contain 'name'
296 //
297 if (!c)
298 return kFALSE;
299
300 //
301 // calculate and check how many bytes remains in the list
302 //
303 len -= c-pos;
304
305 //
306 // if there are not enough bytes to match the query we are done
307 //
308 if (len<nlen)
309 return kFALSE;
310
311 //
312 // check if the next 'nlen' byte (including the trailing '\0'
313 // are matching
314 //
315 if (!memcmp(c, name, nlen))
316 return kTRUE;
317
318 //
319 // we didn't find the string, goto the next 'string'
320 //
321 pos = (char*)memchr(c, '\0', len);
322
323 //
324 // check if there is a 'next' string really
325 //
326 if (!pos)
327 return kFALSE;
328
329 //
330 // calculate the remaining length
331 //
332 len -= pos-c;
333
334 //
335 // if there are not enough bytes to match the query we are done
336 //
337 if (len<nlen)
338 return kFALSE;
339 }
340}
341
342
343// --------------------------------------------------------------------------
344//
345// If you don't want that a branch is enabled within the PreProcess you
346// can set a veto for enabeling the branch. (This means also the
347// corresponding object won't be created automatically)
348//
349// This functionality is for experienced users which don't want to
350// read in branches which are not processed in the program (for
351// speed reasons)
352//
353void MReadTree::VetoBranch(const char *name)
354{
355 //
356 // Add this file as the last entry of the list
357 // (including the trailing '\0')
358 //
359 const int sz = fVetoList->GetSize();
360 const int tsz = strlen(name)+1;
361
362 fVetoList->Set(sz+tsz);
363
364 memcpy(fVetoList->GetArray()+sz, name, tsz);
365}
Note: See TracBrowser for help on using the repository browser.