source: trunk/MagicSoft/Mars/mbase/MTaskList.cc@ 1115

Last change on this file since 1115 was 1108, checked in by tbretz, 23 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 12/2000 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MTaskList //
28// //
29// Collection of tasks. //
30// //
31// A tasklist is necessary to run the eventloop. It contains the scheduled //
32// tasks, which should be executed in your program. //
33// //
34// To add a task use AddToList. //
35// //
36// The tasklist itself is a task, too. You can add a tasklist to another //
37// tasklist. This makes sense, if you want to filter the execution of //
38// more than one task of your tasklist using the same filter. //
39// //
40// The tasks in the list are idetified by their names. If more than one //
41// task has the same name, the tasklist will still work correctly, but //
42// you might run into trouble trying to get a pointer to a task by name //
43// from the list. //
44// //
45// Warning: //
46// Be carefull if you are writing your tasklist //
47// (eg. MWriteRootFile("file.root", "MTaskList")) to a file. You may //
48// not be able to initialize a new working tasklist from a file if //
49// a) Two Paramerer containers with the same names are existing in the //
50// MParList. //
51// b) You used a container somewhere which is not part of MParList. //
52// (eg. You specified a pointer to a MH container in MFillH which is //
53// not added to the parameter list. //
54// //
55/////////////////////////////////////////////////////////////////////////////
56
57#include "MTaskList.h"
58
59#include <TOrdCollection.h>
60
61#include "MLog.h"
62#include "MLogManip.h"
63
64#include "MParList.h"
65#include "MInputStreamID.h"
66
67ClassImp(MTaskList);
68
69// --------------------------------------------------------------------------
70//
71// the name for the task list must be the same for all task lists
72// because the task list (at the moment) is identified by exactly
73// this name in the parameter list (by MEvtLoop::SetParList)
74//
75MTaskList::MTaskList(const char *name, const char *title)
76{
77 fName = name ? name : "MTaskList";
78 fTitle = title ? title : "A list for tasks to be executed";
79
80 fTasks = new TList;
81}
82
83// --------------------------------------------------------------------------
84//
85// CopyConstructor
86// creates a new TaskList and put the contents of an existing
87// TaskList in the new TaskList.
88//
89MTaskList::MTaskList(MTaskList &ts)
90{
91 fTasks->AddAll(ts.fTasks);
92}
93
94// --------------------------------------------------------------------------
95//
96// If the 'IsOwner' bit is set (via SetOwner()) all tasks are deleted
97// by the destructor
98//
99MTaskList::~MTaskList()
100{
101 if (TestBit(kIsOwner))
102 fTasks->SetOwner();
103
104 delete fTasks;
105}
106
107// --------------------------------------------------------------------------
108//
109// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
110// by the destructor
111//
112void MTaskList::SetOwner(Bool_t enable)
113{
114 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
115}
116
117
118// --------------------------------------------------------------------------
119//
120// Set the logging stream for the all tasks in the list and the tasklist
121// itself.
122//
123void MTaskList::SetLogStream(MLog *log)
124{
125 fTasks->ForEach(MTask, SetLogStream)(log);
126 MParContainer::SetLogStream(log);
127}
128
129
130// --------------------------------------------------------------------------
131//
132// schedule task for execution, whether as first task, or after
133// 'where'. 'tType' is the event type which should be processed
134//
135Bool_t MTaskList::AddToList(MTask *task, const char *type, MTask *where)
136{
137 // FIXME: We agreed to put the task into list in an ordered way.
138
139 //
140 // Sanity check
141 //
142 if (!task)
143 return kFALSE;
144
145 //
146 // Get Name of new task
147 //
148 const char *name = task->GetName();
149
150 //
151 // Check if the new task is already existing in the list
152 //
153 const TObject *objn = fTasks->FindObject(name);
154 const TObject *objt = fTasks->FindObject(task);
155
156 if (objn || objt)
157 {
158 //
159 // If the task is already in the list ignore it.
160 //
161 if (objt || objn==task)
162 {
163 *fLog << warn << dbginf << "Warning: Task '" << task->GetName() << ", 0x" << (void*)task;
164 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
165 return kTRUE;
166 }
167
168 //
169 // Otherwise add it to the list, but print a warning message
170 //
171 *fLog << warn << dbginf << "Warning: Task '" << task->GetName();
172 *fLog << "' already existing in '" << GetName() << "'." << endl;
173 *fLog << "You may not be able to get a pointer to this task by name." << endl;
174 }
175
176 if (where)
177 {
178 if (!fTasks->FindObject(where))
179 {
180 *fLog << err << dbginf << "Error: Cannot find task after which the new task should be scheduled!" << endl;
181 return kFALSE;
182 }
183 }
184
185 *fLog << inf << "Adding " << name << " to " << GetName() << " for " << type << "... " << flush;
186
187 task->SetStreamId(type);
188 fTasks->Add(task);
189
190 *fLog << "Done." << endl;
191
192 return kTRUE;
193}
194
195// --------------------------------------------------------------------------
196//
197// Find an object in the list.
198// 'name' is the name of the object you are searching for.
199//
200TObject *MTaskList::FindObject(const char *name) const
201{
202 return fTasks->FindObject(name);
203}
204
205// --------------------------------------------------------------------------
206//
207// check if the object is in the list or not
208//
209TObject *MTaskList::FindObject(const TObject *obj) const
210{
211 return fTasks->FindObject(obj);
212}
213
214// --------------------------------------------------------------------------
215//
216// do reinit of all tasks in the task-list
217//
218Bool_t MTaskList::ReInit(MParList *pList)
219{
220 *fLog << all << "Reinit... " << flush;
221
222 //
223 // create the Iterator over the tasklist
224 //
225 TIter Next(fTasks);
226
227 MTask *task=NULL;
228
229 //
230 // loop over all tasks for preproccesing
231 //
232 while ((task=(MTask*)Next()))
233 {
234 *fLog << all << task->GetName() << "... " << flush;
235
236 if (!task->ReInit(pList?fParList:pList))
237 return kFALSE;
238 }
239
240 *fLog << all << endl;
241
242 return kTRUE;
243}
244
245// --------------------------------------------------------------------------
246//
247// do pre processing (before eventloop) of all tasks in the task-list
248//
249Bool_t MTaskList::PreProcess(MParList *pList)
250{
251 *fLog << all << "Preprocessing... " << flush;
252
253 fParList = pList;
254
255 //
256 // create the Iterator over the tasklist
257 //
258 TIter Next(fTasks);
259
260 MTask *task=NULL;
261
262 //
263 // loop over all tasks for preproccesing
264 //
265 while ((task=(MTask*)Next()))
266 {
267 *fLog << all << task->GetName() << "... " << flush;
268
269 if (!task->CallPreProcess(fParList))
270 return kFALSE;
271 }
272
273 *fLog << all << endl;
274
275 return kTRUE;
276}
277
278// --------------------------------------------------------------------------
279//
280// do the event execution of all tasks in the task-list
281//
282Bool_t MTaskList::Process()
283{
284 //
285 // Reset the ReadyToSave flag.
286 // Reset all containers.
287 //
288 // FIXME: To run a tasklist as a single task in another tasklist we
289 // have to make sure, that the Parameter list isn't reset.
290 //
291 fParList->SetReadyToSave(kFALSE);
292 fParList->Reset();
293
294 //
295 // create the Iterator for the TaskList
296 //
297 TIter Next(fTasks);
298 MTask *task=NULL;
299
300 //
301 // loop over all tasks for processing
302 //
303 while ( (task=(MTask*)Next()) )
304 {
305 //
306 // if the task has the wrong stream id skip it.
307 //
308 if (GetStreamId() != task->GetStreamId() &&
309 task->GetStreamId() != "All")
310 continue;
311
312 //
313 // if it has the right stream id execute the CallProcess() function
314 // and check what the result of it is.
315 // The CallProcess() function increases the execution counter and
316 // calls the Process() function dependent on the existance and
317 // return value of a filter.
318 //
319 switch (task->CallProcess())
320 {
321 case kTRUE:
322 //
323 // everything was OK: go on with the next task
324 //
325 continue;
326
327 case kFALSE:
328 //
329 // an error occured: stop eventloop
330 //
331 return kFALSE;
332
333 case kCONTINUE:
334 //
335 // something occured: skip the rest of the tasks for this event
336 //
337 return kTRUE;
338
339 default:
340 *fLog << warn << "MTaskList::Process: Unknown return value from MTask::Process()... ignored." << endl;
341 }
342 }
343 return kTRUE;
344}
345
346// --------------------------------------------------------------------------
347//
348// do post processing (before eventloop) of all tasks in the task-list
349// only tasks which have successfully been preprocessed are postprocessed.
350//
351Bool_t MTaskList::PostProcess()
352{
353 *fLog << all << "Postprocessing... " << flush;
354
355 //
356 // Reset the ReadyToSave flag.
357 // Reset all containers.
358 //
359 // FIXME: To run a tasklist as a single task in another tasklist we
360 // have to make sure, that the Parameter list isn't reset.
361 //
362 fParList->SetReadyToSave(kFALSE);
363 fParList->Reset();
364
365 //
366 // create the Iterator for the TaskList
367 //
368 TIter Next(fTasks);
369
370 MTask *task=NULL;
371
372 //
373 // loop over all tasks for postprocessing
374 // only tasks which have successfully been preprocessed are postprocessed.
375 //
376 while ( (task=(MTask*)Next()) )
377 {
378 if (!task->CallPostProcess())
379 return kFALSE;
380
381 *fLog << all << task->GetName() << "... " << flush;
382 }
383
384 *fLog << all << endl;
385
386 return kTRUE;
387}
388
389// --------------------------------------------------------------------------
390//
391// Prints the number of times all the tasks in the list has been.
392// For convinience the lvl argument results in a number of spaces at the
393// beginning of the line. So that the structur of a tasklist can be
394// identified. Use MTaskList::PrintStatistics without an argument.
395//
396void MTaskList::PrintStatistics(const Int_t lvl) const
397{
398 if (lvl==0)
399 {
400 *fLog << all << endl;
401 *fLog << "Execution Statistics: " << endl;
402 *fLog << "---------------------" << endl;
403 *fLog << GetDescriptor() << endl;
404 }
405 else
406 {
407 *fLog << setw(lvl) << " " << GetDescriptor() << endl;
408 }
409
410 //
411 // create the Iterator for the TaskList
412 //
413 fTasks->ForEach(MTask, PrintStatistics)(lvl+1);
414
415 if (lvl==0)
416 *fLog << endl;
417}
418
419// --------------------------------------------------------------------------
420void MTaskList::Print(Option_t *t) const
421{
422 *fLog << all << endl;
423 *fLog << GetDescriptor() << endl;
424 *fLog << setfill('-') << setw(strlen(GetDescriptor())) << "" << endl;
425
426 fTasks->Print();
427
428 *fLog << endl;
429}
430
Note: See TracBrowser for help on using the repository browser.