]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliConfig.cxx
Macro to plot pathlengths of back-to-back jets. (A. Dainese)
[u/mrichter/AliRoot.git] / STEER / AliConfig.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 //  Description:
19 //  This class is responsible for creating folder structure
20 //  All stuff of aliroot sits in one folder with name defined by
21 //  fgkTopFolderName data wich do not very trough event to event are
22 //  sitting in directly in "top folder" all data which changes from
23 //  event to event are sitting in one folder (which has more subfolders)
24 //  Idea is to have more than one event in folder structure which allows
25 //  usage of standard procedures in merging
26 //  Add(AliDetector*) calls Add(AliModule*) as AliDetector is a AliModule
27 //  as well and should be listed in module list
28
29 #include <TDatabasePDG.h>
30 #include <TFolder.h>
31 #include <TInterpreter.h>
32 #include <TObjString.h>
33 #include <TROOT.h>
34 #include <TString.h>
35 #include <TSystem.h>
36 #include <TTask.h>
37 #include <TVirtualMC.h>
38
39 #include "AliConfig.h"
40 #include "AliDetector.h"
41 #include "AliGenerator.h" 
42 #include "AliLoader.h"
43
44 enum 
45  {
46   kDetTaskQA = 0,
47   kDetTaskSDigitizer,
48   kDetTaskDigitizer,
49   kDetTaskRecontructioner,
50   kDetTaskTracker,
51   kDetTaskPID,
52   kDetTaskLast
53  };
54
55 enum
56  {
57    kDetFolderData = 0,
58    kDetFolderCalibration,
59    kDetFolderAligmnet,
60    kDetFolderQA,
61    kDetFolderLast
62  };
63 ClassImp(AliConfig)
64
65 AliConfig* AliConfig::fgInstance = 0;
66
67 //0 level folder
68 const TString AliConfig::fgkTopFolderName("Folders");
69
70 //1st level folder
71 const TString AliConfig::fgkTasksFolderName("Tasks"); //task folder, commn
72 const TString AliConfig::fgkConstantsFolderName("Constants");
73 const TString AliConfig::fgkDefaultEventFolderName("Event");  //default folder for event, always used except merging
74
75 //2st level folder
76 //subfolder of event folder
77 const TString AliConfig::fgkDataFolderName("Data");//folder for data (hits, digits, points, tracks) grouped by detectors
78 const TString AliConfig::fgkModuleFolderName("Modules");//folder with modules objects
79 const TString AliConfig::fgkConditionsFolderName("Conditions");//folder with conditions (mag. field etc.)
80 const TString AliConfig::fgkConfigurationFolderName("Configuration");//folder with configuration (setup) of the detector
81 const TString AliConfig::fgkHeaderFolderName("Header");//folder with header and other MC information
82
83 //Tasks names, goes into fgkTasksFolderName folder
84 const TString AliConfig::fgkDigitizerTaskName("Digitizer");
85 const TString AliConfig::fgkSDigitizerTaskName("SDigitizer");
86 const TString AliConfig::fgkReconstructionerTaskName("Reconstructioner");
87 const TString AliConfig::fgkTrackerTaskName("Tracker");
88 const TString AliConfig::fgkPIDTaskName("PIDTask");//;=) PIDer???
89 const TString AliConfig::fgkQATaskName("QAtask");
90
91 //3rd level folder
92 //fgkConditionsFolderName subfolders
93 const TString AliConfig::fgkCalibrationFolderName("Calibration");
94 const TString AliConfig::fgkAligmentFolderName("Aligment");
95 const TString AliConfig::fgkQAFolderName("QAout");
96   
97 //3rd level folder
98 //fgkConfigurationFolderName subfolders
99 const TString AliConfig::fgkFieldFolderName("Field");
100 const TString AliConfig::fgkGeneratorsFolderName("Generators");
101 const TString AliConfig::fgkVirtualMCFolderName("VirtualMC");
102
103
104 const TString AliConfig::fgkPDGFolderName("Constants/DatabasePDG");//folder with PDG Database
105 const TString AliConfig::fgkGeneratorFolderName("Configuration/Generators");//folder with generators
106 const TString AliConfig::fgkMCFolderName("Configuration/VirtualMC");
107
108 //____________________________________________________________________________
109 AliConfig* AliConfig::Instance ()
110 {
111   //
112   // Instance method for singleton class
113   //
114    if(fgInstance == 0) 
115     {
116      fgInstance = new AliConfig (fgkTopFolderName,"Alice data exchange board");
117     }
118    return fgInstance;
119 }
120
121 //____________________________________________________________________________
122 AliConfig::AliConfig():
123   fTopFolder(0x0),
124   fTaskFolder(0x0),
125   fConstFolder(0x0),
126   fDetectorTask(0x0),
127   fDetectorFolder(0x0)
128 {
129   //
130   // Default constructor, mainly to keep coding conventions
131   //
132   fgInstance=0;//never mind, its going to exit in next step
133   Fatal("ctor","Constructor should not be called for a singleton\n");
134 }
135 //____________________________________________________________________________
136
137 AliConfig::AliConfig(const AliConfig& conf):
138   TNamed(conf),
139   fTopFolder(0x0),
140   fTaskFolder(0x0),
141   fConstFolder(0x0),
142   fDetectorTask(0x0),
143   fDetectorFolder(0x0)
144 {
145   //
146   // Copy constructor, mainly to keep coding conventions
147   //
148   fgInstance=0;
149     
150   Fatal("copy ctor",
151    "Copy constructor should not be called for a singleton\n");
152 }
153 //____________________________________________________________________________
154
155 AliConfig& AliConfig::operator=(const AliConfig& /*conf*/)
156 {
157   //
158   // Assignment, mainly to keep coding conventions
159   //
160   fgInstance=0;
161     
162   Fatal("Assignment operator",
163    "Assignment operator should not be called for a singleton\n");
164   return *this;
165 }
166 //____________________________________________________________________________
167
168 AliConfig::AliConfig(const char *name, const char *title): 
169   TNamed(name,title), 
170   fTopFolder(gROOT->GetRootFolder()->AddFolder(name,title)),
171   fTaskFolder(fTopFolder->AddFolder(fgkTasksFolderName, "ALICE Tasks")),
172   fConstFolder(0x0),
173   fDetectorTask(0x0),
174   fDetectorFolder(new TString[kDetFolderLast+1])
175 {
176 // Constructor
177
178   //Main AliRoot Folder
179   if (fTopFolder == 0x0)
180    {
181      Fatal("AliConfig(const char*, const char*)","Can not create Top Alice Folder.");
182      return;//never reached
183    }
184   fTopFolder->SetOwner();
185   
186   fDetectorFolder[kDetFolderData] = fgkDataFolderName;
187   fDetectorFolder[kDetFolderCalibration] = fgkConditionsFolderName+"/"+fgkCalibrationFolderName;
188   fDetectorFolder[kDetFolderAligmnet] = fgkConditionsFolderName+"/"+fgkAligmentFolderName;
189   fDetectorFolder[kDetFolderQA] = fgkConditionsFolderName+"/"+fgkQAFolderName;
190   fDetectorFolder[kDetFolderLast] = "";
191   
192   gROOT->GetListOfBrowsables()->Add(fTopFolder, name);
193
194   //Constants folder
195   fConstFolder = fTopFolder->AddFolder (fgkConstantsFolderName, "Constant parameters");
196   fConstFolder->AddFolder("DatabasePDG", "PDG database");
197   
198   // Add the tasks to //Folders
199   
200   TTask * qa = new TTask(fgkQATaskName, "Alice QA tasks");
201   fTaskFolder->Add(qa); 
202   TTask * sd = new TTask(fgkSDigitizerTaskName, "Alice SDigitizer") ;
203   fTaskFolder->Add(sd); 
204   TTask * di = new TTask(fgkDigitizerTaskName, "Alice Digitizer") ;
205   fTaskFolder->Add(di); 
206   TTask * re = new TTask(fgkReconstructionerTaskName, "Alice Reconstructioner") ;
207   fTaskFolder->Add(re); 
208   TTask * tr = new TTask(fgkTrackerTaskName,"Alice Tracker");
209   fTaskFolder->Add(tr);
210   TTask * pid = new TTask(fgkPIDTaskName,"Alice Particle Identification Task");
211   fTaskFolder->Add(pid);
212   fDetectorTask    =  new TString[kDetTaskLast+1];
213   
214   fDetectorTask[kDetTaskQA] = fgkQATaskName;
215   fDetectorTask[kDetTaskSDigitizer] = fgkSDigitizerTaskName;
216   fDetectorTask[kDetTaskDigitizer] =  fgkDigitizerTaskName;
217   fDetectorTask[kDetTaskRecontructioner] = fgkReconstructionerTaskName;
218   fDetectorTask[kDetTaskTracker] = fgkTrackerTaskName;
219   fDetectorTask[kDetTaskPID] = fgkPIDTaskName;
220   fDetectorTask[kDetTaskLast] = "";
221
222   fgInstance=this;
223 }
224
225 //____________________________________________________________________________
226 AliConfig::~AliConfig()
227
228   // destructor
229   delete [] fDetectorFolder ;  
230   delete [] fDetectorTask;
231   if (fTopFolder)
232    {
233     fTopFolder->SetOwner();
234     delete fTopFolder; 
235    }
236 }
237 //____________________________________________________________________________
238
239 void AliConfig::AddInFolder (const char *dir, TObject *obj)
240 {
241   // Adds object "obj" to folder "dir"
242   TFolder *folder = dynamic_cast<TFolder *>(fTopFolder->FindObject(dir));
243   if (folder)
244     folder->Add (static_cast<TObject *>(obj));
245 }
246 //____________________________________________________________________________
247
248 Int_t AliConfig::AddSubTask(const char *taskname, const char* name,const char* title)
249 {
250 //Create new task named 'name' and titled 'title' 
251 //as a subtask of the task named 'taskname'
252
253    if (AliLoader::GetDebug()) Info("AddSubTask","Try to get folder named %s",taskname);
254    TObject* obj = fTopFolder->FindObject(taskname);
255    TTask * task = (obj)?dynamic_cast<TTask*>(obj):0x0;
256    if (task)
257      {
258       if (AliLoader::GetDebug()) Info("AddSubTask","          Got");
259       TTask * subtask = static_cast<TTask*>(task->GetListOfTasks()->FindObject(name));
260       if (!subtask) 
261         {
262           subtask = new TTask(name,title);
263           task->Add(subtask);
264         }
265       else
266        {
267          Warning("AddSubTask","Task named \"%s\" already exists in Task %s\n",name,taskname);
268        }
269      }
270    else
271      {
272        Error("AddSubTask","Can not find task %s to put a new task in.",taskname);
273        return 1;
274      }
275   return 0;
276 }
277
278 //____________________________________________________________________________
279 TObject* AliConfig::FindInFolder (const char *dir, const char *name)
280 {
281   // Finds object with name "name" in folder "dir"
282   if(!name) return(fTopFolder->FindObject(name));
283   TFolder * folder = dynamic_cast<TFolder *>(fTopFolder->FindObject(dir));
284   if (!folder) return (NULL);
285   return(folder->FindObject(name));
286 }
287
288 //____________________________________________________________________________
289 void    AliConfig::Add (AliGenerator * obj,const char* eventfolder)
290 {
291   // Adds generator "obj" to the event folder "eventfolder"
292   TString path(eventfolder);
293   path = path + "/" + fgkGeneratorsFolderName;
294   AddInFolder(path,obj);
295 }
296
297 //____________________________________________________________________________
298 void AliConfig::Add (TVirtualMC * obj,const char* eventfolder)
299 {
300   // Adds TVirtualMC object to the event folder
301   TString path(eventfolder);
302   path = path + "/" + fgkMCFolderName;
303   AddInFolder(path, obj);
304 }
305
306 //____________________________________________________________________________
307 void  AliConfig::Add (TDatabasePDG * obj)
308 {
309   // Adds TDataBase object
310   AddInFolder(fgkPDGFolderName, obj);
311 }
312
313 //____________________________________________________________________________
314 void AliConfig::Add(AliModule* obj,const char* eventfolder)
315 {
316   // Adds module to the event folder
317   TString path(eventfolder);
318   path = path + "/" + fgkModuleFolderName;
319   if (AliLoader::GetDebug())
320     Info("Add(AliModule*)","module name = %s, Ev. Fold. Name is %s.",
321          obj->GetName(),eventfolder);
322   AddInFolder(path, obj);
323 }
324 //____________________________________________________________________________
325
326 Int_t AliConfig::AddDetector(TFolder* evntfolder, const char *name, const char* title)
327 {
328 //creates folders and tasks for the detector 'name'
329  Int_t retval;//returned value
330  retval = CreateDetectorFolders(evntfolder,name,title);
331  if (retval)
332   {
333     Error("AddDetector","CreateDetectorFolders returned error for detector %s",name);
334     return retval;
335   }
336  return 0; 
337 }
338 //____________________________________________________________________________
339
340 Int_t AliConfig::AddDetector(const char* evntfoldername,const char *name, const char* title)
341 {
342 //creates folders and tasks for the detector 'name'
343  Int_t retval;//returned value
344  retval = CreateDetectorFolders(evntfoldername,name,title);
345  if (retval)
346   {
347     Error("AddDetector","CreateDetectorFolders returned error for detector %s",name);
348     return retval;
349   }
350 // retval = CreateDetectorTasks(name,title);
351 // if (retval)
352 //  {
353 //    Error("AddDetector","CreateDetectorTasks returned error for detector %s",name);
354 //    return retval;
355 //  }
356  return 0; 
357 }
358 //____________________________________________________________________________
359
360 void  AliConfig::Add(AliDetector * obj,const char* eventfolder)
361 {
362   // Adds new AliDetector objest to the correspondent event folder
363   if (AliLoader::GetDebug()) 
364     Info("Add(AliDetector*)","detector name = %s, Ev. Fold. Name is %s.",
365         obj->GetName(),eventfolder);
366
367   TObject* foundobj = GetTopFolder()->FindObject(eventfolder);
368   TFolder* evfolder = (foundobj)?dynamic_cast<TFolder*>(foundobj):0x0;
369   if (evfolder == 0x0)
370    {
371      Fatal("Add(AliDetector * obj,const char* eventfolder)",
372            "Can not find folder %s while adding detector %s",eventfolder,obj->GetName());
373      return;
374    } 
375   CreateDetectorFolders(evfolder, obj->GetName(), obj->GetTitle());
376   
377 //  CreateDetectorTasks(obj->GetName(),obj->GetTitle());
378
379 }
380 //____________________________________________________________________________
381
382 Int_t  AliConfig::CreateDetectorFolders(const char* evntfoldername,const char *name, const char* title)
383 {
384 //creates a folders for detector named 'name' and titled 'title'
385 //in a event folder named 'evntfoldername'
386 //list of folder names where new folders are created is defined in fDetectorFolder array 
387 //detector folders are named 'name' and titled 'title' as well
388
389  TFolder* evfolder = dynamic_cast<TFolder*>(GetTopFolder()->FindObject(evntfoldername));
390  if (evfolder == 0x0)
391   {
392    Error("CreateDetectorFolders",
393          "Can not find folder %s while adding detector %s",evntfoldername,name);
394    return 1;
395   }
396  return CreateDetectorFolders(evfolder,name,title);
397 }
398 //____________________________________________________________________________
399 Int_t  AliConfig::CreateDetectorFolders(TFolder* evntfolder,const char *name, const char* title)
400 {
401 //creates a folders for detector named 'name' and titled 'title'
402 //in a event folder 'evntfolder'
403 //list of folder names where new folders are created is defined in fDetectorFolder array 
404 //detector folders are named 'name' and titled 'title' as well
405 //Here we add only detector not an modules
406  
407  Int_t tmp;
408  Int_t i = 0;//iterator
409  while(!fDetectorFolder[i].IsNull())
410   {
411     tmp = AddSubFolder(evntfolder,fDetectorFolder[i],name,title);
412     if (tmp)
413      {
414       Error("AddDetector(TFolder*","Failed to create subfolder of %s for detector %s",fDetectorFolder[i].Data(),name);
415       return 1;
416      }
417     i++;
418   }
419  return 0;
420 }
421 //____________________________________________________________________________
422 Int_t AliConfig::CreateDetectorTasks(const char *name, const char* title)
423 {
424   // Creates new detector's task "name"
425    Int_t i = 0;
426    Int_t tmp;
427    while (i < kDetTaskLast)
428     {
429       tmp = AddSubTask(fgkTasksFolderName+"/"+fDetectorTask[i],
430                        name+fDetectorTask[i],(fDetectorTask[i]+" for ")+title);
431       if (tmp)
432        {
433          Error("CreateDetectorTasks","Error occured while creating task for %s in %s.",
434                 name,fDetectorTask[i-1].Data());
435          return 1;
436        }
437       i++;
438     }
439    return 0;
440 }
441
442 //____________________________________________________________________________
443 void    AliConfig::Add (char *list)
444 {
445   // Adds space separated list of objects to the
446   // configuration macro (?)
447   char *path;
448   
449   const char   *confPath = gSystem->Getenv ("ALICE_CONFIG_PATH");
450   if  (confPath) {
451     path = new char[strlen (confPath)];
452     strcpy (path, confPath);
453   } else {
454     const char   *alice = gSystem->Getenv ("ALICE_ROOT");
455     path = new char[strlen (alice) + 32];
456     
457     strcpy (path, ".:");
458     if (alice) {
459       strcat (path, alice);
460     }
461     strcat (path, "/macros/config");
462   }
463   
464   char   *token = strtok (path, ":");
465   
466   TList  *dirlist = new TList;
467   
468   while (token != NULL) 
469     {
470       dirlist->Add (new TObjString(token));
471       token = strtok (NULL, ":");
472     }
473   
474   token = strtok (list, " ");
475   
476   while (token != NULL)
477     { 
478       Info("Add(char *list)","Configuring token=%s",token);
479       
480       TObject *obj;
481       TIter   next (dirlist);
482       TString found = "\0";
483       
484       while ((obj = next ()))
485         {
486           TString dir(obj->GetName());
487           TString path  = dir + "/" + token;
488           TString macro = path + ".C";
489           if (!gSystem->AccessPathName (macro.Data()))  
490            {
491             gInterpreter->ExecuteMacro (macro.Data());                             
492             found = "(" + macro + ")";
493             if (macro.Contains("/")) 
494              {
495                TString dirname = gSystem->DirName(macro.Data());
496                TString macroConfigure = dirname + "/Configure.C";
497                if (!gSystem->AccessPathName (macroConfigure.Data()))
498                 {
499                   gInterpreter->ExecuteMacro (macroConfigure.Data());                               
500                   found += " => Configured";
501                 }                             
502              }
503             break;
504            } 
505           else 
506            {
507             TString macroDefault = path + "/Default.C";
508             if (!gSystem->AccessPathName (macroDefault.Data()))
509               {
510                 gInterpreter->ExecuteMacro (macroDefault.Data());
511                 found = "(" + macro + ")";
512                 TString macroConfigure = path + "/Configure.C";
513                 if (!gSystem->AccessPathName (macroConfigure.Data()))   
514                   {
515                     gInterpreter->ExecuteMacro (macroConfigure.Data());                             
516                     found += " => Configured";
517                   }
518                 break;                              
519               }
520            }
521         }
522       
523       if (strlen(found.Data())) 
524         {
525           Info("Add(char *list)","found=%s  => OK",found.Data());
526         } 
527       else 
528         {
529           Error("Add(char *list)"," => FAILED.");
530           exit(1); 
531         }           
532       
533       token = strtok (NULL," ");
534     }
535   
536   if (dirlist) delete dirlist;
537   
538 }
539
540 /*****************************************************************************/
541
542 TFolder* AliConfig::BuildEventFolder(const char* name,const char* title)
543 {
544 /*
545  creates the folder structure for one event
546  TopFolder_
547          | \
548          |  Tasks
549          |_
550          | \
551          |  Constants
552          |_
553          | \
554          |  Event_
555          |      | \
556          |      |  Modules(detector objects)
557          |      |_
558          |      | \              
559          |      |  Header
560          |      |_
561          |      | \              
562          |      |  Data_
563          |      |     | \ 
564          |      |     |  TPC_
565          |      |     |    | \
566          |      |     |    |  Hits(object;e.g. tree)
567          |      |     |    |_  
568          |      |     |    | \ 
569          |      |     |    |  SDigits(object)
570          |      |     |    |_
571          |      |     |    | \ 
572          |      |     |    |  Digits(object)
573          |      |     |    |_
574          |      |     |    | \ 
575          |      |     |    |  RecPoints(object)
576          |      |     |    |_
577          |      |     |      \ 
578          |      |     |       Tracks(object)
579          |      |     |_ 
580          |      |       \
581          |      |        ITS_
582          |      |          | \
583          |      |          |  Hits(object;e.g. tree)
584          |      |          |_  
585          |      |          | \ 
586          |      |          |  SDigits(object)
587          |      |          |_
588          |      |          | \ 
589          |      |          |  Digits(object)
590          |      |          |_
591          |      |          | \ 
592          |      |          |  RecPoints(object)
593          |      |          |_
594          |      |            \ 
595          |      |             Tracks(object)
596          |      |_         
597          |        \       
598          |         Configuration
599          |               
600          |_
601            \
602             Event2_  (to be merged with event)
603                 |  \
604                 |   Modules(detector objects)
605                 |_
606                 | \              
607                 |  Header
608                 |_
609                 | \              
610                 |  Data_
611                 |     | \ 
612                 |     |  TPC_
613                 |     |    | \
614                 |     |    |  Hits(object;e.g. tree)
615                 |     |    |_  
616                 |     |    | \ 
617                 |     |    |  SDigits(object)
618                 |     |    |_
619                 |     |    | \ 
620                 |     |    |  Digits(object)
621                 |     |    |_
622                 |     |    | \ 
623                 |     |    |  RecPoints(object)
624                 |     |    |_
625                 |     |      \ 
626                 |     |       Tracks(object)
627                 |     |_ 
628                 |       \
629                 |        ITS_
630                 |          | \
631                 |          |  Hits(object;e.g. tree)
632                 |          |_  
633                 |          | \ 
634                 |          |  SDigits(object)
635                 |          |_
636                 |          | \ 
637                 |          |  Digits(object)
638                 |          |_
639                 |          | \ 
640                 |          |  RecPoints(object)
641                 |          |_
642                 |            \ 
643                 |             Tracks(object)
644                 |_         
645                   \       
646                    Configuration
647                          
648 */
649   TFolder* eventfolder = fTopFolder->AddFolder(name,title); 
650    
651   //modules
652   eventfolder->AddFolder(fgkModuleFolderName, "Detector objects");
653   //event data
654   eventfolder->AddFolder(fgkDataFolderName, "Detector data");
655   
656     //Conditions
657   TFolder *conditions = eventfolder->AddFolder(fgkConditionsFolderName, "Run conditions");
658   conditions->AddFolder(fgkCalibrationFolderName,"Detector calibration data");
659   conditions->AddFolder(fgkAligmentFolderName,"Detector aligment");
660   conditions->AddFolder(fgkQAFolderName,"Quality Asurance Output"); //Folder with output of the QA task(s)
661   //Configuration
662   TFolder *configuration = eventfolder->AddFolder(fgkConfigurationFolderName, "Run configuration");
663   configuration->AddFolder(fgkFieldFolderName, "Magnetic field maps");
664   configuration->AddFolder(fgkGeneratorsFolderName,"list of generator objects");
665   configuration->AddFolder(fgkVirtualMCFolderName,"the Virtual MC");
666
667   eventfolder->AddFolder(fgkHeaderFolderName,"MonteCarlo event header");
668
669   eventfolder->SetOwner();
670
671   return eventfolder;
672 }
673
674 /*****************************************************************************/
675
676 TString AliConfig::GetQATaskName() const
677  {
678  //returns task name
679   return fDetectorTask[kDetTaskQA];
680  }
681 /*****************************************************************************/
682  
683 TString AliConfig::GetDigitizerTaskName() const
684  {
685  //returns task name
686   return fDetectorTask[kDetTaskDigitizer];
687  }
688 /*****************************************************************************/
689  
690 TString AliConfig::GetSDigitizerTaskName() const
691  {
692  //returns task name
693   return fDetectorTask[kDetTaskSDigitizer];
694  }
695 /*****************************************************************************/
696
697 TString AliConfig::GetReconstructionerTaskName() const
698  {
699  //returns task name
700   return fDetectorTask[kDetTaskRecontructioner];
701  }
702 /*****************************************************************************/
703
704 TString AliConfig::GetTrackerTaskName() const
705  {
706  //returns task name
707   return fDetectorTask[kDetTaskTracker];
708  }
709 /*****************************************************************************/
710
711 TString AliConfig::GetPIDTaskName() const
712  {
713  //returns task name
714   return fDetectorTask[kDetTaskPID];
715  }
716 /*****************************************************************************/
717
718 const TString& AliConfig::GetQAFolderName() const
719 {
720 //returns pathname of folder with QA output relative to Top Alice Folder
721   return fDetectorFolder[kDetFolderQA];
722 }
723 /*****************************************************************************/
724
725 const TString& AliConfig::GetDataFolderName() const
726 {
727 //returns name of data folder path relative to event folder
728  return fgkDataFolderName;
729 }
730 /*****************************************************************************/
731
732 Int_t AliConfig::AddSubFolder(TFolder* topfolder, const char* infoler, 
733                      const char* newfoldname, const char* newfoldtitle)
734 {
735 //helper method
736 //in topfolder looks for folder named 'infolder'
737 //and if it exist it creates inside a new folder named 'newfoldname' and titled 'newfoldtitle'
738
739  if (topfolder == 0x0)//check if exists top folder
740   {
741    Error("AddSubFodler(TFolder*, ....","Parameter TFolder* points to NULL.");
742    return 1;
743   }
744  
745  TObject *obj;
746  TFolder* folder;
747  
748  folder = dynamic_cast<TFolder*>(topfolder->FindObject(infoler));
749  if (folder == 0x0) //check if we got inolder
750   {
751    Error("AddSubFodler(TFolder*, ....","Can not find folder %s in folder %s.",infoler,topfolder->GetName());
752    return 1;
753   }
754  obj = folder->FindObject(newfoldname); //see if such a subfolder already exists
755  if (obj == 0x0) //nope
756   {
757    TFolder *newfolder = folder->AddFolder(newfoldname,newfoldtitle);//add the desired subfolder
758    if (newfolder == 0x0) //check if we managed
759     {
760      Error("AddSubFodler(TFolder*, ....","Can not create folder %s in folder %s",newfoldname,infoler);
761      return 2;
762     }
763    else return 0;//success
764   }
765  //such an object already exists
766  TFolder* fol = dynamic_cast<TFolder*>(obj);
767  if (fol == 0x0)
768    {
769      Error("AddSubFodler(TFolder*, ....",
770            "Object named %s already exists in folder %s AND IT IS NOT A FOLDER",newfoldname,infoler);
771      return 3;
772    }
773  Warning("AddSubFodler(TFolder*, ....",
774          "Folder named %s already exists in folder %s",newfoldname,infoler);
775  return 0;
776 }