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

Last change on this file since 3421 was 3226, checked in by tbretz, 21 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, 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
115void MReadReports::AddToBranchList(const char *name)
116{
117 MTask::AddToBranchList(name);
118}
119
120// --------------------------------------------------------------------------
121//
122// Schedule the contents of this tree for reading. As a default the time
123// branch which is used for the ordering is assumed to by "MTime"+tree.
124// If this is not the case you can overwrite the default specifying the
125// name in time.
126//
127// All calls to AddTree _must_ be BEFORE the calls to AddFile!
128//
129void MReadReports::AddTree(const char *tree, const char *time, Bool_t master)
130{
131 /*
132 if (fTrees->GetNumTasks()>0)
133 {
134 *fLog << warn << "WARNING - AddTree must be called before AddFile... ignored." << endl;
135 *fLog << dbg << fTrees->GetNumTasks() << endl;
136 return kFALSE;
137 }
138 */
139
140 if (master && TestBit(kHasMaster))
141 {
142 *fLog << warn << GetDescriptor() << " already has a master tree... ignored." << endl;
143 master = kFALSE;
144 }
145
146 MReadTree *t = master ? new MReadMarsFile(tree) : new MReadTree(tree);
147 t->SetName(tree);
148 t->SetTitle(time?time:"");
149 if (master)
150 t->SetBit(kHasMaster);
151
152 if (!fEnableAutoScheme)
153 t->DisableAutoScheme();
154
155 //FIXME!
156 //t->DisableAutoScheme();
157
158 fTrees->AddToList(t);
159 // return kTRUE;
160}
161
162// --------------------------------------------------------------------------
163//
164// Schedule a file or several files (using widcards) for reading.
165//
166// All calls to AddTree _must_ be BEFORE the calls to AddFile!
167//
168Int_t MReadReports::AddFile(const char *fname, Int_t entries)
169{
170 Int_t n=0;
171
172 TIter NextT(fTrees->GetList());
173 MReadTree *tree=0;
174 while ((tree=(MReadTree*)NextT()))
175 n += tree->AddFile(fname, entries);
176
177 return n;
178}
179
180// --------------------------------------------------------------------------
181//
182// Find MTaskList and store a pointer to it in fList.
183// Delete all entries in fChains.
184// Create all chains to read the time in the trees in advance.
185// Enable only the time-branch in this chains.
186// PreProcess fTrees (a MTaskList storing MReadTree tasks for reading)
187//
188Int_t MReadReports::PreProcess(MParList *plist)
189{
190 fList = (MTask*)plist->FindObject("MTaskList");
191
192 fChains->Delete();
193
194 Int_t i=0;
195
196 TIter NextT(fTrees->GetList());
197 MReadTree *tree=0;
198 while ((tree=(MReadTree*)NextT()))
199 {
200 if (!((TChain*)tree->fChain)->GetFile())
201 {
202 *fLog << warn << "No files or no tree '" << tree->GetName() << "'... skipped." << endl;
203 fTrees->RemoveFromList(tree);
204 continue;
205 }
206
207 if (tree->GetEntries()==0)
208 {
209 *fLog << warn << "No events in tree '" << tree->GetName() << "'... skipped." << endl;
210 fTrees->RemoveFromList(tree);
211 continue;
212 }
213
214 TString tn(tree->GetTitle());
215 if (tn.IsNull())
216 {
217 tn += "MTime";
218 tn += tree->GetName();
219 tn += ".";
220 }
221
222 TString tn2(tn);
223 tn2 += "*";
224
225 // FIXME: Should be tree->AddToBranchList such that
226 // each run a new 'table' is created, but
227 // MRead is searching for MTaskList in the
228 // parameter list.
229 //AddToBranchList((const char*)tn2);
230
231 //
232 // SetBranchStatus wants to have a pointer to a pointer
233 //
234 MTime **tx = new MTime*;
235 *tx = new MTime;
236
237 TChain *c=new TChain(tree->GetName());
238 c->SetBranchStatus("*", 0);
239 c->SetBranchAddress(tn, tx);
240 tn+="*";
241 c->SetBranchStatus(tn, 1);
242 c->Add((TChain*)tree->fChain);
243 c->GetEntry(0);
244
245 fChains->Add(c);
246
247 i++;
248 }
249
250 if (i==0)
251 {
252 *fLog << err << "Files do not contain any valid tree... abort." << endl;
253 return kFALSE;
254 }
255
256 fPosEntry.Set(i);
257
258 return fTrees->CallPreProcess(plist);
259}
260
261// --------------------------------------------------------------------------
262//
263// Return the MTime corresponding to this TChain...
264//
265MTime** MReadReports::GetTime(TChain *c) const
266{
267 TChainElement *e=(TChainElement*)c->GetStatus()->At(1);
268 return (MTime**)e->GetBaddress();
269}
270
271// --------------------------------------------------------------------------
272//
273// Do not use if fChains->GetSize()==0 !!!
274//
275Int_t MReadReports::FindNextTime()
276{
277 Int_t i=0;
278
279 TIter NextC(fChains);
280 TChain *c=0;
281
282 Int_t nmin=0;
283 MTime tmin(**GetTime((TChain*)NextC()));
284
285 while ((c=(TChain*)NextC()))
286 {
287 MTime &t = **GetTime(c);
288 i++;
289
290 if (t >= tmin)
291 continue;
292
293 tmin = t;
294 nmin = i;
295 }
296 return nmin;
297}
298
299/*
300Bool_t MReadReports::Notify()
301{
302 Bool_t same = kTRUE;
303 for (int i=1; i<fPosTree.GetSize(); i++)
304 if (fPosTree[i]!=fPosTree[0])
305 {
306 same = kFALSE;
307 break;
308 }
309
310 Int_t tn = chain->GetTreeNumber();
311
312 Bool_t read=kFALSE;
313 if (fPosTree[nmin] != tn)
314 {
315 fPosTree[nmin] = tn;
316 read = kTRUE;
317 }
318
319 if (!same || !read)
320 return kTRUE;
321
322
323 *fLog << dbg << "Read Run Headers!" << endl;
324
325 return kTRUE;
326}
327*/
328
329// --------------------------------------------------------------------------
330//
331// Check which is the next tree to read from. Read an event from this tree.
332// Sets the StreamId accordingly.
333//
334Int_t MReadReports::Process()
335{
336 while (fChains->GetSize())
337 {
338 const Int_t nmin=FindNextTime();
339
340 TChain *chain = (TChain*)fChains->At(nmin);
341
342 //Int_t before = chain->GetTreeNumber();
343 if (chain->GetEntry(++fPosEntry[nmin])>0)
344 {
345 MTask *task = (MTask*)fTrees->GetList()->At(nmin);
346
347 if (task->CallProcess())
348 {
349 fList->SetStreamId(task->GetName());
350 return kTRUE;
351 }
352 }
353
354 *fLog << dbg << "Removing chain " << chain->GetName() << " from list." << endl;
355
356 delete *GetTime(chain);
357 delete GetTime(chain);
358 delete fChains->Remove(chain);
359 }
360
361 return kFALSE;
362}
363
364// --------------------------------------------------------------------------
365//
366// PostProcess all MReadTree tasks in fTrees.
367//
368Int_t MReadReports::PostProcess()
369{
370 return fTrees->CallPostProcess();
371}
372
373// --------------------------------------------------------------------------
374//
375// PrintStatistics of this task and of the MReadTree tasks in fTress
376//
377void MReadReports::PrintStatistics(const Int_t lvl, Bool_t title) const
378{
379 MRead::PrintStatistics(lvl, title);
380 fTrees->PrintStatistics(lvl, title);
381}
Note: See TracBrowser for help on using the repository browser.