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