22-jun-2005 NvE Specific job folder recursively removed from the generic AliJob folde...
[u/mrichter/AliRoot.git] / RALICE / AliJob.cxx
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 //
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 //
43 // Optionally one may invoke the MakeFolder() memberfunction to provide
44 // in addition to the above the following job-specific folder structure :
45 //
46 // * A folder which may serve as a whiteboard for transferring pointers to
47 //   objects which are posted there by the top level processor or any
48 //   of its subtasks.
49 //   Objects can be posted in the job folder via the AddObject() facility
50 //   of this AliJob class.
51 //   Access to the job folder is obtained via the GetFolder() memberfunction
52 //   and from this the various objects can be accessed via the usual TFolder
53 //   FindObject and/or iterator facilities.
54 //
55 // Notes :
56 // -------
57 // 1) This AliJob class is derived from TTask, which implies that every
58 //    (user defined) top level processor class is itself also a TTask.
59 //    This allows sub-tasks to be introduced to the top level processor
60 //    using the standard TTask facilities.
61 //
62 // 2) Only references to the various introduced objects are stored.
63 //    It is the user's responsibility to delete all introduced objects,
64 //    either in the Exec() or destructor of the derived top level processor class
65 //    or via Clear() facility as provided by the TTask machinery.
66 //
67 // 3) The top level processor instance is entered into the standard ROOT
68 //    ListOfTasks under the name which was provided by the user in the
69 //    constructor of the top level processor.
70 //    The name of the top level processor is passed automatically as the
71 //    opt argument to the Exec(Option_t* opt) memberfunctions of the 
72 //    various sub-tasks by the ExecuteJob() memberfunction (see below).
73 //    This allows all sub-tasks to obtain the pointer to the top level
74 //    processor instance from its name via the statement :
75 //
76 //      AliJob* parent=(AliJob*)gROOT->GetListOfTasks()->FindObject(opt)
77 //
78 // 4) If selected, the job-specific folder will be created in the generic folder
79 //    called "AliJob-folders" as a sub-folder under the same name as the one
80 //    introduced in the constructor of the derived top level processor class.
81 //    The folder will only be created if the MakeFolder() member function has been
82 //    invoked explicitly and when the first object is posted via the AddObject()
83 //    or SetMainObject() facilities.
84 //
85 // Execution of the (user defined) top level processor has to be invoked via
86 // the memberfunction ExecuteJob() of this AliJob base class.
87 // This will set the default gROOT as the global working directory and then
88 // invoke the (user written) Exec() memberfunction of the top level
89 // processor class with as argument the name of the top level processor instance
90 // as specified by the user in the top level processor constructor.
91 // This will allow stepwise (e.g. event-by-event) execution of the various sub-tasks.
92 //
93 // It is the user's responsibility to invoke the sub-tasks via the
94 // ExecuteTasks() statement at the appropriate location in the top level
95 // processor class. 
96 //
97 //--- Author: Nick van Eijndhoven 07-may-2005 Utrecht University
98 //- Modified: NvE $Date$ Utrecht University
99 ///////////////////////////////////////////////////////////////////////////
100  
101 #include "AliJob.h"
102 #include "Riostream.h"
103
104 ClassImp(AliJob) // Class implementation to enable ROOT I/O
105
106 AliJob::AliJob(const char* name,const char* title) : TTask(name,title)
107 {
108 // Default constructor.
109 // Initialise the working environment for general data access
110 // by the derived task and its subtasks.
111
112  fMakefolder=0;
113  fMainObject=0;
114  fFolder=0;
115  fObjects=0;
116  fSelect=0;
117
118  // Introduce this AliJob based instance into the ROOT task list
119  TSeqCollection* tasks=gROOT->GetListOfTasks();
120  if (tasks) tasks->Add(this);
121 }
122 ///////////////////////////////////////////////////////////////////////////
123 AliJob::~AliJob()
124 {
125 // Default destructor.
126 // The internal array and job specific folder (if any) holding the various
127 // references are deleted.
128 // Note : The objects belonging to the various pointers in the array/folder
129 //        and the main processing object are NOT deleted by this base class.
130
131  if (fObjects)
132  {
133   delete fObjects;
134   fObjects=0;
135  }
136  if (fFolder)
137  {
138   TList* list=gROOT->GetListOfBrowsables();
139   if (list)
140   {
141    TFolder* top=(TFolder*)list->FindObject("AliJob-folders");
142    if (top) RecursiveRemove(fFolder);
143   }
144   delete fFolder;
145   fFolder=0;
146  }
147  if (fSelect)
148  {
149   delete fSelect;
150   fSelect=0;
151  }
152 }
153 ///////////////////////////////////////////////////////////////////////////
154 void AliJob::ListEnvironment()
155 {
156 // Provide listing of the job environment. 
157
158  cout << " ***" << endl;
159  cout << " *** Environment of job " << GetName() << " ***" << endl;
160  cout << " ***" << endl;
161  cout << " === Available (sub)tasks : " << endl;
162  ls();
163  if (fFolder)
164  {
165   cout << " === Current job-folder contents : " << endl;
166   fFolder->ls();
167  }
168  cout << endl;
169 }
170 ///////////////////////////////////////////////////////////////////////////
171 void AliJob::ExecuteJob()
172 {
173 // Invokation of the top level processor via its Exec() memberfunction.
174 // Note : Before execution gROOT is set as the global working directory.
175  gROOT->cd(); 
176  Exec(GetName());
177 }
178 ///////////////////////////////////////////////////////////////////////////
179 void AliJob::MakeFolder()
180 {
181 // Select creation of the folder structure in addition to the internal
182 // array storage of objects.
183  fMakefolder=1;
184 }
185 ///////////////////////////////////////////////////////////////////////////
186 TFolder* AliJob::GetFolder() const
187 {
188 // Provide pointer to the whiteboard folder.
189  return fFolder;
190 }
191 ///////////////////////////////////////////////////////////////////////////
192 TObject* AliJob::GetMainObject() const
193 {
194 // Provide pointer to the main object structure.
195  return fMainObject;
196 }
197 ///////////////////////////////////////////////////////////////////////////
198 void AliJob::SetMainObject(TObject* obj)
199 {
200 // Store pointer to the main object structure.
201  if (obj)
202  {
203   fMainObject=obj;
204   AddObject(obj);
205  }
206 }
207 ///////////////////////////////////////////////////////////////////////////
208 void AliJob::AddObject(TObject* obj)
209 {
210 // Store pointer of specified object in the working environment.
211
212  if (!obj) return;
213
214  if (!fObjects) fObjects=new TObjArray();
215
216  if (fMakefolder && !fFolder)
217  {
218   // Create the top level environment folder for all AliJobs if needed 
219   TList* list=gROOT->GetListOfBrowsables();
220   if (list)
221   {
222    TFolder* top=(TFolder*)list->FindObject("AliJob-folders");
223    if (!top)
224    {
225     top=new TFolder("AliJob-folders","Environment for all AliJob derived tasks");
226     list->Add(top,"AliJob-folders");
227    }
228    // Create the task-specific folder as a sub-folder in the top folder 
229    fFolder=top->AddFolder(GetName(),GetTitle());
230   }
231  }
232
233  // Add object pointer to array and folder if it doesn't already exist 
234  Int_t exist=0;
235  for (Int_t i=0; i<fObjects->GetEntries(); i++)
236  {
237   if (obj==fObjects->At(i))
238   {
239    exist=1;
240    break;
241   }
242  }
243  if (!exist)
244  {
245   fObjects->Add(obj);
246   if (fFolder) fFolder->Add(obj);
247  }
248 }
249 ///////////////////////////////////////////////////////////////////////////
250 void AliJob::AddObjects(TObjArray* arr)
251 {
252 // Store pointers of all the array objects individually in the working environment.
253
254  if (!arr) return;
255
256  TObject* obj=0;
257  for (Int_t i=0; i<arr->GetSize(); i++)
258  {
259   obj=arr->At(i);
260   if (obj) AddObject(obj);
261  }
262 }
263 ///////////////////////////////////////////////////////////////////////////
264 void AliJob::RemoveObject(TObject* obj)
265 {
266 // Remove pointer of specified object from the working environment.
267 // In case the specified object is also the main object, the main object
268 // pointer will be set to 0 as well.
269
270  if (!obj) return;
271
272  if (fObjects)
273  {
274   TObject* test=fObjects->Remove(obj);
275   if (test)
276   {
277    fObjects->Compress();
278    if (test==fMainObject) fMainObject=0;
279   }
280  }
281
282  if (fFolder) fFolder->Remove(obj);
283 }
284 ///////////////////////////////////////////////////////////////////////////
285 void AliJob::RemoveObjects(const char* classname)
286 {
287 // Remove all stored objects inheriting from classname.
288 // In case one of the removed objects is also the main object, the main object
289 // pointer will be set to 0 as well.
290
291  if (!fObjects) return;
292
293  Int_t remove=0;
294  for (Int_t i=0; i<fObjects->GetEntries(); i++)
295  {
296   TObject* obj=fObjects->At(i);
297   if (obj->InheritsFrom(classname))
298   {
299    TObject* test=fObjects->Remove(obj);
300    if (test)
301    {
302     remove=1;
303     if (test==fMainObject) fMainObject=0;
304    }
305    if (fFolder) fFolder->Remove(obj);
306   }
307  }
308  if (remove) fObjects->Compress();
309 }
310 ///////////////////////////////////////////////////////////////////////////
311 TObject* AliJob::GetObject(Int_t j) const
312 {
313 // Provide pointer to j-th stored object.
314 // Note : j=1 indicates the first object.
315
316  if (!fObjects || j<1) return 0;
317
318  TObject* obj=0;
319
320  if (j<=fObjects->GetEntries()) obj=fObjects->At(j-1);
321  return obj;
322 }
323 ///////////////////////////////////////////////////////////////////////////
324 TObject* AliJob::GetObject(const char* classname) const
325 {
326 // Provide pointer to the first stored object which inherits from classname.
327
328  if (!fObjects) return 0;
329
330  TObject* obj=0;
331  for (Int_t i=0; i<fObjects->GetEntries(); i++)
332  {
333   TObject* obx=fObjects->At(i);
334   if (obx->InheritsFrom(classname))
335   {
336    obj=obx;
337    break;
338   }
339  }
340  return obj;
341 }
342 ///////////////////////////////////////////////////////////////////////////
343 TObjArray* AliJob::GetObjects() const
344 {
345 // Provide pointers of all the stored objects.
346  return fObjects;
347 }
348 ///////////////////////////////////////////////////////////////////////////
349 TObjArray* AliJob::GetObjects(const char* classname)
350 {
351 // Provide pointers to all stored objects inheriting from classname.
352
353  if (!fObjects) return 0;
354
355  if (fSelect)
356  {
357   fSelect->Clear();
358  }
359  else
360  {
361   fSelect=new TObjArray();
362  }
363
364  for (Int_t i=0; i<fObjects->GetEntries(); i++)
365  {
366   TObject* obj=fObjects->At(i);
367   if (obj->InheritsFrom(classname)) fSelect->Add(obj);
368  }
369  return fSelect;
370 }
371 ///////////////////////////////////////////////////////////////////////////