#include "AliOADBContainer.h"
#include "AliLog.h"
#include <TObjArray.h>
#include <TArrayI.h>
#include <TFile.h>
#include <TList.h>
#include <TBrowser.h>
#include <TSystem.h>
#include <TError.h>
#include <TROOT.h>
#include "TObjString.h"
ClassImp(AliOADBContainer);
AliOADBContainer::AliOADBContainer() :
TNamed(),
fArray(0),
fDefaultList(0),
fPassNames(0),
fLowerLimits(),
fUpperLimits(),
fEntries(0)
{
}
AliOADBContainer::AliOADBContainer(const char* name) :
TNamed(name, "OADBContainer"),
fArray(new TObjArray(100)),
fDefaultList(new TList()),
fPassNames(new TObjArray(100)),
fLowerLimits(),
fUpperLimits(),
fEntries(0)
{
}
AliOADBContainer::~AliOADBContainer()
{
if (fArray) delete fArray;
if (fDefaultList) delete fDefaultList;
if (fPassNames) delete fPassNames;
}
AliOADBContainer::AliOADBContainer(const AliOADBContainer& cont) :
TNamed(cont),
fArray(cont.fArray),
fDefaultList(cont.fDefaultList),
fPassNames(cont.fPassNames),
fLowerLimits(cont.fLowerLimits),
fUpperLimits(cont.fUpperLimits),
fEntries(cont.fEntries)
{
}
AliOADBContainer& AliOADBContainer::operator=(const AliOADBContainer& cont)
{
if(this!=&cont) {
TNamed::operator=(cont);
fEntries = cont.fEntries;
fLowerLimits.Set(fEntries);
fUpperLimits.Set(fEntries);
for (Int_t i = 0; i < fEntries; i++) {
fLowerLimits[i] = cont.fLowerLimits[i];
fUpperLimits[i] = cont.fUpperLimits[i];
fArray->AddAt(cont.fArray->At(i), i);
if (cont.fPassNames) if (cont.fPassNames->At(i)) fPassNames->AddAt(cont.fPassNames->At(i), i);
}
}
TList* list = cont.GetDefaultList();
TIter next(list);
TObject* obj;
while((obj = next())) fDefaultList->Add(obj);
return *this;
}
void AliOADBContainer::AppendObject(TObject* obj, Int_t lower, Int_t upper, TString passName)
{
if (!fPassNames) {
fPassNames = new TObjArray(100);
for (Int_t i=0;i<fArray->GetEntriesFast();i++) fPassNames->Add(new TObjString(""));
}
Int_t index = HasOverlap(lower, upper, passName);
if (index != -1) {
AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
return;
}
fEntries++;
fLowerLimits.Set(fEntries);
fUpperLimits.Set(fEntries);
fLowerLimits[fEntries - 1] = lower;
fUpperLimits[fEntries - 1] = upper;
fArray->Add(obj);
fPassNames->Add(new TObjString(passName.Data()));
}
void AliOADBContainer::RemoveObject(Int_t idx)
{
if (!fPassNames) {
fPassNames = new TObjArray(100);
for (Int_t i=0;i<fArray->GetEntriesFast();i++) fPassNames->Add(new TObjString(""));
}
if (idx < 0 || idx >= fEntries)
{
AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
return;
}
TObject* obj = fArray->RemoveAt(idx);
delete obj;
TObject* pass = fPassNames->RemoveAt(idx);
delete pass;
for (Int_t i = idx; i < (fEntries-1); i++) {
fLowerLimits[i] = fLowerLimits[i + 1];
fUpperLimits[i] = fUpperLimits[i + 1];
fArray->AddAt(fArray->At(i+1), i);
fPassNames->AddAt(fPassNames->At(i+1),i);
}
fArray->RemoveAt(fEntries - 1);
fPassNames->RemoveAt(fEntries - 1);
fEntries--;
}
void AliOADBContainer::UpdateObject(Int_t idx, TObject* obj, Int_t lower, Int_t upper, TString passName)
{
if (idx < 0 || idx >= fEntries)
{
AliError(Form("Index out of Range %5d >= %5d", idx, fEntries));
return;
}
fArray->RemoveAt(idx);
fLowerLimits[idx] = -1;
fUpperLimits[idx] = -1;
Int_t index = HasOverlap(lower, upper,passName);
if (index != -1) {
AliFatal(Form("Ambiguos validity range (%5d, %5.5d-%5.5d) !\n", index,lower,upper));
return;
}
fLowerLimits[idx] = lower;
fUpperLimits[idx] = upper;
TObjString* pass = (TObjString*) fPassNames->At(idx);
pass->SetString(passName.Data());
fArray->AddAt(obj, idx);
}
void AliOADBContainer::AddDefaultObject(TObject* obj)
{
fDefaultList->Add(obj);
}
void AliOADBContainer::CleanDefaultList()
{
fDefaultList->Delete();
}
Int_t AliOADBContainer::GetIndexForRun(Int_t run, TString passName) const
{
Int_t found = 0;
Int_t index = -1;
for (Int_t i = 0; i < fEntries; i++)
{
if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
if (run >= fLowerLimits[i] && run <= fUpperLimits[i])
{
found++;
index = i;
}
}
if (found > 1) {
AliError(Form("More than one (%5d) object found; return last (%5d) !\n", found, index));
} else if (index == -1) {
AliWarning(Form("No object (%s) found for run %5d !\n", GetName(), run));
}
return index;
}
TObject* AliOADBContainer::GetObject(Int_t run, const char* def, TString passName) const
{
TObject* obj = 0;
Int_t idx = GetIndexForRun(run,passName);
if (idx == -1) idx = GetIndexForRun(run);
if (idx == -1) {
obj = fDefaultList->FindObject(def);
if (!obj) {
AliError(Form("Default Object (%s) not found !\n", GetName()));
return (0);
} else {
return (obj);
}
} else {
return (fArray->At(idx));
}
}
TObject* AliOADBContainer::GetObjectByIndex(Int_t run) const
{
return (fArray->At(run));
}
TObject* AliOADBContainer::GetPassNameByIndex(Int_t idx) const
{
if (!fPassNames) return NULL;
return (fPassNames->At(idx));
}
void AliOADBContainer::WriteToFile(const char* fname) const
{
TFile* f = new TFile(fname, "update");
Write();
f->Purge();
f->Close();
}
Int_t AliOADBContainer::InitFromFile(const char* fname, const char* key)
{
printf("-----------------------------------------------\n");
printf("D-InitFromFile for file: %s and key %s\n",fname,key);
printf("D-List of already open files:\n");
TIter nextFile(gROOT->GetListOfFiles());
while (1) {
TObject *obj = nextFile();
if(!obj)break;
printf("%s\n",obj->GetName());
}
printf("-----------------------------------------------\n");
TFile* file(0);
const TSeqCollection *listOfFiles(gROOT->GetListOfFiles());
if(listOfFiles){
file =dynamic_cast<TFile*> (listOfFiles->FindObject(fname));
}
if(file){
printf("Success! File was already open!\n");
}
else{
printf("Couldn't find file, opening it\n");
file = TFile::Open(fname);
}
if (!file) return (1);
AliOADBContainer* cont = 0;
file->GetObject(key, cont);
if (!cont)
{
AliError(Form("Object (%s) not found in file \n", GetName()));
return 1;
}
SetName(cont->GetName());
SetTitle(cont->GetTitle());
fEntries = cont->GetNumberOfEntries();
fLowerLimits.Set(fEntries);
fUpperLimits.Set(fEntries);
if(fEntries > fArray->GetSize()) fArray->Expand(fEntries);
if (!fPassNames) fPassNames = new TObjArray(100);
if(fEntries > fPassNames->GetSize()) fPassNames->Expand(fEntries);
for (Int_t i = 0; i < fEntries; i++) {
fLowerLimits[i] = cont->LowerLimit(i);
fUpperLimits[i] = cont->UpperLimit(i);
fArray->AddAt(cont->GetObjectByIndex(i), i);
TObject* passName = cont->GetPassNameByIndex(i);
fPassNames->AddAt(passName ? passName : new TObjString(""), i);
}
if (!fDefaultList) fDefaultList = new TList();
TIter next(cont->GetDefaultList());
TObject* obj;
while((obj = next())) fDefaultList->Add(obj);
return 0;
}
void AliOADBContainer::List()
{
printf("Entries %d\n", fEntries);
for (Int_t i = 0; i < fEntries; i++) {
printf("Lower %5d Upper %5d \n", fLowerLimits[i], fUpperLimits[i]);
(fArray->At(i))->Dump();
}
TIter next(fDefaultList);
TObject* obj;
while((obj = next())) obj->Dump();
}
Int_t AliOADBContainer::HasOverlap(Int_t lower, Int_t upper, TString passName) const
{
for (Int_t i = 0; i < fEntries; i++) {
if (fPassNames) if (fPassNames->At(i)) if (passName.CompareTo(fPassNames->At(i)->GetName())) continue;
if ((lower >= fLowerLimits[i] && lower <= fUpperLimits[i]) ||
(upper >= fLowerLimits[i] && upper <= fUpperLimits[i]))
{
return (i);
}
}
return (-1);
}
void AliOADBContainer::Browse(TBrowser *b)
{
if (b) {
for (Int_t i = 0; i < fEntries; i++) {
TString pass = !fPassNames ? " - " : (fPassNames->At(i) ? Form(" - %s",fPassNames->At(i)->GetName()) : " - ");
b->Add(fArray->At(i),Form("%9.9d - %9.9d%s", fLowerLimits[i], fUpperLimits[i],pass.CompareTo(" - ")? pass.Data() :""));
}
TIter next(fDefaultList);
TObject* obj;
while((obj = next())) b->Add(obj);
}
else
TObject::Browse(b);
}
const char* AliOADBContainer::GetOADBPath()
{
static TString oadbPath;
if (gSystem->Getenv("OADB_PATH"))
oadbPath = gSystem->Getenv("OADB_PATH");
else if (gSystem->Getenv("ALICE_ROOT"))
oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
else
::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
return oadbPath;
}