ff0bcba6b16db5f7eeeace49ee04c7e8f3d58ff3
[u/mrichter/AliRoot.git] / STEER / AliRunLoader.cxx
1 #include "AliRunLoader.h"
2 //____________________________________________________________________
3 //////////////////////////////////////////////////////////////////////
4 //                                                                  //
5 // class AliRunLoader                                               //
6 //                                                                  //
7 // This class aims to be the unque interface for managing data I/O. //
8 // It stores Loaders for all modules which, knows names             //
9 // of the files were data are to be stored.                         //
10 //                                                                  //
11 // It aims to substitud AliRun in automatic data managing           //
12 // thus there is no necessity of loading gAlice from file in order  //
13 // to get access to the data.                                       //
14 //                                                                  //
15 // Logical place to put the specific Loader to the given            //
16 // detector is detector  itself (i.e ITSLoader in ITS).             //
17 // But, to load detector object one need to load gAlice, and        //
18 // by the way all other detectors with their geometrieces and       //
19 // so on. So, if one need to open TPC clusters there is no          //
20 // principal need to read everything.                               //
21 //                                                                  //
22 //                                                                  //
23 // When RunLoader is read from the file it does not connect to      //
24 // the folder structure automatically. It must be connected         //
25 // (mounted) manualy. Default event folder is defined by            //
26 // AliConfig::GetDefaultEventFolderName()                           //
27 // but can be mounted elsewhere. Usefull specially in merging case, //
28 // when more than pone session needs to be loaded                   //
29 //                                                                  //
30 //////////////////////////////////////////////////////////////////////
31
32 #include <TBranch.h>
33 #include <TError.h>
34 #include <TFile.h>
35 #include <TFolder.h>
36 #include <TGeometry.h>
37 #include <TObjArray.h>
38 #include <TROOT.h>
39 #include <TString.h>
40 #include <TTask.h>
41 #include <TTree.h>
42
43 #include "AliRun.h"
44 #include "AliConfig.h"
45 #include "AliLoader.h"
46 #include "AliHeader.h"
47 #include "AliStack.h"
48 #include "AliDetector.h"
49 #include "AliRunDigitizer.h"
50
51 ClassImp(AliRunLoader)
52
53 AliRunLoader* AliRunLoader::fgRunLoader = 0x0;
54
55 const TString AliRunLoader::fgkRunLoaderName("RunLoader");
56
57 const TString AliRunLoader::fgkHeaderBranchName("Header");
58 const TString AliRunLoader::fgkHeaderContainerName("TE");
59 const TString AliRunLoader::fgkKineContainerName("TreeK");
60 const TString AliRunLoader::fgkTrackRefsContainerName("TreeTR");
61 const TString AliRunLoader::fgkKineBranchName("Particles");
62 const TString AliRunLoader::fgkDefaultKineFileName("Kinematics.root");
63 const TString AliRunLoader::fgkDefaultTrackRefsFileName("TrackRefs.root");
64 const TString AliRunLoader::fgkGAliceName("gAlice");
65 /**************************************************************************/
66
67 AliRunLoader::AliRunLoader():
68  fLoaders(0x0),
69  fEventFolder(0x0),
70  fCurrentEvent(0),
71  fGAFile(0x0),
72  fHeader(0x0),
73  fStack(0x0),
74  fKineDataLoader(0x0),
75  fTrackRefsDataLoader(0x0),
76  fNEventsPerFile(1),
77  fUnixDirName(".")
78 {
79   AliConfig::Instance();//force to build the folder structure
80   if (!fgRunLoader) fgRunLoader = this;
81 }
82 /**************************************************************************/
83
84 AliRunLoader::AliRunLoader(const char* eventfoldername):
85  TNamed(fgkRunLoaderName,fgkRunLoaderName),
86  fLoaders(new TObjArray()),
87  fEventFolder(0x0),
88  fCurrentEvent(0),
89  fGAFile(0x0),
90  fHeader(0x0),
91  fStack(0x0),
92  fKineDataLoader(new AliDataLoader(fgkDefaultKineFileName,fgkKineContainerName,"Kinematics")),
93  fTrackRefsDataLoader(new AliDataLoader(fgkDefaultTrackRefsFileName,fgkTrackRefsContainerName,"Track References")),
94  fNEventsPerFile(1),
95  fUnixDirName(".")
96 {
97 //ctor
98   SetEventFolderName(eventfoldername);
99  if (!fgRunLoader) fgRunLoader = this;
100 }
101 /**************************************************************************/
102
103 AliRunLoader::~AliRunLoader()
104 {
105 //dtor
106   if (fgRunLoader == this) fgRunLoader = 0x0;
107   
108   UnloadHeader();
109   UnloadgAlice();
110   
111   if(fLoaders) {
112     fLoaders->SetOwner();
113     delete fLoaders;
114   }
115   
116   delete fKineDataLoader;
117   delete fTrackRefsDataLoader;
118   
119   
120   RemoveEventFolder();
121   
122   //fEventFolder is deleted by the way of removing - TopAliceFolder owns it
123   delete fHeader;
124   delete fStack;
125   delete fGAFile;
126 }
127 /**************************************************************************/
128
129 AliRunLoader::AliRunLoader(TFolder* topfolder):
130  TNamed(fgkRunLoaderName,fgkRunLoaderName),
131  fLoaders(new TObjArray()),
132  fEventFolder(topfolder),
133  fCurrentEvent(0),
134  fGAFile(0x0),
135  fHeader(0x0),
136  fStack(0x0),
137  fKineDataLoader(new AliDataLoader(fgkDefaultKineFileName,fgkKineContainerName,"Kinematics")),
138  fTrackRefsDataLoader(new AliDataLoader(fgkDefaultTrackRefsFileName,fgkTrackRefsContainerName,"Track References")),
139  fNEventsPerFile(1),
140  fUnixDirName(".")
141 {
142 //ctor
143  if(topfolder == 0x0)
144   {
145     TString errmsg("Parameter is NULL");
146     Error("AliRunLoader(TFolder*)","%s",errmsg.Data());
147     throw errmsg;
148     return;
149   }
150  
151  TObject* obj = fEventFolder->FindObject(fgkRunLoaderName);
152  if (obj)
153   { //if it is, then sth. is going wrong... exits aliroot session
154     TString errmsg("In Event Folder Named ");
155     errmsg+=fEventFolder->GetName();
156     errmsg+=" object named "+fgkRunLoaderName+" already exists. I am confused ...";
157
158     Error("AliRunLoader(const char*)","%s",errmsg.Data());
159     throw errmsg;
160     return;//never reached
161   }
162
163  if (!fgRunLoader) fgRunLoader = this;
164    
165  fEventFolder->Add(this);//put myself to the folder to accessible for all
166   
167 }
168 /**************************************************************************/
169
170 Int_t AliRunLoader::GetEvent(Int_t evno)
171 {
172 //Gets event number evno
173 //Reloads all data properly
174   if (fCurrentEvent == evno) return 0;
175   
176   if (evno < 0)
177    {
178      Error("GetEvent","Can not give the event with negative number");
179      return 4;
180    }
181
182   if (evno >= GetNumberOfEvents())
183    {
184      Error("GetEvent","There is no event with number %d",evno);
185      return 3;
186    }
187   
188   if (GetDebug()) 
189    {
190      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
191      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
192      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
193      Info("GetEvent","          GETTING EVENT  %d",evno);
194      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
195      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
196      Info("GetEvent",">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
197    }
198    
199   fCurrentEvent = evno;
200
201   Int_t retval;
202   
203   //Reload header (If header was loaded)
204   if (GetHeader())
205    {
206      retval = TreeE()->GetEvent(fCurrentEvent);
207      if ( retval == 0)
208       {
209         Error("GetEvent","Cannot find event: %d\n ",fCurrentEvent);
210         return 5;
211       }
212    }
213   //Reload stack (If header was loaded)
214   if (TreeE()) fStack = GetHeader()->Stack();
215   //Set event folder in stack (it does not mean that we read kinematics from file)
216   if (fStack) 
217    { 
218      fStack->SetEventFolderName(fEventFolder->GetName());
219    }
220   else
221    {
222      Warning("GetEvent","Stack not found in header");
223    }
224   
225   retval = SetEvent();
226   if (retval)
227    {
228      Error("GetEvent","Error occured while setting event %d",evno);
229      return 1;
230    }
231    
232   //Post Track References
233   retval = fTrackRefsDataLoader->GetEvent();
234   if (retval)
235    {
236      Error("GetEvent","Error occured while GetEvent for Track References. Event %d",evno);
237      return 2;
238    }
239
240   //Read Kinematics if loaded
241   fKineDataLoader->GetEvent();
242   if (retval)
243    {
244      Error("GetEvent","Error occured while GetEvent for Kinematics. Event %d",evno);
245      return 2;
246    }
247
248   if (fStack && fKineDataLoader->GetBaseLoader(0)->IsLoaded()) fStack->GetEvent();
249   
250   //Trigger data reloading in all loaders 
251   TIter next(fLoaders);
252   AliLoader *loader;
253   while((loader = (AliLoader*)next())) 
254    {
255      retval = loader->GetEvent();
256      if (retval)
257       {
258        Error("GetEvent","Error occured while getting event for %s. Event %d.",
259               loader->GetDetectorName().Data(), evno);
260        return 3;
261       }
262    }
263   
264   SetDetectorAddresses();
265   
266   return 0;
267 }
268 /**************************************************************************/
269 Int_t AliRunLoader::SetEvent()
270 {
271 //if kinematics was loaded Cleans folder data
272
273   Int_t retval;
274   
275   retval = fKineDataLoader->SetEvent();
276   if (retval)
277    {
278      Error("SetEvent","SetEvent for Kinamtics Data Loader retutned error.");
279      return retval;
280    }
281   retval = fTrackRefsDataLoader->SetEvent(); 
282   if (retval)
283    {
284      Error("SetEvent","SetEvent for Track References Data Loader retutned error.");
285      return retval;
286    }
287
288   TIter next(fLoaders);
289   AliLoader *loader;
290   while((loader = (AliLoader*)next())) 
291    {
292      retval = loader->SetEvent();
293      if (retval)
294       {
295         Error("SetEvent","SetEvent for %s Data Loader retutned error.",loader->GetName());
296         return retval;
297       }
298    }
299
300   return 0;
301 }
302 /**************************************************************************/
303
304 Int_t AliRunLoader::SetEventNumber(Int_t evno)
305 {
306   //cleans folders and sets the root dirs in files 
307   if (fCurrentEvent == evno) return 0;
308   fCurrentEvent = evno;
309   return SetEvent();
310 }
311
312 /**************************************************************************/
313 AliRunLoader* AliRunLoader::Open
314   (const char* filename, const char* eventfoldername, Option_t* option)
315 {
316 //Opens a desired file 'filename'
317 //gets the the run-Loader and mounts it desired folder
318 //returns the pointer to run Loader which can be further used for accessing data 
319 //in case of error returns NULL
320  
321  static const TString webaddress("http://alisoft.cern.ch/people/skowron/codedoc/split/index.html");
322  if (AliLoader::GetDebug()) 
323   ::Info("AliRunLoader::Open",
324          "\n\n\nNew I/O strcture: See more info:\n %s\n\n\n",webaddress.Data());
325  
326  AliRunLoader* result = 0x0;
327  
328  /* ************************************************ */
329  /* Chceck if folder with given name already exists  */
330  /* ************************************************ */
331  
332  TObject* obj = AliConfig::Instance()->GetTopFolder()->FindObject(eventfoldername);
333  if(obj)
334   {
335     TFolder* fold = dynamic_cast<TFolder*>(obj);
336     if (fold == 0x0)
337      {
338       ::Error("AliRunLoader::Open","Such a obejct already exists in top alice folder and it is not a folder.");
339       return 0x0;
340      }
341     
342     //check if we can get RL from that folder
343     result = AliRunLoader::GetRunLoader(eventfoldername);
344     if (result == 0x0)
345      {
346        ::Error("AliRunLoader::Open",
347                "Folder %s already exists, and can not find session there. Can not mount.",eventfoldername);
348        return 0x0;
349      }
350
351     if (result->GetFileName().CompareTo(filename) != 0)
352      {
353        ::Error("AliRunLoader::Open","Other file is mounted in demanded folder. Can not mount.");
354        return 0x0;
355      }
356
357     //check if now is demanded (re)creation 
358     if ( AliLoader::TestFileOption(option) == kFALSE)
359      {
360        ::Error("AliRunLoader::Open",
361                "Session already exists in folder %s and this session option is %s. Unable to proceed.",
362                 eventfoldername,option);
363        return 0x0;
364      }
365      
366     //check if demanded option is update and existing one 
367     TString tmpstr(option);
368     if ( (tmpstr.CompareTo("update",TString::kIgnoreCase) == 0) && 
369          (result->fGAFile->IsWritable() == kFALSE) )
370      { 
371        ::Error("AliRunLoader::Open",
372                "Session already exists in folder %s and is not writable while this session option is %s. Unable to proceed.",
373                 eventfoldername,option);
374        return 0x0;
375      }
376      
377     ::Warning("AliRunLoader::Open","Session is already opened and mounted in demanded folder"); 
378     return result;
379   } //end of checking in case of existance of object named identically that folder session is being opened
380  
381  
382  TFile * gAliceFile = TFile::Open(filename,option);//open a file
383  if (!gAliceFile) 
384   {//null pointer returned
385     ::Error("AliRunLoader::Open","Can not open file %s.",filename);
386     return 0x0;
387   }
388   
389  if (gAliceFile->IsOpen() == kFALSE)
390   {//pointer to valid object returned but file is not opened
391     ::Error("AliRunLoader::Open","Can not open file %s.",filename);
392     return 0x0;
393   }
394  
395  //if file is "read" or "update" than we try to find AliRunLoader there - if not found cry and exit
396  //else create new AliRunLoader
397  if ( AliLoader::TestFileOption(option) )
398   { 
399     if (AliLoader::GetDebug()) 
400      ::Info("AliRunLoader::Open","Reading RL from file");
401     
402     result = dynamic_cast<AliRunLoader*>(gAliceFile->Get(fgkRunLoaderName));//get the run Loader from the file
403     if (result == 0x0)
404      {//didn't get
405        ::Error("AliRunLoader::Open","Can not find run-Loader in file %s.",filename);
406        delete gAliceFile;//close the file
407        return 0x0;
408      }
409     Int_t tmp = result->SetEventFolderName(eventfoldername);//mount a event folder   
410     if (tmp)//if SetEvent  returned error
411      {
412        ::Error("AliRunLoader::Open","Can not mount event in folder %s.",eventfoldername);
413        delete result; //delete run-Loader
414        delete gAliceFile;//close the file
415        return 0x0;
416      }
417   }
418  else
419   {
420     if (AliLoader::GetDebug()) 
421       ::Info("AliRunLoader::Open","Creating new AliRunLoader. Folder name is %s",eventfoldername);
422     try
423      {  
424        result = new AliRunLoader(eventfoldername);
425      }
426     catch (TString& errmsg)
427      {
428        ::Error("Open","AliRunLoader constrcutor has thrown exception: %s\n",errmsg.Data());
429        delete result;
430        delete gAliceFile;//close the file
431        return 0x0;
432      }
433   }
434  
435 //procedure for extracting dir name from the file name 
436  TString fname(filename);
437  Int_t  nsl = fname.Last('/');//look for slash in file name
438  TString dirname;
439  if (nsl < 0) 
440   {//slash not found
441     Int_t  nsl = fname.Last(':');//look for colon e.g. rfio:galice.root
442     if (nsl < 0) dirname = ".";//not found
443     else dirname = fname.Remove(nsl);//found
444   }
445  else dirname = fname.Remove(nsl);//slash found
446  
447  if (AliLoader::GetDebug()) 
448   ::Info("AliRunLoader::Open","Dir name is : %s",dirname.Data());
449  
450  result->SetDirName(dirname); 
451  result->SetGAliceFile(gAliceFile);//set the pointer to gAliceFile
452  if (!fgRunLoader) fgRunLoader = result; //PH get access from any place
453  return result;
454 }
455 /**************************************************************************/
456 Int_t AliRunLoader::GetNumberOfEvents()
457 {
458  //returns number of events in Run
459  Int_t retval;
460  if( TreeE() == 0x0 )
461   {
462     retval = LoadHeader();
463     if (retval) 
464      {
465        Error("GetNumberOfEvents","Error occured while loading header");
466        return -1;
467      }
468   }
469  return (Int_t)TreeE()->GetEntries();
470 }
471 /**************************************************************************/
472
473 void AliRunLoader::MakeHeader()
474 {
475  //Makes header and connects it to header tree (if it exists)
476   if (GetDebug()) Info("MakeHeader","");
477   if(fHeader == 0x0)
478    {
479      if (GetDebug()) Info("MakeHeader","Creating new Header Object");
480      fHeader= new AliHeader();
481    }
482   TTree* tree = TreeE();
483   if (tree)
484    {
485      if (GetDebug()) Info("MakeHeader","Got Tree from folder.");
486      TBranch* branch = tree->GetBranch(fgkHeaderBranchName);
487      if (branch == 0x0)
488       {
489         if (GetDebug()) Info("MakeHeader","Creating new branch");
490         branch = tree->Branch(fgkHeaderBranchName, "AliHeader", &fHeader, 4000, 0);
491         branch->SetAutoDelete(kFALSE);
492       }
493      else
494       {
495         if (GetDebug()) Info("MakeHeader","Got Branch from Tree");
496         branch->SetAddress(&fHeader);
497         tree->GetEvent(fCurrentEvent);
498         fStack = fHeader->Stack(); //should be safe - if we created Stack, header returns pointer to the same object
499         if (fStack)
500          {
501            fStack->SetEventFolderName(fEventFolder->GetName());
502            if (TreeK()) fStack->GetEvent();
503          }
504         else
505         {
506           if (GetDebug()) Info("MakeHeader","Haeder do not have a stack.");
507         }
508       }
509    } 
510   if (GetDebug()) Info("MakeHeader","Exiting MakeHeader method");
511 }
512 /**************************************************************************/
513
514 void AliRunLoader::MakeStack()
515 {
516 //Creates the stack object -  do not connect the tree
517   if(fStack == 0x0)
518    { 
519      fStack = new AliStack(10000);
520      fStack->SetEventFolderName(fEventFolder->GetName());
521    }
522 }
523
524 /**************************************************************************/
525
526 void AliRunLoader::MakeTree(Option_t *option)
527 {
528 //Creates trees
529   const char *oK = strstr(option,"K"); //Kine  
530   const char *oE = strstr(option,"E"); //Header
531
532   if(oK && !TreeK())
533    { 
534      if (fKineDataLoader->GetBaseLoader(0)->IsLoaded() == kFALSE)
535       {
536         Error("MakeTree(\"K\")","Load Kinematics first");
537       }
538      else
539       {
540         fKineDataLoader->MakeTree();
541         MakeStack();
542         fStack->ConnectTree();
543         WriteKinematics("OVERWRITE");
544      }
545    }
546   
547   if(oE && !TreeE())
548    { 
549      fGAFile->cd();
550      TTree* tree = new TTree(fgkHeaderContainerName,"Tree with Headers");
551      GetEventFolder()->Add(tree);
552      MakeHeader();
553      WriteHeader("OVERWRITE");
554    }
555   
556   TIter next(fLoaders);
557   AliLoader *loader;
558   while((loader = (AliLoader*)next()))
559    {
560     loader->MakeTree(option);
561    }
562
563 }
564 /**************************************************************************/
565     
566 Int_t AliRunLoader::LoadgAlice()
567 {
568 //Loads gAlice from file
569  if (GetAliRun())
570   {
571     Warning("LoadgAlice","AliRun is already in folder. Unload first.");
572     return 0;
573   }
574  AliRun* alirun = dynamic_cast<AliRun*>(fGAFile->Get(fgkGAliceName));
575  if (alirun == 0x0)
576   {
577     Error("LoadgAlice"," Can not find gAlice in file %s",fGAFile->GetName());
578     return 2;
579   }
580  alirun->SetRunLoader(this);
581  if (gAlice)
582   {
583     Warning("LoadgAlice","gAlice already exists. Putting retrived object in folder named %s",
584              GetEventFolder()->GetName());
585   }
586  else
587   {
588     gAlice = alirun;
589   }
590  SetDetectorAddresses();//calls SetTreeAddress for all detectors
591  return 0; 
592 }
593 /**************************************************************************/
594
595 Int_t AliRunLoader::LoadHeader()
596 {
597 //loads treeE and reads header object for current event
598  if (TreeE())
599   {
600      Warning("LoadHeader","Header is already loaded. Use ReloadHeader to force reload. Nothing done");
601      return 0;
602   }
603  
604  if (GetEventFolder() == 0x0)
605   {
606     Error("LoadHeader","Event folder not specified yet");
607     return 1;
608   }
609
610  if (fGAFile == 0x0)
611   {
612     Error("LoadHeader","Session not opened. Use AliRunLoader::Open");
613     return 2;
614   }
615  
616  if (fGAFile->IsOpen() == kFALSE)
617   {
618     Error("LoadHeader","Session not opened. Use AliRunLoader::Open");
619     return 2;
620   }
621
622  TTree* tree = dynamic_cast<TTree*>(fGAFile->Get(fgkHeaderContainerName));
623  if (tree == 0x0)
624   {
625     Error("LoadHeader","Can not find header tree named %s in file %s",
626            fgkHeaderContainerName.Data(),fGAFile->GetName());
627     return 2;
628   }
629
630  if (tree == TreeE()) return 0;
631
632  CleanHeader();
633  GetEventFolder()->Add(tree);
634  MakeHeader();//creates header object and connects to tree
635  return 0; 
636
637 }
638 /**************************************************************************/
639
640 Int_t AliRunLoader::LoadKinematics(Option_t* option)
641 {
642 //Loads the kinematics 
643  Int_t retval = fKineDataLoader->GetBaseLoader(0)->Load(option);
644  if (retval)
645   {
646     Error("LoadKinematics","Error occured while loading kinamatics tree.");
647     return retval;
648   }
649  if (fStack) 
650   {
651     retval = fStack->GetEvent();
652     if ( retval == kFALSE)
653      {
654        Error("LoadKinematics","Error occured while loading kinamatics tree.");
655        return retval;
656      }
657     
658   }
659  return 0;
660 }
661 /**************************************************************************/
662
663 Int_t AliRunLoader::OpenDataFile(const TString& filename,TFile*& file,TDirectory*& dir,Option_t* opt,Int_t cl)
664 {
665 //Opens File with kinematics
666  if (file)
667   {
668     if (file->IsOpen() == kFALSE)
669      {//pointer is not null but file is not opened
670        Warning("OpenDataFile","Pointer to file is not null, but file is not opened");//risky any way
671        delete file;
672        file = 0x0; //proceed with opening procedure
673      }
674     else
675      { 
676        Warning("OpenDataFile","File  %s already opened",filename.Data());
677        return 0;
678      }
679   }
680 //try to find if that file is opened somewere else
681  file = (TFile *)( gROOT->GetListOfFiles()->FindObject(filename) );
682  if (file)
683   {
684    if(file->IsOpen() == kTRUE)
685     {
686      Warning("OpenDataFile","File %s already opened by sombody else.",file->GetName());
687      return 0;
688     }
689   }
690
691  file = TFile::Open(filename,opt);
692  if (file == 0x0)
693   {//file is null
694     Error("LoadKinematics","Can not open file %s",filename.Data());
695     return 1;
696   }
697  if (file->IsOpen() == kFALSE)
698   {//file is not opened
699    Error("LoadKinematics","Can not open file %s",filename.Data());
700    return 1;
701   }
702   
703  file->SetCompressionLevel(cl);
704  
705  dir = AliLoader::ChangeDir(file,fCurrentEvent);
706  if (dir == 0x0)
707   {
708     Error("OpenKineFile","Can not change to root directory in file %s",filename.Data());
709     return 3;
710   }
711  return 0; 
712 }
713 /**************************************************************************/
714
715 TTree* AliRunLoader::TreeE() const
716 {
717  //returns the tree from folder; shortcut method
718  if (GetDebug() > 10) fEventFolder->ls();
719  TObject *obj = fEventFolder->FindObject(fgkHeaderContainerName);
720  return (obj)?dynamic_cast<TTree*>(obj):0x0;
721 }
722 /**************************************************************************/
723
724 AliHeader* AliRunLoader::GetHeader() const
725 {
726 //returns pointer header object
727  return fHeader;
728 }
729 /**************************************************************************/
730  
731 TTree* AliRunLoader::TreeK() const
732 {
733  //returns the tree from folder; shortcut method
734  TObject *obj = GetEventFolder()->FindObject(fgkKineContainerName);
735  return (obj)?dynamic_cast<TTree*>(obj):0x0;
736 }
737 /**************************************************************************/
738
739 TTree* AliRunLoader::TreeTR() const
740 {
741  //returns the tree from folder; shortcut method
742  TObject* obj = GetEventFolder()->FindObject(fgkTrackRefsContainerName);
743  return (obj)?dynamic_cast<TTree*>(obj):0x0;
744 }
745 /**************************************************************************/
746
747 AliRun* AliRunLoader::GetAliRun() const
748 {
749 //returns AliRun which sits in the folder
750  if (fEventFolder == 0x0) return 0x0;
751  TObject *obj = fEventFolder->FindObject(fgkGAliceName);
752  return (obj)?dynamic_cast<AliRun*>(obj):0x0;
753 }
754 /**************************************************************************/
755
756 Int_t AliRunLoader::WriteGeometry(Option_t* /*opt*/)
757 {
758 //writes geometry to the file
759   fGAFile->cd();
760   TGeometry* geo = GetAliRun()->GetGeometry();
761   if (geo == 0x0)
762    {
763      Error("WriteGeometry","Can not get geometry from gAlice");
764      return 1;
765    }
766   geo->Write();
767   return 0;
768 }
769 /**************************************************************************/
770
771 Int_t AliRunLoader::WriteHeader(Option_t* opt)
772 {
773 //writes treeE
774   if (GetDebug()) Info("WriteHeader","  WRITING HEADER");
775   
776   TTree* tree = TreeE();
777   if ( tree == 0x0)
778    {
779      Warning("WriteHeader","Can not find Header Tree in Folder");
780      return 0;
781    } 
782   if (fGAFile->IsWritable() == kFALSE)
783    {
784      Error("WriteHeader","File %s is not writable",fGAFile->GetName());
785      return 1;
786    }
787
788   TObject* obj = fGAFile->Get(fgkHeaderContainerName);
789   if (obj)
790    { //if they exist, see if option OVERWRITE is used
791      TString tmp(opt);
792      if(tmp.Contains("OVERWRITE",TString::kIgnoreCase) == 0)
793       {//if it is not used -  give an error message and return an error code
794         Error("WriteHeader","Tree already exisists. Use option \"OVERWRITE\" to overwrite previous data");
795         return 3;
796       }
797    }
798   fGAFile->cd();
799   tree->SetDirectory(fGAFile);
800   tree->Write(0,TObject::kOverwrite);
801
802   if (GetDebug()) Info("WriteHeader","WRITTEN\n\n");
803   
804   return 0;
805 }
806 /**************************************************************************/
807
808 Int_t AliRunLoader::WriteAliRun(Option_t* /*opt*/)
809 {
810 //writes AliRun object to the file
811   fGAFile->cd();
812   if (GetAliRun()) GetAliRun()->Write();
813   return 0;
814 }
815 /**************************************************************************/
816
817 Int_t AliRunLoader::WriteKinematics(Option_t* opt)
818 {
819 //writes Kinematics
820   return fKineDataLoader->GetBaseLoader(0)->WriteData(opt);
821 }
822 /**************************************************************************/
823 Int_t AliRunLoader::WriteTrackRefs(Option_t* opt)
824 {
825 //writes Track References tree
826   return fTrackRefsDataLoader->GetBaseLoader(0)->WriteData(opt);
827 }
828 /**************************************************************************/
829
830 Int_t AliRunLoader::WriteHits(Option_t* opt)
831 {
832 //Calls WriteHits for all loaders
833   Int_t res;
834   Int_t result = 0;
835   TIter next(fLoaders);
836   AliLoader *loader;
837   while((loader = (AliLoader*)next()))
838    {
839      res = loader->WriteHits(opt);
840      if (res)
841       {
842         Error("WriteHits","Failed to write hits for %s (%d)",loader->GetDetectorName().Data(),res);
843         result = 1;
844       }
845    }
846   return result;
847 }
848 /**************************************************************************/
849
850 Int_t AliRunLoader::WriteSDigits(Option_t* opt)
851 {
852 //Calls WriteSDigits for all loaders
853   Int_t res;
854   Int_t result = 0;
855   TIter next(fLoaders);
856   AliLoader *loader;
857   while((loader = (AliLoader*)next()))
858    {
859      res = loader->WriteSDigits(opt);
860      if (res)
861       {
862         Error("WriteSDigits","Failed to write summable digits for %s.",loader->GetDetectorName().Data());
863         result = 1;
864       }
865    }
866   return result;
867 }
868 /**************************************************************************/
869
870 Int_t AliRunLoader::WriteDigits(Option_t* opt)
871 {
872 //Calls WriteDigits for all loaders
873   Int_t res;
874   Int_t result = 0;
875   TIter next(fLoaders);
876   AliLoader *loader;
877   while((loader = (AliLoader*)next()))
878    { 
879      res = loader->WriteDigits(opt);
880      if (res)
881       {
882         Error("WriteDigits","Failed to write digits for %s.",loader->GetDetectorName().Data());
883         result = 1;
884       }
885    }
886   return result;
887 }
888 /**************************************************************************/
889
890 Int_t AliRunLoader::WriteRecPoints(Option_t* opt)
891 {
892 //Calls WriteRecPoints for all loaders
893   Int_t res;
894   Int_t result = 0;
895   TIter next(fLoaders);
896   AliLoader *loader;
897   while((loader = (AliLoader*)next()))
898    {
899      res = loader->WriteRecPoints(opt);
900      if (res)
901       {
902         Error("WriteRecPoints","Failed to write Reconstructed Points for %s.",
903               loader->GetDetectorName().Data());
904         result = 1;
905       }
906    }
907   return result;
908 }
909 /**************************************************************************/
910
911 Int_t AliRunLoader::WriteTracks(Option_t* opt)
912 {
913 //Calls WriteTracks for all loaders
914   Int_t res;
915   Int_t result = 0;
916   TIter next(fLoaders);
917   AliLoader *loader;
918   while((loader = (AliLoader*)next()))
919    {
920      res = loader->WriteTracks(opt);
921      if (res)
922       {
923         Error("WriteTracks","Failed to write Tracks for %s.",
924               loader->GetDetectorName().Data());
925         result = 1;
926       }
927    }
928   return result;
929 }
930 /**************************************************************************/
931
932 Int_t AliRunLoader::WriteRunLoader(Option_t* /*opt*/)
933 {
934 //Writes itself to the file
935   CdGAFile();
936   this->Write(0,TObject::kOverwrite);
937   return 0;
938 }
939 /**************************************************************************/
940
941 Int_t AliRunLoader::SetEventFolderName(const TString& name)
942 {  
943 //sets top folder name for this run; of alread
944   if (name.IsNull())
945    {
946      Error("SetTopFolderName","Name is empty");
947      return 1;
948    }
949   
950   //check if such a folder already exists - try to find it in alice top folder
951   TObject* obj = AliConfig::Instance()->GetTopFolder()->FindObject(name);
952   if(obj)
953    {
954      TFolder* fold = dynamic_cast<TFolder*>(obj);
955      if (fold == 0x0)
956       {
957        Error("SetTopFolderName","Such a obejct already exists in top alice folder and it is not a folder.");
958        return 2;
959       }
960      //folder which was found is our folder
961      if (fEventFolder == fold)
962       {
963        return 0;
964       }
965      else
966       {
967        Error("SetTopFolderName","Such a folder already exists in top alice folder. Can not mount.");
968        return 2;
969       }
970    }
971
972   //event is alredy connected, just change name of the folder
973   if (fEventFolder) 
974    {
975      fEventFolder->SetName(name);
976      return 0;
977    }
978
979   if (fKineDataLoader == 0x0)
980     fKineDataLoader = new AliDataLoader(fgkDefaultKineFileName,fgkKineContainerName,"Kinematics");
981
982   if ( fTrackRefsDataLoader == 0x0)
983     fTrackRefsDataLoader = new AliDataLoader(fgkDefaultTrackRefsFileName,fgkTrackRefsContainerName,"Track References");
984    
985   //build the event folder structure
986   if (GetDebug()) Info("SetEventFolderName","Creating new event folder named %s",name.Data());
987   fEventFolder = AliConfig::Instance()->BuildEventFolder(name,"Event Folder");
988   fEventFolder->Add(this);//put myself to the folder to accessible for all
989   
990   if (Stack()) Stack()->SetEventFolderName(fEventFolder->GetName());
991   TIter next(fLoaders);
992   AliLoader *loader;
993   while((loader = (AliLoader*)next()))
994    {
995      loader->Register(fEventFolder);//build folder structure for this detector
996    }
997   
998   fKineDataLoader->SetEventFolder(GetEventFolder());
999   fTrackRefsDataLoader->SetEventFolder(GetEventFolder());
1000   fKineDataLoader->SetFolder(GetEventFolder());
1001   fTrackRefsDataLoader->SetFolder(GetEventFolder());
1002   
1003   fEventFolder->SetOwner();
1004   return 0;
1005 }
1006 /**************************************************************************/
1007
1008 void AliRunLoader::AddLoader(AliLoader* loader)
1009  {
1010  //Adds the Loader for given detector 
1011   if (loader == 0x0) //if null shout and exit
1012    {
1013      Error("AddLoader","Parameter is NULL");
1014      return;
1015    }
1016   loader->SetDirName(fUnixDirName);
1017   if (fEventFolder) loader->SetEventFolder(fEventFolder); //if event folder is already defined, 
1018                                                           //pass information to the Loader
1019   fLoaders->Add(loader);//add the Loader to the array
1020  }
1021 /**************************************************************************/
1022
1023 void AliRunLoader::AddLoader(AliDetector* det)
1024  {
1025 //Asks module (detector) ro make a Loader and stores in the array
1026    if (det == 0x0) return;
1027    AliLoader* get = det->GetLoader();//try to get loader
1028    if (get == 0x0)  get = det->MakeLoader(fEventFolder->GetName());//if did not obtain, ask to make it
1029
1030    if (get) 
1031     {
1032       if (GetDebug()) Info("AddLoader","Detector: %s   Loader : %s",det->GetName(),get->GetName());
1033       AddLoader(get);
1034     }
1035  }
1036
1037 /**************************************************************************/
1038
1039 AliLoader* AliRunLoader::GetLoader(const char* detname) const
1040 {
1041 //returns loader for given detector
1042 //note that naming convention is TPCLoader not just TPC
1043   return (AliLoader*)fLoaders->FindObject(detname);
1044 }
1045
1046 /**************************************************************************/
1047
1048 AliLoader* AliRunLoader::GetLoader(AliDetector* det) const
1049 {
1050 //get loader for detector det
1051  if(det == 0x0) return 0x0;
1052  TString getname(det->GetName());
1053  getname+="Loader";
1054  if (GetDebug()) Info("GetLoader(AliDetector* det)"," Loader name is %s",getname.Data());
1055  return GetLoader(getname);
1056 }
1057
1058 /**************************************************************************/
1059
1060 void AliRunLoader::CleanFolders()
1061 {
1062 //  fEventFolder->Add(this);//put myself to the folder to accessible for all
1063
1064   CleanDetectors();
1065   CleanHeader();
1066   CleanKinematics();
1067 }
1068 /**************************************************************************/
1069
1070 void AliRunLoader::CleanDetectors()
1071 {
1072 //Calls CleanFolders for all detectors
1073   TIter next(fLoaders);
1074   AliLoader *loader;
1075   while((loader = (AliLoader*)next())) 
1076    {
1077      loader->CleanFolders();
1078    }
1079 }
1080 /**************************************************************************/
1081
1082 void AliRunLoader::RemoveEventFolder()
1083 {
1084 //remove all the tree of event 
1085 //all the stuff changing EbE stays untached (PDGDB, tasks, etc.)
1086
1087  if (fEventFolder == 0x0) return;
1088  fEventFolder->SetOwner(kFALSE);//don't we want to deleted while removing the folder that we are sitting in
1089  fEventFolder->Remove(this);//remove us drom folder
1090  
1091  AliConfig::Instance()->GetTopFolder()->SetOwner(); //brings ownership back for fEventFolder since it sits in top folder
1092  AliConfig::Instance()->GetTopFolder()->Remove(fEventFolder); //remove the event tree
1093  delete fEventFolder;
1094 }
1095 /**************************************************************************/
1096
1097 void AliRunLoader::SetGAliceFile(TFile* gafile)
1098 {
1099 //sets pointer to galice.root file
1100  fGAFile = gafile;
1101 }
1102
1103 /**************************************************************************/
1104
1105 Int_t AliRunLoader::LoadHits(Option_t* detectors,Option_t* opt)
1106 {
1107 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1108
1109   if (GetDebug()) Info("LoadHits","Loading Hits");
1110   TObjArray* loaders;
1111   TObjArray arr;
1112
1113   const char* oAll = strstr(detectors,"all");
1114   if (oAll)
1115    {
1116      if (GetDebug()) Info("LoadHits","Option is All");
1117      loaders = fLoaders;
1118    }
1119   else
1120    {
1121      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1122      loaders = &arr;//get the pointer array
1123    }   
1124
1125   if (GetDebug()) Info("LoadHits","For detectors. Number of detectors chosen for loading %d",loaders->GetEntries());
1126   
1127   TIter next(loaders);
1128   AliLoader *loader;
1129   while((loader = (AliLoader*)next())) 
1130    {
1131     if (GetDebug()) Info("LoadHits","    Calling LoadHits(%s) for %s",opt,loader->GetName());
1132     loader->LoadHits(opt);
1133    }
1134   if (GetDebug()) Info("LoadHits","Done");
1135   return 0;
1136
1137
1138 /**************************************************************************/
1139
1140 Int_t AliRunLoader::LoadSDigits(Option_t* detectors,Option_t* opt)
1141 {
1142 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1143
1144   TObjArray* loaders;
1145   TObjArray arr;
1146
1147   const char* oAll = strstr(detectors,"all");
1148   if (oAll)
1149    {
1150      loaders = fLoaders;
1151    }
1152   else
1153    {
1154      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1155      loaders = &arr;//get the pointer to array
1156    }   
1157
1158   TIter next(loaders);
1159   AliLoader *loader;
1160   while((loader = (AliLoader*)next())) 
1161    {
1162     loader->LoadSDigits(opt);
1163    }
1164   return 0;
1165
1166
1167 /**************************************************************************/
1168
1169 Int_t AliRunLoader::LoadDigits(Option_t* detectors,Option_t* opt)
1170 {
1171 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1172
1173   TObjArray* loaders;
1174   TObjArray arr;
1175
1176   const char* oAll = strstr(detectors,"all");
1177   if (oAll)
1178    {
1179      loaders = fLoaders;
1180    }
1181   else
1182    {
1183      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1184      loaders = &arr;//get the pointer array
1185    }   
1186
1187   TIter next(loaders);
1188   AliLoader *loader;
1189   while((loader = (AliLoader*)next())) 
1190    {
1191     loader->LoadDigits(opt);
1192    }
1193   return 0;
1194
1195 /**************************************************************************/
1196
1197 Int_t AliRunLoader::LoadRecPoints(Option_t* detectors,Option_t* opt)
1198 {
1199 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1200
1201   TObjArray* loaders;
1202   TObjArray arr;
1203
1204   const char* oAll = strstr(detectors,"all");
1205   if (oAll)
1206    {
1207      loaders = fLoaders;
1208    }
1209   else
1210    {
1211      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1212      loaders = &arr;//get the pointer array
1213    }   
1214
1215   TIter next(loaders);
1216   AliLoader *loader;
1217   while((loader = (AliLoader*)next())) 
1218    {
1219     loader->LoadRecPoints(opt);
1220    }
1221   return 0;
1222
1223 /**************************************************************************/
1224
1225 Int_t AliRunLoader::LoadRecParticles(Option_t* detectors,Option_t* opt)
1226 {
1227 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1228
1229   TObjArray* loaders;
1230   TObjArray arr;
1231
1232   const char* oAll = strstr(detectors,"all");
1233   if (oAll)
1234    {
1235      loaders = fLoaders;
1236    }
1237   else
1238    {
1239      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1240      loaders = &arr;//get the pointer array
1241    }   
1242
1243   TIter next(loaders);
1244   AliLoader *loader;
1245   while((loader = (AliLoader*)next())) 
1246    {
1247     loader->LoadRecParticles(opt);
1248    }
1249   return 0;
1250
1251 /**************************************************************************/
1252
1253 Int_t AliRunLoader::LoadTracks(Option_t* detectors,Option_t* opt)
1254 {
1255 //LoadHits in selected detectors i.e. detectors="ITS TPC TRD" or "all"
1256
1257   TObjArray* loaders;
1258   TObjArray arr;
1259
1260   const char* oAll = strstr(detectors,"all");
1261   if (oAll)
1262    {
1263      loaders = fLoaders;
1264    }
1265   else
1266    {
1267      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1268      loaders = &arr;//get the pointer array
1269    }   
1270
1271   TIter next(loaders);
1272   AliLoader *loader;
1273   while((loader = (AliLoader*)next())) 
1274    {
1275     loader->LoadTracks(opt);
1276    }
1277   return 0;
1278
1279 /**************************************************************************/
1280
1281 void AliRunLoader::UnloadHits(Option_t* detectors)
1282 {
1283   //unloads hits for detectors specified in parameter
1284   TObjArray* loaders;
1285   TObjArray arr;
1286
1287   const char* oAll = strstr(detectors,"all");
1288   if (oAll)
1289    {
1290      loaders = fLoaders;
1291    }
1292   else
1293    {
1294      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1295      loaders = &arr;//get the pointer to array
1296    }   
1297
1298   TIter next(loaders);
1299   AliLoader *loader;
1300   while((loader = (AliLoader*)next())) 
1301    {
1302     loader->UnloadHits();
1303    }
1304 }
1305 /**************************************************************************/
1306
1307 void AliRunLoader::UnloadSDigits(Option_t* detectors)
1308 {
1309   //unloads SDigits for detectors specified in parameter
1310   TObjArray* loaders;
1311   TObjArray arr;
1312
1313   const char* oAll = strstr(detectors,"all");
1314   if (oAll)
1315    {
1316      loaders = fLoaders;
1317    }
1318   else
1319    {
1320      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1321      loaders = &arr;//get the pointer to array
1322    }   
1323
1324   TIter next(loaders);
1325   AliLoader *loader;
1326   while((loader = (AliLoader*)next())) 
1327    {
1328     loader->UnloadSDigits();
1329    }
1330 }
1331 /**************************************************************************/
1332
1333 void AliRunLoader::UnloadDigits(Option_t* detectors)
1334 {
1335   //unloads Digits for detectors specified in parameter
1336   TObjArray* loaders;
1337   TObjArray arr;
1338
1339   const char* oAll = strstr(detectors,"all");
1340   if (oAll)
1341    {
1342      loaders = fLoaders;
1343    }
1344   else
1345    {
1346      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1347      loaders = &arr;//get the pointer to array
1348    }   
1349
1350   TIter next(loaders);
1351   AliLoader *loader;
1352   while((loader = (AliLoader*)next())) 
1353    {
1354     loader->UnloadDigits();
1355    }
1356 }
1357 /**************************************************************************/
1358
1359 void AliRunLoader::UnloadRecPoints(Option_t* detectors)
1360 {
1361   //unloads RecPoints for detectors specified in parameter
1362   TObjArray* loaders;
1363   TObjArray arr;
1364
1365   const char* oAll = strstr(detectors,"all");
1366   if (oAll)
1367    {
1368      loaders = fLoaders;
1369    }
1370   else
1371    {
1372      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1373      loaders = &arr;//get the pointer to array
1374    }   
1375
1376   TIter next(loaders);
1377   AliLoader *loader;
1378   while((loader = (AliLoader*)next())) 
1379    {
1380     loader->UnloadRecPoints();
1381    }
1382 }
1383 /**************************************************************************/
1384
1385 void AliRunLoader::UnloadAll(Option_t* detectors)
1386 {
1387   //calls UnloadAll for detectors names specified in parameter
1388   // option "all" passed can be passed
1389   TObjArray* loaders;
1390   TObjArray arr;
1391
1392   const char* oAll = strstr(detectors,"all");
1393   if (oAll)
1394    {
1395      loaders = fLoaders;
1396    }
1397   else
1398    {
1399      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1400      loaders = &arr;//get the pointer to array
1401    }   
1402
1403   TIter next(loaders);
1404   AliLoader *loader;
1405   while((loader = (AliLoader*)next())) 
1406    {
1407     loader->UnloadAll();
1408    }
1409 }
1410 /**************************************************************************/
1411
1412 void AliRunLoader::UnloadTracks(Option_t* detectors)
1413 {
1414   //unloads Tracks for detectors specified in parameter
1415   TObjArray* loaders;
1416   TObjArray arr;
1417
1418   const char* oAll = strstr(detectors,"all");
1419   if (oAll)
1420    {
1421      loaders = fLoaders;
1422    }
1423   else
1424    {
1425      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1426      loaders = &arr;//get the pointer to array
1427    }   
1428
1429   TIter next(loaders);
1430   AliLoader *loader;
1431   while((loader = (AliLoader*)next())) 
1432    {
1433     loader->UnloadTracks();
1434    }
1435 }
1436 /**************************************************************************/
1437
1438 void AliRunLoader::UnloadRecParticles(Option_t* detectors)
1439 {
1440   //unloads Particles for detectors specified in parameter
1441   TObjArray* loaders;
1442   TObjArray arr;
1443
1444   const char* oAll = strstr(detectors,"all");
1445   if (oAll)
1446    {
1447      loaders = fLoaders;
1448    }
1449   else
1450    {
1451      GetListOfDetectors(detectors,arr);//this method looks for all Loaders corresponding to names (many) specified in detectors option
1452      loaders = &arr;//get the pointer to array
1453    }   
1454
1455   TIter next(loaders);
1456   AliLoader *loader;
1457   while((loader = (AliLoader*)next())) 
1458    {
1459     loader->UnloadRecParticles();
1460    }
1461 }
1462 /**************************************************************************/
1463
1464 AliRunLoader* AliRunLoader::GetRunLoader(const char* eventfoldername)
1465 {
1466 //returns RunLoader from folder named eventfoldername
1467   TFolder* evfold= dynamic_cast<TFolder*>(AliConfig::Instance()->GetTopFolder()->FindObject(eventfoldername));
1468   if (evfold == 0x0)
1469    {
1470      return 0x0;
1471    }
1472   AliRunLoader* runget = dynamic_cast<AliRunLoader*>(evfold->FindObject(AliRunLoader::fgkRunLoaderName));
1473   return runget;
1474   
1475 }
1476 /**************************************************************************/
1477
1478 AliLoader* AliRunLoader::GetDetectorLoader(const char* detname, const char* eventfoldername)
1479 {
1480 //get the loader of the detector with the given name from the global
1481 //run loader object
1482   AliRunLoader* runLoader = GetRunLoader(eventfoldername);
1483   if (!runLoader) {
1484     ::Error("AliRunLoader::GetDetectorLoader","No run loader found");
1485     return NULL;
1486   }
1487   return runLoader->GetDetectorLoader(detname);
1488 }
1489 /**************************************************************************/
1490
1491 AliLoader* AliRunLoader::GetDetectorLoader(const char* detname)
1492 {
1493 //get the loader of the detector with the given name from the global
1494 //run loader object
1495   
1496   char loadername[256];
1497   sprintf(loadername, "%sLoader", detname);
1498   AliLoader* loader = GetLoader(loadername);
1499   if (!loader) {
1500     Error("GetDetectorLoader", "No loader for %s found", detname);
1501     return NULL;
1502   }
1503   return loader;
1504 }
1505 /**************************************************************************/
1506
1507 TTree* AliRunLoader::GetTreeH(const char* detname, Bool_t maketree, const char* eventfoldername)
1508 {
1509 //get the tree with hits of the detector with the given name
1510 //if maketree is true and the tree does not exist, the tree is created
1511   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1512   if (!loader) return NULL;
1513   if (!loader->TreeH() && maketree) loader->MakeTree("H");
1514   return loader->TreeH();
1515 }
1516
1517 /**************************************************************************/
1518
1519 TTree* AliRunLoader::GetTreeH(const char* detname, Bool_t maketree)
1520 {
1521 //get the tree with hits of the detector with the given name
1522 //if maketree is true and the tree does not exist, the tree is created
1523   AliLoader* loader = GetDetectorLoader(detname);
1524   if (!loader) return NULL;
1525   if (!loader->TreeH() && maketree) loader->MakeTree("H");
1526   return loader->TreeH();
1527 }
1528 /**************************************************************************/
1529
1530 TTree* AliRunLoader::GetTreeS(const char* detname, Bool_t maketree,const char* eventfoldername)
1531 {
1532 //get the tree with summable digits of the detector with the given name
1533 //if maketree is true and the tree does not exist, the tree is created
1534   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1535   if (!loader) return NULL;
1536   if (!loader->TreeS() && maketree) loader->MakeTree("S");
1537   return loader->TreeS();
1538 }
1539 /**************************************************************************/
1540
1541 TTree* AliRunLoader::GetTreeS(const char* detname, Bool_t maketree)
1542 {
1543 //get the tree with summable digits of the detector with the given name
1544 //if maketree is true and the tree does not exist, the tree is created
1545   AliLoader* loader = GetDetectorLoader(detname);
1546   if (!loader) return NULL;
1547   if (!loader->TreeS() && maketree) loader->MakeTree("S");
1548   return loader->TreeS();
1549 }
1550 /**************************************************************************/
1551
1552 TTree* AliRunLoader::GetTreeD(const char* detname, Bool_t maketree,const char* eventfoldername)
1553 {
1554 //get the tree with digits of the detector with the given name
1555 //if maketree is true and the tree does not exist, the tree is created
1556   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1557   if (!loader) return NULL;
1558   if (!loader->TreeD() && maketree) loader->MakeTree("D");
1559   return loader->TreeD();
1560 }
1561 /**************************************************************************/
1562
1563 TTree* AliRunLoader::GetTreeD(const char* detname, Bool_t maketree)
1564 {
1565 //get the tree with digits of the detector with the given name
1566 //if maketree is true and the tree does not exist, the tree is created
1567   AliLoader* loader = GetDetectorLoader(detname);
1568   if (!loader) return NULL;
1569   if (!loader->TreeD() && maketree) loader->MakeTree("D");
1570   return loader->TreeD();
1571 }
1572 /**************************************************************************/
1573 TTree* AliRunLoader::GetTreeR(const char* detname, Bool_t maketree,const char* eventfoldername)
1574 {
1575 //get the tree with clusters of the detector with the given name
1576 //if maketree is true and the tree does not exist, the tree is created
1577   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1578   if (!loader) return NULL;
1579   if (!loader->TreeR() && maketree) loader->MakeTree("R");
1580   return loader->TreeR();
1581 }
1582 /**************************************************************************/
1583
1584 TTree* AliRunLoader::GetTreeR(const char* detname, Bool_t maketree)
1585 {
1586 //get the tree with clusters of the detector with the given name
1587 //if maketree is true and the tree does not exist, the tree is created
1588   AliLoader* loader = GetDetectorLoader(detname);
1589   if (!loader) return NULL;
1590   if (!loader->TreeR() && maketree) loader->MakeTree("R");
1591   return loader->TreeR();
1592 }
1593 /**************************************************************************/
1594
1595 TTree* AliRunLoader::GetTreeT(const char* detname, Bool_t maketree,const char* eventfoldername)
1596 {
1597 //get the tree with tracks of the detector with the given name
1598 //if maketree is true and the tree does not exist, the tree is created
1599   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1600   if (!loader) return NULL;
1601   if (!loader->TreeT() && maketree) loader->MakeTree("T");
1602   return loader->TreeT();
1603 }
1604 /**************************************************************************/
1605
1606 TTree* AliRunLoader::GetTreeT(const char* detname, Bool_t maketree)
1607 {
1608 //get the tree with tracks of the detector with the given name
1609 //if maketree is true and the tree does not exist, the tree is created
1610   AliLoader* loader = GetDetectorLoader(detname);
1611   if (!loader) return NULL;
1612   if (!loader->TreeT() && maketree) loader->MakeTree("T");
1613   return loader->TreeT();
1614 }
1615 /**************************************************************************/
1616
1617 TTree* AliRunLoader::GetTreeP(const char* detname, Bool_t maketree,const char* eventfoldername)
1618 {
1619 //get the tree with particles of the detector with the given name
1620 //if maketree is true and the tree does not exist, the tree is created
1621   AliLoader* loader = GetDetectorLoader(detname,eventfoldername);
1622   if (!loader) return NULL;
1623   if (!loader->TreeP() && maketree) loader->MakeTree("P");
1624   return loader->TreeP();
1625 }
1626 /**************************************************************************/
1627
1628 TTree* AliRunLoader::GetTreeP(const char* detname, Bool_t maketree)
1629 {
1630 //get the tree with particles of the detector with the given name
1631 //if maketree is true and the tree does not exist, the tree is created
1632   AliLoader* loader = GetDetectorLoader(detname);
1633   if (!loader) return NULL;
1634   if (!loader->TreeP() && maketree) loader->MakeTree("P");
1635   return loader->TreeP();
1636 }
1637
1638 /**************************************************************************/
1639
1640 void AliRunLoader::CdGAFile()
1641 {
1642 //sets gDirectory to galice file
1643 //work around 
1644   if(fGAFile) fGAFile->cd();
1645 }
1646  
1647 /**************************************************************************/
1648
1649 void AliRunLoader::GetListOfDetectors(const char * namelist,TObjArray& pointerarray) const
1650  {
1651 //this method looks for all Loaders corresponding 
1652 //to names (many) specified in namelist i.e. namelist ("ITS TPC TRD")
1653   
1654    char buff[10];
1655    char dets [200];
1656    strcpy(dets,namelist);//compiler cries when char* = const Option_t*;
1657    dets[strlen(dets)+1] = '\n';//set endl at the end of string 
1658    char* pdet = dets;
1659    Int_t tmp;
1660    for(;;)
1661     {
1662       tmp = sscanf(pdet,"%s",buff);//read the string from the input string pdet into buff
1663       if ( (buff[0] == 0) || (tmp == 0) ) break; //if not read
1664      
1665       pdet = strstr(pdet,buff) + strlen(buff);//move the input pointer about number of bytes (letters) read
1666       //I am aware that is a little complicated. I don't know the number of spaces between detector names
1667       //so I read the string, than I find where it starts (strstr) and move the pointer about length of a string
1668       //If there is a better way, please write me (Piotr.Skowronski@cern.ch)
1669       //construct the Loader name
1670       TString getname(buff);
1671       getname+="Loader";
1672       AliLoader* loader = GetLoader(getname);//get the Loader
1673       if (loader)
1674        {
1675         pointerarray.Add(loader);
1676        }
1677       else
1678        {
1679         Error("GetListOfDetectors","Can not find Loader for %s",buff);
1680        }
1681         
1682       buff[0] = 0;
1683     }
1684  }
1685 /*****************************************************************************/ 
1686
1687 void AliRunLoader::Clean(const TString& name)
1688 {
1689 //removes object with given name from event folder and deletes it
1690   if (GetEventFolder() == 0x0) return;
1691   TObject* obj = GetEventFolder()->FindObject(name);
1692   if(obj)
1693    {
1694      if (GetDebug()) Info("Clean(const TString&)","name=%s, cleaning %s.",GetName(),name.Data());
1695      GetEventFolder()->Remove(obj);
1696      delete obj;
1697    }
1698 }
1699
1700 /*****************************************************************************/ 
1701
1702 TTask* AliRunLoader::GetRunDigitizer()
1703 {
1704 //returns Run Digitizer from folder
1705
1706  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1707  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetDigitizerTaskName());
1708  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1709 }
1710 /*****************************************************************************/ 
1711
1712 TTask* AliRunLoader::GetRunSDigitizer()
1713 {
1714 //returns SDigitizer Task from folder
1715
1716  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1717  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetSDigitizerTaskName());
1718  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1719 }
1720 /*****************************************************************************/ 
1721
1722 TTask* AliRunLoader::GetRunReconstructioner()
1723 {
1724 //returns Reconstructioner Task from folder
1725  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1726  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetReconstructionerTaskName());
1727  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1728 }
1729 /*****************************************************************************/ 
1730
1731 TTask* AliRunLoader::GetRunTracker()
1732 {
1733 //returns Tracker Task from folder
1734  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1735  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetTrackerTaskName());
1736  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1737 }
1738 /*****************************************************************************/ 
1739
1740 TTask* AliRunLoader::GetRunPIDTask()
1741 {
1742 //returns Tracker Task from folder
1743  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1744  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetPIDTaskName());
1745  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1746 }
1747 /*****************************************************************************/ 
1748
1749 TTask* AliRunLoader::GetRunQATask()
1750 {
1751 //returns Quality Assurance Task from folder
1752  TFolder* topf = AliConfig::Instance()->GetTaskFolder();
1753  if (topf == 0x0)
1754   {
1755     ::Error("AliRunLoader::GetRunQATask","Can not get task folder from AliConfig");
1756     return 0x0;
1757   }
1758  TObject* obj = topf->FindObjectAny(AliConfig::Instance()->GetQATaskName());
1759  return (obj)?dynamic_cast<TTask*>(obj):0x0;
1760 }
1761
1762 /*****************************************************************************/ 
1763
1764 void AliRunLoader::SetCompressionLevel(Int_t cl)
1765 {
1766 //Sets Compression Level in all files
1767  if (fGAFile) fGAFile->SetCompressionLevel(cl);
1768  SetKineComprLevel(cl);
1769  SetTrackRefsComprLevel(cl);
1770  TIter next(fLoaders);
1771  AliLoader *loader;
1772  while((loader = (AliLoader*)next()))
1773   {
1774    loader->SetCompressionLevel(cl);
1775   }
1776 }
1777 /**************************************************************************/
1778
1779 void AliRunLoader::SetKineComprLevel(Int_t cl)
1780 {
1781 //Sets comression level in Kine File
1782   fKineDataLoader->SetCompressionLevel(cl);
1783 }
1784 /**************************************************************************/
1785
1786 void AliRunLoader::SetTrackRefsComprLevel(Int_t cl)
1787 {
1788 //Sets comression level in Track Refences File
1789   fTrackRefsDataLoader->SetCompressionLevel(cl);
1790 }
1791 /**************************************************************************/
1792
1793 void AliRunLoader::UnloadHeader()
1794 {
1795  //removes TreeE from folder and deletes it
1796  // as well as fHeader object
1797  CleanHeader();
1798  delete fHeader;
1799  fHeader = 0x0;
1800 }
1801 /**************************************************************************/
1802
1803 void AliRunLoader::UnloadKinematics()
1804 {
1805 //Unloads Kinematics
1806  fKineDataLoader->GetBaseLoader(0)->Unload();
1807 }
1808 /**************************************************************************/
1809
1810 void AliRunLoader::UnloadTrackRefs()
1811 {
1812 //Unloads Track Refernces
1813  fTrackRefsDataLoader->GetBaseLoader(0)->Unload();
1814 }
1815 /**************************************************************************/
1816
1817 void AliRunLoader::UnloadgAlice()
1818 {
1819 //Unloads gAlice
1820  if (gAlice == GetAliRun())
1821   {
1822    if (GetDebug()) Info("UnloadgAlice","Set gAlice = 0x0");
1823    gAlice = 0x0;//if gAlice is the same that in folder (to be deleted by the way of folder)
1824   }
1825  AliRun* alirun = GetAliRun();
1826  if (GetEventFolder()) GetEventFolder()->Remove(alirun);
1827  delete alirun;
1828 }
1829 /**************************************************************************/
1830
1831 void  AliRunLoader::MakeTrackRefsContainer()
1832 {
1833 // Makes a tree for Track References
1834   fTrackRefsDataLoader->MakeTree();
1835 }
1836 /**************************************************************************/
1837
1838 Int_t AliRunLoader::LoadTrackRefs(Option_t* option)
1839 {
1840 //Load track references from file (opens file and posts tree to folder)
1841
1842  return fTrackRefsDataLoader->GetBaseLoader(0)->Load(option);
1843 }
1844 /**************************************************************************/
1845
1846 void  AliRunLoader::SetDirName(TString& dirname)
1847 {
1848 //sets directory name 
1849   if (dirname.IsNull()) return;
1850   fUnixDirName = dirname;
1851   fKineDataLoader->SetDirName(dirname);
1852   fTrackRefsDataLoader->SetDirName(dirname);
1853   
1854   TIter next(fLoaders);
1855   AliLoader *loader;
1856   while((loader = (AliLoader*)next()))
1857    {
1858     loader->SetDirName(dirname);
1859    }
1860
1861 }
1862 /*****************************************************************************/ 
1863
1864 Int_t AliRunLoader::GetFileOffset() const
1865 {
1866 //returns the file number that is added to the file name for current event
1867   return Int_t(fCurrentEvent/fNEventsPerFile);
1868 }
1869
1870 /*****************************************************************************/ 
1871 const TString AliRunLoader::SetFileOffset(const TString& fname)
1872 {
1873 //adds the the number to the file name at proper place for current event
1874   Long_t offset = (Long_t)GetFileOffset();
1875   if (offset < 1) return fname;
1876   TString soffset;
1877   soffset += offset;//automatic conversion to string
1878   TString dotroot(".root");
1879   const TString& offfsetdotroot = offset + dotroot;
1880   TString out = fname;
1881   out = out.ReplaceAll(dotroot,offfsetdotroot);
1882   if (GetDebug()) Info("SetFileOffset"," in=%s out=%s",fname.Data(),out.Data());
1883   return out;
1884 }
1885 /*****************************************************************************/ 
1886
1887 void AliRunLoader::SetDigitsFileNameSuffix(const TString& suffix)
1888 {
1889 //adds the suffix before ".root", 
1890 //e.g. TPC.Digits.root -> TPC.DigitsMerged.root
1891 //made on Jiri Chudoba demand
1892
1893   TIter next(fLoaders);
1894   AliLoader *loader;
1895   while((loader = (AliLoader*)next())) 
1896    {
1897      loader->SetDigitsFileNameSuffix(suffix);
1898    }
1899 }
1900 /*****************************************************************************/ 
1901
1902 TString AliRunLoader::GetFileName() const
1903 {
1904 //returns name of galice file
1905  TString result;
1906  if (fGAFile == 0x0) return result;
1907  result = fGAFile->GetName();
1908  return result;
1909 }
1910 /*****************************************************************************/ 
1911
1912 void AliRunLoader::SetDetectorAddresses()
1913 {
1914  //calls SetTreeAddress for all detectors
1915   if (GetAliRun()==0x0) return;
1916   TIter next(GetAliRun()->Modules());
1917   AliModule* mod;
1918   while((mod = (AliModule*)next())) 
1919    {
1920      AliDetector* det = dynamic_cast<AliDetector*>(mod);
1921      if (det) det->SetTreeAddress();
1922    }
1923 }
1924 /*****************************************************************************/ 
1925
1926 void AliRunLoader::Synchronize()
1927 {
1928   //synchrinizes all writtable files 
1929   TIter next(fLoaders);
1930   AliLoader *loader;
1931   while((loader = (AliLoader*)next()))
1932    {
1933      loader->Synchronize();
1934    }
1935   
1936   fKineDataLoader->Synchronize();
1937   fTrackRefsDataLoader->Synchronize();
1938   
1939   if (fGAFile) fGAFile->Flush();
1940 }
1941 /*****************************************************************************/ 
1942 /*****************************************************************************/