1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
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).
28 // However, being designed as a base class for a user defined top level
29 // processor, this class can also be used as a "hook" to specify
30 // various sub-tasks in an (interactive) user environment.
31 // Usage of the memberfunction ProcessObject() allows an (interactive)
32 // event-by-event processing of the various specified subtasks.
34 // This base class provides a working environment for the derived
35 // (user defined) processor class and all of its subtasks.
37 // The default working environment consists of :
39 // * An array containing pointers to the objects which are stored
40 // via the AddObject() facility of this AliJob class.
41 // From this storage the objects can be directly accessed via the
42 // GetObject() and GetObjects() memberfunctions.
43 // * A pointer to the main object structure during job processing.
44 // This pointer can be initiated/updated only by the derived top level
45 // processor via the SetMainObject() facility but all sub-tasks can access
46 // it via the above array facilities or the GetMainObject() memberfunction.
47 // The latter provides faster access to the main object structure than
48 // the GetObject (search) based procedures.
50 // Optionally one may invoke the MakeFolder() memberfunction or use the
51 // "mode" argument of ExecuteJob (see below) to provide in addition to the above
52 // the following job-specific folder structure :
54 // * A folder which may serve as a whiteboard for transferring pointers to
55 // objects which are posted there by the top level processor or any
57 // Objects can be posted in the job folder via the AddObject() facility
58 // of this AliJob class.
59 // Access to the job folder is obtained via the GetFolder() memberfunction
60 // and from this the various objects can be accessed via the usual TFolder
61 // FindObject and/or iterator facilities.
65 // 1) This AliJob class is derived from TTask, which implies that every
66 // (user defined) top level processor class is itself also a TTask.
67 // This allows sub-tasks to be introduced to the top level processor
68 // using the standard TTask facilities.
70 // 2) Only references to the various introduced objects are stored.
71 // It is the user's responsibility to delete all introduced objects,
72 // either in the Exec() or destructor of the derived top level processor class
73 // or via Clear() facility as provided by the TTask machinery.
75 // 3) The top level processor instance is entered into the standard ROOT
76 // ListOfTasks under the name which was provided by the user in the
77 // constructor of the top level processor.
78 // The name of the top level processor is passed automatically as the
79 // opt argument to the Exec(Option_t* opt) memberfunctions of the
80 // various sub-tasks by the ExecuteJob() memberfunction (see below).
81 // This allows all sub-tasks to obtain the pointer to the top level
82 // processor instance from its name via the statement :
84 // AliJob* parent=(AliJob*)gROOT->GetListOfTasks()->FindObject(opt)
86 // 4) If selected, the job-specific folder will be created in the generic folder
87 // called "AliJob-folders" as a sub-folder under the same name as the one
88 // introduced in the constructor of the derived top level processor class.
89 // The folder will only be created if the MakeFolder() member function has been
90 // invoked or when selected explicitly by the "mode" argument of ExecuteJob().
91 // Actual creation of the folder environment (and internal array storage as well)
92 // only takes place when the first object is posted via the AddObject()
93 // or SetMainObject() facilities.
95 // Execution of the (user defined) top level processor has to be invoked via
96 // the memberfunction ExecuteJob() of this AliJob base class.
97 // This will set the default gROOT as the global working directory and then
98 // invoke the (user written) Exec() memberfunction of the top level
99 // processor class with as argument the name of the top level processor instance
100 // as specified by the user in the top level processor constructor.
101 // This will allow stepwise (e.g. event-by-event) execution of the various sub-tasks.
102 // In addition the "mode" argument of ExecuteJob() may be used to select/overrule
103 // creation of the folder environment for the complete job.
104 // See the docs of ExecuteJob() for further details.
106 // It is the user's responsibility to invoke the sub-tasks via the
107 // ExecuteTasks() statement at the appropriate location in the top level
108 // processor class if auto-execution was not explicitly selected via the
109 // "mode" argument of the ExecuteJob() memberfunction.
111 //--- Author: Nick van Eijndhoven 07-may-2005 Utrecht University
112 //- Modified: NvE $Date$ Utrecht University
113 ///////////////////////////////////////////////////////////////////////////
117 #include "Riostream.h"
119 ClassImp(AliJob) // Class implementation to enable ROOT I/O
121 AliJob::AliJob(const char* name,const char* title) : TTask(name,title)
123 // Default constructor.
124 // Initialise the working environment for general data access
125 // by the derived task and its subtasks.
133 // Introduce this AliJob based instance into the ROOT task list
134 TSeqCollection* tasks=gROOT->GetListOfTasks();
135 if (tasks) tasks->Add(this);
137 ///////////////////////////////////////////////////////////////////////////
140 // Default destructor.
141 // The internal array and job specific folder (if any) holding the various
142 // references are deleted.
143 // Note : The objects belonging to the various pointers in the array/folder
144 // and the main processing object are NOT deleted by this base class.
146 // Remove this AliJob based instance into the ROOT task list
147 TSeqCollection* tasks=gROOT->GetListOfTasks();
148 if (tasks) tasks->Remove(this);
157 TList* list=gROOT->GetListOfBrowsables();
160 TFolder* top=(TFolder*)list->FindObject("AliJob-folders");
161 if (top) RecursiveRemove(fFolder);
172 ///////////////////////////////////////////////////////////////////////////
173 void AliJob::ListEnvironment()
175 // Provide listing of the job environment.
177 cout << " ***" << endl;
178 cout << " *** Environment of job " << GetName() << " ***" << endl;
179 cout << " ***" << endl;
180 cout << " === Available (sub)tasks : " << endl;
184 cout << " === Current job-folder contents : " << endl;
189 ///////////////////////////////////////////////////////////////////////////
190 void AliJob::ExecuteJob(Int_t mode)
192 // Invokation of the top level processor via its Exec() memberfunction.
193 // The input argument "mode" can be used to explicitly specify the
194 // (de)selection of the folder environment creation and automatic
195 // invokation of all subtasks after execution of the top level
196 // Exec() memberfunction.
197 // The latter is convenient if an AliJob instance is used directly
198 // by the user (e.g. in a ROOT macro) in order to provide a hook
199 // for event-by-event processing of various subtasks.
200 // An even more convenient alternative to achieve this is invokation of the
201 // memberfunction ProcessObject().
203 // mode = -1 : Explicitly prohibit folder creation for the complete job
204 // 0 : Folder creation selection steered by MakeFolder()
205 // 1 : Explicitly select creation of the folder environment
206 // for the complete job.
207 // -11 : Same as mode=-1 but also auto-execution of subtasks after Exec()
208 // 10 : Same as mode=0 but also auto-execution of subtasks after Exec()
209 // 11 : Same as mode=1 but also auto-execution of subtasks after Exec()
211 // The default is mode=0.
213 // Note : Before execution gROOT is set as the global working directory.
215 if (mode<0) fMakefolder=-1;
216 if (mode==1 || mode==11) fMakefolder=1;
224 ExecuteTasks(GetName());
227 ///////////////////////////////////////////////////////////////////////////
228 void AliJob::MakeFolder()
230 // Select creation of the folder structure in addition to the internal
231 // array storage of objects.
232 // Creation of the folder structure is only activated if it was not
233 // explicitly forbidden by the specified "mode" on invokation of the
234 // ExecuteJob() memberfunction.
236 if (!fMakefolder) fMakefolder=1;
238 ///////////////////////////////////////////////////////////////////////////
239 TFolder* AliJob::GetFolder() const
241 // Provide pointer to the whiteboard folder.
244 ///////////////////////////////////////////////////////////////////////////
245 TObject* AliJob::GetMainObject() const
247 // Provide pointer to the main object structure.
250 ///////////////////////////////////////////////////////////////////////////
251 void AliJob::SetMainObject(TObject* obj)
253 // Store pointer to the main object structure.
260 ///////////////////////////////////////////////////////////////////////////
261 void AliJob::AddObject(TObject* obj)
263 // Store pointer of specified object in the working environment.
267 if (!fObjects) fObjects=new TObjArray();
269 if (fMakefolder>0 && !fFolder)
271 // Create the top level environment folder for all AliJobs if needed
272 TList* list=gROOT->GetListOfBrowsables();
275 TFolder* top=(TFolder*)list->FindObject("AliJob-folders");
278 top=new TFolder("AliJob-folders","Environment for all AliJob derived tasks");
279 list->Add(top,"AliJob-folders");
281 // Create the task-specific folder as a sub-folder in the top folder
282 fFolder=top->AddFolder(GetName(),GetTitle());
286 // Add object pointer to array and folder if it doesn't already exist
288 for (Int_t i=0; i<fObjects->GetEntries(); i++)
290 if (obj==fObjects->At(i))
299 if (fFolder) fFolder->Add(obj);
302 ///////////////////////////////////////////////////////////////////////////
303 void AliJob::AddObjects(TObjArray* arr)
305 // Store pointers of all the array objects individually in the working environment.
310 for (Int_t i=0; i<arr->GetSize(); i++)
313 if (obj) AddObject(obj);
316 ///////////////////////////////////////////////////////////////////////////
317 void AliJob::RemoveObject(TObject* obj)
319 // Remove pointer of specified object from the working environment.
320 // In case the specified object is also the main object, the main object
321 // pointer will be set to 0 as well.
327 TObject* test=fObjects->Remove(obj);
330 fObjects->Compress();
331 if (test==fMainObject) fMainObject=0;
335 if (fFolder) fFolder->Remove(obj);
337 ///////////////////////////////////////////////////////////////////////////
338 void AliJob::RemoveObjects(const char* classname)
340 // Remove all stored objects inheriting from classname.
341 // In case one of the removed objects is also the main object, the main object
342 // pointer will be set to 0 as well.
344 if (!fObjects) return;
347 for (Int_t i=0; i<fObjects->GetEntries(); i++)
349 TObject* obj=fObjects->At(i);
350 if (obj->InheritsFrom(classname))
352 TObject* test=fObjects->Remove(obj);
356 if (test==fMainObject) fMainObject=0;
358 if (fFolder) fFolder->Remove(obj);
361 if (remove) fObjects->Compress();
363 ///////////////////////////////////////////////////////////////////////////
364 TObject* AliJob::GetObject(Int_t j) const
366 // Provide pointer to j-th stored object.
367 // Note : j=1 indicates the first object.
369 if (!fObjects || j<1) return 0;
373 if (j<=fObjects->GetEntries()) obj=fObjects->At(j-1);
376 ///////////////////////////////////////////////////////////////////////////
377 TObject* AliJob::GetObject(const char* classname) const
379 // Provide pointer to the first stored object which inherits from classname.
381 if (!fObjects) return 0;
384 for (Int_t i=0; i<fObjects->GetEntries(); i++)
386 TObject* obx=fObjects->At(i);
387 if (obx->InheritsFrom(classname))
395 ///////////////////////////////////////////////////////////////////////////
396 TObjArray* AliJob::GetObjects() const
398 // Provide pointers of all the stored objects.
401 ///////////////////////////////////////////////////////////////////////////
402 TObjArray* AliJob::GetObjects(const char* classname)
404 // Provide pointers to all stored objects inheriting from classname.
406 if (!fObjects) return 0;
414 fSelect=new TObjArray();
417 for (Int_t i=0; i<fObjects->GetEntries(); i++)
419 TObject* obj=fObjects->At(i);
420 if (obj->InheritsFrom(classname)) fSelect->Add(obj);
424 ///////////////////////////////////////////////////////////////////////////
425 void AliJob::ProcessObject(TObject* obj)
427 // Invokation of all user defined sub-tasks for the specified object.
428 // This facility is very convenient when performing a task based
429 // event-by-event analysis in an (interactive) user application.
433 // Before processing gROOT is set as the global working directory.
434 // The specified object will be added to the job's object list
435 // as main object before the processing starts.
436 // This will allow the various sub-tasks to access the object in the
438 // After the processing of this object has been performed, the object
439 // will be removed from the object list and the main object pointer will
448 ExecuteTasks(GetName());
452 ///////////////////////////////////////////////////////////////////////////