Clean-up of include files
[u/mrichter/AliRoot.git] / STEER / AliDataLoader.cxx
1 /////////////////////////////////////////////////////////////////////////////////////////////
2 //                                                                                         //
3 //  class AliDataLoader                                                                    //
4 //                                                                                         //
5 //  Container of all data needed for full                                                  //
6 //  description of each data type                                                          //
7 //  (Hits, Kine, ...)                                                                      //
8 //                                                                                         //
9 //  Each data loader has a basic standard setup of BaseLoaders                             //
10 //  which can be identuified by indexes (defined by EStdBasicLoaders)                      //
11 //  Data managed by these standard base loaders has fixed naming convention                //
12 //  e.g. - tree with hits is always named TreeH                                            //
13 //                     (defined in AliLoader::fgkDefaultHitsContainerName)                 //
14 //       - task DtectorName+Name defined                                                   //
15 //                                                                                         //
16 //  EStdBasicLoaders   idx     Object Type        Description                              //
17 //      kData           0    TTree or TObject     main data itself (hits,digits,...)       //
18 //      kTask           1        TTask            object producing main data               //
19 //      kQA             2        TTree                quality assurance tree               //
20 //      kQATask         3        TTask            task producing QA object                 //
21 //                                                                                         //
22 //                                                                                         //
23 //  User can define and add more basic loaders even Run Time.                              //
24 //  Caution: in order to save information about added base loader                          //
25 //  user must rewrite Run Loader to galice.file, overwriting old setup                     //
26 //                                                                                         //
27 /////////////////////////////////////////////////////////////////////////////////////////////
28
29 /* $Id$ */
30
31 #include "AliDataLoader.h"
32 #include "AliRunLoader.h"
33 #include "AliLoader.h"
34 #include "AliObjectLoader.h"
35 #include "AliTreeLoader.h"
36 #include "AliTaskLoader.h"
37 #include "AliLog.h"
38
39 #include <TFile.h>
40 #include <TROOT.h>
41 #include <TString.h>
42 #include <TBits.h>
43
44 ClassImp(AliDataLoader)
45
46 //______________________________________________________________________________
47 AliDataLoader::AliDataLoader():
48  fFileName(0),
49  fFile(0x0),
50  fDirectory(0x0),
51  fFileOption(),
52  fCompressionLevel(2),
53  fNEventsPerFile(0),
54  fBaseLoaders(0x0),
55  fHasTask(kFALSE),
56  fTaskName(),
57  fParentalTask(0x0),
58  fEventFolder(0x0),
59  fFolder(0x0)
60 {
61   
62 }
63
64 //______________________________________________________________________________
65 AliDataLoader::AliDataLoader(const char* filename, const char* contname, 
66                              const char* name, Option_t* opt):
67  TNamed(name,name),
68  fFileName(filename),
69  fFile(0x0),
70  fDirectory(0x0),
71  fFileOption(0),
72  fCompressionLevel(2),
73  fNEventsPerFile(0),
74  fBaseLoaders(new TObjArray(4)),
75  fHasTask(kFALSE),
76  fTaskName(),
77  fParentalTask(0x0),
78  fEventFolder(0x0),
79  fFolder(0x0)
80 {
81   //constructor
82   // creates a 0 loader, depending on option, default "T" is specialized loader for trees
83   // else standard object loader
84   // trees needs special care, becouse we need to set dir before writing
85   AliDebug(1, Form("File name is %s",fFileName.Data()));
86   
87   TString option(opt);
88   AliBaseLoader* bl;
89   if (option.CompareTo("T",TString::kIgnoreCase) == 0)
90     bl = new AliTreeLoader(contname,this);
91   else 
92     bl = new AliObjectLoader(contname,this);
93   fBaseLoaders->AddAt(bl,kData);
94   
95 }
96
97 //______________________________________________________________________________
98 AliDataLoader::~AliDataLoader()
99 {
100   //
101   //dtor
102   //
103   UnloadAll();
104 }
105
106 //______________________________________________________________________________
107 Int_t  AliDataLoader::SetEvent()
108 {
109   //
110   // The same that GetEvent but do not post data to folders
111   //
112   AliRunLoader* rl = GetRunLoader();
113   if (rl == 0x0)
114     {
115       AliError("Can not get RunGettr");
116       return 1;
117     }
118   
119   Int_t evno = rl->GetEventNumber();
120   
121   TIter next(fBaseLoaders);
122   AliBaseLoader* bl;
123   while ((bl = (AliBaseLoader*)next()))
124     {
125       if (bl->DoNotReload() == kFALSE) bl->Clean();
126     }
127   
128   if(fFile)
129     {
130       if (CheckReload())
131         {
132           delete fFile;
133           fFile = 0x0;
134           AliDebug(1, Form("Reloading new file. File opt is %s",fFileOption.Data()));
135           OpenFile(fFileOption);
136         }
137       
138       fDirectory = AliLoader::ChangeDir(fFile,evno);
139       if (fDirectory == 0x0)
140         {
141           AliError(Form("Can not chage directory in file %s",fFile->GetName()));
142           return 1;
143         }
144     }
145   return 0;
146 }
147
148 //______________________________________________________________________________
149 Int_t  AliDataLoader::GetEvent()
150 {
151   // posts all loaded data from files to White Board
152   // event number is defined in RunLoader
153   // 
154   //returns:
155   //     0  - in case of no error
156   //     1  - event not found
157   //     
158   //for each base laoder post, if was loaded before GetEvent
159   
160   //call set event to switch to new directory in file
161   
162   
163   //post all data that were loaded before 
164   // ->SetEvent does not call Unload, but only cleans White Board
165   // such IsLoaded flag stays untached
166   
167   if ( AliLoader::TestFileOption(fFileOption) == kTRUE ) //if file is read or update mode try to post
168     {                                                     //in other case there is no sense to post: file is new
169       TIter nextbl(fBaseLoaders);
170       AliBaseLoader* bl;
171       while ((bl = (AliBaseLoader*)nextbl()))
172         {
173           if (bl->IsLoaded())
174             {
175               if (bl->DoNotReload() == kFALSE) bl->Post();
176             }
177         } 
178     }
179   return 0;
180 }
181
182 //______________________________________________________________________________
183 Int_t AliDataLoader::OpenFile(Option_t* opt)
184 {
185   //Opens file named 'filename', and assigns pointer to it to 'file'
186   //jumps to fDirectoryectory corresponding to current event and stores the pointer to it in 'fDirectory'
187   //option 'opt' is passed to TFile::Open
188   if (fFile)
189     {
190       if(fFile->IsOpen() == kTRUE)
191         {
192           AliWarning(Form(" File %s already opened. First close it.",fFile->GetName()));
193           return 0;
194         }
195       else
196         {
197           AliWarning(Form("Pointer to file %s is not null, but file is not opened",
198                           fFile->GetName()));
199           delete fFile;
200           fFile = 0x0;
201         }
202     }
203   
204   TString fname(SetFileOffset(fFileName));
205   
206   fFile = (TFile *)(gROOT->GetListOfFiles()->FindObject(fname));
207   if (fFile)
208     {
209       if(fFile->IsOpen() == kTRUE)
210         {
211           TString option1 = fFile->GetOption();
212           if (option1.CompareTo("read",TString::kIgnoreCase) == 0)
213             {
214               AliInfo(Form("File %s already opened in read mode.",fFile->GetName()));
215             }
216           else
217             {
218               TString option2 = opt;
219               if (option2.CompareTo("read",TString::kIgnoreCase) == 0)
220                 {
221                   AliInfo(Form("Open already opened file %s in read mode.",fFile->GetName()));
222                 }
223               else {
224                 AliWarning(Form("File %s already opened by sombody else. First close it.",
225                                 fFile->GetName()));
226                 return 0;
227               }
228             }
229         }
230     }
231   
232   fFileOption = opt;
233   fFile = TFile::Open(fname,fFileOption);//open the file
234   if (fFile == 0x0)
235     {//file is null
236       AliError(Form("Can not open file %s",fname.Data()));
237       return 1;
238     }
239   if (fFile->IsOpen() == kFALSE)
240     {//file is null
241       AliError(Form("Can not open file %s",fname.Data()));
242       return 1;
243     }
244   
245   fFile->SetCompressionLevel(fCompressionLevel);
246   
247   AliRunLoader* rg = GetRunLoader();
248   if (rg == 0x0)
249     {
250       AliError("Can not find Run-Loader in folder.");
251       return 2;
252     }
253   Int_t evno = rg->GetEventNumber();
254   
255   fDirectory = AliLoader::ChangeDir(fFile,evno);
256   if (fDirectory == 0x0)
257     {
258       AliError(Form("Can not chage fDirectory in file %s.",fFile->GetName()));
259       return 3; 
260     }
261   return 0;
262 }
263
264 //______________________________________________________________________________
265 void AliDataLoader::Unload()
266 {
267   //
268   //unloads main data -  shortcut method 
269   //
270   GetBaseLoader(0)->Unload();
271 }
272
273 //______________________________________________________________________________
274 void AliDataLoader::UnloadAll()
275 {
276   //
277   // Unloads all data and tasks
278   //
279   if ( fFile == 0x0 ) return; //nothing loaded
280   
281   TIter next(fBaseLoaders);
282   AliBaseLoader* bl;
283   while ((bl = (AliBaseLoader*)next()))
284     {
285       bl->Unload();
286     }
287 }
288
289
290 //______________________________________________________________________________
291 Int_t AliDataLoader::Reload()
292 {
293   //
294   // Unloads and loads data again
295   //
296   if ( fFile == 0x0 ) return 0;
297   
298   TBits loaded(fBaseLoaders->GetEntries());  
299   TIter next(fBaseLoaders);
300   AliBaseLoader* bl;
301   
302   Int_t i = 0;
303   while ((bl = (AliBaseLoader*)next()))
304     {
305       if (bl->IsLoaded())
306         {
307           loaded.SetBitNumber(i++,kTRUE);
308           bl->Unload();
309         }
310     }
311   
312   Int_t retval;
313   i = 0;  
314   next.Reset();
315   while ((bl = (AliBaseLoader*)next()))
316     {
317       if (loaded.TestBitNumber(i++))
318         {
319           retval = bl->Load(fFileOption);
320           if (retval) 
321             {
322               AliError(Form("Error occur while loading %s",bl->GetName()));
323               return retval;
324             }
325         }
326     }
327   return 0;
328 }
329
330
331 //______________________________________________________________________________
332 Int_t AliDataLoader::WriteData(Option_t* opt)
333 {
334   //
335   // Writes primary data ==  first BaseLoader
336   //
337   AliDebug(1, Form("Writing %s container for %s data. Option is %s.",
338                    GetBaseLoader(0)->GetName(),GetName(),opt));
339   return GetBaseLoader(0)->WriteData(opt);
340 }
341
342 //______________________________________________________________________________
343 Int_t AliDataLoader::Load(Option_t* opt)
344 {
345   //
346   // Writes primary data ==  first BaseLoader
347   //
348   return GetBaseLoader(0)->Load(opt);
349 }
350
351 //______________________________________________________________________________
352 Int_t  AliDataLoader::SetEventFolder(TFolder* eventfolder)
353 {
354   //
355   // Sets the event folder
356   //
357   if (eventfolder == 0x0)
358     {
359       AliError("Stupid joke. Argument is NULL");
360       return 1;
361     }
362   AliDebug(1, Form("name = %s Setting Event Folder named %s.",
363                    GetName(),eventfolder->GetName()));
364   
365   fEventFolder = eventfolder;
366   return 0;
367 }
368
369
370 //______________________________________________________________________________
371 Int_t  AliDataLoader::SetFolder(TFolder* folder)
372 {
373   // Sets the folder and the data loaders
374   if (folder == 0x0)
375     {
376       AliError("Stupid joke. Argument is NULL");
377     return 1;
378     }
379   
380   AliDebug(1, Form("name = %s Setting folder named %s.",GetName(),folder->GetName()));
381   
382   fFolder = folder;
383   TIter next(fBaseLoaders);
384   AliBaseLoader* bl;
385   
386   while ((bl = (AliBaseLoader*)next()))
387     {
388       bl->SetDataLoader(this);
389     }  
390   
391   return 0;
392 }
393
394 //______________________________________________________________________________
395 TFolder* AliDataLoader::GetEventFolder()
396 {
397   //
398   // Get EVENT folder
399   // Data that are changing from event to event, even in single run
400   //
401   AliDebug(1, "EF = %#x");
402   return fEventFolder;
403 }
404
405 //______________________________________________________________________________
406 AliRunLoader* AliDataLoader::GetRunLoader()
407 {
408   //
409   // Gets the run-loader from event folder
410   //
411   AliRunLoader* rg = 0x0;
412   TFolder* ef = GetEventFolder();
413   if (ef == 0x0)
414    {
415      AliError("Can not get event folder.");
416      return 0;
417    }
418   rg = dynamic_cast<AliRunLoader*>(ef->FindObject(AliRunLoader::GetRunLoaderName()));
419   return rg;
420 }
421
422 //______________________________________________________________________________
423 void AliDataLoader::CloseFile()
424 {
425   //
426   // Closes file
427   //
428   TIter next(fBaseLoaders);
429   AliBaseLoader* bl;
430   while ((bl = (AliBaseLoader*)next()))
431     {
432       if (bl->IsLoaded()) return;
433     }
434   
435   AliDebug(1, "Closing and deleting (object) file.");
436   
437   delete fFile;
438   fFile = 0x0;
439   fDirectory = 0x0;
440 }
441
442
443 //______________________________________________________________________________
444 void AliDataLoader::Clean()
445 {
446   //
447   // Cleans main data
448   //
449   GetBaseLoader(0)->Clean();
450 }
451
452 //______________________________________________________________________________
453 void AliDataLoader::CleanAll()
454 {
455   //
456   // Cleans all folders and tasks
457   //
458   TIter next(fBaseLoaders);
459   AliBaseLoader* bl;
460   while ((bl = (AliBaseLoader*)next()))
461     {
462       bl->Clean();
463     }
464 }
465
466 //______________________________________________________________________________
467 void AliDataLoader::SetFileNameSuffix(const TString& suffix)
468 {
469   //
470   // adds the suffix before ".root", 
471   // e.g. TPC.Digits.root -> TPC.DigitsMerged.root
472   // made on Jiri Chudoba demand
473   //
474   AliDebug(1, Form("suffix=%s",suffix.Data()));
475   AliDebug(1, Form("   Digits File Name before: %s",fFileName.Data()));
476   
477   static const TString dotroot(".root");
478   const TString& suffixdotroot = suffix + dotroot;
479   fFileName = fFileName.ReplaceAll(dotroot,suffixdotroot);
480   
481   AliDebug(1, Form("                    after : %s",fFileName.Data()));
482 }
483
484 //______________________________________________________________________________
485 Bool_t AliDataLoader::CheckReload()
486 {
487   //
488   // Checks if we have to reload given file
489   //
490   if (fFile == 0x0) return kFALSE;
491   TString tmp = SetFileOffset(fFileName);
492   if (tmp.CompareTo(fFile->GetName())) return kTRUE;  //file must be reloaded
493   return  kFALSE;
494 }
495
496 //______________________________________________________________________________
497 const TString AliDataLoader::SetFileOffset(const TString& fname)
498 {
499   //
500   // Return fname
501   //
502   Long_t offset = (Long_t)GetRunLoader()->GetFileOffset();
503   if (fNEventsPerFile > 0) {
504     offset = GetRunLoader()->GetEventNumber()/fNEventsPerFile;
505   }
506   if (offset < 1) return fname;
507   
508   TString soffset;
509   soffset += offset;//automatic conversion to string
510   TString dotroot(".root");
511   const TString& offfsetdotroot = offset + dotroot;
512   TString out = fname;
513   out = out.ReplaceAll(dotroot,offfsetdotroot);
514   AliDebug(1, Form("in=%s  out=%s.",fname.Data(),out.Data()));
515   return out;
516 }
517
518 //______________________________________________________________________________
519 void AliDataLoader::SetFileOption(Option_t* newopt)
520 {
521   //
522   // Sets file option
523   //
524   if (fFileOption.CompareTo(newopt) == 0) return;
525   fFileOption = newopt;
526   Reload();
527 }
528
529 //______________________________________________________________________________
530 void AliDataLoader::SetCompressionLevel(Int_t cl)
531 {
532   //
533   // Sets comression level for data defined by di
534   //
535   fCompressionLevel = cl;
536   if (fFile) fFile->SetCompressionLevel(cl);
537 }
538
539 //______________________________________________________________________________
540 void AliDataLoader::MakeTree()
541 {
542   //
543   // Makes tree for the current data loader
544   //
545   AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(fBaseLoaders->At(0));
546   if (tl == 0x0)
547    {
548      AliError("Can not make a tree because main base loader is not a tree loader");
549      return;
550    }
551   tl->MakeTree();
552 }
553
554 //______________________________________________________________________________
555 Bool_t AliDataLoader::IsFileWritable() const
556 {
557   //
558   // Returns true if file is writable
559   //
560   return (fFile)?fFile->IsWritable():kFALSE;
561 }
562
563 //______________________________________________________________________________
564 Bool_t AliDataLoader::IsFileOpen() const
565 {
566   //
567   // Returns true if file is writable
568   //
569   return (fFile)?fFile->IsOpen():kFALSE;
570 }
571
572 //______________________________________________________________________________
573 Bool_t AliDataLoader::IsOptionContrary(const TString& option) const
574 {
575   // Checks if passed option is contrary with file open option 
576   // which is passed option "writable" and existing option not wriable
577   // in reverse case it is no harm so it is NOT contrary
578   if (fFile == 0x0) return kFALSE; //file is not opened - no problem
579   
580   if ( ( AliLoader::IsOptionWritable(option)      == kTRUE  ) &&     // passed option is writable and 
581        ( AliLoader::IsOptionWritable(fFileOption) == kFALSE )    )   // existing one is not writable
582     {
583       return kTRUE;
584     }
585   
586   return kFALSE;
587 }
588
589
590 //______________________________________________________________________________
591 void AliDataLoader::AddBaseLoader(AliBaseLoader* bl)
592 {
593   //Adds a base loader to lits of base loaders managed by this data loader
594   //Managed data/task will be stored in proper root directory,
595   //and posted to 
596   // - in case of tree/object - data folder connected with detector associated with this data loader
597   // - in case of task - parental task which defined in this AliTaskLoader 
598   
599   if (bl == 0x0)
600     {
601       AliWarning("Pointer is null.");
602       return;
603     }
604   
605   TObject* obj = fBaseLoaders->FindObject(bl->GetName());
606   if (obj)
607     {
608       AliError("Can not add this base loader.");
609       AliError(Form("There exists already base loader which manages data named %s for this detector.",obj->GetName()));
610       return;
611     }
612  
613   fBaseLoaders->Add(bl);
614 }
615
616 //______________________________________________________________________________
617 AliBaseLoader* AliDataLoader::GetBaseLoader(const TString& name) const
618 {
619   //
620   // Return pointer to base loader
621   //
622   return dynamic_cast<AliBaseLoader*>(fBaseLoaders->FindObject(name));
623 }
624
625 //______________________________________________________________________________
626 AliBaseLoader* AliDataLoader::GetBaseLoader(Int_t n) const
627 {
628   //
629   // Gets the n-th base loader (what is n?)
630   //
631   return dynamic_cast<AliBaseLoader*>(fBaseLoaders->At(n));
632 }
633
634 //______________________________________________________________________________
635 TTree* AliDataLoader::Tree() const
636 {
637   // Returns tree from the main base loader
638   // it is just shortcut method for comfort of user
639   // main storage object does not have to be Tree  - 
640   // that is why first we need to check if it is a TreeLoader 
641   AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(GetBaseLoader(0));
642   if (tl == 0x0) return 0x0;
643   return tl->Tree();
644 }
645
646 //______________________________________________________________________________
647 void  AliDataLoader::SetDirName(TString& dirname)
648 {
649   //
650   // Sets the directory name where the files will be stored
651   //
652   AliDebug(10, Form("FileName before %s",fFileName.Data()));
653   Int_t n = fFileName.Last('/');
654   AliDebug(10, Form("Slash found on pos %d",n));
655   if (n > 0) fFileName = fFileName.Remove(0,n+1);
656   AliDebug(10, Form("Core FileName %s",fFileName.Data()));
657   fFileName = dirname + fFileName;
658   AliDebug(10, Form("FileName after %s",fFileName.Data()));
659 }
660
661 //______________________________________________________________________________
662 AliObjectLoader* AliDataLoader::GetBaseDataLoader()
663 {
664   //
665   // Gets the base data loader
666   //
667   return dynamic_cast<AliObjectLoader*>(GetBaseLoader(kData));
668 }
669
670 //______________________________________________________________________________
671 AliTaskLoader* AliDataLoader::GetBaseTaskLoader()
672 {
673   //
674   // Gets the base task loader
675   //
676   return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kTask));
677 }
678
679 //______________________________________________________________________________
680 AliBaseLoader* AliDataLoader::GetBaseQALoader()
681 {
682   //
683   // Gets the base QA loader
684   //
685   return GetBaseLoader(kQA);
686 }
687
688 //______________________________________________________________________________
689 AliTaskLoader* AliDataLoader::GetBaseQATaskLoader()
690 {
691   //
692   // Returns pointer to QA base loader
693   //
694   return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kQATask));
695 }
696
697 //______________________________________________________________________________
698 void AliDataLoader::SetBaseDataLoader(AliBaseLoader* bl)
699 {
700   //
701   // Sets data base loader
702   //
703   if (bl == 0x0)
704     {
705       AliError("Parameter is null");
706       return;
707     }
708   if (GetBaseDataLoader()) delete GetBaseDataLoader();
709   fBaseLoaders->AddAt(bl,kData);
710 }
711
712 //______________________________________________________________________________
713 void AliDataLoader::SetBaseTaskLoader(AliTaskLoader* bl)
714 {
715   //
716   // Sets Task base loader
717   //
718   if (bl == 0x0)
719    {
720      AliError("Parameter is null");
721      return;
722    }
723   if (GetBaseTaskLoader()) delete GetBaseTaskLoader();
724   fBaseLoaders->AddAt(bl,kTask);
725 }
726
727 //______________________________________________________________________________
728 void AliDataLoader::SetBaseQALoader(AliBaseLoader* bl)
729 {
730   //
731   // Sets QA base loader
732   //
733   if (bl == 0x0)
734     {
735       AliError("Parameter is null");
736       return;
737     }
738   if (GetBaseQALoader()) delete GetBaseQALoader();
739   fBaseLoaders->AddAt(bl,kQA);
740 }
741
742 //______________________________________________________________________________
743 void AliDataLoader::SetBaseQATaskLoader(AliTaskLoader* bl)
744 {
745   //
746   // Sets QA Task base loader
747   //
748   if (bl == 0x0)
749     {
750       AliError("Parameter is null");
751       return;
752    }
753   if (GetBaseQATaskLoader()) delete GetBaseQATaskLoader();
754   fBaseLoaders->AddAt(bl,kQATask);
755 }
756
757 //______________________________________________________________________________
758 void AliDataLoader::Synchronize()
759 {
760   //
761   // Synchronizes all writable files 
762   //
763   if ( fFile ) fFile->Flush();
764 }
765
766
767