#include "TClass.h"
#include <Riostream.h>
#include "TError.h"
#include "AliSegmentID.h"
#include "AliH2F.h"
#include "TArrayI.h"
#include "AliDigits.h"
#include "AliSimDigits.h"
#include <TClonesArray.h>
ClassImp(AliSimDigits)
AliSimDigits::AliSimDigits()
:AliDigits(),
fTracks(0),
fTrIndex(0),
fNlevel(0),
fTrBufType(0)
{
InvalidateTrack();
}
AliSimDigits::AliSimDigits(const AliSimDigits ¶m)
:AliDigits(),
fTracks(0),
fTrIndex(0),
fNlevel(0),
fTrBufType(0)
{
fTrIndex = param.fTrIndex;
}
AliSimDigits::~AliSimDigits()
{
if (fTracks != 0) {
delete fTracks;
}
if (fTrIndex != 0) {
delete fTrIndex;
}
}
AliSimDigits & AliSimDigits::operator =(const AliSimDigits & param)
{
if(this!=¶m){
fTrIndex=param.fTrIndex;
}
return (*this);
}
void AliSimDigits::InvalidateTrack()
{
if ( fTracks != 0) delete fTracks;
fTracks = new TArrayI;
if ( fTrIndex != 0) delete fTrIndex;
fTrIndex = new TArrayI;
for (Int_t i = 0; i<3; i++){
fTracks->Set(0);
fTrIndex->Set(0);
}
}
void AliSimDigits::AllocateTrack(Int_t length)
{
InvalidateTrack();
fNlevel = length;
fTracks->Set(fNcols*fNrows*fNlevel);
fTrIndex->Set(0);
fTrBufType =0;
}
Int_t AliSimDigits::GetTrackID(Int_t row, Int_t column, Int_t level)
{
if (fTrBufType == 0) return GetTrackIDFast(row, column,level);
if (fTrBufType == 1) return GetTrackID1(row, column,level);
if (fTrBufType == 2) return GetTrackID2(row, column,level);
return 0;
}
void AliSimDigits::ExpandTrackBuffer()
{
if (fTrBufType<0) {
Error("ExpandBuffer", "buffer doesn't exist");
return;
}
if (fTrBufType==0) return;
if (fTrBufType==1) {ExpandTrackBuffer1(); return;}
if (fTrBufType==2) ExpandTrackBuffer2();
}
void AliSimDigits::CompresTrackBuffer(Int_t bufType)
{
if (fTrBufType<0) {
Error("CompressBuffer", "buffer doesn't exist");
return;
}
if (fTrBufType == bufType) return;
if (fTrBufType>0) ExpandTrackBuffer();
if (fTrBufType !=0) {
Error("CompressBuffer", "buffer doesn't exist");
return;
}
if (bufType==1) {CompresTrackBuffer1();return;}
if (bufType==2) CompresTrackBuffer2();
}
Int_t AliSimDigits::GetTrackID1(Int_t row, Int_t column, Int_t level)
{
Int_t i,n1,n2;
i = level*fNcols+column;
if ( (i+1)>=fTrIndex->fN) n2 = fTracks->fN;
else
n2 = fTrIndex->At(i+1);
n1 = fTrIndex->At(i);
Int_t rownew = 0;
Int_t rowold=0;
Int_t id;
for (i = n1;(i<n2);i++){
id = 0;
Int_t num = fTracks->At(i);
if (num<0) {
rownew-=num;
rowold = rownew;
i++;
if (i<n2){
num = fTracks->At(i);
rownew+=num;
i++;
id = fTracks->At(i);
}
}
else {
rowold = rownew;
rownew+=num;
i++;
id = fTracks->At(i);
}
id-=2;
if ( (row>=rowold) && (row<rownew) ) return id;
if (row < rownew ) return -2;
}
return -2;
}
void AliSimDigits::ExpandTrackBuffer1()
{
fTrBufType = 0;
Int_t i,j;
Int_t all = fNrows*fNcols;
Int_t elems = all*fNlevel;
TArrayI * buf = new TArrayI;
buf->Set(elems);
fTrIndex->Set(0);
Int_t level = 0;
Int_t col=0;
Int_t row = 0;
Int_t n=fTracks->fN;
for (i=0;i<n;i++){
Int_t num = fTracks->At(i);
if (num<0) row-=num;
else {
num %= 10000000;
i++;
Int_t id = fTracks->At(i);
for (j = 0; j<num; j++,row++) {
if (level*all+col*fNrows+row<elems) (*buf)[level*all+col*fNrows+row]=id;
}
}
if (row>=fNrows) {
row=0;
col++;
}
if (col>=fNcols) {
col=0;
level++;
}
}
delete fTracks;
fTracks = buf;
}
void AliSimDigits::CompresTrackBuffer1()
{
fTrBufType = 1;
TArrayI * buf = new TArrayI;
buf->Set(fNrows*fNcols*fNlevel);
TArrayI * index = new TArrayI;
index->Set(fNcols*fNlevel);
Int_t icurrent=-1;
Int_t izero;
Int_t inum;
Int_t lastID =0;
Int_t *cbuff=fTracks->GetArray();
for (Int_t lev =0; lev<fNlevel; lev++){
for (Int_t col = 0; col<fNcols; col++){
izero = 0;
inum = 0;
lastID = 0;
(*index)[lev*fNcols+col]=icurrent+1;
Int_t id=0;
for (Int_t row = 0; row< fNrows;row++){
id = *cbuff;
if (id <= 0) {
if ( inum> 0 ) {
icurrent++;
if ((icurrent+1)>=buf->fN) buf->Set(icurrent*2+1);
(*buf)[icurrent] = inum;
icurrent++;
(*buf)[icurrent] = lastID;
inum = 0;
lastID = 0;
}
izero++;
}
else
if (id != lastID)
if ( izero > 0 ) {
icurrent++;
if (icurrent>=buf->fN) buf->Set(icurrent*2+1);
(*buf)[icurrent]= -izero;
inum++;
izero = 0;
lastID = id;
}
else{
icurrent++;
if ((icurrent+1)>=buf->fN) buf->Set(icurrent*2+1);
(*buf)[icurrent] = inum;
icurrent++;
(*buf)[icurrent] = lastID;
lastID = id;
inum = 1;
izero = 0;
}
else {
inum++;
}
cbuff++;
}
if ( izero > 0 ) {
icurrent++;
if (icurrent>=buf->fN) buf->Set(icurrent*2);
(*buf)[icurrent]= -izero;
}
if ( inum> 0 ) {
icurrent++;
if ((icurrent+1)>=buf->fN) buf->Set(icurrent*2);
(*buf)[icurrent] = inum;
icurrent++;
(*buf)[icurrent] = id;
}
}
}
buf->Set(icurrent+1);
delete fTracks;
fTracks = buf;
delete fTrIndex;
fTrIndex = index;
}
void AliSimDigits::ExpandTrackBuffer2()
{
fTrBufType = 0;
}
void AliSimDigits::CompresTrackBuffer2()
{
fTrBufType = 2;
}
Int_t AliSimDigits::GetTrackID2(Int_t , Int_t , Int_t )
{
return -2;
}
AliH2F * AliSimDigits::DrawTracks( const char *option,Int_t level,
Float_t x1, Float_t x2, Float_t y1, Float_t y2)
{
char ch[30];
snprintf(ch,30,"Track Segment_%d level %d ",GetID(),level );
if ( (fNrows<1)|| (fNcols<1)) {
return 0;
}
AliH2F * his = new AliH2F("Track histo",ch,fNrows,0,fNrows,fNcols,0,fNcols);
ExpandTrackBuffer();
for (Int_t i = 0; i<fNrows;i++)
for (Int_t j = 0; j<fNcols;j++)
his->Fill(i,j,GetTrackIDFast(i,j,level));
if (x1>=0) {
AliH2F *h2fsub = his->GetSubrange2d(x1,x2,y1,y2);
delete his;
his=h2fsub;
}
if (his==0) return 0;
if (option!=0) his->Draw(option);
else his->Draw();
return his;
}
void AliSimDigits::GlitchFilter(){
for (Int_t i=0;i<fNcols;i++){
for(Int_t j=1;j<fNrows-1;j++){
if(GetDigitFast(j,i)){
if (!GetDigitFast(j-1,i) && !GetDigitFast(j+1,i)) {
SetDigitFast(0,j,i);
SetTrackIDFast(-2,j,i,0);
SetTrackIDFast(-2,j,i,1);
SetTrackIDFast(-2,j,i,2);
}
}
}
if(GetDigitFast(0,i) && !GetDigitFast(1,i)) {
SetDigitFast(0,0,i);
SetTrackIDFast(-2,0,i,0);
SetTrackIDFast(-2,0,i,1);
SetTrackIDFast(-2,0,i,2);
}
if(GetDigitFast(fNrows-1,i) && !GetDigitFast(fNrows-2,i)){
SetDigitFast(0,fNrows-1,i);
SetTrackIDFast(-2,fNrows-1,i,0);
SetTrackIDFast(-2,fNrows-1,i,1);
SetTrackIDFast(-2,fNrows-1,i,2);
}
}
}