#include "PelIO.h"
#include <iostream>

using namespace std;

ClassImp(PelIO)

/*!
Default contructor. Set object name and title
\param name is the object name
\param title is the object tile
*/
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);
}
/*!
Default destructor
*/
PelIO::~PelIO()
{
  for(int i=0;i<MAXOUTPUT;i++) closeOutput(i);
  closeInput();
}
/*!
Open input file from stream
\param file is the file name
*/
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;
}
/*!
Open output stream file 
\param file is the file name
\param out is the output number (0 to 4)
*/
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;
}
/*!
Close input file 
*/
int PelIO::closeInput()
{
  mIsInputOpen = false;
  if(mInput!=0)
  {
    fclose(mInput);
    mInput=0;
    return kOk;
  }
  return kWarn;
}
/*!
Close output file 
\param out is the output number (0 to 4)
*/
int PelIO::closeOutput(int out)
{
  mIsOutputOpen[out]=false;
  if(mOutput[out])
  {
    fflush(mOutput[out]);
    fclose(mOutput[out]);
    mOutput[out]=NULL;
    return kOk;
  }

  return kWarn;
}
/*!
Write event to the output 
\param event is the event number
\param out is the output number (0 to 4)
*/
int PelIO::writeEventToOutput(int out)
{
  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);
      fwrite((const char*)&mDataStream[start],size,1,mOutput[out]);
      mBytesOutput[out]+=size;
    }
  }
  else
  {
    if(!mSaveOnlyNew)
    {
      size = sizeof(unsigned short)*(stop-start-1);
      fwrite((const char*)&mDataStream[start],size,1,mOutput[out]);
      mBytesOutput[out]+=size;
    }
    size = sizeof(unsigned short)*(mNAddedPar*2);
    fwrite((const char*)&mParAdded[0],size,1,mOutput[out]);
    mBytesOutput[out]+=size;
    size = sizeof(unsigned short);
    unsigned short end = 0xFFFF;
    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;
}
/*!
Read data block from input
*/
int PelIO::readBlock()
{
  if(!mInput) return kWarn;

  if(feof(mInput))
  {
    // the next line will purge any residual data block in the memory
    // in the case we reached the end of file
    if(mLastInput==kOk) { mLastInput = kEOF; return decodeBlock(1); }
    return kEOF;
  }
  char * pointer = (char*)mBlock;
  long pos0,pos1;
  pos0 = ftell(mInput);
  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;
    for(int i=(BLOCKSIZE-1)/8;i<BLOCKSIZE/8;i++)
    //for(int i=0;i<BLOCKSIZE/8;i++) 
    {
      cout <<hex<<i<<" : ";
      for (int j=0;j<8;j++) cout <<hex<<(unsigned int)mBlock[i*8+j]<<"  ";
      cout <<dec<<endl;
    }
  }
  return decodeBlock();
}
/*!
Decode data block and save the position of each event in the block in the memory
*/
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);
      //mResidual[mResidualSize++] = mDataStream[i];
    }

  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;
}
/*!
Decode event from data block in the memory
\param event is the event number
\param npar returns the number of parameters in the event
\param parIndex returns an array with the parameter indexes in the event
\param parValues return an array with the parameter values in the event
*/
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;
  mNRead++;
  do
  {
    i++;
    if(mDataStream[i]==0xFFFF)
    {
      mCurrentSize = (i-start)*sizeof(unsigned short);
      mNextPosition = i+1;
      if(mDebug) cout <<dec<<i<<hex<<":   DATA = 0x"<<mDataStream[i]<<"  END OF EVENT"<<endl;;
      return kOk;
    }
    unsigned short data = mDataStream[i];
    if(mDebug) cout <<dec<<i<<hex<<":   DATA = 0x"<<mDataStream[i]<<dec;
    if((data&0x8000)==0x8000)
    {
      param = data&0x7FFF;
      if(mDebug) cout <<"  PARAMETER = "<<dec<<param<<endl;
    }
    else
    {
	if(data!=0)
	{
	  parValues[npar] = (float)data;
	  parIndex[npar] = param;
	  param++;
	  npar++;
	  if(mDebug) cout <<"  VALUE = 0x"<<hex<<data<<" - "<<dec<<data<<endl;
	} else if(mDebug) cout <<endl;
    }
  } while(0==0);
  return kOk;
}
/*!
Print statistics about I/O
*/
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;
  }
}
/*!
Read event from data block in the memory and return the parameters in the
right position. Make sure that the array parValues have a size well defined
\param size is the size of the array parValues
\param parValues return an array with the parameter values in the event
*/
int PelIO::readEvent(short size,short &npar, float* parValues)
{
  if(size>MAXPAR) return kWarn;
  if(mNextPosition>=mLastPosition)
  {
    mStat = readBlock();
    if(mStat!=1) 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;
}
/*!
Write event to the output 
\param out is the output number (0 to 4)
*/
int PelIO::writeEvent(int out)
{
  return writeEventToOutput(out);
}
/*!
add parameter to the output 
\param par is the parameter number
\param value is the parameter value
*/
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;
}









ROOT page - Class index - Class Hierarchy - Top of the page

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.