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