Updated Unload functionality (P.Skowronski)
[u/mrichter/AliRoot.git] / STEER / AliDataLoader.cxx
1 #include <AliDataLoader.h>
2 //__________________________________________
3 /////////////////////////////////////////////////////////////////////////////////////////////
4 //                                                                                         //
5 //  class AliDataLoader                                                                    //
6 //                                                                                         //
7 //  Container of all data needed for full                                                  //
8 //  description of each data type                                                          //
9 //  (Hits, Kine, ...)                                                                      //
10 //                                                                                         //
11 //  Each data loader has a basic standard setup of BaseLoaders                             //
12 //  which can be identuified by indexes (defined by EStdBasicLoaders)                      //
13 //  Data managed by these standard base loaders has fixed naming convention                //
14 //  e.g. - tree with hits is always named TreeH                                            //
15 //                     (defined in AliLoader::fgkDefaultHitsContainerName)                 //
16 //       - task DtectorName+Name defined                                                   //
17 //                                                                                         //
18 //  EStdBasicLoaders   idx     Object Type        Description                              //
19 //      kData           0    TTree or TObject     main data itself (hits,digits,...)       //
20 //      kTask           1        TTask            object producing main data               //
21 //      kQA             2        TTree                quality assurance tree               //
22 //      kQATask         3        TTask            task producing QA object                 //
23 //                                                                                         //
24 //                                                                                         //
25 //  User can define and add more basic loaders even Run Time.                              //
26 //  Caution: in order to save information about added base loader                          //
27 //  user must rewrite Run Loader to galice.file, overwriting old setup                     //
28 //                                                                                         //
29 /////////////////////////////////////////////////////////////////////////////////////////////
30
31 #include <TROOT.h>
32 #include <TFile.h>
33 #include <TString.h>
34 #include <TBits.h>
35 #include <TList.h>
36
37 #include "AliRunLoader.h"
38
39 ClassImp(AliDataLoader)
40
41 AliDataLoader::AliDataLoader():
42  fFileName(0),
43  fFile(0x0),
44  fDirectory(0x0),
45  fFileOption(),
46  fCompressionLevel(2),
47  fBaseLoaders(0x0),
48  fHasTask(kFALSE),
49  fTaskName(),
50  fParentalTask(0x0),
51  fEventFolder(0x0),
52  fFolder(0x0)
53 {
54   
55 }
56 /*****************************************************************************/ 
57
58 AliDataLoader::AliDataLoader(const char* filename, const char* contname, const char* name, Option_t* opt):
59  TNamed(name,name),
60  fFileName(filename),
61  fFile(0x0),
62  fDirectory(0x0),
63  fFileOption(0),
64  fCompressionLevel(2),
65  fBaseLoaders(new TObjArray(4)),
66  fHasTask(kFALSE),
67  fTaskName(),
68  fParentalTask(0x0),
69  fEventFolder(0x0),
70  fFolder(0x0)
71 {
72 //constructor
73 // creates a 0 loader, depending on option, default "T" is specialized loader for trees
74 // else standard object loader
75 // trees needs special care, becouse we need to set dir before writing
76   if (GetDebug())
77    Info("AliDataLoader","File name is %s",fFileName.Data());
78    
79   TString option(opt);
80   AliBaseLoader* bl;
81   if (option.CompareTo("T",TString::kIgnoreCase) == 0)
82     bl = new AliTreeLoader(contname,this);
83   else 
84     bl = new AliObjectLoader(contname,this);
85   fBaseLoaders->AddAt(bl,kData);
86   
87 }
88 /*****************************************************************************/ 
89
90 AliDataLoader::~AliDataLoader()
91 {
92 //dtor
93  UnloadAll();
94 }
95 /*****************************************************************************/ 
96
97 Int_t  AliDataLoader::SetEvent()
98 {
99 //basically the same that GetEvent but do not post data to folders
100  AliRunLoader* rl = GetRunLoader();
101  if (rl == 0x0)
102   {
103     Error("SetEvent","Can not get RunGettr");
104     return 1;
105   }
106  
107  Int_t evno = rl->GetEventNumber();
108
109  TIter next(fBaseLoaders);
110  AliBaseLoader* bl;
111  while ((bl = (AliBaseLoader*)next()))
112   {
113     if (bl->DoNotReload() == kFALSE) bl->Clean();
114   }
115
116  if(fFile)
117   {
118     if (CheckReload())
119      {
120        delete fFile;
121        fFile = 0x0;
122        if (GetDebug()) Info("SetEvent","Reloading new file. File opt is %s",fFileOption.Data());
123        OpenFile(fFileOption);
124      }
125
126     fDirectory = AliLoader::ChangeDir(fFile,evno);
127     if (fDirectory == 0x0)
128       {
129         Error("SetEvent","Can not chage directory in file %s",fFile->GetName());
130         return 1;
131       }
132    }
133  return 0;
134 }
135 /*****************************************************************************/ 
136
137 Int_t  AliDataLoader::GetEvent()
138 {
139  // posts all loaded data from files to White Board
140  // event number is defined in RunLoader
141  // 
142  //returns:
143  //     0  - in case of no error
144  //     1  - event not found
145  //     
146  //for each base laoder post, if was loaded before GetEvent
147  
148  //call set event to switch to new directory in file
149
150
151  //post all data that were loaded before 
152  // ->SetEvent does not call Unload, but only cleans White Board
153  // such IsLoaded flag stays untached
154  
155  if ( AliLoader::TestFileOption(fFileOption) == kTRUE ) //if file is read or update mode try to post
156   {                                                     //in other case there is no sense to post: file is new
157    TIter nextbl(fBaseLoaders);
158    AliBaseLoader* bl;
159    while ((bl = (AliBaseLoader*)nextbl()))
160     {
161      if (bl->IsLoaded())
162       {
163         if (bl->DoNotReload() == kFALSE) bl->Post();
164       }
165     } 
166   }
167  return 0;
168 }
169 /*****************************************************************************/ 
170
171 Int_t AliDataLoader::OpenFile(Option_t* opt)
172 {
173 //Opens file named 'filename', and assigns pointer to it to 'file'
174 //jumps to fDirectoryectory corresponding to current event and stores the pointer to it in 'fDirectory'
175 //option 'opt' is passed to TFile::Open
176   if (fFile)
177    {
178      if(fFile->IsOpen() == kTRUE)
179        {
180          Warning("OpenFile"," File %s already opened. First close it.",fFile->GetName());
181          return 0;
182        }
183      else
184        {
185          Warning("OpenFile","Pointer to file %s is not null, but file is not opened",
186                 fFile->GetName());
187          delete fFile;
188          fFile = 0x0;
189        }
190    }
191   
192   TString fname(SetFileOffset(fFileName));
193   
194   fFile = (TFile *)(gROOT->GetListOfFiles()->FindObject(fname));
195   if (fFile)
196    {
197      if(fFile->IsOpen() == kTRUE)
198        {
199          Warning("OpenFile","File %s already opened by sombody else. First close it.",
200                  fFile->GetName());
201          return 0;
202        }
203    }
204   
205   fFileOption = opt;
206   fFile = TFile::Open(fname,fFileOption);//open the file
207   if (fFile == 0x0)
208    {//file is null
209      Error("OpenFile","Can not open file %s",fname.Data());
210      return 1;
211    }
212   if (fFile->IsOpen() == kFALSE)
213    {//file is null
214      Error("OpenFile","Can not open file %s",fname.Data());
215      return 1;
216    }
217
218   fFile->SetCompressionLevel(fCompressionLevel);
219   
220   AliRunLoader* rg = GetRunLoader();
221   if (rg == 0x0)
222    {
223      Error("OpenFile","Can not find Run-Loader in folder.");
224      return 2;
225    }
226   Int_t evno = rg->GetEventNumber();
227   
228   fDirectory = AliLoader::ChangeDir(fFile,evno);
229   if (fDirectory == 0x0)
230    {
231      Error("OpenFile","Can not chage fDirectory in file %s.",fFile->GetName());
232      return 3; 
233    }
234   return 0;
235 }
236 /*****************************************************************************/ 
237
238 void AliDataLoader::Unload()
239 {
240  //unloads main data -  shortcut method 
241   GetBaseLoader(0)->Unload();
242 }
243 /*****************************************************************************/ 
244
245 void AliDataLoader::UnloadAll()
246 {
247 //Unloads all data and tasks
248  if ( fFile == 0x0 ) return; //nothing loaded
249  
250  TIter next(fBaseLoaders);
251  AliBaseLoader* bl;
252  while ((bl = (AliBaseLoader*)next()))
253   {
254     bl->Unload();
255   }
256 }
257 /*****************************************************************************/ 
258
259 Int_t AliDataLoader::Reload()
260 {
261  //Unloads and loads data again
262  if ( fFile == 0x0 ) return 0;
263    
264  TBits loaded(fBaseLoaders->GetEntries());  
265  TIter next(fBaseLoaders);
266  AliBaseLoader* bl;
267
268  Int_t i = 0;
269  while ((bl = (AliBaseLoader*)next()))
270   {
271     if (bl->IsLoaded())
272      {
273        loaded.SetBitNumber(i++,kTRUE);
274        bl->Unload();
275      }
276   }
277  
278  Int_t retval;
279  i = 0;  
280  next.Reset();
281  while ((bl = (AliBaseLoader*)next()))
282   {
283     if (loaded.TestBitNumber(i++))
284      {
285        retval = bl->Load(fFileOption);
286        if (retval) 
287         {
288          Error("Reload","Error occur while loading %s",bl->GetName());
289          return retval;
290         }
291      }
292   }
293  
294
295  return 0;
296  }
297 /*****************************************************************************/ 
298 Int_t AliDataLoader::WriteData(Option_t* opt)
299 {
300 //Writes primary data ==  first BaseLoader
301   if (GetDebug())
302    Info("WriteData","Writing %s container for %s data. Option is %s.",
303           GetBaseLoader(0)->GetName(),GetName(),opt);
304   return GetBaseLoader(0)->WriteData(opt);
305 }
306 /*****************************************************************************/ 
307
308 Int_t AliDataLoader::Load(Option_t* opt)
309 {
310 //Writes primary data ==  first BaseLoader
311   return GetBaseLoader(0)->Load(opt);
312 }
313 /*****************************************************************************/ 
314
315 Int_t  AliDataLoader::SetEventFolder(TFolder* eventfolder)
316 {
317  //sets the event folder
318  if (eventfolder == 0x0)
319   {
320     Error("SetEventFolder","Stupid joke. Argument is NULL");
321     return 1;
322   }
323  if (GetDebug()) 
324    Info("SetFolder","name = %s Setting Event Folder named %s.",
325          GetName(),eventfolder->GetName());
326
327  fEventFolder = eventfolder;
328  return 0;
329 }
330 /*****************************************************************************/ 
331
332 Int_t  AliDataLoader::SetFolder(TFolder* folder)
333 {
334
335  if (folder == 0x0)
336   {
337     Error("SetFolder","Stupid joke. Argument is NULL");
338     return 1;
339   }
340  
341  if (GetDebug()) Info("SetFolder","name = %s Setting folder named %s.",GetName(),folder->GetName());
342  
343  fFolder = folder;
344  TIter next(fBaseLoaders);
345  AliBaseLoader* bl;
346
347  while ((bl = (AliBaseLoader*)next()))
348   {
349    bl->SetDataLoader(this);
350   }  
351
352  return 0;
353 }
354 /******************************************************************/
355
356 TFolder* AliDataLoader::GetEventFolder()
357 {
358 //get EVENT folder (data that are changing from event to event, even in single run)
359   if (GetDebug()) Info("GetEventFolder","EF = %#x");
360   return fEventFolder;
361 }
362 /*****************************************************************************/ 
363
364 AliRunLoader* AliDataLoader::GetRunLoader()
365 {
366 //gets the run-loader from event folder
367   AliRunLoader* rg = 0x0;
368   TFolder* ef = GetEventFolder();
369   if (ef == 0x0)
370    {
371      Error("GetRunLoader","Can not get event folder.");
372      return 0;
373    }
374   rg = dynamic_cast<AliRunLoader*>(ef->FindObject(AliRunLoader::fgkRunLoaderName));
375   return rg;
376 }
377
378 /*****************************************************************************/ 
379 void AliDataLoader::CloseFile()
380 {
381   //closes file
382   TIter next(fBaseLoaders);
383   AliBaseLoader* bl;
384   while ((bl = (AliBaseLoader*)next()))
385    {
386      if (bl->IsLoaded()) return;
387    }
388   
389   if (GetDebug())
390     Info("CloseFile","Closing and deleting (object) file.");
391     
392   delete fFile;
393   fFile = 0x0;
394   fDirectory = 0x0;
395 }
396 /*****************************************************************************/ 
397
398 void AliDataLoader::Clean()
399 {
400   //Cleans main data
401   GetBaseLoader(0)->Clean();
402 }  
403 /*****************************************************************************/ 
404
405 void AliDataLoader::CleanAll()
406 {
407   //Cleans all folders and tasks
408   TIter next(fBaseLoaders);
409   AliBaseLoader* bl;
410   while ((bl = (AliBaseLoader*)next()))
411    {
412       bl->Clean();
413    }
414 }
415 /*****************************************************************************/ 
416
417 void AliDataLoader::SetFileNameSuffix(const TString& suffix)
418 {
419   //adds the suffix before ".root", 
420   //e.g. TPC.Digits.root -> TPC.DigitsMerged.root
421   //made on Jiri Chudoba demand
422   if (GetDebug()) 
423    {
424      Info("SetFileNameSuffix","suffix=%s",suffix.Data());
425      Info("SetFileNameSuffix","   Digits File Name before: %s",fFileName.Data());
426    }
427    
428   static TString dotroot(".root");
429   const TString& suffixdotroot = suffix + dotroot;
430   fFileName = fFileName.ReplaceAll(dotroot,suffixdotroot);
431
432   if (GetDebug()) 
433     Info("SetDigitsFileNameSuffix","                    after : %s",fFileName.Data());
434 }
435 /*****************************************************************************/ 
436
437 Bool_t AliDataLoader::CheckReload()
438 {
439 //checks if we have to reload given file
440  if (fFile == 0x0) return kFALSE;
441  TString tmp = SetFileOffset(fFileName);
442  if (tmp.CompareTo(fFile->GetName())) return kTRUE;  //file must be reloaded
443  return  kFALSE;
444 }
445 /*****************************************************************************/ 
446
447 const TString AliDataLoader::SetFileOffset(const TString& fname)
448 {
449
450 //return fname;
451   Long_t offset = (Long_t)GetRunLoader()->GetFileOffset();
452   if (offset < 1) return fname;
453
454   TString soffset;
455   soffset += offset;//automatic conversion to string
456   TString dotroot(".root");
457   const TString& offfsetdotroot = offset + dotroot;
458   TString out = fname;
459   out = out.ReplaceAll(dotroot,offfsetdotroot);
460   if (GetDebug()) Info("SetFileOffset","in=%s  out=%s.",fname.Data(),out.Data());
461   return out;
462
463 }
464 /*****************************************************************************/ 
465
466 void AliDataLoader::SetFileOption(Option_t* newopt)
467 {
468   //sets file option
469   if (fFileOption.CompareTo(newopt) == 0) return;
470   fFileOption = newopt;
471   Reload();
472 }
473 /*****************************************************************************/ 
474
475 void AliDataLoader::SetCompressionLevel(Int_t cl)
476 {
477 //sets comression level for data defined by di
478   fCompressionLevel = cl;
479   if (fFile) fFile->SetCompressionLevel(cl);
480 }
481 /*****************************************************************************/ 
482
483 Int_t AliDataLoader::GetDebug() const 
484
485   //it is not inline bacause AliLoader.h includes AliDataLoaer.h 
486   //and there is circular depenedence
487  return AliLoader::GetDebug();
488 }
489 /*****************************************************************************/ 
490
491 void AliDataLoader::MakeTree()
492 {
493   AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(fBaseLoaders->At(0));
494   if (tl == 0x0)
495    {
496      Error("MakeTree","Can not make a tree because main base loader is not a tree loader");
497      return;
498    }
499   tl->MakeTree();
500 }
501 /*****************************************************************************/ 
502
503 Bool_t AliDataLoader::IsFileWritable() const
504 {
505 //returns true if file is writable
506  return (fFile)?fFile->IsWritable():kFALSE;
507 }
508 /*****************************************************************************/ 
509
510 Bool_t AliDataLoader::IsFileOpen() const
511 {
512 //returns true if file is writable
513  return (fFile)?fFile->IsOpen():kFALSE;
514 }
515 /*****************************************************************************/ 
516
517 Bool_t AliDataLoader::IsOptionContrary(const TString& option) const
518 {
519 //Checks if passed option is contrary with file open option 
520 //which is passed option "writable" and existing option not wriable
521 //in reverse case it is no harm so it is NOT contrary
522   if (fFile == 0x0) return kFALSE; //file is not opened - no problem
523   
524   if ( ( AliLoader::IsOptionWritable(option)      == kTRUE  ) &&     // passed option is writable and 
525        ( AliLoader::IsOptionWritable(fFileOption) == kFALSE )    )   // existing one is not writable
526     {
527       return kTRUE;
528     }
529
530   return kFALSE;
531 }
532 /*****************************************************************************/ 
533 void AliDataLoader::AddBaseLoader(AliBaseLoader* bl)
534 {
535 //Adds a base loader to lits of base loaders managed by this data loader
536 //Managed data/task will be stored in proper root directory,
537 //and posted to 
538 // - in case of tree/object - data folder connected with detector associated with this data loader
539 // - in case of task - parental task which defined in this AliTaskLoader 
540
541  if (bl == 0x0)
542   {
543     Warning("AddBaseLoader","Pointer is null.");
544     return;
545   }
546  
547  TObject* obj = fBaseLoaders->FindObject(bl->GetName());
548  if (obj)
549   {
550     Error("AddBaseLoader","Can not add this base loader.");
551     Error("AddBaseLoader","There exists already base loader which manages data named %s for this detector.");
552     return;
553   }
554  
555  
556  fBaseLoaders->Add(bl);
557 }
558
559 /*****************************************************************************/ 
560
561 AliBaseLoader* AliDataLoader::GetBaseLoader(const TString& name) const
562 {
563   return dynamic_cast<AliBaseLoader*>(fBaseLoaders->FindObject(name));
564 }
565 /*****************************************************************************/ 
566
567 AliBaseLoader* AliDataLoader::GetBaseLoader(Int_t n) const
568 {
569  return dynamic_cast<AliBaseLoader*>(fBaseLoaders->At(n));
570 }
571 /*****************************************************************************/ 
572
573 TTree* AliDataLoader::Tree() const
574 {
575 //returns tree from the main base loader
576 //it is just shortcut method for comfort of user
577 //main storage object does not have to be Tree  - 
578 //that is why first we need to check if it is a TreeLoader 
579  AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(GetBaseLoader(0));
580  if (tl == 0x0) return 0x0;
581  return tl->Tree();
582 }
583 /*****************************************************************************/ 
584
585 void  AliDataLoader::SetDirName(TString& dirname)
586 {
587   if (GetDebug()>9) Info("SetDirName","FileName before %s",fFileName.Data());
588
589   Int_t n = fFileName.Last('/');
590
591   if (GetDebug()>9) Info("SetDirName","Slash found on pos %d",n);
592
593   if (n > 0) fFileName = fFileName.Remove(0,n+1);
594
595   if (GetDebug()>9) Info("SetDirName","Core FileName %s",fFileName.Data());
596
597   fFileName = dirname + "/" + fFileName;
598
599   if (GetDebug()>9) Info("SetDirName","FileName after %s",fFileName.Data());
600 }
601 /*****************************************************************************/ 
602 AliObjectLoader* AliDataLoader::GetBaseDataLoader()
603 {
604  return dynamic_cast<AliObjectLoader*>(GetBaseLoader(kData));
605 }
606 /*****************************************************************************/ 
607 AliTaskLoader* AliDataLoader::GetBaseTaskLoader()
608 {
609  return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kTask));
610 }
611 /*****************************************************************************/ 
612 AliBaseLoader* AliDataLoader::GetBaseQALoader()
613 {
614   return GetBaseLoader(kQA);
615 }
616 /*****************************************************************************/ 
617 AliTaskLoader* AliDataLoader::GetBaseQATaskLoader()
618 {
619 //returns pointer to QA base loader
620  return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kQATask));
621 }
622 /*****************************************************************************/ 
623 void AliDataLoader::SetBaseDataLoader(AliBaseLoader* bl)
624 {
625 //sets data base loader
626   if (bl == 0x0)
627    {
628      Error("SetBaseDataLoader","Parameter is null");
629      return;
630    }
631   if (GetBaseDataLoader()) delete GetBaseDataLoader();
632   fBaseLoaders->AddAt(bl,kData);
633 }
634 /*****************************************************************************/ 
635 void AliDataLoader::SetBaseTaskLoader(AliTaskLoader* bl)
636 {
637 //sets Task base loader
638   if (bl == 0x0)
639    {
640      Error("SetBaseTaskLoader","Parameter is null");
641      return;
642    }
643   if (GetBaseTaskLoader()) delete GetBaseTaskLoader();
644   fBaseLoaders->AddAt(bl,kTask);
645 }
646 /*****************************************************************************/ 
647 void AliDataLoader::SetBaseQALoader(AliBaseLoader* bl)
648 {
649 //sets QA base loader
650   if (bl == 0x0)
651    {
652      Error("SetBaseQALoader","Parameter is null");
653      return;
654    }
655   if (GetBaseQALoader()) delete GetBaseQALoader();
656   fBaseLoaders->AddAt(bl,kQA);
657 }
658 /*****************************************************************************/ 
659 void AliDataLoader::SetBaseQATaskLoader(AliTaskLoader* bl)
660 {
661 //sets QA Task base loader
662   if (bl == 0x0)
663    {
664      Error("SetBaseQATaskLoader","Parameter is null");
665      return;
666    }
667   if (GetBaseQATaskLoader()) delete GetBaseQATaskLoader();
668   fBaseLoaders->AddAt(bl,kQATask);
669 }
670 void AliDataLoader::Synchronize()
671 {
672   //synchrinizes all writtable files 
673   if ( fFile == 0x0 ) return;
674   if ( fFile->IsWritable() == kFALSE ) return;
675   fFile->Write(0,TObject::kOverwrite);
676 }
677
678 /*****************************************************************************/ 
679 /*****************************************************************************/ 
680 /*****************************************************************************/ 
681 //__________________________________________
682 ///////////////////////////////////////////////////////////////////////////////
683 //                                                                           //
684 //  class AliBaseLoader                                                      //
685 //                                                                           //
686 //                                                                           //
687 ///////////////////////////////////////////////////////////////////////////////
688 ClassImp(AliBaseLoader)
689
690 AliBaseLoader::AliBaseLoader():
691  fIsLoaded(kFALSE),
692  fStoreInTopOfFile(kFALSE),
693  fDoNotReload(kFALSE),
694  fDataLoader(0x0)
695 {
696 }
697 /*****************************************************************************/ 
698
699 AliBaseLoader::AliBaseLoader(const TString& name,  AliDataLoader* dl, Bool_t storeontop):
700  TNamed(name,name+" Base Loader"),
701  fIsLoaded(kFALSE),
702  fStoreInTopOfFile(storeontop),
703  fDoNotReload(storeontop),//if stored on top of file - this object is loaded ones pe
704  fDataLoader(dl)
705 {
706 }
707
708 /*****************************************************************************/ 
709
710 Int_t AliBaseLoader::Load(Option_t* opt)
711 {
712   if (GetDebug())
713     Info("Load","data type = %s, option = %s",GetName(),opt);
714
715   if (Get())
716    {
717       Warning("Load","Data <<%s>> are already loaded. Use ReloadData to force reload. Nothing done",GetName());
718       return 0;
719    }
720   
721   Int_t retval;
722   
723   if (GetDataLoader()->IsFileOpen() == kTRUE)
724    {
725      if (GetDataLoader()->IsOptionContrary(opt) == kTRUE)
726        {
727          Error("Load","Data Type %s, Container Name %s", GetDataLoader()->GetName(),GetName());
728          Error("Load","File was already opened in READ-ONLY mode, while now WRITEABLE access is requested.");
729          Error("Load","Use AliDataLoader::SetOption to enforce change of access mode OR");
730          Error("Load","Load previosly loaded data with coherent option.");
731          return 10;
732        }
733    }
734   else
735    {
736      retval = GetDataLoader()->OpenFile(opt);
737      if (retval) 
738       {
739         Error("Load","Error occured while opening <<%s>> file",GetName());
740         return retval;
741       }
742    }
743   //if file is recreated there is no sense to search for data to post and get Error message
744   if (AliLoader::TestFileOption(opt) == kFALSE)
745    {
746     AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(this);
747     if (tl) tl->MakeTree();
748     fIsLoaded = kTRUE;
749     return 0;
750    }
751
752   retval = Post();
753   if (retval)
754    {
755     Error("Load","Error occured while posting %s from file to folder.",GetName());
756     return retval;
757    }
758   
759   fIsLoaded = kTRUE;
760   return 0;
761 }
762 /*****************************************************************************/ 
763
764 Int_t AliBaseLoader::Post()
765 {
766 //Posts data container to proper folders
767
768   if ( GetDirectory() == 0x0)
769    {
770      Error("Post","%s directory is NULL. Load before.",GetDataLoader()->GetName());
771      return 2; 
772    }
773   
774   TObject* data = GetFromDirectory(fName);
775   if(data)
776    {
777      //if such an obejct already exists - remove it first
778      return Post(data);
779    }
780   else
781    {
782     //check if file is in update mode
783     Int_t fileupdate = GetDataLoader()->GetFileOption().CompareTo("update",TString::kIgnoreCase);
784     if ( fileupdate == 0)
785      { //if it is, it is normal that there is no data yet
786        if (GetDebug())
787         {
788          Info("Post","Can not find %s in file %s (file is opened in UPDATE mode).",
789                GetName(),GetDataLoader()->GetFile()->GetName());
790         }
791      }
792     else
793      {
794         Warning("Post","Can not find %s in file %s", GetName(),GetDataLoader()->GetFile()->GetName());
795      }
796    }
797   return 0;
798 }
799 /*****************************************************************************/ 
800
801 Int_t AliBaseLoader::Post(TObject* data)
802 {
803 //Posts data container to proper folders
804  if (data == 0x0)
805   {
806     Error("Post","Pointer to object is NULL");
807     return 1;
808   }
809  TObject* obj = Get();
810  if (data == obj)
811   {
812     if (GetDebug()) Warning("Post","This object was already posted.");
813     return 0;
814   }
815  if (obj)
816   {
817     Warning("PostData","Object named %s already exitsts in data folder. Removing it",GetName());
818     Clean();
819   }
820  return AddToBoard(data);
821 }
822 /*****************************************************************************/ 
823
824 Int_t AliBaseLoader::WriteData(Option_t* opt)
825 {
826 //Writes data defined by di object
827 //opt might be "OVERWRITE" in case of forcing overwriting
828   if (GetDebug()) 
829     Info("WriteData","Writing %s container for %s data. Option is %s.",
830           GetName(),GetDataLoader()->GetName(),opt);
831   
832   TObject *data = Get();
833   if(data == 0x0)
834    {//did not get, nothing to write
835      Warning("WriteData","Tree named %s not found in folder. Nothing to write.",GetName());
836      return 0;
837    }
838   
839   //check if file is opened
840   if (GetDirectory() == 0x0)
841    { 
842      //if not try to open
843      GetDataLoader()->SetFileOption("UPDATE");
844      if (GetDataLoader()->OpenFile("UPDATE"))
845       {  
846         //oops, can not open the file, give an error message and return error code
847         Error("WriteData","Can not open hits file. %s ARE NOT WRITTEN",GetName());
848         return 1;
849       }
850    }
851
852   if (GetDataLoader()->IsFileWritable() == kFALSE)
853    {
854      Error("WriteData","File %s is not writable",GetDataLoader()->GetFileName().Data());
855      return 2;
856    }
857   
858   GetDirectory()->cd(); //set the proper directory active
859
860   //see if hits container already exists in this (root) directory
861   TObject* obj = GetFromDirectory(GetName());
862   if (obj)
863    { //if they exist, see if option OVERWRITE is used
864      const char *oOverWrite = strstr(opt,"OVERWRITE");
865      if(!oOverWrite)
866       {//if it is not used -  give an error message and return an error code
867         Error("WriteData","Tree already exisists. Use option \"OVERWRITE\" to overwrite previous data");
868         return 3;
869       }
870    }
871   
872   if (GetDebug()) Info("WriteData","DataName = %s, opt = %s, data object name = %s",
873                    GetName(),opt,data->GetName());
874   if (GetDebug()) Info("WriteData","File Name = %s, Directory Name = %s Directory's File Name = %s",
875                    GetDataLoader()->GetFile()->GetName(),GetDirectory()->GetName(),
876                    GetDirectory()->GetFile()->GetName());
877   
878   if (GetDebug()) Info("WriteData","Writing data");
879   data->Write(0,TObject::kOverwrite);
880
881   fIsLoaded = kTRUE;  // Just to ensure flag is on. Object can be posted manually to folder structure, not using loader.
882
883   return 0;
884  
885 }
886 /*****************************************************************************/ 
887
888 Int_t AliBaseLoader::Reload()
889 {
890 //Unloads and loads datat again - if loaded before
891  if (IsLoaded())
892   {
893     Unload();
894     return Load(GetDataLoader()->GetFileOption());
895   }
896   return 0;
897 }
898 /*****************************************************************************/ 
899
900 void AliBaseLoader::Clean()
901 {
902 //removes objects from folder/task
903   if (GetDebug()) Info("Clean","%s %s",GetName(),GetDataLoader()->GetName());
904   TObject* obj = Get();
905   if(obj)
906    { 
907      if (GetDebug()) 
908        Info("Clean","cleaning %s.",GetName());
909      RemoveFromBoard(obj);
910      delete obj;
911    }
912 }
913 /*****************************************************************************/ 
914
915 void AliBaseLoader::Unload()
916 {
917   Clean();
918   fIsLoaded = kFALSE;
919   GetDataLoader()->CloseFile();
920 }
921 /*****************************************************************************/ 
922 AliDataLoader* AliBaseLoader::GetDataLoader() const
923 {
924  if (fDataLoader == 0x0) 
925   {
926     Fatal("GetDataLoader","Pointer to Data Loader is NULL");
927   }
928  return fDataLoader;
929 }
930 /*****************************************************************************/ 
931
932 Int_t AliBaseLoader::GetDebug() const 
933
934  return (Int_t)AliLoader::fgDebug;
935 }
936
937 TDirectory* AliBaseLoader::GetDirectory()
938 {
939  // returnd TDirectory where data are to be saved
940  //if fStoreInTopOfFile flag is true - returns pointer to file
941   return (fStoreInTopOfFile)?GetDataLoader()->GetFile():GetDataLoader()->GetDirectory();
942 }
943 /*****************************************************************************/ 
944 /*****************************************************************************/ 
945 /*****************************************************************************/ 
946 //__________________________________________
947 ///////////////////////////////////////////////////////////////////////////////
948 //                                                                           //
949 //  class AliObjectLoader                                                      //
950 //                                                                           //
951 //                                                                           //
952 ///////////////////////////////////////////////////////////////////////////////
953
954 ClassImp(AliObjectLoader)
955
956 AliObjectLoader::AliObjectLoader(const TString& name, AliDataLoader* dl, Bool_t storeontop):
957  AliBaseLoader(name,dl,storeontop)
958 {
959 //constructor
960 }
961 /*****************************************************************************/ 
962
963 TFolder* AliObjectLoader::GetFolder() const
964 {
965   TFolder* df = GetDataLoader()->GetFolder();
966   if (df == 0x0)
967    {
968      Fatal("GetFolder","Data Folder is NULL");
969    }
970   return df;
971 }
972 /*****************************************************************************/ 
973
974 void AliObjectLoader::RemoveFromBoard(TObject* obj)
975 {
976   GetFolder()->Remove(obj);
977 }
978 /*****************************************************************************/ 
979 Int_t AliObjectLoader::AddToBoard(TObject* obj)
980 {
981   GetFolder()->Add(obj);
982   return 0;
983 }
984 /*****************************************************************************/ 
985
986 TObject* AliObjectLoader::Get() const
987 {
988   return (GetFolder()) ? GetFolder()->FindObject(GetName()) : 0x0;
989 }
990
991 /*****************************************************************************/ 
992 /*****************************************************************************/ 
993 /*****************************************************************************/ 
994 //__________________________________________
995 ///////////////////////////////////////////////////////////////////////////////
996 //                                                                           //
997 //  class AliTreeLoader                                                      //
998 //                                                                           //
999 //                                                                           //
1000 ///////////////////////////////////////////////////////////////////////////////
1001
1002 ClassImp(AliTreeLoader)
1003
1004 AliTreeLoader::AliTreeLoader(const TString& name, AliDataLoader* dl,Bool_t storeontop):
1005  AliObjectLoader(name,dl,storeontop)
1006 {
1007 //constructor
1008 }
1009
1010 /*****************************************************************************/ 
1011
1012 Int_t AliTreeLoader::WriteData(Option_t* opt)
1013 {
1014 //Writes data defined by di object
1015 //opt might be "OVERWRITE" in case of forcing overwriting
1016
1017   if (GetDebug()) 
1018     Info("WriteData","Writing %s container for %s data. Option is %s.",
1019           GetName(),GetDataLoader()->GetName(),opt);
1020
1021   TObject *data = Get();
1022   if(data == 0x0)
1023    {//did not get, nothing to write
1024      Warning("WriteData","Tree named %s not found in folder. Nothing to write.",GetName());
1025      return 0;
1026    }
1027   
1028   //check if file is opened
1029   if (GetDirectory() == 0x0)
1030    { 
1031      //if not try to open
1032      GetDataLoader()->SetFileOption("UPDATE");
1033      if (GetDataLoader()->OpenFile("UPDATE"))
1034       {  
1035         //oops, can not open the file, give an error message and return error code
1036         Error("WriteData","Can not open hits file. %s ARE NOT WRITTEN",GetName());
1037         return 1;
1038       }
1039    }
1040
1041   if (GetDataLoader()->IsFileWritable() == kFALSE)
1042    {
1043      Error("WriteData","File %s is not writable",GetDataLoader()->GetFileName().Data());
1044      return 2;
1045    }
1046   
1047   GetDirectory()->cd(); //set the proper directory active
1048
1049   //see if hits container already exists in this (root) directory
1050   TObject* obj = GetFromDirectory(GetName());
1051   if (obj)
1052    { //if they exist, see if option OVERWRITE is used
1053      const char *oOverWrite = strstr(opt,"OVERWRITE");
1054      if(!oOverWrite)
1055       {//if it is not used -  give an error message and return an error code
1056         Error("WriteData","Tree already exisists. Use option \"OVERWRITE\" to overwrite previous data");
1057         return 3;
1058       }
1059    }
1060   
1061   if (GetDebug()) Info("WriteData","DataName = %s, opt = %s, data object name = %s",
1062                    GetName(),opt,data->GetName());
1063   if (GetDebug()) Info("WriteData","File Name = %s, Directory Name = %s Directory's File Name = %s",
1064                    GetDataLoader()->GetFile()->GetName(),GetDirectory()->GetName(),
1065                    GetDirectory()->GetFile()->GetName());
1066   
1067   //if a data object is a tree set the directory
1068   TTree* tree = dynamic_cast<TTree*>(data);
1069   if (tree) tree->SetDirectory(GetDirectory()); //forces setting the directory to this directory (we changed dir few lines above)
1070   
1071   if (GetDebug()) Info("WriteData","Writing tree");
1072   data->Write(0,TObject::kOverwrite);
1073
1074   fIsLoaded = kTRUE;  // Just to ensure flag is on. Object can be posted manually to folder structure, not using loader.
1075   
1076   return 0;
1077  
1078 }
1079 /*****************************************************************************/ 
1080
1081 void AliTreeLoader::MakeTree()
1082 {
1083 //this virtual method creates the tree in the file
1084   if (Tree()) 
1085    {
1086     if (GetDebug()) 
1087       Info("MakeTree","name = %s, Data Name = %s Tree already exists.",
1088             GetName(),GetDataLoader()->GetName());
1089     return;//tree already made 
1090    }
1091   if (GetDebug()) 
1092     Info("MakeTree","Making Tree named %s.",GetName());
1093    
1094   TString dtypename(GetDataLoader()->GetName());
1095   TTree* tree = new TTree(GetName(), dtypename + " Container"); //make a tree
1096   if (tree == 0x0)
1097    {
1098      Error("MakeTree","Can not create %s tree.",GetName());
1099      return;
1100    }
1101   tree->SetAutoSave(1000000000); //no autosave
1102   GetFolder()->Add(tree);
1103   WriteData("OVERWRITE");//write tree to the file
1104 }
1105
1106
1107 /*****************************************************************************/ 
1108 /*****************************************************************************/ 
1109 /*****************************************************************************/ 
1110 //__________________________________________
1111 ///////////////////////////////////////////////////////////////////////////////
1112 //                                                                           //
1113 //  class AliTaskLoader                                                      //
1114 //                                                                           //
1115 //                                                                           //
1116 ///////////////////////////////////////////////////////////////////////////////
1117
1118 ClassImp(AliTaskLoader)
1119
1120 AliTaskLoader::AliTaskLoader(const TString& name, AliDataLoader* dl, TTask* parentaltask, Bool_t storeontop):
1121  AliBaseLoader(name,dl,storeontop),
1122  fParentalTask(parentaltask)
1123 {
1124 //constructor
1125 }
1126
1127 /*****************************************************************************/ 
1128
1129 void AliTaskLoader::RemoveFromBoard(TObject* obj)
1130 {
1131   GetParentalTask()->GetListOfTasks()->Remove(obj);
1132 }
1133 /*****************************************************************************/ 
1134
1135 Int_t AliTaskLoader::AddToBoard(TObject* obj)
1136 {
1137   TTask* task = dynamic_cast<TTask*>(obj);
1138   if (task == 0x0)
1139    {
1140      Error("AddToBoard","To TTask board can be added only tasks.");
1141      return 1;
1142    }
1143   GetParentalTask()->Add(task);
1144   return 0;
1145 }
1146 /*****************************************************************************/ 
1147
1148 TObject* AliTaskLoader::Get() const
1149 {
1150   return (GetParentalTask()) ? GetParentalTask()->GetListOfTasks()->FindObject(GetName()) : 0x0;
1151 }
1152 /*****************************************************************************/ 
1153
1154 TTask* AliTaskLoader::GetParentalTask() const
1155 {
1156 //returns parental tasks for this task
1157   return fParentalTask;
1158 }
1159
1160 /*****************************************************************************/ 
1161
1162 /*****************************************************************************/ 
1163 /*****************************************************************************/ 
1164 /*****************************************************************************/ 
1165
1166