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