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

Last change on this file since 1177 was 1132, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 13.2 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?pList:fParList))
237 return kFALSE;
238 }
239
240 *fLog << all << endl;
241
242 return kTRUE;
243}
244
245// --------------------------------------------------------------------------
246//
247// removes a task from the list (used in PreProcess).
248// if kIsOwner is set the task is deleted. (see SetOwner())
249//
250void MTaskList::Remove(MTask *task)
251{
252 TObject *obj = fTasks->Remove(task);
253
254 if (TestBit(kIsOwner))
255 delete obj;
256}
257
258// --------------------------------------------------------------------------
259//
260// do pre processing (before eventloop) of all tasks in the task-list
261//
262Bool_t MTaskList::PreProcess(MParList *pList)
263{
264 *fLog << all << "Preprocessing... " << flush;
265
266 fParList = pList;
267
268 //
269 // create the Iterator over the tasklist
270 //
271 TIter Next(fTasks);
272
273 MTask *task=NULL;
274
275 //
276 // loop over all tasks for preproccesing
277 //
278 while ((task=(MTask*)Next()))
279 {
280 *fLog << all << task->GetName() << "... " << flush;
281
282 switch (task->CallPreProcess(fParList))
283 {
284 case kFALSE:
285 return kFALSE;
286
287 case kTRUE:
288 continue;
289
290 case kSKIP:
291 Remove(task);
292 continue;
293 }
294
295 *fLog << err << dbginf << "PreProcess of " << task->GetDescriptor();
296 *fLog << " returned an unknown value... aborting." << endl;
297 return kFALSE;
298 }
299
300 *fLog << all << endl;
301
302 return kTRUE;
303}
304
305// --------------------------------------------------------------------------
306//
307// do the event execution of all tasks in the task-list
308//
309Bool_t MTaskList::Process()
310{
311 //
312 // Reset the ReadyToSave flag.
313 // Reset all containers.
314 //
315 // FIXME: To run a tasklist as a single task in another tasklist we
316 // have to make sure, that the Parameter list isn't reset.
317 //
318 fParList->SetReadyToSave(kFALSE);
319 fParList->Reset();
320
321 //
322 // create the Iterator for the TaskList
323 //
324 TIter Next(fTasks);
325 MTask *task=NULL;
326
327 //
328 // loop over all tasks for processing
329 //
330 while ( (task=(MTask*)Next()) )
331 {
332 //
333 // if the task has the wrong stream id skip it.
334 //
335 if (GetStreamId() != task->GetStreamId() &&
336 task->GetStreamId() != "All")
337 continue;
338
339 //
340 // if it has the right stream id execute the CallProcess() function
341 // and check what the result of it is.
342 // The CallProcess() function increases the execution counter and
343 // calls the Process() function dependent on the existance and
344 // return value of a filter.
345 //
346 switch (task->CallProcess())
347 {
348 case kTRUE:
349 //
350 // everything was OK: go on with the next task
351 //
352 continue;
353
354 case kFALSE:
355 //
356 // an error occured: stop eventloop
357 //
358 return kFALSE;
359
360 case kCONTINUE:
361 //
362 // something occured: skip the rest of the tasks for this event
363 //
364 return kTRUE;
365
366 default:
367 *fLog << warn << "MTaskList::Process: Unknown return value from MTask::Process()... ignored." << endl;
368 }
369 }
370 return kTRUE;
371}
372
373// --------------------------------------------------------------------------
374//
375// do post processing (before eventloop) of all tasks in the task-list
376// only tasks which have successfully been preprocessed are postprocessed.
377//
378Bool_t MTaskList::PostProcess()
379{
380 *fLog << all << "Postprocessing... " << flush;
381
382 //
383 // Reset the ReadyToSave flag.
384 // Reset all containers.
385 //
386 // FIXME: To run a tasklist as a single task in another tasklist we
387 // have to make sure, that the Parameter list isn't reset.
388 //
389 fParList->SetReadyToSave(kFALSE);
390 fParList->Reset();
391
392 //
393 // create the Iterator for the TaskList
394 //
395 TIter Next(fTasks);
396
397 MTask *task=NULL;
398
399 //
400 // loop over all tasks for postprocessing
401 // only tasks which have successfully been preprocessed are postprocessed.
402 //
403 while ( (task=(MTask*)Next()) )
404 {
405 if (!task->CallPostProcess())
406 return kFALSE;
407
408 *fLog << all << task->GetName() << "... " << flush;
409 }
410
411 *fLog << all << endl;
412
413 return kTRUE;
414}
415
416// --------------------------------------------------------------------------
417//
418// Prints the number of times all the tasks in the list has been.
419// For convinience the lvl argument results in a number of spaces at the
420// beginning of the line. So that the structur of a tasklist can be
421// identified. Use MTaskList::PrintStatistics without an argument.
422//
423void MTaskList::PrintStatistics(const Int_t lvl) const
424{
425 if (lvl==0)
426 {
427 *fLog << all << endl;
428 *fLog << "Execution Statistics: " << endl;
429 *fLog << "---------------------" << endl;
430 *fLog << GetDescriptor() << endl;
431 }
432 else
433 {
434 *fLog << setw(lvl) << " " << GetDescriptor() << endl;
435 }
436
437 //
438 // create the Iterator for the TaskList
439 //
440 fTasks->ForEach(MTask, PrintStatistics)(lvl+1);
441
442 if (lvl==0)
443 *fLog << endl;
444}
445
446// --------------------------------------------------------------------------
447void MTaskList::Print(Option_t *t) const
448{
449 *fLog << all << endl;
450 *fLog << GetDescriptor() << endl;
451 *fLog << setfill('-') << setw(strlen(GetDescriptor())) << "" << endl;
452
453 fTasks->Print();
454
455 *fLog << endl;
456}
457
Note: See TracBrowser for help on using the repository browser.