#include "TTreeFormulaManager.h"
#include "TArrayI.h"
#include "TError.h"
#include "TLeafElement.h"
ClassImp(TTreeFormulaManager)
TTreeFormulaManager::TTreeFormulaManager() : TObject()
{
fMultiplicity = 0;
fMultiVarDim = kFALSE;
fNeedSync = kFALSE;
fNdata = 1;
for(Int_t i=0; i<kMAXFORMDIM+1; i++) {
fVarDims[i] = 0;
fCumulUsedSizes[i] = 1;
fUsedSizes[i] = 1;
fVirtUsedSizes[i] = 1;
}
fCumulUsedVarDims = 0;
}
TTreeFormulaManager::~TTreeFormulaManager()
{
for (int l = 0; l<kMAXFORMDIM; l++) {
if (fVarDims[l]) delete fVarDims[l];
fVarDims[l] = 0;
}
if (fCumulUsedVarDims) delete fCumulUsedVarDims;
}
void TTreeFormulaManager::Remove(TTreeFormula* adding)
{
fFormulas.Remove(adding);
}
void TTreeFormulaManager::Add(TTreeFormula* adding)
{
TTreeFormulaManager * old = adding->fManager;
if (old) {
if (old==this) {
if (fFormulas.FindObject(adding)) return;
} else {
old->fFormulas.Remove(adding);
if (old->fFormulas.GetLast()==-1) delete adding->fManager;
}
}
fFormulas.Add(adding);
adding->fManager = this;
fNeedSync = kTRUE;
}
void TTreeFormulaManager::AddVarDims(Int_t virt_dim)
{
if (!fVarDims[virt_dim]) fVarDims[virt_dim] = new TArrayI;
}
void TTreeFormulaManager::CancelDimension(Int_t virt_dim)
{
fCumulUsedSizes[virt_dim] = 0;
}
void TTreeFormulaManager::EnableMultiVarDims()
{
fMultiVarDim = kTRUE;
if (!fCumulUsedVarDims) fCumulUsedVarDims = new TArrayI;
}
Int_t TTreeFormulaManager::GetNdata(Bool_t forceLoadDim)
{
Int_t k;
if (fMultiplicity==0) return fNdata;
if (fMultiplicity==2) return fNdata;
for(k=0; k<=kMAXFORMDIM; k++) {
fUsedSizes[k] = TMath::Abs(fVirtUsedSizes[k]);
if (fVarDims[k]) {
for(Int_t i0=0;i0<fVarDims[k]->GetSize();i0++) {
fVarDims[k]->AddAt(0,i0);
}
}
}
if (fCumulUsedVarDims) {
for(Int_t i0=0;i0<fCumulUsedVarDims->GetSize();++i0) {
fCumulUsedVarDims->AddAt(0,i0);
}
}
TTreeFormula* current = 0;
Int_t size = fFormulas.GetLast()+1;
for(Int_t i=0; i<size; i++) {
current = (TTreeFormula*)fFormulas.UncheckedAt(i);
if (current->fMultiplicity!=1 && !current->fHasCast) continue;
if (!current->LoadCurrentDim() ) {
if (forceLoadDim) {
for(Int_t j=i+1; j<size; j++) {
current = (TTreeFormula*)fFormulas.UncheckedAt(j);
if (current->fMultiplicity!=1 && !current->fHasCast) continue;
current->LoadCurrentDim();
}
}
fNdata = 0;
return 0;
}
}
if (fMultiplicity==-1) { fNdata = 1; return fCumulUsedSizes[0]; }
Int_t overall = 1;
if (!fMultiVarDim) {
for (k = kMAXFORMDIM; (k >= 0) ; k--) {
if (fUsedSizes[k]>=0) {
overall *= fUsedSizes[k];
fCumulUsedSizes[k] = overall;
} else {
Error("GetNdata","a dimension is still negative!");
}
}
} else {
overall = 0;
if (fUsedSizes[0]>fCumulUsedVarDims->GetSize()) fCumulUsedVarDims->Set(fUsedSizes[0]);
for(Int_t i = 0; i < fUsedSizes[0]; i++) {
Int_t local_overall = 1;
for (k = kMAXFORMDIM; (k > 0) ; k--) {
if (fVarDims[k]) {
Int_t index = fVarDims[k]->At(i);
if (fCumulUsedVarDims->At(i)==1 && index) index = 1;
if (fUsedSizes[k]==1 || (index!=1 && index<fUsedSizes[k]))
local_overall *= index;
else local_overall *= fUsedSizes[k];
} else {
local_overall *= fUsedSizes[k];
}
}
if (fCumulUsedVarDims->At(i)<0) fCumulUsedVarDims->AddAt(0,i);
else {
fCumulUsedVarDims->AddAt(local_overall,i);
overall += local_overall;
}
}
}
fNdata = overall;
return overall;
}
Bool_t TTreeFormulaManager::Sync()
{
if (!fNeedSync) return true;
TTreeFormula* current = 0;
Bool_t hasCast = kFALSE;
fMultiplicity = 0;
for(Int_t i=0; i<fFormulas.GetLast()+1; i++) {
current = (TTreeFormula*)fFormulas.UncheckedAt(i);
hasCast |= current->fHasCast;
current->ResetDimensions();
switch (current->GetMultiplicity()) {
case 0:
break;
case 1:
fMultiplicity = 1;
break;
case 2:
if (fMultiplicity!=1) fMultiplicity = 2;
break;
default:
Error("Sync","Unexpected case!");
}
}
fCumulUsedSizes[kMAXFORMDIM] = fUsedSizes[kMAXFORMDIM];
for (Int_t k = kMAXFORMDIM; (k > 0) ; k--) {
if (fUsedSizes[k-1]>=0) {
fCumulUsedSizes[k-1] = fUsedSizes[k-1] * fCumulUsedSizes[k];
} else {
fCumulUsedSizes[k-1] = - TMath::Abs(fCumulUsedSizes[k]);
}
}
if (fCumulUsedSizes[0]==1 && fMultiplicity>0) {
fMultiplicity -= 2;
} else if (fCumulUsedSizes[0]<0 && fMultiplicity==2) {
fMultiplicity = 1;
} else if (fMultiplicity==0 && hasCast) {
fMultiplicity = -1;
}
switch(fMultiplicity) {
case 0: fNdata = 1; break;
case 2: fNdata = fCumulUsedSizes[0]; break;
default: fNdata = 0;
}
fNeedSync = kFALSE;
return true;
}
void TTreeFormulaManager::UpdateFormulaLeaves()
{
Int_t size = fFormulas.GetLast()+1;
for(Int_t i=0; i<size; i++) {
TTreeFormula *current = (TTreeFormula*)fFormulas.UncheckedAt(i);
current->UpdateFormulaLeaves();
}
}
void TTreeFormulaManager::UpdateUsedSize(Int_t &virt_dim, Int_t vsize)
{
if (vsize<0)
fVirtUsedSizes[virt_dim] = -1 * TMath::Abs(fVirtUsedSizes[virt_dim]);
else
if ( TMath::Abs(fVirtUsedSizes[virt_dim])==1
|| (vsize < TMath::Abs(fVirtUsedSizes[virt_dim]) ) ) {
if (fVirtUsedSizes[virt_dim] < 0) {
fVirtUsedSizes[virt_dim] = -1 * vsize;
} else {
fVirtUsedSizes[virt_dim] = vsize;
}
}
fUsedSizes[virt_dim] = fVirtUsedSizes[virt_dim];
virt_dim++;
}
Last change: Wed Jun 25 08:54:21 2008
Last generated: 2008-06-25 08:54
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.