Bug fix. Removed delete statement
[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 <TBits.h>
32 #include <TFile.h>
33 #include <TROOT.h>
34 #include <TString.h>
35
36 #include "AliDataLoader.h"
37 #include "AliLog.h"
38 #include "AliObjectLoader.h"
39 #include "AliRunLoader.h"
40 #include "AliTreeLoader.h"
41
42 ClassImp(AliDataLoader)
43
44 //______________________________________________________________________________
45 AliDataLoader::AliDataLoader():
46  fFileName(0),
47  fFile(0x0),
48  fDirectory(0x0),
49  fFileOption(),
50  fCompressionLevel(2),
51  fNEventsPerFile(0),
52  fBaseLoaders(0x0),
53  fHasTask(kFALSE),
54  fTaskName(),
55  fParentalTask(0x0),
56  fEventFolder(0x0),
57  fFolder(0x0)
58 {
59   
60 }
61
62 //______________________________________________________________________________
63 AliDataLoader::AliDataLoader(const char* filename, const char* contname, 
64                              const char* name, Option_t* opt):
65  TNamed(name,name),
66  fFileName(filename),
67  fFile(0x0),
68  fDirectory(0x0),
69  fFileOption(0),
70  fCompressionLevel(2),
71  fNEventsPerFile(0),
72  fBaseLoaders(new TObjArray(4)),
73  fHasTask(kFALSE),
74  fTaskName(),
75  fParentalTask(0x0),
76  fEventFolder(0x0),
77  fFolder(0x0)
78 {
79   //constructor
80   // creates a 0 loader, depending on option, default "T" is specialized loader for trees
81   // else standard object loader
82   // trees needs special care, becouse we need to set dir before writing
83   AliDebug(1, Form("File name is %s",fFileName.Data()));
84   
85   TString option(opt);
86   AliBaseLoader* bl;
87   if (option.CompareTo("T",TString::kIgnoreCase) == 0)
88     bl = new AliTreeLoader(contname,this);
89   else 
90     bl = new AliObjectLoader(contname,this);
91   fBaseLoaders->AddAt(bl,kData);
92   
93 }
94
95 //______________________________________________________________________________
96 AliDataLoader::~AliDataLoader()
97 {
98   //
99   //dtor
100   //
101   UnloadAll();
102 }
103
104 //______________________________________________________________________________
105 Int_t  AliDataLoader::SetEvent()
106 {
107   //
108   // The same that GetEvent but do not post data to folders
109   //
110   AliRunLoader* rl = GetRunLoader();
111   if (rl == 0x0)
112     {
113       AliError("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           AliDebug(1, Form("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           AliError(Form("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           AliWarning(Form(" File %s already opened. First close it.",fFile->GetName()));
191           return 0;
192         }
193       else
194         {
195           AliWarning(Form("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           AliWarning(Form("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       AliError(Form("Can not open file %s",fname.Data()));
220       return 1;
221     }
222   if (fFile->IsOpen() == kFALSE)
223     {//file is null
224       AliError(Form("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       AliError("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       AliError(Form("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   //
251   //unloads main data -  shortcut method 
252   //
253   GetBaseLoader(0)->Unload();
254 }
255
256 //______________________________________________________________________________
257 void AliDataLoader::UnloadAll()
258 {
259   //
260   // Unloads all data and tasks
261   //
262   if ( fFile == 0x0 ) return; //nothing loaded
263   
264   TIter next(fBaseLoaders);
265   AliBaseLoader* bl;
266   while ((bl = (AliBaseLoader*)next()))
267     {
268       bl->Unload();
269     }
270 }
271
272
273 //______________________________________________________________________________
274 Int_t AliDataLoader::Reload()
275 {
276   //
277   // Unloads and loads data again
278   //
279   if ( fFile == 0x0 ) return 0;
280   
281   TBits loaded(fBaseLoaders->GetEntries());  
282   TIter next(fBaseLoaders);
283   AliBaseLoader* bl;
284   
285   Int_t i = 0;
286   while ((bl = (AliBaseLoader*)next()))
287     {
288       if (bl->IsLoaded())
289         {
290           loaded.SetBitNumber(i++,kTRUE);
291           bl->Unload();
292         }
293     }
294   
295   Int_t retval;
296   i = 0;  
297   next.Reset();
298   while ((bl = (AliBaseLoader*)next()))
299     {
300       if (loaded.TestBitNumber(i++))
301         {
302           retval = bl->Load(fFileOption);
303           if (retval) 
304             {
305               AliError(Form("Error occur while loading %s",bl->GetName()));
306               return retval;
307             }
308         }
309     }
310   return 0;
311 }
312
313
314 //______________________________________________________________________________
315 Int_t AliDataLoader::WriteData(Option_t* opt)
316 {
317   //
318   // Writes primary data ==  first BaseLoader
319   //
320   AliDebug(1, Form("Writing %s container for %s data. Option is %s.",
321                    GetBaseLoader(0)->GetName(),GetName(),opt));
322   return GetBaseLoader(0)->WriteData(opt);
323 }
324
325 //______________________________________________________________________________
326 Int_t AliDataLoader::Load(Option_t* opt)
327 {
328   //
329   // Writes primary data ==  first BaseLoader
330   //
331   return GetBaseLoader(0)->Load(opt);
332 }
333
334 //______________________________________________________________________________
335 Int_t  AliDataLoader::SetEventFolder(TFolder* eventfolder)
336 {
337   //
338   // Sets the event folder
339   //
340   if (eventfolder == 0x0)
341     {
342       AliError("Stupid joke. Argument is NULL");
343       return 1;
344     }
345   AliDebug(1, Form("name = %s Setting Event Folder named %s.",
346                    GetName(),eventfolder->GetName()));
347   
348   fEventFolder = eventfolder;
349   return 0;
350 }
351
352
353 //______________________________________________________________________________
354 Int_t  AliDataLoader::SetFolder(TFolder* folder)
355 {
356   // Sets the folder and the data loaders
357   if (folder == 0x0)
358     {
359       AliError("Stupid joke. Argument is NULL");
360     return 1;
361     }
362   
363   AliDebug(1, Form("name = %s Setting folder named %s.",GetName(),folder->GetName()));
364   
365   fFolder = folder;
366   TIter next(fBaseLoaders);
367   AliBaseLoader* bl;
368   
369   while ((bl = (AliBaseLoader*)next()))
370     {
371       bl->SetDataLoader(this);
372     }  
373   
374   return 0;
375 }
376
377 //______________________________________________________________________________
378 TFolder* AliDataLoader::GetEventFolder()
379 {
380   //
381   // Get EVENT folder
382   // Data that are changing from event to event, even in single run
383   //
384   AliDebug(1, "EF = %#x");
385   return fEventFolder;
386 }
387
388 //______________________________________________________________________________
389 AliRunLoader* AliDataLoader::GetRunLoader()
390 {
391   //
392   // Gets the run-loader from event folder
393   //
394   AliRunLoader* rg = 0x0;
395   TFolder* ef = GetEventFolder();
396   if (ef == 0x0)
397    {
398      AliError("Can not get event folder.");
399      return 0;
400    }
401   rg = dynamic_cast<AliRunLoader*>(ef->FindObject(AliRunLoader::GetRunLoaderName()));
402   return rg;
403 }
404
405 //______________________________________________________________________________
406 void AliDataLoader::CloseFile()
407 {
408   //
409   // Closes file
410   //
411   TIter next(fBaseLoaders);
412   AliBaseLoader* bl;
413   while ((bl = (AliBaseLoader*)next()))
414     {
415       if (bl->IsLoaded()) return;
416     }
417   
418   AliDebug(1, "Closing and deleting (object) file.");
419   
420   delete fFile;
421   fFile = 0x0;
422   fDirectory = 0x0;
423 }
424
425
426 //______________________________________________________________________________
427 void AliDataLoader::Clean()
428 {
429   //
430   // Cleans main data
431   //
432   GetBaseLoader(0)->Clean();
433 }
434
435 //______________________________________________________________________________
436 void AliDataLoader::CleanAll()
437 {
438   //
439   // Cleans all folders and tasks
440   //
441   TIter next(fBaseLoaders);
442   AliBaseLoader* bl;
443   while ((bl = (AliBaseLoader*)next()))
444     {
445       bl->Clean();
446     }
447 }
448
449 //______________________________________________________________________________
450 void AliDataLoader::SetFileNameSuffix(const TString& suffix)
451 {
452   //
453   // adds the suffix before ".root", 
454   // e.g. TPC.Digits.root -> TPC.DigitsMerged.root
455   // made on Jiri Chudoba demand
456   //
457   AliDebug(1, Form("suffix=%s",suffix.Data()));
458   AliDebug(1, Form("   Digits File Name before: %s",fFileName.Data()));
459   
460   static TString dotroot(".root");
461   const TString& suffixdotroot = suffix + dotroot;
462   fFileName = fFileName.ReplaceAll(dotroot,suffixdotroot);
463   
464   AliDebug(1, Form("                    after : %s",fFileName.Data()));
465 }
466
467 //______________________________________________________________________________
468 Bool_t AliDataLoader::CheckReload()
469 {
470   //
471   // Checks if we have to reload given file
472   //
473   if (fFile == 0x0) return kFALSE;
474   TString tmp = SetFileOffset(fFileName);
475   if (tmp.CompareTo(fFile->GetName())) return kTRUE;  //file must be reloaded
476   return  kFALSE;
477 }
478
479 //______________________________________________________________________________
480 const TString AliDataLoader::SetFileOffset(const TString& fname)
481 {
482   //
483   // Return fname
484   //
485   Long_t offset = (Long_t)GetRunLoader()->GetFileOffset();
486   if (fNEventsPerFile > 0) {
487     offset = GetRunLoader()->GetEventNumber()/fNEventsPerFile;
488   }
489   if (offset < 1) return fname;
490   
491   TString soffset;
492   soffset += offset;//automatic conversion to string
493   TString dotroot(".root");
494   const TString& offfsetdotroot = offset + dotroot;
495   TString out = fname;
496   out = out.ReplaceAll(dotroot,offfsetdotroot);
497   AliDebug(1, Form("in=%s  out=%s.",fname.Data(),out.Data()));
498   return out;
499 }
500
501 //______________________________________________________________________________
502 void AliDataLoader::SetFileOption(Option_t* newopt)
503 {
504   //
505   // Sets file option
506   //
507   if (fFileOption.CompareTo(newopt) == 0) return;
508   fFileOption = newopt;
509   Reload();
510 }
511
512 //______________________________________________________________________________
513 void AliDataLoader::SetCompressionLevel(Int_t cl)
514 {
515   //
516   // Sets comression level for data defined by di
517   //
518   fCompressionLevel = cl;
519   if (fFile) fFile->SetCompressionLevel(cl);
520 }
521
522 //______________________________________________________________________________
523 void AliDataLoader::MakeTree()
524 {
525   //
526   // Makes tree for the current data loader
527   //
528   AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(fBaseLoaders->At(0));
529   if (tl == 0x0)
530    {
531      AliError("Can not make a tree because main base loader is not a tree loader");
532      return;
533    }
534   tl->MakeTree();
535 }
536
537 //______________________________________________________________________________
538 Bool_t AliDataLoader::IsFileWritable() const
539 {
540   //
541   // Returns true if file is writable
542   //
543   return (fFile)?fFile->IsWritable():kFALSE;
544 }
545
546 //______________________________________________________________________________
547 Bool_t AliDataLoader::IsFileOpen() const
548 {
549   //
550   // Returns true if file is writable
551   //
552   return (fFile)?fFile->IsOpen():kFALSE;
553 }
554
555 //______________________________________________________________________________
556 Bool_t AliDataLoader::IsOptionContrary(const TString& option) const
557 {
558   // Checks if passed option is contrary with file open option 
559   // which is passed option "writable" and existing option not wriable
560   // in reverse case it is no harm so it is NOT contrary
561   if (fFile == 0x0) return kFALSE; //file is not opened - no problem
562   
563   if ( ( AliLoader::IsOptionWritable(option)      == kTRUE  ) &&     // passed option is writable and 
564        ( AliLoader::IsOptionWritable(fFileOption) == kFALSE )    )   // existing one is not writable
565     {
566       return kTRUE;
567     }
568   
569   return kFALSE;
570 }
571
572
573 //______________________________________________________________________________
574 void AliDataLoader::AddBaseLoader(AliBaseLoader* bl)
575 {
576   //Adds a base loader to lits of base loaders managed by this data loader
577   //Managed data/task will be stored in proper root directory,
578   //and posted to 
579   // - in case of tree/object - data folder connected with detector associated with this data loader
580   // - in case of task - parental task which defined in this AliTaskLoader 
581   
582   if (bl == 0x0)
583     {
584       AliWarning("Pointer is null.");
585       return;
586     }
587   
588   TObject* obj = fBaseLoaders->FindObject(bl->GetName());
589   if (obj)
590     {
591       AliError("Can not add this base loader.");
592       AliError(Form("There exists already base loader which manages data named %s for this detector.",obj->GetName()));
593       return;
594     }
595  
596   fBaseLoaders->Add(bl);
597 }
598
599 //______________________________________________________________________________
600 AliBaseLoader* AliDataLoader::GetBaseLoader(const TString& name) const
601 {
602   //
603   // Return pointer to base loader
604   //
605   return dynamic_cast<AliBaseLoader*>(fBaseLoaders->FindObject(name));
606 }
607
608 //______________________________________________________________________________
609 AliBaseLoader* AliDataLoader::GetBaseLoader(Int_t n) const
610 {
611   //
612   // Gets the n-th base loader (what is n?)
613   //
614   return dynamic_cast<AliBaseLoader*>(fBaseLoaders->At(n));
615 }
616
617 //______________________________________________________________________________
618 TTree* AliDataLoader::Tree() const
619 {
620   // Returns tree from the main base loader
621   // it is just shortcut method for comfort of user
622   // main storage object does not have to be Tree  - 
623   // that is why first we need to check if it is a TreeLoader 
624   AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(GetBaseLoader(0));
625   if (tl == 0x0) return 0x0;
626   return tl->Tree();
627 }
628
629 //______________________________________________________________________________
630 void  AliDataLoader::SetDirName(TString& dirname)
631 {
632   //
633   // Sets the directory name where the files will be stored
634   //
635   AliDebug(10, Form("FileName before %s",fFileName.Data()));
636   Int_t n = fFileName.Last('/');
637   AliDebug(10, Form("Slash found on pos %d",n));
638   if (n > 0) fFileName = fFileName.Remove(0,n+1);
639   AliDebug(10, Form("Core FileName %s",fFileName.Data()));
640   fFileName = dirname + fFileName;
641   AliDebug(10, Form("FileName after %s",fFileName.Data()));
642 }
643
644 //______________________________________________________________________________
645 AliObjectLoader* AliDataLoader::GetBaseDataLoader()
646 {
647   //
648   // Gets the base data loader
649   //
650   return dynamic_cast<AliObjectLoader*>(GetBaseLoader(kData));
651 }
652
653 //______________________________________________________________________________
654 AliTaskLoader* AliDataLoader::GetBaseTaskLoader()
655 {
656   //
657   // Gets the base task loader
658   //
659   return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kTask));
660 }
661
662 //______________________________________________________________________________
663 AliBaseLoader* AliDataLoader::GetBaseQALoader()
664 {
665   //
666   // Gets the base QA loader
667   //
668   return GetBaseLoader(kQA);
669 }
670
671 //______________________________________________________________________________
672 AliTaskLoader* AliDataLoader::GetBaseQATaskLoader()
673 {
674   //
675   // Returns pointer to QA base loader
676   //
677   return dynamic_cast<AliTaskLoader*>(GetBaseLoader(kQATask));
678 }
679
680 //______________________________________________________________________________
681 void AliDataLoader::SetBaseDataLoader(AliBaseLoader* bl)
682 {
683   //
684   // Sets data base loader
685   //
686   if (bl == 0x0)
687     {
688       AliError("Parameter is null");
689       return;
690     }
691   if (GetBaseDataLoader()) delete GetBaseDataLoader();
692   fBaseLoaders->AddAt(bl,kData);
693 }
694
695 //______________________________________________________________________________
696 void AliDataLoader::SetBaseTaskLoader(AliTaskLoader* bl)
697 {
698   //
699   // Sets Task base loader
700   //
701   if (bl == 0x0)
702    {
703      AliError("Parameter is null");
704      return;
705    }
706   if (GetBaseTaskLoader()) delete GetBaseTaskLoader();
707   fBaseLoaders->AddAt(bl,kTask);
708 }
709
710 //______________________________________________________________________________
711 void AliDataLoader::SetBaseQALoader(AliBaseLoader* bl)
712 {
713   //
714   // Sets QA base loader
715   //
716   if (bl == 0x0)
717     {
718       AliError("Parameter is null");
719       return;
720     }
721   if (GetBaseQALoader()) delete GetBaseQALoader();
722   fBaseLoaders->AddAt(bl,kQA);
723 }
724
725 //______________________________________________________________________________
726 void AliDataLoader::SetBaseQATaskLoader(AliTaskLoader* bl)
727 {
728   //
729   // Sets QA Task base loader
730   //
731   if (bl == 0x0)
732     {
733       AliError("Parameter is null");
734       return;
735    }
736   if (GetBaseQATaskLoader()) delete GetBaseQATaskLoader();
737   fBaseLoaders->AddAt(bl,kQATask);
738 }
739
740 //______________________________________________________________________________
741 void AliDataLoader::Synchronize()
742 {
743   //
744   // Synchronizes all writable files 
745   //
746   if ( fFile ) fFile->Flush();
747 }
748
749
750