ebc999bf5096d2bd12d8f73d8ae29aa63ab52963
[u/mrichter/AliRoot.git] / OADB / 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
24
25
26 #include "AliOADBContainer.h"
27 #include "AliLog.h"
28 #include <TObjArray.h>
29 #include <TArrayI.h>
30 #include <TFile.h>
31 #include <TList.h>
32 #include "TBrowser.h"
33
34 ClassImp(AliOADBContainer);
35
36 //______________________________________________________________________________
37 AliOADBContainer::AliOADBContainer() : 
38   TNamed(),
39   fArray(0),
40   fDefaultList(0),
41   fLowerLimits(),
42   fUpperLimits(),
43   fEntries(0)
44 {
45   // Default constructor
46 }
47
48 AliOADBContainer::AliOADBContainer(const char* name) : 
49   TNamed(name, "OADBContainer"),
50   fArray(new TObjArray(100)),
51   fDefaultList(new TList()),
52   fLowerLimits(),
53   fUpperLimits(),
54   fEntries(0)
55 {
56   // Constructor
57 }
58
59
60 //______________________________________________________________________________
61 AliOADBContainer::~AliOADBContainer() 
62 {
63   // destructor
64 }
65
66 //______________________________________________________________________________
67 AliOADBContainer::AliOADBContainer(const AliOADBContainer& cont) :
68   TNamed(cont),
69   fArray(cont.fArray),
70   fDefaultList(cont.fDefaultList),
71   fLowerLimits(cont.fLowerLimits),
72   fUpperLimits(cont.fUpperLimits),
73   fEntries(cont.fEntries)
74 {
75   // Copy constructor.
76 }
77
78 //______________________________________________________________________________
79 AliOADBContainer& AliOADBContainer::operator=(const AliOADBContainer& cont)
80 {
81   //
82   // Assignment operator
83   // Copy objects related to run ranges
84   if(this!=&cont) {
85     TNamed::operator=(cont);
86     fEntries = cont.fEntries;
87     fLowerLimits.Set(fEntries);
88     fUpperLimits.Set(fEntries);
89     for (Int_t i = 0; i < fEntries; i++) {
90         fLowerLimits[i] = cont.fLowerLimits[i]; 
91         fUpperLimits[i] = cont.fUpperLimits[i];
92         fArray->AddAt(cont.fArray->At(i), i);
93     }
94   }
95   //
96   // Copy default objects
97   TList* list = cont.GetDefaultList();
98   TIter next(list);
99   TObject* obj;
100   while((obj = next())) fDefaultList->Add(obj);
101   //
102   return *this;
103 }
104
105 void AliOADBContainer::AppendObject(TObject* obj, Int_t lower, Int_t upper)
106 {
107   //
108   // Append a new object to the list 
109   //
110   // Check that there is no overlap with existing run ranges
111   Int_t index = HasOverlap(lower, upper);
112   
113   if (index != -1) {
114     AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
115     return;
116   }
117   //
118   // Adjust arrays
119   fEntries++;
120   fLowerLimits.Set(fEntries);
121   fUpperLimits.Set(fEntries);
122
123   // Add the object
124   fLowerLimits[fEntries - 1] = lower;
125   fUpperLimits[fEntries - 1] = upper;
126   fArray->Add(obj);
127 }
128
129 void AliOADBContainer::RemoveObject(Int_t idx)
130 {
131   //
132   // Remove object from the list 
133
134   //
135   // Check that index is inside range 
136   if (idx < 0 || idx >= fEntries) 
137     {
138       AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
139       return;
140     }
141   //
142   // Remove the object
143   TObject* obj = fArray->RemoveAt(idx);
144   delete obj;
145   //
146   // Adjust the run ranges and shrink the array
147   for (Int_t i = idx; i < (fEntries-1); i++) {
148     fLowerLimits[i] = fLowerLimits[i + 1]; 
149     fUpperLimits[i] = fUpperLimits[i + 1];
150     fArray->AddAt(fArray->At(i+1), i);
151   }
152   fArray->RemoveAt(fEntries - 1);
153   fEntries--;
154 }
155
156 void AliOADBContainer::UpdateObject(Int_t idx, TObject* obj, Int_t lower, Int_t upper)
157 {
158   //
159   // Update an existing object, at a given position 
160
161   // Check that index is inside range
162   if (idx < 0 || idx >= fEntries) 
163     {
164       AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
165       return;
166     }
167   //
168   // Remove the old object and reset the range
169   //  TObject* obj2 = 
170   fArray->RemoveAt(idx);
171   // don't delete it: if you are updating it may be pointing to the same location of obj...
172   //  delete obj2;
173   fLowerLimits[idx] = -1;
174   fUpperLimits[idx] = -1;
175   // Check that there is no overlap with existing run ranges  
176   Int_t index = HasOverlap(lower, upper);
177   if (index != -1) {
178     AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
179     return;
180   }
181   //
182   // Add object at the same position
183   //printf("idx %d obj %llx\n", idx, obj);
184   fLowerLimits[idx] = lower;
185   fUpperLimits[idx] = upper;
186   fArray->AddAt(obj, idx);
187
188 }
189     
190  
191 void  AliOADBContainer::AddDefaultObject(TObject* obj)
192 {
193   // Add a default object
194   fDefaultList->Add(obj);
195 }
196
197 void  AliOADBContainer::CleanDefaultList()
198 {
199   // Clean default list
200   fDefaultList->Delete();
201 }
202
203 Int_t AliOADBContainer::GetIndexForRun(Int_t run) const
204 {
205   //
206   // Find the index for a given run 
207   
208   Int_t found = 0;
209   Int_t index = -1;
210   for (Int_t i = 0; i < fEntries; i++) 
211     {
212       if (run >= fLowerLimits[i] && run <= fUpperLimits[i])
213         {
214           found++;
215           index = i;
216         }
217     }
218
219   if (found > 1) {
220     AliError(Form("More than one (%5d) object found; return last (%5d) !\n", found, index));
221   } else if (index == -1) {
222     AliWarning(Form("No object found for run %5d !\n", run));
223   }
224   
225   return index;
226 }
227
228 TObject* AliOADBContainer::GetObject(Int_t run, const char* def) const
229 {
230   // Return object for given run or default if not found
231   TObject* obj = 0;
232   Int_t idx = GetIndexForRun(run);
233   if (idx == -1) {
234     // no object found, try default
235     obj = fDefaultList->FindObject(def);
236     if (!obj) {
237       AliError("Default Object not found !\n");
238       return (0);
239     } else {
240       return (obj);
241     }
242   } else {
243     return (fArray->At(idx));
244   }
245 }
246
247 TObject* AliOADBContainer::GetObjectByIndex(Int_t run) const
248 {
249   // Return object for given index
250   return (fArray->At(run));
251 }
252
253 void AliOADBContainer::WriteToFile(const char* fname) const
254 {
255   //
256   // Write object to file
257   TFile* f = new TFile(fname, "update");
258   Write();
259   f->Purge();
260   f->Close();
261 }
262
263 Int_t AliOADBContainer::InitFromFile(const char* fname, const char* key)
264 {
265     // 
266     // Initialize object from file
267     TFile* file = TFile::Open(fname);
268     if (!file) return (1);
269     AliOADBContainer* cont  = 0;
270     file->GetObject(key, cont);
271     if (!cont)
272     {
273         AliError("Object not found in file \n");        
274         return 1;
275     }
276
277     SetName(cont->GetName());
278     SetTitle(cont->GetTitle());
279
280     fEntries = cont->GetNumberOfEntries();
281     fLowerLimits.Set(fEntries);
282     fUpperLimits.Set(fEntries);
283     for (Int_t i = 0; i < fEntries; i++) {
284         fLowerLimits[i] = cont->LowerLimit(i); 
285         fUpperLimits[i] = cont->UpperLimit(i);
286         fArray->AddAt(cont->GetObjectByIndex(i), i);
287     }
288     if (!fDefaultList) fDefaultList = new TList(); 
289     TIter next(cont->GetDefaultList());
290     TObject* obj;
291     while((obj = next())) fDefaultList->Add(obj);
292
293     return 0;
294     
295 }
296
297
298 void AliOADBContainer::List()
299 {
300   //
301   // List Objects
302   printf("Entries %d\n", fEntries);
303   
304   for (Int_t i = 0; i < fEntries; i++) {
305     printf("Lower %5d Upper %5d \n", fLowerLimits[i], fUpperLimits[i]);
306     (fArray->At(i))->Dump();
307   }
308   TIter next(fDefaultList);
309   TObject* obj;
310   while((obj = next())) obj->Dump();
311
312 }
313
314 Int_t AliOADBContainer::HasOverlap(Int_t lower, Int_t upper) const
315 {
316   //
317   // Checks for overlpapping validity regions
318   for (Int_t i = 0; i < fEntries; i++) {
319     if ((lower >= fLowerLimits[i] && lower <= fUpperLimits[i]) ||
320         (upper >= fLowerLimits[i] && upper <= fUpperLimits[i]))
321       {
322         return (i);
323       }
324   }
325   return (-1);
326 }
327
328 void AliOADBContainer::Browse(TBrowser *b)
329 {
330    // Browse this object.
331    // If b=0, there is no Browse call TObject::Browse(0) instead.
332    //         This means TObject::Inspect() will be invoked indirectly
333
334
335   if (b) {
336     for (Int_t i = 0; i < fEntries; i++) {
337       b->Add(fArray->At(i),Form("%9.9d - %9.9d", fLowerLimits[i], fUpperLimits[i]));
338     }
339     TIter next(fDefaultList);
340     TObject* obj;
341     while((obj = next())) b->Add(obj);
342         
343   }     
344    else
345       TObject::Browse(b);
346 }
347