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