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

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