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