Update master to aliroot
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliOADBContainer.cxx
CommitLineData
cc336771 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
cc336771 23#include "AliOADBContainer.h"
24#include "AliLog.h"
25#include <TObjArray.h>
26#include <TArrayI.h>
27#include <TFile.h>
bad1b400 28#include <TList.h>
60cfe266 29#include <TBrowser.h>
30#include <TSystem.h>
31#include <TError.h>
e7d0c332 32#include <TROOT.h>
10699bec 33#include "TObjString.h"
cc336771 34
35ClassImp(AliOADBContainer);
36
37//______________________________________________________________________________
38AliOADBContainer::AliOADBContainer() :
39 TNamed(),
63671ce7 40 fArray(0),
41 fDefaultList(0),
10699bec 42 fPassNames(0),
cc336771 43 fLowerLimits(),
44 fUpperLimits(),
45 fEntries(0)
46{
58a28442 47 // Default constructor
cc336771 48}
49
0add5ddf 50AliOADBContainer::AliOADBContainer(const char* name) :
cc336771 51 TNamed(name, "OADBContainer"),
52 fArray(new TObjArray(100)),
bad1b400 53 fDefaultList(new TList()),
10699bec 54 fPassNames(new TObjArray(100)),
cc336771 55 fLowerLimits(),
56 fUpperLimits(),
57 fEntries(0)
58{
58a28442 59 // Constructor
cc336771 60}
61
62
63//______________________________________________________________________________
64AliOADBContainer::~AliOADBContainer()
65{
66 // destructor
2a210779 67 if (fArray) delete fArray;
68 if (fDefaultList) delete fDefaultList;
10699bec 69 if (fPassNames) delete fPassNames;
2a210779 70
cc336771 71}
72
73//______________________________________________________________________________
74AliOADBContainer::AliOADBContainer(const AliOADBContainer& cont) :
75 TNamed(cont),
76 fArray(cont.fArray),
bad1b400 77 fDefaultList(cont.fDefaultList),
10699bec 78 fPassNames(cont.fPassNames),
cc336771 79 fLowerLimits(cont.fLowerLimits),
80 fUpperLimits(cont.fUpperLimits),
81 fEntries(cont.fEntries)
82{
83 // Copy constructor.
84}
85
86//______________________________________________________________________________
87AliOADBContainer& AliOADBContainer::operator=(const AliOADBContainer& cont)
88{
58a28442 89 //
cc336771 90 // Assignment operator
58a28442 91 // Copy objects related to run ranges
cc336771 92 if(this!=&cont) {
93 TNamed::operator=(cont);
35f37af6 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);
10699bec 101 if (cont.fPassNames) if (cont.fPassNames->At(i)) fPassNames->AddAt(cont.fPassNames->At(i), i);
35f37af6 102 }
cc336771 103 }
58a28442 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 //
cc336771 111 return *this;
112}
113
10699bec 114void AliOADBContainer::AppendObject(TObject* obj, Int_t lower, Int_t upper, TString passName)
cc336771 115{
10699bec 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 }
58a28442 120 //
cc336771 121 // Append a new object to the list
58a28442 122 //
123 // Check that there is no overlap with existing run ranges
10699bec 124 Int_t index = HasOverlap(lower, upper, passName);
58a28442 125
126 if (index != -1) {
dcfbfe28 127 AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
58a28442 128 return;
129 }
130 //
131 // Adjust arrays
cc336771 132 fEntries++;
133 fLowerLimits.Set(fEntries);
134 fUpperLimits.Set(fEntries);
58a28442 135 // Add the object
cc336771 136 fLowerLimits[fEntries - 1] = lower;
137 fUpperLimits[fEntries - 1] = upper;
cc336771 138 fArray->Add(obj);
10699bec 139 fPassNames->Add(new TObjString(passName.Data()));
cc336771 140}
141
142void AliOADBContainer::RemoveObject(Int_t idx)
143{
10699bec 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
58a28442 149 //
cc336771 150 // Remove object from the list
58a28442 151
152 //
153 // Check that index is inside range
cc336771 154 if (idx < 0 || idx >= fEntries)
155 {
156 AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
157 return;
158 }
58a28442 159 //
160 // Remove the object
cc336771 161 TObject* obj = fArray->RemoveAt(idx);
162 delete obj;
10699bec 163
164 TObject* pass = fPassNames->RemoveAt(idx);
165 delete pass;
58a28442 166 //
167 // Adjust the run ranges and shrink the array
cc336771 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);
10699bec 172 fPassNames->AddAt(fPassNames->At(i+1),i);
cc336771 173 }
174 fArray->RemoveAt(fEntries - 1);
10699bec 175 fPassNames->RemoveAt(fEntries - 1);
cc336771 176 fEntries--;
177}
178
10699bec 179void AliOADBContainer::UpdateObject(Int_t idx, TObject* obj, Int_t lower, Int_t upper, TString passName)
cc336771 180{
58a28442 181 //
0add5ddf 182 // Update an existing object, at a given position
183
58a28442 184 // Check that index is inside range
cc336771 185 if (idx < 0 || idx >= fEntries)
186 {
187 AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
188 return;
189 }
58a28442 190 //
0add5ddf 191 // Remove the old object and reset the range
d0f63026 192 // TObject* obj2 =
193 fArray->RemoveAt(idx);
e3c81f72 194 // don't delete it: if you are updating it may be pointing to the same location of obj...
0add5ddf 195 // delete obj2;
196 fLowerLimits[idx] = -1;
197 fUpperLimits[idx] = -1;
58a28442 198 // Check that there is no overlap with existing run ranges
10699bec 199 Int_t index = HasOverlap(lower, upper,passName);
58a28442 200 if (index != -1) {
9939b6b6 201 AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
58a28442 202 return;
203 }
204 //
0add5ddf 205 // Add object at the same position
e3c81f72 206 //printf("idx %d obj %llx\n", idx, obj);
cc336771 207 fLowerLimits[idx] = lower;
208 fUpperLimits[idx] = upper;
10699bec 209 TObjString* pass = (TObjString*) fPassNames->At(idx);
210 pass->SetString(passName.Data());
cc336771 211 fArray->AddAt(obj, idx);
0add5ddf 212
cc336771 213}
58a28442 214
08b752d1 215void AliOADBContainer::AddDefaultObject(TObject* obj)
bad1b400 216{
217 // Add a default object
218 fDefaultList->Add(obj);
219}
220
221void AliOADBContainer::CleanDefaultList()
222{
223 // Clean default list
224 fDefaultList->Delete();
225}
226
10699bec 227Int_t AliOADBContainer::GetIndexForRun(Int_t run, TString passName) const
cc336771 228{
bad1b400 229 //
cc336771 230 // Find the index for a given run
0add5ddf 231
cc336771 232 Int_t found = 0;
233 Int_t index = -1;
234 for (Int_t i = 0; i < fEntries; i++)
235 {
10699bec 236 if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
237 if (run >= fLowerLimits[i] && run <= fUpperLimits[i])
cc336771 238 {
239 found++;
240 index = i;
241 }
242 }
bad1b400 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) {
4dcd83a4 247 AliWarning(Form("No object (%s) found for run %5d !\n", GetName(), run));
bad1b400 248 }
249
cc336771 250 return index;
251}
252
10699bec 253TObject* AliOADBContainer::GetObject(Int_t run, const char* def, TString passName) const
bad1b400 254{
255 // Return object for given run or default if not found
256 TObject* obj = 0;
10699bec 257 Int_t idx = GetIndexForRun(run,passName);
258 if (idx == -1) idx = GetIndexForRun(run); // try default pass for this run range
bad1b400 259 if (idx == -1) {
260 // no object found, try default
261 obj = fDefaultList->FindObject(def);
262 if (!obj) {
4dcd83a4 263 AliError(Form("Default Object (%s) not found !\n", GetName()));
bad1b400 264 return (0);
265 } else {
266 return (obj);
267 }
268 } else {
269 return (fArray->At(idx));
270 }
271}
272
273TObject* AliOADBContainer::GetObjectByIndex(Int_t run) const
274{
275 // Return object for given index
276 return (fArray->At(run));
277}
278
10699bec 279TObject* 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
0add5ddf 287void AliOADBContainer::WriteToFile(const char* fname) const
cc336771 288{
bad1b400 289 //
cc336771 290 // Write object to file
a18817ac 291 TFile* f = new TFile(fname, "update");
cc336771 292 Write();
a18817ac 293 f->Purge();
cc336771 294 f->Close();
295}
bad1b400 296
0add5ddf 297Int_t AliOADBContainer::InitFromFile(const char* fname, const char* key)
35f37af6 298{
e7d0c332 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
35f37af6 329 // Initialize object from file
35f37af6 330 if (!file) return (1);
331 AliOADBContainer* cont = 0;
332 file->GetObject(key, cont);
333 if (!cont)
334 {
4dcd83a4 335 AliError(Form("Object (%s) not found in file \n", GetName()));
35f37af6 336 return 1;
337 }
d40bb25d 338
339 SetName(cont->GetName());
340 SetTitle(cont->GetTitle());
341
35f37af6 342 fEntries = cont->GetNumberOfEntries();
343 fLowerLimits.Set(fEntries);
344 fUpperLimits.Set(fEntries);
685113d4 345 if(fEntries > fArray->GetSize()) fArray->Expand(fEntries);
10699bec 346 if (!fPassNames) fPassNames = new TObjArray(100);
347 if(fEntries > fPassNames->GetSize()) fPassNames->Expand(fEntries);
685113d4 348
35f37af6 349 for (Int_t i = 0; i < fEntries; i++) {
350 fLowerLimits[i] = cont->LowerLimit(i);
351 fUpperLimits[i] = cont->UpperLimit(i);
bad1b400 352 fArray->AddAt(cont->GetObjectByIndex(i), i);
10699bec 353 TObject* passName = cont->GetPassNameByIndex(i);
354 fPassNames->AddAt(passName ? passName : new TObjString(""), i);
35f37af6 355 }
d40bb25d 356 if (!fDefaultList) fDefaultList = new TList();
58a28442 357 TIter next(cont->GetDefaultList());
358 TObject* obj;
359 while((obj = next())) fDefaultList->Add(obj);
360
35f37af6 361 return 0;
362
363}
364
cc336771 365
366void AliOADBContainer::List()
367{
bad1b400 368 //
cc336771 369 // List Objects
0add5ddf 370 printf("Entries %d\n", fEntries);
371
cc336771 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 }
58a28442 376 TIter next(fDefaultList);
377 TObject* obj;
378 while((obj = next())) obj->Dump();
379
380}
381
10699bec 382Int_t AliOADBContainer::HasOverlap(Int_t lower, Int_t upper, TString passName) const
58a28442 383{
384 //
385 // Checks for overlpapping validity regions
386 for (Int_t i = 0; i < fEntries; i++) {
10699bec 387 if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
58a28442 388 if ((lower >= fLowerLimits[i] && lower <= fUpperLimits[i]) ||
389 (upper >= fLowerLimits[i] && upper <= fUpperLimits[i]))
390 {
391 return (i);
392 }
393 }
394 return (-1);
cc336771 395}
08b752d1 396
397void 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++) {
10699bec 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() :""));
08b752d1 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
60cfe266 418//______________________________________________________________________________
419const 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}