#include "TClass.h"
#include <Riostream.h>
#include "TError.h"
#include "AliSegmentID.h"
#include "AliH2F.h"
#include <TArrayI.h>
#include <TArrayS.h>
#include "AliDigits.h"
ClassImp(AliDigits)
AliDigits::AliDigits()
:AliSegmentID(),
fNrows(0),
fNcols(0),
fElements(0),
fIndex(0),
fBufType(0),
fThreshold(0),
fNelems(0),
fCurrentRow(0),
fCurrentCol(0),
fCurrentIndex(0)
{
Invalidate();
}
AliDigits::AliDigits(const AliDigits& digits)
:AliSegmentID(digits),
fNrows(0),
fNcols(0),
fElements(0),
fIndex(0),
fBufType(0),
fThreshold(0),
fNelems(0),
fCurrentRow(0),
fCurrentCol(0),
fCurrentIndex(0)
{
fNrows = digits.fNrows;
fNcols = digits.fNcols;
fElements = new TArrayS(*(digits.fElements));
fIndex = new TArrayI(*(digits.fIndex));
fBufType = digits.fBufType;
fThreshold = digits.fThreshold;
fNelems = digits.fNelems;
}
AliDigits & AliDigits::operator =(const AliDigits & digits)
{
if (this == &digits) return (*this);
fNrows = digits.fNrows;
fNcols = digits.fNcols;
if (fElements) delete fElements;
fElements = new TArrayS(*(digits.fElements));
if (fIndex) delete fIndex;
fIndex = new TArrayI(*(digits.fIndex));
fBufType = digits.fBufType;
fThreshold = digits.fThreshold;
fNelems = digits.fNelems;
return (*this);
}
AliDigits::~AliDigits()
{
if (fIndex !=0 ) {
delete fIndex;
}
if (fElements != 0) {
delete fElements;
}
}
Bool_t AliDigits::OutOfBoundsError(const char *where, Int_t row, Int_t column)
{
::Error(where, "row %d col %d out of bounds (size: %d x %d, this: 0x%08lx)",
row, column, fNrows, fNcols, (ULong_t) this);
return kFALSE;
}
void AliDigits::Invalidate()
{
if (fIndex != 0) delete fIndex;
fIndex = new TArrayI;
if (fElements!= 0) delete fElements;
fElements = new TArrayS;
fNrows = fNcols =fNelems= -1;
fElements->Set(0);
fIndex->Set(0);
fBufType = -1;
}
void AliDigits::Allocate(Int_t rows, Int_t columns)
{
Invalidate();
if (rows <= 0) {
Error("Allocate", "no of rows has to be positive");
return;
}
if (columns <= 0) {
Error("Allocate", "no of columns has to be positive");
return;
}
fNrows = rows;
fNcols=columns;
fNelems = fNrows * fNcols;
fElements->Set(fNelems);
fIndex->Set(fNcols);
for (Int_t i =0,k=0; i<fNcols;i++,k+=fNrows)
(*fIndex)[i]=k;
fBufType =0;
}
Int_t AliDigits::GetSize()
{
Int_t size = 0;
if (fIndex!=0) size+= sizeof(fIndex)+fIndex->GetSize()*sizeof(Int_t);
if (fElements!=0) size+= sizeof(fElements)+fElements->GetSize()*sizeof(Short_t);
return size;
}
Int_t AliDigits::GetDigitSize()
{
if (fElements==0) return 0;
else return sizeof(fElements)+fElements->GetSize()*sizeof(Short_t);
}
Int_t AliDigits::GetOverTh(Float_t threshold,Float_t x1, Float_t x2, Float_t y1, Float_t y2)
{
if ( (fElements==0) || (fElements->GetSize()<=0)) return 0;
if (x1<=x2) {
x1=0;
x2=fNrows;
}
if (y1<=y2) {
y1=0;
y2=fNcols;
}
Int_t over=0;
Bool_t cont=First();
for ( cont=First(); cont==kTRUE;cont=Next()) {
if ( (CurrentRow()<x1) || (CurrentRow()>x2)) continue;
if ( (CurrentColumn()<y1) || (CurrentColumn()>y2)) continue;
if (CurrentDigit()>threshold) over++;
}
return over;
}
Short_t AliDigits::GetDigit(Int_t row, Int_t column)
{
if (fBufType ==0) return GetDigitFast(row,column);
if (fBufType ==1) return GetDigit1(row,column);
return 0;
}
void AliDigits::ExpandBuffer()
{
if (fBufType<0) {
Error("ExpandBuffer", "buffer doesn't exist");
return;
}
if (fBufType==0) return;
if (fBufType==1) ExpandBuffer1();
fBufType = 0;
}
void AliDigits::CompresBuffer(Int_t bufferType,Int_t threshold)
{
if (fBufType<0) {
Error("CompressBuffer", "buffer doesn't exist");
return;
}
if (fBufType == bufferType) return;
if (fBufType>0) ExpandBuffer();
if (fBufType !=0) {
Error("CompressBuffer", "buffer doesn't exist");
return;
}
fThreshold = threshold;
if ( bufferType == 1) CompresBuffer1();
}
Bool_t AliDigits::First()
{
if (fBufType ==0) return First0();
if (fBufType ==1) return First1();
return kFALSE;
}
Bool_t AliDigits::Next()
{
if (fBufType ==0) return Next0();
if (fBufType ==1) return Next1();
return kFALSE;
}
void AliDigits::AcceptHisto(AliH2F * his)
{
Int_t idim =his->GetNbinsX();
Int_t jdim =his->GetNbinsY();
if ( (idim<1)|| (jdim<1)) {
return;
}
Allocate(idim,jdim);
for (Int_t i = 0; i<idim;i++)
for (Int_t j = 0; j<jdim;j++)
{
Int_t index = his->GetBin(i+1,j+1);
SetDigitFast((Short_t)his->GetBinContent(index),i,j);
}
}
AliH2F * AliDigits::GenerHisto()
{
char ch[30];
snprintf(ch,30, "Segment_%d ",GetID());
if ( (fNrows<1)|| (fNcols<1)) {
return 0;
}
AliH2F * his = new AliH2F("Digit histo",ch,fNrows,0,fNrows,fNcols,0,fNcols);
ExpandBuffer();
for (Int_t i = 0; i<fNrows;i++)
for (Int_t j = 0; j<fNcols;j++)
his->Fill(i,j,GetDigitFast(i,j));
return his;
}
AliH2F *AliDigits::DrawDigits(const char *option,Float_t x1, Float_t x2, Float_t y1, Float_t y2)
{
AliH2F *h2f = GenerHisto();
if (x1>=0) {
AliH2F *h2fsub = h2f->GetSubrange2d(x1,x2,y1,y2);
delete h2f;
h2f=h2fsub;
}
if (h2f==0) return 0;
if (option!=0) h2f->Draw(option);
else h2f->Draw();
return h2f;
}
void AliDigits::ExpandBuffer1()
{
Int_t i,k;
fNelems = fNrows*fNcols;
Short_t * buf = new Short_t[fNelems];
memset(buf,0,fNelems*sizeof(Short_t));
fIndex->Set(fNcols);
for (i =0,k=0 ;i<fNcols;i++,k+=fNrows) (*fIndex)[i]=k;
Int_t col=0;
Int_t row = 0;
Int_t n=fElements->fN;
for (i=0;i<n;i++){
if ((*fElements)[i]<0) row-=fElements->At(i);
else {
buf[(*fIndex)[col]+row]=fElements->At(i);
row++;
}
if (row==fNrows) {
row=0;
col++;
}else
if (row>fNrows){
Invalidate();
delete [] buf;
return;
}
}
fElements->Adopt(fNelems,buf);
}
void AliDigits::CompresBuffer1()
{
TArrayS buf;
buf.Set(fNelems);
TArrayI index;
index.Set(fNcols);
Int_t icurrent=-1;
Int_t izero;
Short_t * cbuff = fElements->GetArray();
for (Int_t col = 0; col<fNcols; col++){
index[col]=icurrent+1;
izero = 0;
for (Int_t row = 0; row< fNrows;row++){
if (*cbuff<=fThreshold) izero++;
else{
if (izero>0) {
icurrent++;
if (icurrent>=buf.fN) buf.Set(icurrent*2);
buf[icurrent]= -izero;
izero = 0;
}
icurrent++;
if (icurrent>=buf.fN) buf.Set(icurrent*2);
buf[icurrent] = *cbuff;
}
cbuff++;
}
if (izero>0) {
icurrent++;
if (icurrent>=buf.fN) buf.Set(icurrent*2);
buf[icurrent]= -izero;
}
}
buf.Set(icurrent+1);
(*fElements)=buf;
fNelems = fElements->fN;
fBufType = 1;
(*fIndex) =index;
}
Bool_t AliDigits::First0()
{
fCurrentRow = -1;
fCurrentCol = -1;
fCurrentIndex = -1;
Int_t i;
for (i=0; (( i<fNelems) && (fElements->At(i)<=fThreshold));i++) {}
if (i == fNelems) return kFALSE;
fCurrentCol =i/fNrows;
fCurrentRow =i%fNrows;
fCurrentIndex = i;
return kTRUE;
}
Bool_t AliDigits::Next0()
{
if (fCurrentIndex<0) return kFALSE;
Int_t i;
for (i=fCurrentIndex+1; ( (i<fNelems) && (fElements->At(i)<=fThreshold) ) ;i++) {}
if (i >= fNelems) {
fCurrentIndex = -1;
return kFALSE;
}
fCurrentCol =i/fNrows;
fCurrentRow =i%fNrows;
fCurrentIndex = i;
return kTRUE;
}
Bool_t AliDigits::First1()
{
fCurrentRow = -1;
fCurrentCol = 0;
fCurrentIndex = -1;
Int_t i;
for (i=0; i<fNelems; i++){
if (fElements->At(i) < 0) fCurrentRow-=fElements->At(i);
else
fCurrentRow++;
if (fCurrentRow>=fNrows) {
fCurrentCol++;
fCurrentRow-=fNrows;
}
if (fElements->At(i)>fThreshold) break;
}
fCurrentIndex = i;
if (fCurrentIndex>=0&&i<fNelems) return kTRUE;
fCurrentRow =-1;
fCurrentCol =-1;
return kFALSE;
}
Bool_t AliDigits::Next1()
{
if (fCurrentIndex<0) return kFALSE;
Int_t i;
for (i=fCurrentIndex+1; i<fNelems;i++){
if (fElements->At(i) < 0) fCurrentRow-=fElements->At(i);
else
fCurrentRow++;
if (fCurrentRow>=fNrows) {
fCurrentCol++;
fCurrentRow-=fNrows;
}
if (fElements->At(i)>fThreshold) break;
}
fCurrentIndex = i;
if ( (i>=0) && (i<fNelems) ) return kTRUE;
fCurrentRow =-1;
fCurrentCol =-1;
return kFALSE;
}
Short_t AliDigits::GetDigit1(Int_t row, Int_t column)
{
Int_t i,n2;
if ( (column+1)>=fNcols) n2 = fNelems;
else
n2 = fIndex->At(column+1);
Int_t irow = 0;
for (i=fIndex->At(column); ( (i<n2) && (irow<row) );i++){
if (fElements->At(i) < 0) irow-=fElements->At(i);
else
irow++;
}
if ( irow == row ) return fElements->At(i);
return -1;
}