source: trunk/MagicSoft/Mars/mfileio/MReadReports.cc@ 8590

Last change on this file since 8590 was 7838, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 12.5 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, 11/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2006
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MReadReports
28//
29// Read from a file events from different trees ordered in time, eg:
30//
31// Having a file with:
32//
33// Tree1 Tree2 Tree3
34// ------------ ------------ -----------
35// (0) MTime[0]
36// (0) MTime[1]
37// (1) MTime[2]
38// (2) MTime[3]
39// (0) MTime[1]
40// (3) MTime[4]
41//
42// MReadReports will read the events in the tree in the following order:
43// <0> (0) from Tree1
44// <1> (0) from Tree2
45// <2> (1) from Tree1
46// <3> (2) from Tree1
47// <4> (0) from Tree3
48// <5> (3) from Tree1
49// ...
50//
51// To tell MReadReports which Trees to read use: MReadReports::AddTree()
52// To schedule a file for reading use MReadReports::AddFile()
53//
54// All calls to AddTree _must_ be before the calls to AddFile!
55//
56// After reading from a tree with the name 'TreeName' the stream id of
57// the main tasklist ('MTaskList' found in MParList in PreProcess) is
58// set to this name. This means that only tasks having this stream id
59// are executed.
60//
61/////////////////////////////////////////////////////////////////////////////
62#include "MReadReports.h"
63
64#include <TChain.h>
65#include <TChainElement.h>
66
67#include "MLog.h"
68#include "MLogManip.h"
69
70#include "MTime.h"
71#include "MParList.h"
72#include "MTaskList.h"
73
74#include "MReadMarsFile.h"
75
76ClassImp(MReadReports);
77
78using namespace std;
79
80// --------------------------------------------------------------------------
81//
82// Default constructor. Set fName and fTitle. Instatiate fTrees and fChains.
83// Call SetOwner for fTrees and fChains
84//
85MReadReports::MReadReports() : fEnableAutoScheme(kFALSE)
86{
87 fName = "MRead";
88 fTitle = "Reads events and reports from a root file ordered in time";
89
90 fTrees = new MTaskList("MReadReports");
91 fChains = new TList;
92
93 fTrees->SetOwner();
94 fChains->SetOwner();
95}
96
97// --------------------------------------------------------------------------
98//
99// Destructor, delete everything which was allocated by this task...
100//
101MReadReports::~MReadReports()
102{
103 TObject *o=0;
104 TIter NextC(fChains);
105 while ((o=NextC()))
106 delete *GetTime((TChain*)o);
107
108 delete fTrees;
109 delete fChains;
110}
111
112// --------------------------------------------------------------------------
113//
114// Return the number of entries in all trees.
115//
116UInt_t MReadReports::GetEntries()
117{
118 UInt_t n=0;
119
120 TIter NextT(fTrees->GetList());
121 MReadTree *tree=0;
122 while ((tree=(MReadTree*)NextT()))
123 n += tree->GetEntries();
124
125 return n;
126}
127
128// --------------------------------------------------------------------------
129//
130// In case of a Master Tree GetFileName() of the MReadMarsFile is returned.
131// If no master is available "<MReadReports>" is returned.
132//
133TString MReadReports::GetFullFileName() const
134{
135 if (!TestBit(kHasMaster))
136 return "<MReadReports>";
137
138 TIter NextT(fTrees->GetList());
139 MReadTree *tree=0;
140 while ((tree=(MReadTree*)NextT()))
141 if (tree->InheritsFrom("MReadMarsFile"))
142 return tree->GetFileName();
143
144 return "<n/a>";
145
146}
147
148void MReadReports::AddToBranchList(const char *name)
149{
150 MTask::AddToBranchList(name);
151}
152
153// --------------------------------------------------------------------------
154//
155// Schedule the contents of this tree for reading. As a default the time
156// branch which is used for the ordering is assumed to by "MTime"+tree.
157// If this is not the case you can overwrite the default specifying the
158// name in time.
159//
160// All calls to AddTree _must_ be BEFORE the calls to AddFile!
161//
162// To be done: A flag(?) telling whether the headers can be skipped.
163//
164void MReadReports::AddTree(const char *tree, const char *time, Type_t master)
165{
166 /*
167 if (fTrees->GetNumTasks()>0)
168 {
169 *fLog << warn << "WARNING - AddTree must be called before AddFile... ignored." << endl;
170 *fLog << dbg << fTrees->GetNumTasks() << endl;
171 return kFALSE;
172 }
173 */
174
175 if (master==kMaster && TestBit(kHasMaster))
176 {
177 *fLog << warn << GetDescriptor() << " already has a master tree... ignored." << endl;
178 master = kStandard;
179 }
180
181 MReadTree *t = master==kMaster ? new MReadMarsFile(tree) : new MReadTree(tree);
182 t->SetName(tree);
183 t->SetTitle(time?time:"");
184 if (master==kMaster)
185 SetBit(kHasMaster);
186 if (master==kRequired)
187 t->SetBit(kIsRequired);
188
189 if (!fEnableAutoScheme)
190 t->DisableAutoScheme();
191
192 //FIXME!
193 //t->DisableAutoScheme();
194
195 fTrees->AddToList(t);
196 // return kTRUE;
197}
198
199MReadTree *MReadReports::GetReader(const char *tree) const
200{
201 return (MReadTree*)fTrees->FindObject(tree);
202}
203
204// --------------------------------------------------------------------------
205//
206// Schedule a file or several files (using widcards) for reading.
207//
208// All calls to AddTree _must_ be BEFORE the calls to AddFile!
209//
210Int_t MReadReports::AddFile(const char *fname, Int_t entries)
211{
212 Int_t n=0;
213
214 TIter NextT(fTrees->GetList());
215 MReadTree *tree=0;
216 while ((tree=(MReadTree*)NextT()))
217 n += tree->AddFile(fname, entries);
218
219 return n;
220}
221
222// --------------------------------------------------------------------------
223//
224// Count the number of required trees and store the number if fNumRequired.
225// Reset the kIsProcessed bit.
226//
227void MReadReports::ForceRequired()
228{
229 fNumRequired = 0;
230
231 TIter Next(fTrees->GetList());
232 TObject *o=0;
233 while ((o=Next()))
234 if (o->TestBit(kIsRequired))
235 {
236 o->ResetBit(kIsProcessed);
237 fNumRequired++;
238 }
239
240 *fLog << dbg << "Number of required trees: " << fNumRequired << endl;
241}
242
243// --------------------------------------------------------------------------
244//
245// Find MTaskList and store a pointer to it in fList.
246// Delete all entries in fChains.
247// Create all chains to read the time in the trees in advance.
248// Enable only the time-branch in this chains.
249// PreProcess fTrees (a MTaskList storing MReadTree tasks for reading)
250//
251Int_t MReadReports::PreProcess(MParList *plist)
252{
253 fChains->Delete();
254
255 Int_t i=0;
256
257 TIter NextT(fTrees->GetList());
258 MReadTree *tree=0;
259 while ((tree=(MReadTree*)NextT()))
260 {
261 if (!((TChain*)tree->fChain)->GetFile())
262 {
263 *fLog << warn << "No files or no tree '" << tree->GetName() << "'... skipped." << endl;
264 fTrees->RemoveFromList(tree);
265 continue;
266 }
267
268 if (tree->GetEntries()==0)
269 {
270 *fLog << warn << "No events in tree '" << tree->GetName() << "'... skipped." << endl;
271 fTrees->RemoveFromList(tree);
272 continue;
273 }
274
275 TString tn(tree->GetTitle());
276 if (tn.IsNull())
277 {
278 tn += "MTime";
279 tn += tree->GetName();
280 tn += ".";
281 }
282
283 TString tn2(tn);
284 tn2 += "*";
285
286 // FIXME: Should be tree->AddToBranchList such that
287 // each run a new 'table' is created, but
288 // MRead is searching for MTaskList in the
289 // parameter list.
290 //AddToBranchList((const char*)tn2);
291
292 //
293 // SetBranchStatus wants to have a pointer to a pointer
294 //
295 MTime **tx = new MTime*;
296 *tx = 0;//new MTime;
297
298 TChain *c=new TChain(tree->GetName());
299
300 c->SetBranchStatus("*", 0);
301 c->SetBranchAddress(tn, tx);
302 c->SetBranchStatus(tn2, 1);
303
304 c->Add((TChain*)tree->fChain);
305 c->GetEntry(0);
306
307 fChains->Add(c);
308
309 i++;
310 }
311
312 if (i==0)
313 {
314 *fLog << err << "Files do not contain any valid tree... abort." << endl;
315 return kFALSE;
316 }
317
318 fPosEntry.Set(i);
319
320 // Force that with the next call to Process the required events are read
321 ForceRequired();
322 //fFirstReInit=kTRUE;
323
324 // Preprocess all tasks in fTrees
325 return fTrees->CallPreProcess(plist);
326}
327
328// --------------------------------------------------------------------------
329//
330// If this is not the first ReInit after PreProcess force the required
331// trees to be read first (call FirstRequired())
332//
333/*
334Bool_t MReadReports::ReInit(MParList *plist)
335{
336 if (!fFirstReInit)
337 ForceRequired();
338 fFirstReInit=kFALSE;
339 return kTRUE;
340}
341*/
342
343// --------------------------------------------------------------------------
344//
345// Return the number of the tree which is the next one to be read.
346// The condition for this decision is the time-stamp.
347//
348Int_t MReadReports::FindNextTime()
349{
350 TIter NextC(fChains);
351 TChain *c=0;
352
353 Int_t nmin=0;
354 MTime tmin(**GetTime((TChain*)NextC()));
355
356 Int_t i=0;
357
358 while ((c=(TChain*)NextC()))
359 {
360 MTime &t = **GetTime(c);
361 i++;
362
363 if (t >= tmin)
364 continue;
365
366 tmin = t;
367 nmin = i;
368 }
369 return nmin;
370}
371
372// --------------------------------------------------------------------------
373//
374// Return the number of the tree which is the next one to be read.
375// The condition for this decision kIsRequired but not kIsProcessed is set.
376//
377Int_t MReadReports::FindNextRequired()
378{
379 Int_t n = 0;
380
381 TIter Next(fTrees->GetList());
382 TObject *o=0;
383 while ((o=Next()))
384 {
385 if (o->TestBit(kIsRequired) && !o->TestBit(kIsProcessed))
386 {
387 o->SetBit(kIsProcessed);
388 fNumRequired--;
389 *fLog << dbg << "Reading from tree " << n << " " << o->GetName() << endl;
390 return n;
391 }
392 n++;
393 }
394
395 return -1;
396}
397
398// --------------------------------------------------------------------------
399//
400// Return the MTime corresponding to this TChain...
401//
402MTime** MReadReports::GetTime(TChain *c) const
403{
404 TChainElement *e=(TChainElement*)c->GetStatus()->At(1);
405 return (MTime**)e->GetBaddress();
406}
407
408// --------------------------------------------------------------------------
409//
410// Check which is the next tree to read from. Read an event from this tree.
411// Sets the StreamId accordingly.
412//
413Int_t MReadReports::Process()
414{
415 while (fChains->GetSize())
416 {
417 const Int_t nmin=FindNext();
418 if (nmin<0)
419 {
420 *fLog << err << "MReadReports::Process: ERROR - Determination of next tree failed... abort." << endl;
421 return kERROR;
422 }
423
424 TChain *chain = (TChain*)fChains->At(nmin);
425
426 MTask *task = (MTask*)fTrees->GetList()->At(nmin);
427
428 //Int_t before = chain->GetTreeNumber();
429 if (chain->GetEntry(++fPosEntry[nmin])>0)
430 {
431 const Int_t rc = task->CallProcess();
432 if (rc)
433 return rc;
434 }
435
436 *fLog << dbg << "Removing chain " << chain->GetName() << " from list" << flush;
437
438 delete *GetTime(chain); // Delete MTime*
439 *fLog << "." << flush;
440 delete fChains->Remove(chain); // Remove chain from TList
441 *fLog << "." << flush;
442
443 // FIXME: Maybe MTaskList should have a member function to
444 // reorder the tasks?
445
446 // Move this task to the end of the list so that nmin still
447 // corresponds to the correct task in the list.
448 const_cast<TList*>(fTrees->GetList())->Remove(task);
449 *fLog << "." << flush;
450 const_cast<TList*>(fTrees->GetList())->AddLast(task);
451 *fLog << "done." << endl;
452 }
453
454 return kFALSE;
455}
456
457// --------------------------------------------------------------------------
458//
459// PostProcess all MReadTree tasks in fTrees.
460//
461Int_t MReadReports::PostProcess()
462{
463 return fTrees->CallPostProcess();
464}
465
466// --------------------------------------------------------------------------
467//
468// PrintStatistics of this task and of the MReadTree tasks in fTress
469//
470void MReadReports::PrintStatistics(const Int_t lvl, Bool_t title, Double_t time) const
471{
472 MRead::PrintStatistics(lvl, title, time);
473 fTrees->PrintStatistics(lvl+1, title, GetCpuTime());
474}
Note: See TracBrowser for help on using the repository browser.