Including TFile.h
[u/mrichter/AliRoot.git] / STEER / AliBaseLoader.cxx
1 /////////////////////////////////////////////////////////////////////////////////////////////
2 //                                                                                         //
3 //  class AliBaseLoader                                                                    //
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 <TString.h>
32 #include <TFile.h>
33
34 #include "AliBaseLoader.h"
35 #include "AliLog.h"
36 #include "AliTreeLoader.h"
37 #include "AliRunLoader.h"
38
39 ClassImp(AliBaseLoader)
40
41 //______________________________________________________________________________
42 AliBaseLoader::AliBaseLoader():
43  fIsLoaded(kFALSE),
44  fStoreInTopOfFile(kFALSE),
45  fDoNotReload(kFALSE),
46  fDataLoader(0x0)
47 {
48   //
49   // default constructor
50   //
51 }
52
53 //______________________________________________________________________________
54 AliBaseLoader::AliBaseLoader(const TString& name,  AliDataLoader* dl, Bool_t storeontop):
55  TNamed(name,name+" Base Loader"),
56  fIsLoaded(kFALSE),
57  fStoreInTopOfFile(storeontop),
58  fDoNotReload(storeontop),//if stored on top of file - this object is loaded ones pe
59  fDataLoader(dl)
60 {
61   //
62   // constructor
63   //
64 }
65
66 //______________________________________________________________________________
67 AliBaseLoader::AliBaseLoader(const AliBaseLoader& source) : 
68   TNamed(source),
69   fIsLoaded(source.fIsLoaded),
70   fStoreInTopOfFile(source.fStoreInTopOfFile),
71   fDoNotReload(source.fDoNotReload),
72   fDataLoader(source.fDataLoader)
73 {
74   //
75   // copy constructor
76   //
77   AliFatal("Copy constructor not implemented");
78 }
79
80 //______________________________________________________________________________
81 AliBaseLoader& AliBaseLoader::operator=(const AliBaseLoader& /*source*/) 
82 {
83   //
84   // Assignment operator
85   //
86   AliFatal("Assignment operator not implemented");
87   return *this;
88 }
89
90 //______________________________________________________________________________
91 Int_t AliBaseLoader::Load(Option_t* opt)
92 {
93   //
94   // Loads and posts the data
95   //
96   AliDebug(1, Form("data type = %s, option = %s",GetName(),opt));
97   
98   if (Get())
99     {
100       AliDebug(1,Form("Data <<%s>> are already loaded. Use ReloadData to force reload. Nothing done",GetName()));
101       return 0;
102     }
103   
104   Int_t retval;
105   
106   if (GetDataLoader()->IsFileOpen() == kTRUE)
107     {
108       if (GetDataLoader()->IsOptionContrary(opt) == kTRUE)
109         {
110           AliError(Form("Data Type %s, Container Name %s", GetDataLoader()->GetName(),GetName()));
111           AliError("File was already opened in READ-ONLY mode, while now WRITEABLE access is requested.");
112           AliError("Use AliDataLoader::SetOption to enforce change of access mode OR");
113           AliError("Load previosly loaded data with coherent option.");
114           return 10;
115         }
116     }
117   else
118     {
119       retval = GetDataLoader()->OpenFile(opt);
120       if (retval) 
121         {
122           AliError(Form("Error occured while opening <<%s>> file",GetName()));
123           return retval;
124         }
125     }
126   //if file is recreated there is no sense to search for data to post and get Error message
127   if (AliLoader::TestFileOption(opt) == kFALSE)
128     {
129       AliTreeLoader* tl = dynamic_cast<AliTreeLoader*>(this);
130       if (tl) tl->MakeTree();
131       fIsLoaded = kTRUE;
132       return 0;
133     }
134   
135   retval = Post();
136   if (retval)
137     {
138       AliError(Form("Error occured while posting %s from file to folder.",GetName()));
139       return retval;
140     }
141   
142   fIsLoaded = kTRUE;
143   return 0;
144 }
145
146 //______________________________________________________________________________
147 Int_t AliBaseLoader::Post()
148 {
149   //
150   // Posts data container to proper folders
151   //
152   
153   if ( GetDirectory() == 0x0)
154     {
155       AliError(Form("%s directory is NULL. Load before.",GetDataLoader()->GetName()));
156       return 2; 
157     }
158   
159   TObject* data = GetFromDirectory(fName);
160   if(data)
161     {
162       //if such an obejct already exists - remove it first
163       return Post(data);
164     }
165   else
166     {
167       //check if file is in update mode
168       Int_t fileupdate = GetDataLoader()->GetFileOption().CompareTo("update",TString::kIgnoreCase);
169       if ( fileupdate == 0)
170         { //if it is, it is normal that there is no data yet
171           AliDebug(1, Form("Can not find %s in file %s (file is opened in UPDATE mode).",
172                            GetName(),GetDataLoader()->GetFile()->GetName()));
173         }
174       else
175         {
176           AliError(Form("Can not find %s in file %s", GetName(),GetDataLoader()->GetFile()->GetName()));
177           return 5;
178         }
179     }
180   return 0;
181 }
182
183 //______________________________________________________________________________
184 Int_t AliBaseLoader::Post(TObject* data)
185 {
186   //
187   // Posts data container to proper folders
188   //
189   if (data == 0x0)
190     {
191       AliError("Pointer to object is NULL");
192       return 1;
193     }
194   
195   if ( fName.CompareTo(data->GetName()) != 0)
196     {
197       AliFatal(Form("Object name is <<%s>> while <<%s>> expected",data->GetName(),GetName()));
198       return -1;//pro forma
199     }
200   
201   TObject* obj = Get();
202   if (data == obj)
203     {
204       AliWarning("This object was already posted.");
205       return 0;
206     }
207   if (obj)
208     {
209       AliWarning(Form("Object named %s already exitsts in data folder. Removing it",GetName()));
210       Clean();
211     }
212   return AddToBoard(data);
213 }
214
215 //______________________________________________________________________________
216 Int_t AliBaseLoader::WriteData(Option_t* opt)
217 {
218   //
219   // Writes data defined by di object
220   // opt might be "OVERWRITE" in case of forcing overwriting
221   //
222   AliDebug(1, Form("Writing %s container for %s data. Option is %s.",
223                    GetName(),GetDataLoader()->GetName(),opt));
224   
225   TObject *data = Get();
226   if(data == 0x0)
227     {//did not get, nothing to write
228       AliWarning(Form("Tree named %s not found in folder. Nothing to write.",GetName()));
229       return 0;
230     }
231   
232   //check if file is opened
233   if (GetDirectory() == 0x0)
234     { 
235       //if not try to open
236       GetDataLoader()->SetFileOption("UPDATE");
237       if (GetDataLoader()->OpenFile("UPDATE"))
238         {  
239           //oops, can not open the file, give an error message and return error code
240           AliError(Form("Can not open hits file. %s ARE NOT WRITTEN",GetName()));
241           return 1;
242         }
243     }
244   
245   if (GetDataLoader()->IsFileWritable() == kFALSE)
246     {
247       AliError(Form("File %s is not writable",GetDataLoader()->GetFileName().Data()));
248       return 2;
249     }
250   
251   GetDirectory()->cd(); //set the proper directory active
252   
253   //see if hits container already exists in this (root) directory
254   TObject* obj = GetFromDirectory(GetName());
255   if (obj)
256     { //if they exist, see if option OVERWRITE is used
257       const char *oOverWrite = strstr(opt,"OVERWRITE");
258       if(!oOverWrite)
259         {//if it is not used -  give an error message and return an error code
260           AliError("Tree already exisists. Use option \"OVERWRITE\" to overwrite previous data");
261           return 3;
262         }
263     }
264   
265   AliDebug(1, Form("DataName = %s, opt = %s, data object name = %s",
266                    GetName(),opt,data->GetName()));
267   AliDebug(1, Form("File Name = %s, Directory Name = %s Directory's File Name = %s",
268                    GetDataLoader()->GetFile()->GetName(),GetDirectory()->GetName(),
269                    GetDirectory()->GetFile()->GetName()));
270   
271   AliDebug(1, "Writing data");
272   data->Write(0,TObject::kOverwrite);
273   
274   fIsLoaded = kTRUE;  // Just to ensure flag is on. Object can be posted manually to folder structure, not using loader.
275   
276   return 0;
277   
278 }
279
280 //______________________________________________________________________________
281 Int_t AliBaseLoader::Reload()
282 {
283   //
284   // Unloads and loads datat again - if loaded before
285   //
286   if (IsLoaded())
287     {
288       Unload();
289       return Load(GetDataLoader()->GetFileOption());
290     }
291   return 0;
292 }
293
294 //______________________________________________________________________________
295 void AliBaseLoader::Clean()
296 {
297   //
298   // Removes objects from folder/task
299   //
300   AliDebug(1, Form("%s %s",GetName(),GetDataLoader()->GetName()));
301   TObject* obj = Get();
302   if(obj)
303     { 
304       AliDebug(1, Form("cleaning %s.",GetName()));
305       RemoveFromBoard(obj);
306       delete obj;
307     }
308 }
309
310 //______________________________________________________________________________
311 void AliBaseLoader::Unload()
312 {
313   // Unloads data and closes the files
314   Clean();
315   fIsLoaded = kFALSE;
316   GetDataLoader()->CloseFile();
317 }
318
319 //______________________________________________________________________________
320 AliDataLoader* AliBaseLoader::GetDataLoader() const
321 {
322   //
323   // Returns pointer to the data loader
324   //
325   if (fDataLoader == 0x0) 
326     {
327       AliFatal("Pointer to Data Loader is NULL");
328     }
329   return fDataLoader;
330 }
331
332 //______________________________________________________________________________
333 TDirectory* AliBaseLoader::GetDirectory() const
334 {
335   //
336   // returnd TDirectory where data are to be saved
337   // if fStoreInTopOfFile flag is true - returns pointer to file
338   //
339   return (fStoreInTopOfFile)?GetDataLoader()->GetFile():GetDataLoader()->GetDirectory();
340 }
341
342
343