]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEERBase/AliOADBContainer.cxx
Update master to aliroot
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliOADBContainer.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //-------------------------------------------------------------------------
19 //     Offline Analysis Database Container and Service Class 
20 //     Author: Andreas Morsch, CERN
21 //-------------------------------------------------------------------------
22
23 #include "AliOADBContainer.h"
24 #include "AliLog.h"
25 #include <TObjArray.h>
26 #include <TArrayI.h>
27 #include <TFile.h>
28 #include <TList.h>
29 #include <TBrowser.h>
30 #include <TSystem.h>
31 #include <TError.h>
32 #include <TROOT.h>
33 #include "TObjString.h"
34
35 ClassImp(AliOADBContainer);
36
37 //______________________________________________________________________________
38 AliOADBContainer::AliOADBContainer() : 
39   TNamed(),
40   fArray(0),
41   fDefaultList(0),
42   fPassNames(0),
43   fLowerLimits(),
44   fUpperLimits(),
45   fEntries(0)
46 {
47   // Default constructor
48 }
49
50 AliOADBContainer::AliOADBContainer(const char* name) : 
51   TNamed(name, "OADBContainer"),
52   fArray(new TObjArray(100)),
53   fDefaultList(new TList()),
54   fPassNames(new TObjArray(100)),
55   fLowerLimits(),
56   fUpperLimits(),
57   fEntries(0)
58 {
59   // Constructor
60 }
61
62
63 //______________________________________________________________________________
64 AliOADBContainer::~AliOADBContainer() 
65 {
66   // destructor
67   if (fArray)       delete fArray;
68   if (fDefaultList) delete fDefaultList;
69   if (fPassNames)   delete fPassNames;
70
71 }
72
73 //______________________________________________________________________________
74 AliOADBContainer::AliOADBContainer(const AliOADBContainer& cont) :
75   TNamed(cont),
76   fArray(cont.fArray),
77   fDefaultList(cont.fDefaultList),
78   fPassNames(cont.fPassNames),
79   fLowerLimits(cont.fLowerLimits),
80   fUpperLimits(cont.fUpperLimits),
81   fEntries(cont.fEntries)
82 {
83   // Copy constructor.
84 }
85
86 //______________________________________________________________________________
87 AliOADBContainer& AliOADBContainer::operator=(const AliOADBContainer& cont)
88 {
89   //
90   // Assignment operator
91   // Copy objects related to run ranges
92   if(this!=&cont) {
93     TNamed::operator=(cont);
94     fEntries = cont.fEntries;
95     fLowerLimits.Set(fEntries);
96     fUpperLimits.Set(fEntries);
97     for (Int_t i = 0; i < fEntries; i++) {
98         fLowerLimits[i] = cont.fLowerLimits[i]; 
99         fUpperLimits[i] = cont.fUpperLimits[i];
100         fArray->AddAt(cont.fArray->At(i), i);
101         if (cont.fPassNames) if (cont.fPassNames->At(i)) fPassNames->AddAt(cont.fPassNames->At(i), i);
102     }
103   }
104   //
105   // Copy default objects
106   TList* list = cont.GetDefaultList();
107   TIter next(list);
108   TObject* obj;
109   while((obj = next())) fDefaultList->Add(obj);
110   //
111   return *this;
112 }
113
114 void AliOADBContainer::AppendObject(TObject* obj, Int_t lower, Int_t upper, TString passName)
115 {
116   if (!fPassNames) { // create array of pass names for compatibility with old format
117     fPassNames = new TObjArray(100);
118     for (Int_t i=0;i<fArray->GetEntriesFast();i++) fPassNames->Add(new TObjString(""));
119   }
120   //
121   // Append a new object to the list 
122   //
123   // Check that there is no overlap with existing run ranges
124   Int_t index = HasOverlap(lower, upper, passName);
125   
126   if (index != -1) {
127     AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
128     return;
129   }
130   //
131   // Adjust arrays
132   fEntries++;
133   fLowerLimits.Set(fEntries);
134   fUpperLimits.Set(fEntries);
135   // Add the object
136   fLowerLimits[fEntries - 1] = lower;
137   fUpperLimits[fEntries - 1] = upper;
138   fArray->Add(obj);
139   fPassNames->Add(new TObjString(passName.Data()));
140 }
141
142 void AliOADBContainer::RemoveObject(Int_t idx)
143 {
144   if (!fPassNames) { // create array of pass names for compatibility with old format
145     fPassNames = new TObjArray(100);
146     for (Int_t i=0;i<fArray->GetEntriesFast();i++) fPassNames->Add(new TObjString(""));
147   }
148
149   //
150   // Remove object from the list 
151
152   //
153   // Check that index is inside range 
154   if (idx < 0 || idx >= fEntries) 
155     {
156       AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
157       return;
158     }
159   //
160   // Remove the object
161   TObject* obj = fArray->RemoveAt(idx);
162   delete obj;
163
164   TObject* pass = fPassNames->RemoveAt(idx);
165   delete pass;
166   //
167   // Adjust the run ranges and shrink the array
168   for (Int_t i = idx; i < (fEntries-1); i++) {
169     fLowerLimits[i] = fLowerLimits[i + 1]; 
170     fUpperLimits[i] = fUpperLimits[i + 1];
171     fArray->AddAt(fArray->At(i+1), i);
172     fPassNames->AddAt(fPassNames->At(i+1),i);
173   }
174   fArray->RemoveAt(fEntries - 1);
175   fPassNames->RemoveAt(fEntries - 1);
176   fEntries--;
177 }
178
179 void AliOADBContainer::UpdateObject(Int_t idx, TObject* obj, Int_t lower, Int_t upper, TString passName)
180 {
181   //
182   // Update an existing object, at a given position 
183
184   // Check that index is inside range
185   if (idx < 0 || idx >= fEntries) 
186     {
187       AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
188       return;
189     }
190   //
191   // Remove the old object and reset the range
192   //  TObject* obj2 = 
193   fArray->RemoveAt(idx);
194   // don't delete it: if you are updating it may be pointing to the same location of obj...
195   //  delete obj2;
196   fLowerLimits[idx] = -1;
197   fUpperLimits[idx] = -1;
198   // Check that there is no overlap with existing run ranges  
199   Int_t index = HasOverlap(lower, upper,passName);
200   if (index != -1) {
201     AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
202     return;
203   }
204   //
205   // Add object at the same position
206   //printf("idx %d obj %llx\n", idx, obj);
207   fLowerLimits[idx] = lower;
208   fUpperLimits[idx] = upper;
209   TObjString* pass = (TObjString*) fPassNames->At(idx);
210   pass->SetString(passName.Data());
211   fArray->AddAt(obj, idx);
212
213 }
214  
215 void  AliOADBContainer::AddDefaultObject(TObject* obj)
216 {
217   // Add a default object
218   fDefaultList->Add(obj);
219 }
220
221 void  AliOADBContainer::CleanDefaultList()
222 {
223   // Clean default list
224   fDefaultList->Delete();
225 }
226
227 Int_t AliOADBContainer::GetIndexForRun(Int_t run, TString passName) const
228 {
229   //
230   // Find the index for a given run 
231   
232   Int_t found = 0;
233   Int_t index = -1;
234   for (Int_t i = 0; i < fEntries; i++) 
235     {
236         if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
237         if (run >= fLowerLimits[i] && run <= fUpperLimits[i])
238         {
239           found++;
240           index = i;
241         }
242     }
243
244   if (found > 1) {
245     AliError(Form("More than one (%5d) object found; return last (%5d) !\n", found, index));
246   } else if (index == -1) {
247     AliWarning(Form("No object (%s) found for run %5d !\n", GetName(), run));
248   }
249   
250   return index;
251 }
252
253 TObject* AliOADBContainer::GetObject(Int_t run, const char* def, TString passName) const
254 {
255   // Return object for given run or default if not found
256   TObject* obj = 0;
257   Int_t idx = GetIndexForRun(run,passName);
258   if (idx == -1) idx = GetIndexForRun(run); // try default pass for this run range
259   if (idx == -1) {
260     // no object found, try default
261     obj = fDefaultList->FindObject(def);
262     if (!obj) {
263       AliError(Form("Default Object (%s) not found !\n", GetName()));
264       return (0);
265     } else {
266       return (obj);
267     }
268   } else {
269     return (fArray->At(idx));
270   }
271 }
272
273 TObject* AliOADBContainer::GetObjectByIndex(Int_t run) const
274 {
275   // Return object for given index
276   return (fArray->At(run));
277 }
278
279 TObject* AliOADBContainer::GetPassNameByIndex(Int_t idx) const
280 {
281   // Return object for given index
282   if (!fPassNames) return NULL; 
283   return (fPassNames->At(idx));
284 }
285
286
287 void AliOADBContainer::WriteToFile(const char* fname) const
288 {
289   //
290   // Write object to file
291   TFile* f = new TFile(fname, "update");
292   Write();
293   f->Purge();
294   f->Close();
295 }
296
297 Int_t AliOADBContainer::InitFromFile(const char* fname, const char* key)
298 {
299   //
300   // Hans: See whether the file is already open
301   //
302   // For now print info
303   printf("-----------------------------------------------\n");
304   printf("D-InitFromFile for file: %s and key %s\n",fname,key);
305   printf("D-List of already open files:\n");
306   TIter nextFile(gROOT->GetListOfFiles());
307   while (1) {
308     TObject *obj = nextFile();
309     if(!obj)break;
310     printf("%s\n",obj->GetName());
311   }
312   printf("-----------------------------------------------\n");
313
314   // Declare the file
315   TFile* file(0);
316   // Try to get the file from the list of already open files
317   const TSeqCollection *listOfFiles(gROOT->GetListOfFiles());
318   if(listOfFiles){
319     file =dynamic_cast<TFile*> (listOfFiles->FindObject(fname));
320   }
321   if(file){
322     printf("Success! File was already open!\n");
323   }
324   else{
325     printf("Couldn't find file, opening it\n");
326     file = TFile::Open(fname);
327   }
328
329     // Initialize object from file
330     if (!file) return (1);
331     AliOADBContainer* cont  = 0;
332     file->GetObject(key, cont);
333     if (!cont)
334     {
335       AliError(Form("Object (%s) not found in file \n", GetName()));    
336         return 1;
337     }
338
339     SetName(cont->GetName());
340     SetTitle(cont->GetTitle());
341
342     fEntries = cont->GetNumberOfEntries();
343     fLowerLimits.Set(fEntries);
344     fUpperLimits.Set(fEntries);
345     if(fEntries > fArray->GetSize()) fArray->Expand(fEntries);
346     if (!fPassNames) fPassNames = new TObjArray(100);
347     if(fEntries > fPassNames->GetSize()) fPassNames->Expand(fEntries);
348
349     for (Int_t i = 0; i < fEntries; i++) {
350         fLowerLimits[i] = cont->LowerLimit(i); 
351         fUpperLimits[i] = cont->UpperLimit(i);
352         fArray->AddAt(cont->GetObjectByIndex(i), i);
353         TObject* passName = cont->GetPassNameByIndex(i);
354         fPassNames->AddAt(passName ? passName : new TObjString(""), i);
355     }
356     if (!fDefaultList) fDefaultList = new TList(); 
357     TIter next(cont->GetDefaultList());
358     TObject* obj;
359     while((obj = next())) fDefaultList->Add(obj);
360
361     return 0;
362     
363 }
364
365
366 void AliOADBContainer::List()
367 {
368   //
369   // List Objects
370   printf("Entries %d\n", fEntries);
371   
372   for (Int_t i = 0; i < fEntries; i++) {
373     printf("Lower %5d Upper %5d \n", fLowerLimits[i], fUpperLimits[i]);
374     (fArray->At(i))->Dump();
375   }
376   TIter next(fDefaultList);
377   TObject* obj;
378   while((obj = next())) obj->Dump();
379
380 }
381
382 Int_t AliOADBContainer::HasOverlap(Int_t lower, Int_t upper, TString passName) const
383 {
384   //
385   // Checks for overlpapping validity regions
386   for (Int_t i = 0; i < fEntries; i++) {
387     if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
388     if ((lower >= fLowerLimits[i] && lower <= fUpperLimits[i]) ||
389         (upper >= fLowerLimits[i] && upper <= fUpperLimits[i]))
390       {
391         return (i);
392       }
393   }
394   return (-1);
395 }
396
397 void AliOADBContainer::Browse(TBrowser *b)
398 {
399    // Browse this object.
400    // If b=0, there is no Browse call TObject::Browse(0) instead.
401    //         This means TObject::Inspect() will be invoked indirectly
402
403
404   if (b) {
405     for (Int_t i = 0; i < fEntries; i++) {
406       TString pass = !fPassNames ? " - " : (fPassNames->At(i) ? Form(" - %s",fPassNames->At(i)->GetName()) : " - ");
407       b->Add(fArray->At(i),Form("%9.9d - %9.9d%s", fLowerLimits[i], fUpperLimits[i],pass.CompareTo(" - ")? pass.Data() :""));
408     }
409     TIter next(fDefaultList);
410     TObject* obj;
411     while((obj = next())) b->Add(obj);
412         
413   }     
414    else
415       TObject::Browse(b);
416 }
417
418 //______________________________________________________________________________
419 const char* AliOADBContainer::GetOADBPath()
420 {
421 // returns the path of the OADB
422 // this static function just depends on environment variables
423
424    static TString oadbPath;
425
426    if (gSystem->Getenv("OADB_PATH"))
427       oadbPath = gSystem->Getenv("OADB_PATH");
428    else if (gSystem->Getenv("ALICE_ROOT"))
429       oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
430    else
431    ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
432    return oadbPath;
433 }