]>
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 | |
101 | // processor class. | |
102 | // | |
103 | //--- Author: Nick van Eijndhoven 07-may-2005 Utrecht University | |
104 | //- Modified: NvE $Date$ Utrecht University | |
105 | /////////////////////////////////////////////////////////////////////////// | |
106 | ||
107 | #include "AliJob.h" | |
108 | #include "Riostream.h" | |
109 | ||
110 | ClassImp(AliJob) // Class implementation to enable ROOT I/O | |
111 | ||
112 | AliJob::AliJob(const char* name,const char* title) : TTask(name,title) | |
113 | { | |
114 | // Default constructor. | |
115 | // Initialise the working environment for general data access | |
116 | // by the derived task and its subtasks. | |
117 | ||
1c9018c6 | 118 | fMakefolder=0; |
5481c137 | 119 | fMainObject=0; |
120 | fFolder=0; | |
121 | fObjects=0; | |
122 | fSelect=0; | |
123 | ||
124 | // Introduce this AliJob based instance into the ROOT task list | |
125 | TSeqCollection* tasks=gROOT->GetListOfTasks(); | |
126 | if (tasks) tasks->Add(this); | |
127 | } | |
128 | /////////////////////////////////////////////////////////////////////////// | |
129 | AliJob::~AliJob() | |
130 | { | |
131 | // Default destructor. | |
1c9018c6 | 132 | // The internal array and job specific folder (if any) holding the various |
133 | // references are deleted. | |
134 | // Note : The objects belonging to the various pointers in the array/folder | |
5481c137 | 135 | // and the main processing object are NOT deleted by this base class. |
136 | ||
9f575717 | 137 | // Remove this AliJob based instance into the ROOT task list |
138 | TSeqCollection* tasks=gROOT->GetListOfTasks(); | |
139 | if (tasks) tasks->Remove(this); | |
140 | ||
5481c137 | 141 | if (fObjects) |
142 | { | |
143 | delete fObjects; | |
144 | fObjects=0; | |
145 | } | |
146 | if (fFolder) | |
147 | { | |
1c9018c6 | 148 | TList* list=gROOT->GetListOfBrowsables(); |
149 | if (list) | |
150 | { | |
151 | TFolder* top=(TFolder*)list->FindObject("AliJob-folders"); | |
152 | if (top) RecursiveRemove(fFolder); | |
153 | } | |
5481c137 | 154 | delete fFolder; |
155 | fFolder=0; | |
156 | } | |
157 | if (fSelect) | |
158 | { | |
159 | delete fSelect; | |
160 | fSelect=0; | |
161 | } | |
162 | } | |
163 | /////////////////////////////////////////////////////////////////////////// | |
164 | void AliJob::ListEnvironment() | |
165 | { | |
166 | // Provide listing of the job environment. | |
167 | ||
168 | cout << " ***" << endl; | |
169 | cout << " *** Environment of job " << GetName() << " ***" << endl; | |
170 | cout << " ***" << endl; | |
171 | cout << " === Available (sub)tasks : " << endl; | |
172 | ls(); | |
1c9018c6 | 173 | if (fFolder) |
174 | { | |
175 | cout << " === Current job-folder contents : " << endl; | |
176 | fFolder->ls(); | |
177 | } | |
5481c137 | 178 | cout << endl; |
179 | } | |
180 | /////////////////////////////////////////////////////////////////////////// | |
9f575717 | 181 | void AliJob::ExecuteJob(Int_t mode) |
5481c137 | 182 | { |
183 | // Invokation of the top level processor via its Exec() memberfunction. | |
9f575717 | 184 | // The input argument "mode" can be used to explicitly specify the |
185 | // (de)selection of the folder environment creation. | |
186 | // | |
187 | // mode = -1 : Explicitly prohibit folder creation for the complete job | |
188 | // 0 : Folder creation selection steered by MakeFolder() | |
189 | // 1 : Explicitly select creation of the folder environment | |
190 | // for the complete job. | |
191 | // | |
192 | // The default is mode=0. | |
193 | // | |
1c9018c6 | 194 | // Note : Before execution gROOT is set as the global working directory. |
9f575717 | 195 | |
196 | if (mode<0) fMakefolder=-1; | |
197 | if (mode>0) fMakefolder=1; | |
198 | ||
1c9018c6 | 199 | gROOT->cd(); |
5481c137 | 200 | Exec(GetName()); |
201 | } | |
202 | /////////////////////////////////////////////////////////////////////////// | |
1c9018c6 | 203 | void AliJob::MakeFolder() |
204 | { | |
205 | // Select creation of the folder structure in addition to the internal | |
206 | // array storage of objects. | |
9f575717 | 207 | // Creation of the folder structure is only activated if it was not |
208 | // explicitly forbidden by the specified "mode" on invokation of the | |
209 | // ExecuteJob() memberfunction. | |
210 | ||
211 | if (!fMakefolder) fMakefolder=1; | |
1c9018c6 | 212 | } |
213 | /////////////////////////////////////////////////////////////////////////// | |
5481c137 | 214 | TFolder* AliJob::GetFolder() const |
215 | { | |
216 | // Provide pointer to the whiteboard folder. | |
217 | return fFolder; | |
218 | } | |
219 | /////////////////////////////////////////////////////////////////////////// | |
220 | TObject* AliJob::GetMainObject() const | |
221 | { | |
222 | // Provide pointer to the main object structure. | |
223 | return fMainObject; | |
224 | } | |
225 | /////////////////////////////////////////////////////////////////////////// | |
226 | void AliJob::SetMainObject(TObject* obj) | |
227 | { | |
228 | // Store pointer to the main object structure. | |
229 | if (obj) | |
230 | { | |
231 | fMainObject=obj; | |
232 | AddObject(obj); | |
233 | } | |
234 | } | |
235 | /////////////////////////////////////////////////////////////////////////// | |
236 | void AliJob::AddObject(TObject* obj) | |
237 | { | |
238 | // Store pointer of specified object in the working environment. | |
239 | ||
240 | if (!obj) return; | |
241 | ||
242 | if (!fObjects) fObjects=new TObjArray(); | |
243 | ||
9f575717 | 244 | if (fMakefolder>0 && !fFolder) |
5481c137 | 245 | { |
246 | // Create the top level environment folder for all AliJobs if needed | |
247 | TList* list=gROOT->GetListOfBrowsables(); | |
248 | if (list) | |
249 | { | |
250 | TFolder* top=(TFolder*)list->FindObject("AliJob-folders"); | |
251 | if (!top) | |
252 | { | |
253 | top=new TFolder("AliJob-folders","Environment for all AliJob derived tasks"); | |
254 | list->Add(top,"AliJob-folders"); | |
255 | } | |
256 | // Create the task-specific folder as a sub-folder in the top folder | |
257 | fFolder=top->AddFolder(GetName(),GetTitle()); | |
258 | } | |
259 | } | |
260 | ||
261 | // Add object pointer to array and folder if it doesn't already exist | |
262 | Int_t exist=0; | |
263 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
264 | { | |
265 | if (obj==fObjects->At(i)) | |
266 | { | |
267 | exist=1; | |
268 | break; | |
269 | } | |
270 | } | |
271 | if (!exist) | |
272 | { | |
273 | fObjects->Add(obj); | |
1c9018c6 | 274 | if (fFolder) fFolder->Add(obj); |
5481c137 | 275 | } |
276 | } | |
277 | /////////////////////////////////////////////////////////////////////////// | |
278 | void AliJob::AddObjects(TObjArray* arr) | |
279 | { | |
280 | // Store pointers of all the array objects individually in the working environment. | |
281 | ||
282 | if (!arr) return; | |
283 | ||
284 | TObject* obj=0; | |
285 | for (Int_t i=0; i<arr->GetSize(); i++) | |
286 | { | |
287 | obj=arr->At(i); | |
288 | if (obj) AddObject(obj); | |
289 | } | |
290 | } | |
291 | /////////////////////////////////////////////////////////////////////////// | |
292 | void AliJob::RemoveObject(TObject* obj) | |
293 | { | |
294 | // Remove pointer of specified object from the working environment. | |
1c9018c6 | 295 | // In case the specified object is also the main object, the main object |
296 | // pointer will be set to 0 as well. | |
5481c137 | 297 | |
298 | if (!obj) return; | |
299 | ||
300 | if (fObjects) | |
301 | { | |
302 | TObject* test=fObjects->Remove(obj); | |
1c9018c6 | 303 | if (test) |
304 | { | |
305 | fObjects->Compress(); | |
306 | if (test==fMainObject) fMainObject=0; | |
307 | } | |
5481c137 | 308 | } |
309 | ||
310 | if (fFolder) fFolder->Remove(obj); | |
311 | } | |
312 | /////////////////////////////////////////////////////////////////////////// | |
313 | void AliJob::RemoveObjects(const char* classname) | |
314 | { | |
315 | // Remove all stored objects inheriting from classname. | |
1c9018c6 | 316 | // In case one of the removed objects is also the main object, the main object |
317 | // pointer will be set to 0 as well. | |
5481c137 | 318 | |
319 | if (!fObjects) return; | |
320 | ||
321 | Int_t remove=0; | |
322 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
323 | { | |
324 | TObject* obj=fObjects->At(i); | |
325 | if (obj->InheritsFrom(classname)) | |
326 | { | |
327 | TObject* test=fObjects->Remove(obj); | |
1c9018c6 | 328 | if (test) |
329 | { | |
330 | remove=1; | |
331 | if (test==fMainObject) fMainObject=0; | |
332 | } | |
5481c137 | 333 | if (fFolder) fFolder->Remove(obj); |
334 | } | |
335 | } | |
336 | if (remove) fObjects->Compress(); | |
337 | } | |
338 | /////////////////////////////////////////////////////////////////////////// | |
339 | TObject* AliJob::GetObject(Int_t j) const | |
340 | { | |
341 | // Provide pointer to j-th stored object. | |
342 | // Note : j=1 indicates the first object. | |
343 | ||
344 | if (!fObjects || j<1) return 0; | |
345 | ||
346 | TObject* obj=0; | |
347 | ||
348 | if (j<=fObjects->GetEntries()) obj=fObjects->At(j-1); | |
349 | return obj; | |
350 | } | |
351 | /////////////////////////////////////////////////////////////////////////// | |
352 | TObject* AliJob::GetObject(const char* classname) const | |
353 | { | |
354 | // Provide pointer to the first stored object which inherits from classname. | |
355 | ||
356 | if (!fObjects) return 0; | |
357 | ||
358 | TObject* obj=0; | |
359 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
360 | { | |
361 | TObject* obx=fObjects->At(i); | |
362 | if (obx->InheritsFrom(classname)) | |
363 | { | |
364 | obj=obx; | |
365 | break; | |
366 | } | |
367 | } | |
368 | return obj; | |
369 | } | |
370 | /////////////////////////////////////////////////////////////////////////// | |
371 | TObjArray* AliJob::GetObjects() const | |
372 | { | |
373 | // Provide pointers of all the stored objects. | |
374 | return fObjects; | |
375 | } | |
376 | /////////////////////////////////////////////////////////////////////////// | |
377 | TObjArray* AliJob::GetObjects(const char* classname) | |
378 | { | |
379 | // Provide pointers to all stored objects inheriting from classname. | |
380 | ||
381 | if (!fObjects) return 0; | |
382 | ||
383 | if (fSelect) | |
384 | { | |
385 | fSelect->Clear(); | |
386 | } | |
387 | else | |
388 | { | |
389 | fSelect=new TObjArray(); | |
390 | } | |
391 | ||
392 | for (Int_t i=0; i<fObjects->GetEntries(); i++) | |
393 | { | |
394 | TObject* obj=fObjects->At(i); | |
395 | if (obj->InheritsFrom(classname)) fSelect->Add(obj); | |
396 | } | |
397 | return fSelect; | |
398 | } | |
399 | /////////////////////////////////////////////////////////////////////////// |