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

Last change on this file since 1081 was 1080, checked in by tbretz, 25 years ago
*** empty log message ***
File size: 11.9 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; //OrdCollection;
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 pre processing (before eventloop) of all tasks in the task-list
217//
218Bool_t MTaskList::PreProcess(MParList *pList)
219{
220 *fLog << all << "Preprocessing... " << flush;
221
222 fParList = pList;
223
224 //
225 // create the Iterator over the tasklist
226 //
227 TIter Next(fTasks);
228
229 MTask *task=NULL;
230
231 //
232 // loop over all tasks for preproccesing
233 //
234 while ((task=(MTask*)Next()))
235 {
236 *fLog << all << task->GetName() << "... " << flush;
237
238 if (!task->CallPreProcess(fParList))
239 return kFALSE;
240 }
241
242 *fLog << endl;
243
244 return kTRUE;
245}
246
247// --------------------------------------------------------------------------
248//
249// do the event execution of all tasks in the task-list
250//
251Bool_t MTaskList::Process()
252{
253 //
254 // Reset the ReadyToSave flag.
255 // Reset all containers.
256 //
257 // FIXME: To run a tasklist as a single task in another tasklist we
258 // have to make sure, that the Parameter list isn't reset.
259 //
260 fParList->SetReadyToSave(kFALSE);
261 fParList->Reset();
262
263 //
264 // create the Iterator for the TaskList
265 //
266 TIter Next(fTasks);
267 MTask *task=NULL;
268
269 //
270 // loop over all tasks for processing
271 //
272 while ( (task=(MTask*)Next()) )
273 {
274 //
275 // if the task has the wrong stream id skip it.
276 //
277 if (GetStreamId() != task->GetStreamId() &&
278 task->GetStreamId() != "All")
279 continue;
280
281 //
282 // if it has the right stream id execute the CallProcess() function
283 // and check what the result of it is.
284 // The CallProcess() function increases the execution counter and
285 // calls the Process() function dependent on the existance and
286 // return value of a filter.
287 //
288 switch (task->CallProcess())
289 {
290 case kTRUE:
291 //
292 // everything was OK: go on with the next task
293 //
294 continue;
295
296 case kFALSE:
297 //
298 // an error occured: stop eventloop
299 //
300 return kFALSE;
301
302 case kCONTINUE:
303 //
304 // something occured: skip the rest of the tasks for this event
305 //
306 return kTRUE;
307
308 default:
309 *fLog << warn << "MTaskList::Process: Unknown return value from MTask::Process()... ignored." << endl;
310 }
311 }
312 return kTRUE;
313}
314
315// --------------------------------------------------------------------------
316//
317// do post processing (before eventloop) of all tasks in the task-list
318// only tasks which have successfully been preprocessed are postprocessed.
319//
320Bool_t MTaskList::PostProcess()
321{
322 *fLog << all << "Postprocessing... " << flush;
323
324 //
325 // Reset the ReadyToSave flag.
326 // Reset all containers.
327 //
328 // FIXME: To run a tasklist as a single task in another tasklist we
329 // have to make sure, that the Parameter list isn't reset.
330 //
331 fParList->SetReadyToSave(kFALSE);
332 fParList->Reset();
333
334 //
335 // create the Iterator for the TaskList
336 //
337 TIter Next(fTasks);
338
339 MTask *task=NULL;
340
341 //
342 // loop over all tasks for postprocessing
343 // only tasks which have successfully been preprocessed are postprocessed.
344 //
345 while ( (task=(MTask*)Next()) )
346 {
347 if (!task->CallPostProcess())
348 return kFALSE;
349
350 *fLog << all << task->GetName() << "... " << flush;
351 }
352
353 *fLog << all << endl;
354
355 return kTRUE;
356}
357
358// --------------------------------------------------------------------------
359//
360// Prints the number of times all the tasks in the list has been.
361// For convinience the lvl argument results in a number of spaces at the
362// beginning of the line. So that the structur of a tasklist can be
363// identified. Use MTaskList::PrintStatistics without an argument.
364//
365void MTaskList::PrintStatistics(const Int_t lvl) const
366{
367 if (lvl==0)
368 {
369 *fLog << all << endl;
370 *fLog << "Execution Statistics: " << endl;
371 *fLog << "---------------------" << endl;
372 *fLog << GetDescriptor() << endl;
373 }
374 else
375 {
376 *fLog << setw(lvl) << " " << GetDescriptor() << endl;
377 }
378
379 //
380 // create the Iterator for the TaskList
381 //
382 fTasks->ForEach(MTask, PrintStatistics)(lvl+1);
383
384 if (lvl==0)
385 *fLog << endl;
386}
387
388// --------------------------------------------------------------------------
389void MTaskList::Print(Option_t *t) const
390{
391 *fLog << all << endl;
392 *fLog << GetDescriptor() << endl;
393 *fLog << setfill('-') << setw(strlen(GetDescriptor())) << "" << endl;
394
395 fTasks->Print();
396
397 *fLog << endl;
398}
399
Note: See TracBrowser for help on using the repository browser.