#include "PelIO.h"
#include <iostream>
using namespace std;
ClassImp(PelIO)
PelIO::PelIO(char* name,char* title):TNamed(name,title)
{
mDebug = false;
mInput = 0;
mSaveOnlyNew = false;
mSmearing = false;
for(int i=0;i<MAXOUTPUT;i++)
{
mOutput[i] = 0;
mNSaved[i] = 0;
mIsOutputOpen[i] = false;
}
mNRead = 0;
gROOT->Add(this);
}
PelIO::~PelIO()
{
for(int i=0;i<MAXOUTPUT;i++) closeOutput(i);
closeInput();
}
int PelIO::openInput(char *file)
{
if(mDebug) cout <<"Opening file "<<file<<endl;
if(mInput) closeInput();
mResidualSize = 0;
mNRead = 0;
mNBlockRead = 0;
if(file)
{
mInput = fopen(file,"rb");
if(!mInput)
{
if(mDebug) cout <<"Can not open input file at "<<file<<endl;
return kWarn;
}
mFileName = file;
mIsInputOpen = true;
}
mLastInput = kOk;
return kOk;
}
int PelIO::rewind()
{
if(mDebug) cout <<"Rewinding file "<<getFileName()<<endl;
if(!mInput) return kOk;
closeInput();
openInput(getFileName());
return kOk;
}
int PelIO::openOutput(char *file,int out,int run, char* comment)
{
if(mDebug) cout <<"Opening file for output "<<file<<endl;
if(mOutput[out]) closeOutput(out);
if(file)
{
mOutput[out] = fopen(file,"wb");
if(!mOutput[out])
{
if(mDebug) cout <<"Can not open output FILE at "<<file<<endl;
mOutput[out]=NULL;
return kWarn;
}
char *pointer =(char*)&mOutputBuffer[out][0];
setvbuf(mOutput[out],(char*)pointer,_IOFBF,BLOCKSIZEWRITE);
mFileNameOutput[out] = file;
mBytesOutput[out] = 0;
mNSaved[out] = 0;
mIsOutputOpen[out] = true;
}
return kOk;
}
int PelIO::closeInput()
{
mIsInputOpen = false;
if(mInput!=0)
{
fclose(mInput);
mInput=0;
return kOk;
}
return kWarn;
}
int PelIO::closeOutput(int out)
{
mIsOutputOpen[out]=false;
if(mOutput[out])
{
fflush(mOutput[out]);
fclose(mOutput[out]);
mOutput[out]=NULL;
return kOk;
}
return kWarn;
}
int PelIO::writeEventToOutput(int out)
{
size_t tmp;
if(!mOutput[out]) return kWarn;
if(mCurrentPosition>mLastPosition) return kWarn;
int size=0;
short start = mCurrentPosition;
short stop = mNextPosition;
if(stop==start) return kWarn;
if(mNAddedPar==0)
{
if(!mSaveOnlyNew)
{
size = sizeof(unsigned short)*(stop-start);
tmp = fwrite((const char*)&mDataStream[start],size,1,mOutput[out]);
mBytesOutput[out]+=size;
}
}
else
{
if(!mSaveOnlyNew)
{
size = sizeof(unsigned short)*(stop-start-1);
tmp = fwrite((const char*)&mDataStream[start],size,1,mOutput[out]);
mBytesOutput[out]+=size;
}
size = sizeof(unsigned short)*(mNAddedPar*2);
tmp = fwrite((const char*)&mParAdded[0],size,1,mOutput[out]);
mBytesOutput[out]+=size;
size = sizeof(unsigned short);
unsigned short end = 0xFFFF;
tmp = fwrite((const char*)&end,size,1,mOutput[out]);
mBytesOutput[out]+=size;
}
if(mBytesOutput[out]>=BLOCKSIZEWRITE) { fflush(mOutput[out]); mBytesOutput[out] = 0; }
mNSaved[out]++;
return kOk;
}
int PelIO::readBlock()
{
size_t tmp;
if(!mInput) return kWarn;
if(feof(mInput))
{
if(mLastInput==kOk) { mLastInput = kEOF; return decodeBlock(1); }
return kEOF;
}
char * pointer = (char*)mBlock;
long pos0,pos1;
pos0 = ftell(mInput);
tmp = fread(pointer,(int)sizeof(unsigned short)*MAXBLOCKSIZE,1,mInput);
pos1 = ftell(mInput);
BLOCKSIZE=(pos1-pos0)/(int)sizeof(unsigned short);
if(mDebug)
{
cout <<"pos0 = "<<pos0<<" pos1 = "<<pos1<<endl;
cout <<"BLOCKSIZEWANTED = "<<MAXBLOCKSIZE<<" BLOCKSIZE = "<<BLOCKSIZE<<endl;
}
return decodeBlock();
}
int PelIO::decodeBlock(int mode)
{
int i;
int index = 0;
int size = sizeof(unsigned short int);
if(mResidualSize>0)
{
memcpy(&mDataStream[0],&mResidual[0],size*mResidualSize);
index+=mResidualSize;
}
mNBlockRead++;
if(mode==0)
{
memcpy(&mDataStream[index],&mBlock[0],size*BLOCKSIZE);
index+=BLOCKSIZE;
}
if(index==0) return kOk;
int lastword = index;
for(i = index-1;i>=0;i--)
if(mDataStream[i]==0xFFFF)
{
lastword = i+1;
if(mDebug) cout <<"FOUND LAST EVENT POSITION = "
<<lastword<<" mDataStream[lastword-1] = "<<hex<<mDataStream[i]<<dec<<endl;
break;
}
mResidualSize = 0;
for(i = lastword;i<index;i++)
if(mDataStream[i]!=0)
{
memcpy(&mResidual[mResidualSize++],&mDataStream[i],size);
}
mCurrentPosition = 0;
mNextPosition = 0;
mLastPosition = lastword;
if(mDebug)
{
cout <<"Number of block read = "<<dec<<mNBlockRead<<endl;
cout <<"Residual from last event = "<<dec<<mResidualSize<<endl;
cout <<"index = "<<dec<<index<<endl;
cout <<"lastword = "<<dec<<lastword<<endl;
cout <<"Residual from this event = "<<dec<<mResidualSize<<endl;
cout <<"index = "<<dec<<index<<endl;
cout <<"LastPosition = "<<dec<<mLastPosition<<endl;
}
return kOk;
}
int PelIO::decodeEvent(short& npar,short* parIndex,float* parValues)
{
npar=0;
mNAddedPar = 0;
mCurrentPosition = mNextPosition;
if(mCurrentPosition>=mLastPosition) return kWarn;
short start = mCurrentPosition;
short i = start-1;
short param = 0;
char line[200];
mNRead++;
if(mDebug) sprintf(line," %07x | ",i+1);
do
{
i++;
if(mDataStream[i]==0xFFFF)
{
mCurrentSize = (i-start)*sizeof(unsigned short);
mNextPosition = i+1;
if(mDebug)
{
sprintf(line,"%s %04x(EOE)",line,(int)mDataStream[i]);
cout <<line<<endl;
}
return kOk;
}
unsigned short data = mDataStream[i];
if(mDebug) sprintf(line,"%s %04x",line,(int)mDataStream[i]);
if((data&0x8000)==0x8000)
{
param = data&0x7FFF;
if(mDebug) sprintf(line,"%s(P%03d) ",line,param);
}
else
{
if(data!=0)
{
parValues[npar] = (float)data;
parIndex[npar] = param;
param++;
npar++;
if(mDebug) sprintf(line,"%s(D) ",line);
}
}
} while(0==0);
if(mDebug) cout <<line<<" NO EOV"<<endl;
return kOk;
}
void PelIO::printStats()
{
cout <<"Number of events read from input file = "<<getNRead()<<endl;
for(int i=0;i<MAXOUTPUT;i++) if(mOutput[i])
{
cout <<"Number of events saved on file "<<getFileNameOutput(i)<<" = "<<getNSaved(i)<<endl;
}
}
int PelIO::readEvent(short size,short &npar, float* parValues)
{
if(size>MAXPAR) return kWarn;
if(mNextPosition>=mLastPosition)
{
mStat = readBlock();
if(mStat!=kOk) return mStat;
}
mStat = decodeEvent(npar,&mParIndexTmp[0],&mParValuesTmp[0]);
if(mStat==kOk && npar>0)
{
memset(&parValues[0],0,size*sizeof(float));
for(int i=0;i<npar;i++) if(mParIndexTmp[i]<size)
{
if(mSmearing) mParValuesTmp[i]+=gRandom->Uniform();
memcpy(&parValues[mParIndexTmp[i]],&mParValuesTmp[i],sizeof(float));
}
}
return mStat;
}
int PelIO::skipEvents(int n)
{
short npar;
int nskip = 0;
for(int i = 0; i<n;i++)
{
if(mNextPosition>=mLastPosition)
{
mStat = readBlock();
if(mStat!=kOk) return nskip;
}
mStat = decodeEvent(npar,&mParIndexTmp[0],&mParValuesTmp[0]);
if(mStat!=kOk) return nskip;
nskip++;
}
return nskip;
}
int PelIO::writeEvent(int out)
{
return writeEventToOutput(out);
}
void PelIO::addPar(int par, float value)
{
int pos = mNAddedPar*2;
mParAdded[pos] = (0x8000 | ((unsigned short)par&0x7FFF)) & 0xFFFF;
mParAdded[pos+1] = ((unsigned short)value) & 0x7FFF;
mNAddedPar++;
return;
}