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