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