#include <Riostream.h>
#include <TList.h>
#include <TCollection.h>
#include "AliLog.h"
#include "AliCFContainer.h"
#include "AliRsnValue.h"
#include "AliRsnValueDaughter.h"
#include "AliRsnValueEvent.h"
#include "AliRsnLoop.h"
#include "AliRsnListOutput.h"
ClassImp(AliRsnListOutput)
AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) :
TNamed(name, ""),
fSkipFailed(kTRUE),
fType(type),
fSteps(0),
fValues(0),
fNValues(0),
fList(0x0),
fIndex(-1),
fCheckHistRange(kTRUE),
fArray(0)
{
}
AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) :
TNamed(copy),
fSkipFailed(copy.fSkipFailed),
fType(copy.fType),
fSteps(copy.fSteps),
fValues(copy.fValues),
fNValues(copy.fNValues),
fList(copy.fList),
fIndex(copy.fIndex),
fCheckHistRange(copy.fCheckHistRange),
fArray(0)
{
}
AliRsnListOutput &AliRsnListOutput::operator=(const AliRsnListOutput ©)
{
TNamed::operator=(copy);
if (this == ©)
return *this;
fSkipFailed = copy.fSkipFailed;
fType = copy.fType;
fSteps = copy.fSteps;
fValues = copy.fValues;
fNValues = copy.fNValues;
fList = copy.fList;
fIndex = copy.fIndex;
fCheckHistRange = copy.fCheckHistRange;
fArray = copy.fArray;
Reset();
return (*this);
}
AliRsnListOutput::~AliRsnListOutput()
{
Reset();
}
void AliRsnListOutput::Reset()
{
fList = 0x0;
}
void AliRsnListOutput::AddValue(AliRsnValue *value)
{
fValues.AddLast(value);
}
Bool_t AliRsnListOutput::Init(const char *prefix, TList *list)
{
Int_t i;
Reset();
fNValues = fValues.GetEntries();
if (fNValues < 1) {
AliError("Need at least 1 value");
return kFALSE;
}
if (fType == kHistoDefault && fNValues > 3) {
AliInfo(Form("NValues = %d > 3 --> cannot use a normal histogram, need to use a sparse", fNValues));
fType = kHistoSparse;
}
fArray.Set(fNValues);
Bool_t isPair=kFALSE;
TString name(GetName());
if (!name.CompareTo("pair")) isPair = kTRUE;
if (isPair) name = "";
else name.Prepend(".");
name.Prepend(prefix);
AliRsnValue *val = 0x0;
for (i = 0; i < fNValues; i++) {
val = GetValue(i);
if (!val) {
AliError(Form("Slot %d in value list is NULL", i));
return kFALSE;
}
if (!isPair) {
name += '_';
name += val->GetName();
}
}
TObject *object = 0x0;
switch (fType) {
case kHistoDefault:
object = CreateHistogram(name.Data());
break;
case kHistoSparse:
object = CreateHistogramSparse(name.Data());
break;
case kCFContainer:
object = CreateCFContainer(name.Data());
break;
default:
AliWarning("Wrong type output or initialization failure");
}
if (object) {
fList = list;
fList->Add(object);
fIndex = fList->IndexOf(object);
return kTRUE;
}
return kFALSE;
}
TH1 *AliRsnListOutput::CreateHistogram(const char *name)
{
Int_t i, nbins[3] = {0, 0, 0};
TArrayD array[3];
for (i = 0; i < fNValues; i++) {
AliRsnValue *val = GetValue(i);
if (!val) {
AliError(Form("Expected axis %d is NULL", i));
return 0x0;
}
nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
array[i] = GetValue(i)->GetArray();
}
TH1 *hist = 0x0;
switch (fNValues) {
case 1:
hist = new TH1F(name, "", nbins[0], array[0].GetArray());
break;
case 2:
hist = new TH2F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray());
break;
case 3:
hist = new TH3F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray(), nbins[2], array[2].GetArray());
break;
default:
return 0x0;
}
if (hist) hist->Sumw2();
return hist;
}
THnSparseF *AliRsnListOutput::CreateHistogramSparse(const char *name)
{
Int_t i, *nbins = new Int_t[fNValues];
TArrayD *array = new TArrayD[fNValues];
for (i = 0; i < fNValues; i++) {
nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
array[i] = GetValue(i)->GetArray();
}
THnSparseF *hist = new THnSparseF(name, "", fNValues, nbins);
hist->Sumw2();
AliRsnValue *val = 0x0;
for (i = 0; i < fNValues; i++) {
val = GetValue(i);
if (val) hist->GetAxis(i)->SetName(val->GetName());
hist->GetAxis(i)->Set(nbins[i], array[i].GetArray());
}
delete [] nbins;
delete [] array;
return hist;
}
AliCFContainer *AliRsnListOutput::CreateCFContainer(const char *name)
{
Int_t i, *nbins = new Int_t[fNValues];
TArrayD *array = new TArrayD[fNValues];
for (i = 0; i < fNValues; i++) {
nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
array[i] = GetValue(i)->GetArray();
}
AliCFContainer *cont = new AliCFContainer(name, "", fSteps, fNValues, nbins);
for (i = 0; i < fNValues; i++) {
cont->SetBinLimits(i, array[i].GetArray());
}
delete [] nbins;
delete [] array;
return cont;
}
Bool_t AliRsnListOutput::Fill(TObject *target, Int_t step)
{
Int_t i;
Bool_t globalOK = kTRUE;
AliRsnValue *val = 0x0;
for (i = 0; i < fNValues; i++) {
val = GetValue(i);
if (!val) {
AliError("NULL value found");
return kFALSE;
}
globalOK = globalOK && val->Eval(target);
fArray[i] = (Double_t)val->GetComputedValue();
}
if (!globalOK && fSkipFailed) return kFALSE;
if (!fList || fIndex < 0) {
AliError("List not initialized");
return kFALSE;
}
TObject *obj = fList->At(fIndex);
if (!obj) {
AliError("Null pointer");
return kFALSE;
}
if (obj->IsA() == TH1F::Class()) {
TH1F *h = (TH1F *)obj;
h->Fill(fArray[0]);
return kTRUE;
} else if (obj->IsA() == TH2F::Class()) {
TH2F *h = (TH2F *)obj;
h->Fill(fArray[0], fArray[1]);
return kTRUE;
} else if (obj->IsA() == TH3F::Class()) {
TH3F *h = (TH3F *)obj;
h->Fill(fArray[0], fArray[1], fArray[2]);
return kTRUE;
} else if (obj->InheritsFrom(THnSparse::Class())) {
THnSparseF *h = (THnSparseF *)obj;
if (fCheckHistRange) {
for (Int_t iAxis = 0; iAxis<h->GetNdimensions(); iAxis++) {
if (fArray.At(iAxis)>h->GetAxis(iAxis)->GetXmax() || fArray.At(iAxis)<h->GetAxis(iAxis)->GetXmin()) return kFALSE;
}
}
h->Fill(fArray.GetArray());
return kTRUE;
} else if (obj->InheritsFrom(AliCFContainer::Class())) {
AliCFContainer *c = (AliCFContainer *)obj;
c->Fill(fArray.GetArray(), step);
return kTRUE;
} else {
AliError(Form("Not handled class '%s'", obj->ClassName()));
return kFALSE;
}
}
Bool_t AliRsnListOutput::Fill(AliRsnEvent *ev, AliRsnDaughter *d)
{
if (!fList || fIndex < 0) {
AliError("List not initialized");
return kFALSE;
}
TObject *obj = fList->At(fIndex);
if (!obj) {
AliError("Null pointer");
return kFALSE;
}
TIter next(&fValues);
AliRsnValue *val;
Int_t i=0;
Bool_t globalOK = kTRUE;
Double_t values[fValues.GetEntries()];
while ((val = (AliRsnValue *)next())) {
if (val->InheritsFrom(AliRsnValueDaughter::Class())) {
if (!d && fSkipFailed) return kFALSE;
globalOK = globalOK && val->Eval(d);
} else if (val->InheritsFrom(AliRsnValueEvent::Class())) {
if (!ev && fSkipFailed) return kFALSE;
globalOK = globalOK && val->Eval(ev);
}
values[i] = (Double_t)val->GetComputedValue();
if (!globalOK && fSkipFailed) return kFALSE;
i++;
}
if (obj->IsA() == TH1F::Class()) {
TH1F *h = (TH1F *)obj;
h->Fill(values[0]);
return kTRUE;
} else if (obj->IsA() == TH2F::Class()) {
TH2F *h = (TH2F *)obj;
h->Fill(values[0], values[1]);
return kTRUE;
} else if (obj->IsA() == TH3F::Class()) {
TH3F *h = (TH3F *)obj;
h->Fill(values[0], values[1], values[2]);
return kTRUE;
} else if (obj->InheritsFrom(THnSparse::Class())) {
THnSparseF *h = (THnSparseF *)obj;
if (fCheckHistRange) {
for (Int_t iAxis = 0; iAxis<h->GetNdimensions(); iAxis++) {
if (values[iAxis]>h->GetAxis(iAxis)->GetXmax() || values[iAxis]<h->GetAxis(iAxis)->GetXmin()) return kFALSE;
}
}
h->Fill(values);
return kTRUE;
} else {
AliError(Form("Not handled class '%s'", obj->ClassName()));
return kFALSE;
}
}