]>
Commit | Line | Data |
---|---|---|
5481c137 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // $Id$ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////// | |
19 | // Class AliJob | |
20 | // Base class for the top level processor class in a task based procedure. | |
21 | // It allows stepwise invokation of various sub-tasks by the derived | |
22 | // (user defined) top level processor, based on looping over a certain | |
23 | // main object structure (e.g. AliEvent for event-by-event processing). | |
24 | // The main object structure (if needed) may be specified by the derived | |
25 | // top level processor class and will be stored automatically in the | |
26 | // working environment (see below). | |
27 | // This base class provides a working environment for the derived | |
28 | // (user defined) processor class and all of its subtasks. | |
29 | // | |
1c9018c6 | 30 | // The default working environment consists of : |
31 | // | |
32 | // * An array containing pointers to the objects which are stored | |
33 | // via the AddObject() facility of this AliJob class. | |
34 | // From this storage the objects can be directly accessed via the | |
35 | // GetObject() and GetObjects() memberfunctions. | |
36 | // * A pointer to the main object structure during job processing. | |
37 | // This pointer can be initiated/updated only by the derived top level | |
38 | // processor via the SetMainObject() facility but all sub-tasks can access | |
39 | // it via the above array facilities or the GetMainObject() memberfunction. | |
40 | // The latter provides faster access to the main object structure than | |
41 | // the GetObject (search) based procedures. | |
42 | // | |
9f575717 | 43 | // Optionally one may invoke the MakeFolder() memberfunction or use the |
44 | // "mode" argument of ExecuteJob (see below) to provide in addition to the above | |
45 | // the following job-specific folder structure : | |
1c9018c6 | 46 | // |
5481c137 | 47 | // * A folder which may serve as a whiteboard for transferring pointers to |
48 | // objects which are posted there by the top level processor or any | |
49 | // of its subtasks. | |
50 | // Objects can be posted in the job folder via the AddObject() facility | |
51 | // of this AliJob class. | |
52 | // Access to the job folder is obtained via the GetFolder() memberfunction | |
53 | // and from this the various objects can be accessed via the usual TFolder | |
54 | // FindObject and/or iterator facilities. | |
5481c137 | 55 | // |
56 | // Notes : | |
57 | // ------- | |
58 | // 1) This AliJob class is derived from TTask, which implies that every | |
59 | // (user defined) top level processor class is itself also a TTask. | |
60 | // This allows sub-tasks to be introduced to the top level processor | |
61 | // using the standard TTask facilities. | |
62 | // | |
63 | // 2) Only references to the various introduced objects are stored. | |
64 | // It is the user's responsibility to delete all introduced objects, | |
1c9018c6 | 65 | // either in the Exec() or destructor of the derived top level processor class |
5481c137 | 66 | // or via Clear() facility as provided by the TTask machinery. |
67 | // | |
68 | // 3) The top level processor instance is entered into the standard ROOT | |
69 | // ListOfTasks under the name which was provided by the user in the | |
70 | // constructor of the top level processor. | |
71 | // The name of the top level processor is passed automatically as the | |
72 | // opt argument to the Exec(Option_t* opt) memberfunctions of the | |
73 | // various sub-tasks by the ExecuteJob() memberfunction (see below). | |
74 | // This allows all sub-tasks to obtain the pointer to the top level | |
75 | // processor instance from its name via the statement : | |
76 | // | |
77 | // AliJob* parent=(AliJob*)gROOT->GetListOfTasks()->FindObject(opt) | |
78 | // | |
1c9018c6 | 79 | // 4) If selected, the job-specific folder will be created in the generic folder |
80 | // called "AliJob-folders" as a sub-folder under the same name as the one | |
5481c137 | 81 | // introduced in the constructor of the derived top level processor class. |
1c9018c6 | 82 | // The folder will only be created if the MakeFolder() member function has been |
9f575717 | 83 | // invoked or when selected explicitly by the "mode" argument of ExecuteJob(). |
84 | // Actual creation of the folder environment (and internal array storage as well) | |
85 | // only takes place when the first object is posted via the AddObject() | |
1c9018c6 | 86 | // or SetMainObject() facilities. |
5481c137 | 87 | // |
88 | // Execution of the (user defined) top level processor has to be invoked via | |
89 | // the memberfunction ExecuteJob() of this AliJob base class. | |
1c9018c6 | 90 | // This will set the default gROOT as the global working directory and then |
91 | // invoke the (user written) Exec() memberfunction of the top level | |
5481c137 | 92 | // processor class with as argument the name of the top level processor instance |
93 | // as specified by the user in the top level processor constructor. | |
94 | // This will allow stepwise (e.g. event-by-event) execution of the various sub-tasks. | |
9f575717 | 95 | // In addition the "mode" argument of ExecuteJob() may be used to select/overrule |
96 | // creation of the folder environment for the complete job. | |
97 | // See the docs of ExecuteJob() for further details. | |
5481c137 | 98 | // |
99 | // It is the user's responsibility to invoke the sub-tasks via the | |
100 | // ExecuteTasks() statement at the appropriate location in the top level | |
9c826438 | 101 | // processor class if auto-execution was not explicitly selected via the |
102 | // "mode" argument of the ExecuteJob() memberfunction. | |
5481c137 | 103 | // |
104 | //--- Author: Nick van Eijndhoven 07-may-2005 Utrecht University | |
105 | //- Modified: NvE $Date$ Utrecht University | |
106 | /////////////////////////////////////////////////////////////////////////// | |
107 | ||
108 | #include "AliJob.h" | |
109 | #include "Riostream.h" | |
110 | ||
111 | ClassImp(AliJob) // Class implementation to enable ROOT I/O | |
112 | ||
113 | AliJob::AliJob(const char* name,const char* title) : TTask(name,title) | |
114 | { | |
115 | // Default constructor. | |
116 | // Initialise the working environment for general data access | |
117 | // by the derived task and its subtasks. | |
118 | ||
1c9018c6 | 119 | fMakefolder=0; |
5481c137 | 120 | fMainObject=0; |
121 | fFolder=0; | |
122 | fObjects=0; | |
123 | fSelect=0; | |
124 | ||
125 | // Introduce this AliJob based instance into the ROOT task list | |
126 | TSeqCollection* tasks=gROOT->GetListOfTasks(); | |
127 | if (tasks) tasks->Add(this); | |
128 | } | |
129 | /////////////////////////////////////////////////////////////////////////// | |
130 | AliJob::~AliJob() | |
131 | { | |
132 | // Default destructor. | |
1c9018c6 | 133 | // The internal array and job specific folder (if any) holding the various |
134 | // references are deleted. | |
135 | // Note : The objects belonging to the various pointers in the array/folder | |
5481c137 | 136 | // and the main processing object are NOT deleted by this base class. |
137 | ||
9f575717 | 138 | // Remove this AliJob based instance into the ROOT task list |
139 | TSeqCollection* tasks=gROOT->GetListOfTasks(); | |
140 | if (tasks) tasks->Remove(this); | |
141 | ||
5481c137 | 142 | if (fObjects) |
143 | { | |
144 | delete fObjects; | |
145 | fObjects=0; | |
146 | } | |
147 | if (fFolder) | |
148 | { | |
1c9018c6 | 149 | TList* list=gROOT->GetListOfBrowsables(); |
150 | if (list) | |
151 | { | |
152 | TFolder* top=(TFolder*)list->FindObject("AliJob-folders"); | |
153 | if (top) RecursiveRemove(fFolder); | |
154 | } | |
5481c137 | 155 | delete fFolder; |
156 | fFolder=0; | |
157 | } | |
158 | if (fSelect) | |
159 | { | |
160 | delete fSelect; | |
161 | fSelect=0; | |
162 | } | |
163 | } | |
164 | /////////////////////////////////////////////////////////////////////////// | |
165 | void AliJob::ListEnvironment() | |
166 | { | |
167 | // Provide listing of the job environment. | |
168 | ||
169 | cout << " ***" << endl; | |
170 | cout << " *** Environment of job " << GetName() << " ***" << endl; | |
171 | cout << " ***" << endl; | |
172 | cout << " === Available (sub)tasks : " << endl; | |
173 | ls(); | |
1c9018c6 | 174 | if (fFolder) |
175 | { | |
176 | cout << " === Current job-folder contents : " << endl; | |
177 | fFolder->ls(); | |
178 | } | |
5481c137 | 179 | cout << endl; |
180 | } | |
181 | /////////////////////////////////////////////////////////////////////////// | |
9f575717 | 182 | void AliJob::ExecuteJob(Int_t mode) |
5481c137 | 183 | { |
184 | // Invokation of the top level processor via its Exec() memberfunction. | |
9f575717 | 185 | // The input argument "mode" can be used to explicitly specify the |
9c826438 | 186 | // (de)selection of the folder environment creation and automatic |
187 | // invokation of all subtasks after execution of the top level | |
188 | // Exec() memberfunction. | |
189 | // The latter is convenient if an AliJob instance is used directly | |
190 | // by the user (e.g. in a ROOT macro) in order to provide a hook | |
191 | // for event-by-event processing of various subtasks. | |
9f575717 | 192 | // |
193 | // mode = -1 : Explicitly prohibit folder creation for the complete job | |
194 | // 0 : Folder creation selection steered by MakeFolder() | |
195 | // 1 : Explicitly select creation of the folder environment | |
196 | // for the complete job. | |
9c826438 | 197 | // -11 : Same as mode=-1 but also auto-execution of subtasks after Exec() |
198 | // 10 : Same as mode=0 but also auto-execution of subtasks after Exec() | |
199 | // 11 : Same as mode=1 but also auto-execution of subtasks after Exec() | |
9f575717 | 200 | // |
201 | // The default is mode=0. | |
202 | // | |
1c9018c6 | 203 | // Note : Before execution gROOT is set as the global working directory. |
9f575717 | 204 | |
205 | if (mode<0) fMakefolder=-1; | |
9c826438 | 206 | if (mode==1 || mode==11) fMakefolder=1; |
9f575717 | 207 | |
1c9018c6 | 208 | gROOT->cd(); |
5481c137 | 209 | Exec(GetName()); |
9c826438 | 210 | |
211 | if (abs(mode)>9) | |
212 | { | |
213 | CleanTasks(); | |
214 | ExecuteTasks(GetName()); | |
215 | } | |
5481c137 | 216 | } |
217 | /////////////////////////////////////////////////////////////////////////// | |
1c9018c6 | 218 | void AliJob::MakeFolder() |
219 | { | |
220 | // Select creation of the folder structure in addition to the internal | |
221 | // array storage of objects. | |
9f575717 | 222 | // Creation of the folder structure is only activated if it was not |
223 | // explicitly forbidden by the specified "mode" on invokation of the | |
224 | // ExecuteJob() memberfunction. | |
225 | ||
226 | if (!fMakefolder) fMakefolder=1; | |
1c9018c6 | 227 | } |
228 | /////////////////////////////////////////////////////////////////////////// | |
5481c137 | 229 | TFolder* AliJob::GetFolder() const |
230 | { | |
231 | // Provide pointer to the whiteboard folder. | |
232 | return fFolder; | |
233 | } | |
234 | /////////////////////////////////////////////////////////////////////////// | |
235 | TObject* AliJob::GetMainObject() const | |
236 | { | |
237 | // Provide pointer to the main object structure. | |
238 | return fMainObject; | |
239 | } | |
240 | /////////////////////////////////////////////////////////////////////////// | |
241 | void AliJob::SetMainObject(TObject* obj) | |
242 | { | |
243 | // Store pointer to the main object structure. | |
244 | if (obj) | |
245 | { | |
246 | fMainObject=obj; | |
247 | AddObject(obj); | |
248 | } | |
249 | } | |
250 | /////////////////////////////////////////////////////////////////////////// | |
251 | void AliJob::AddObject(TObject* obj) | |
252 | { | |
253 | // Store pointer of specified object in the working environment. | |
254 | ||
255 | if (!obj) return; | |
256 | ||
257 | if (!fObjects) fObjects=new TObjArray(); | |
258 | ||
9f575717 | 259 | if (fMakefolder>0 && !fFolder) |
5481c137 | 260 | { |
261 | // Create the top level environment folder for all AliJobs if needed | |
262 | TList* list=gROOT->GetListOfBrowsables(); | |
263 | if (list) | |
264 | { | |
265 | TFolder* top=(TFolder*)list->FindObject("AliJob-folders"); | |
266 | if (!top) | |
267 | { | |
268 | top=new TFolder("AliJob-folders","Environment for all AliJob derived tasks"); | |
269 | list->Add(top,"AliJob-folders"); | |
270 | } | |
271 | // Create the task-specific folder as a sub-folder in the top folder | |
272 | fFolder=top->AddFolder(GetName(),GetTitle()); | |
273 | } | |
274 | } | |
275 | ||
276 | // Add object pointer to array and folder if it doesn't already exist | |
277 | Int_t exist=0; | |
278 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
279 | { | |
280 | if (obj==fObjects->At(i)) | |
281 | { | |
282 | exist=1; | |
283 | break; | |
284 | } | |
285 | } | |
286 | if (!exist) | |
287 | { | |
288 | fObjects->Add(obj); | |
1c9018c6 | 289 | if (fFolder) fFolder->Add(obj); |
5481c137 | 290 | } |
291 | } | |
292 | /////////////////////////////////////////////////////////////////////////// | |
293 | void AliJob::AddObjects(TObjArray* arr) | |
294 | { | |
295 | // Store pointers of all the array objects individually in the working environment. | |
296 | ||
297 | if (!arr) return; | |
298 | ||
299 | TObject* obj=0; | |
300 | for (Int_t i=0; i<arr->GetSize(); i++) | |
301 | { | |
302 | obj=arr->At(i); | |
303 | if (obj) AddObject(obj); | |
304 | } | |
305 | } | |
306 | /////////////////////////////////////////////////////////////////////////// | |
307 | void AliJob::RemoveObject(TObject* obj) | |
308 | { | |
309 | // Remove pointer of specified object from the working environment. | |
1c9018c6 | 310 | // In case the specified object is also the main object, the main object |
311 | // pointer will be set to 0 as well. | |
5481c137 | 312 | |
313 | if (!obj) return; | |
314 | ||
315 | if (fObjects) | |
316 | { | |
317 | TObject* test=fObjects->Remove(obj); | |
1c9018c6 | 318 | if (test) |
319 | { | |
320 | fObjects->Compress(); | |
321 | if (test==fMainObject) fMainObject=0; | |
322 | } | |
5481c137 | 323 | } |
324 | ||
325 | if (fFolder) fFolder->Remove(obj); | |
326 | } | |
327 | /////////////////////////////////////////////////////////////////////////// | |
328 | void AliJob::RemoveObjects(const char* classname) | |
329 | { | |
330 | // Remove all stored objects inheriting from classname. | |
1c9018c6 | 331 | // In case one of the removed objects is also the main object, the main object |
332 | // pointer will be set to 0 as well. | |
5481c137 | 333 | |
334 | if (!fObjects) return; | |
335 | ||
336 | Int_t remove=0; | |
337 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
338 | { | |
339 | TObject* obj=fObjects->At(i); | |
340 | if (obj->InheritsFrom(classname)) | |
341 | { | |
342 | TObject* test=fObjects->Remove(obj); | |
1c9018c6 | 343 | if (test) |
344 | { | |
345 | remove=1; | |
346 | if (test==fMainObject) fMainObject=0; | |
347 | } | |
5481c137 | 348 | if (fFolder) fFolder->Remove(obj); |
349 | } | |
350 | } | |
351 | if (remove) fObjects->Compress(); | |
352 | } | |
353 | /////////////////////////////////////////////////////////////////////////// | |
354 | TObject* AliJob::GetObject(Int_t j) const | |
355 | { | |
356 | // Provide pointer to j-th stored object. | |
357 | // Note : j=1 indicates the first object. | |
358 | ||
359 | if (!fObjects || j<1) return 0; | |
360 | ||
361 | TObject* obj=0; | |
362 | ||
363 | if (j<=fObjects->GetEntries()) obj=fObjects->At(j-1); | |
364 | return obj; | |
365 | } | |
366 | /////////////////////////////////////////////////////////////////////////// | |
367 | TObject* AliJob::GetObject(const char* classname) const | |
368 | { | |
369 | // Provide pointer to the first stored object which inherits from classname. | |
370 | ||
371 | if (!fObjects) return 0; | |
372 | ||
373 | TObject* obj=0; | |
374 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
375 | { | |
376 | TObject* obx=fObjects->At(i); | |
377 | if (obx->InheritsFrom(classname)) | |
378 | { | |
379 | obj=obx; | |
380 | break; | |
381 | } | |
382 | } | |
383 | return obj; | |
384 | } | |
385 | /////////////////////////////////////////////////////////////////////////// | |
386 | TObjArray* AliJob::GetObjects() const | |
387 | { | |
388 | // Provide pointers of all the stored objects. | |
389 | return fObjects; | |
390 | } | |
391 | /////////////////////////////////////////////////////////////////////////// | |
392 | TObjArray* AliJob::GetObjects(const char* classname) | |
393 | { | |
394 | // Provide pointers to all stored objects inheriting from classname. | |
395 | ||
396 | if (!fObjects) return 0; | |
397 | ||
398 | if (fSelect) | |
399 | { | |
400 | fSelect->Clear(); | |
401 | } | |
402 | else | |
403 | { | |
404 | fSelect=new TObjArray(); | |
405 | } | |
406 | ||
407 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
408 | { | |
409 | TObject* obj=fObjects->At(i); | |
410 | if (obj->InheritsFrom(classname)) fSelect->Add(obj); | |
411 | } | |
412 | return fSelect; | |
413 | } | |
414 | /////////////////////////////////////////////////////////////////////////// |