ROOT logo
#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;
}
/*!
Rewind input file
*/
int PelIO::rewind()
{
  if(mDebug) cout <<"Rewinding file  "<<getFileName()<<endl;
  if(!mInput) return kOk;
  closeInput();
	openInput(getFileName());
  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)
{
  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;
}
/*!
Read data block from input
*/
int PelIO::readBlock()
{
  size_t tmp;
  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);
  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;
    //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;
	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;
}
/*!
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!=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;
}
/*!
Skips events from input file. It is faster than reading but still need
to look at every single event because of the different sizes
the method returns the number of skipped events. This may be smaller
than requested
\param n is the number of events to be skipped. Default is 1
*/
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;
}
/*!
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;
}







 PelIO.cxx:1
 PelIO.cxx:2
 PelIO.cxx:3
 PelIO.cxx:4
 PelIO.cxx:5
 PelIO.cxx:6
 PelIO.cxx:7
 PelIO.cxx:8
 PelIO.cxx:9
 PelIO.cxx:10
 PelIO.cxx:11
 PelIO.cxx:12
 PelIO.cxx:13
 PelIO.cxx:14
 PelIO.cxx:15
 PelIO.cxx:16
 PelIO.cxx:17
 PelIO.cxx:18
 PelIO.cxx:19
 PelIO.cxx:20
 PelIO.cxx:21
 PelIO.cxx:22
 PelIO.cxx:23
 PelIO.cxx:24
 PelIO.cxx:25
 PelIO.cxx:26
 PelIO.cxx:27
 PelIO.cxx:28
 PelIO.cxx:29
 PelIO.cxx:30
 PelIO.cxx:31
 PelIO.cxx:32
 PelIO.cxx:33
 PelIO.cxx:34
 PelIO.cxx:35
 PelIO.cxx:36
 PelIO.cxx:37
 PelIO.cxx:38
 PelIO.cxx:39
 PelIO.cxx:40
 PelIO.cxx:41
 PelIO.cxx:42
 PelIO.cxx:43
 PelIO.cxx:44
 PelIO.cxx:45
 PelIO.cxx:46
 PelIO.cxx:47
 PelIO.cxx:48
 PelIO.cxx:49
 PelIO.cxx:50
 PelIO.cxx:51
 PelIO.cxx:52
 PelIO.cxx:53
 PelIO.cxx:54
 PelIO.cxx:55
 PelIO.cxx:56
 PelIO.cxx:57
 PelIO.cxx:58
 PelIO.cxx:59
 PelIO.cxx:60
 PelIO.cxx:61
 PelIO.cxx:62
 PelIO.cxx:63
 PelIO.cxx:64
 PelIO.cxx:65
 PelIO.cxx:66
 PelIO.cxx:67
 PelIO.cxx:68
 PelIO.cxx:69
 PelIO.cxx:70
 PelIO.cxx:71
 PelIO.cxx:72
 PelIO.cxx:73
 PelIO.cxx:74
 PelIO.cxx:75
 PelIO.cxx:76
 PelIO.cxx:77
 PelIO.cxx:78
 PelIO.cxx:79
 PelIO.cxx:80
 PelIO.cxx:81
 PelIO.cxx:82
 PelIO.cxx:83
 PelIO.cxx:84
 PelIO.cxx:85
 PelIO.cxx:86
 PelIO.cxx:87
 PelIO.cxx:88
 PelIO.cxx:89
 PelIO.cxx:90
 PelIO.cxx:91
 PelIO.cxx:92
 PelIO.cxx:93
 PelIO.cxx:94
 PelIO.cxx:95
 PelIO.cxx:96
 PelIO.cxx:97
 PelIO.cxx:98
 PelIO.cxx:99
 PelIO.cxx:100
 PelIO.cxx:101
 PelIO.cxx:102
 PelIO.cxx:103
 PelIO.cxx:104
 PelIO.cxx:105
 PelIO.cxx:106
 PelIO.cxx:107
 PelIO.cxx:108
 PelIO.cxx:109
 PelIO.cxx:110
 PelIO.cxx:111
 PelIO.cxx:112
 PelIO.cxx:113
 PelIO.cxx:114
 PelIO.cxx:115
 PelIO.cxx:116
 PelIO.cxx:117
 PelIO.cxx:118
 PelIO.cxx:119
 PelIO.cxx:120
 PelIO.cxx:121
 PelIO.cxx:122
 PelIO.cxx:123
 PelIO.cxx:124
 PelIO.cxx:125
 PelIO.cxx:126
 PelIO.cxx:127
 PelIO.cxx:128
 PelIO.cxx:129
 PelIO.cxx:130
 PelIO.cxx:131
 PelIO.cxx:132
 PelIO.cxx:133
 PelIO.cxx:134
 PelIO.cxx:135
 PelIO.cxx:136
 PelIO.cxx:137
 PelIO.cxx:138
 PelIO.cxx:139
 PelIO.cxx:140
 PelIO.cxx:141
 PelIO.cxx:142
 PelIO.cxx:143
 PelIO.cxx:144
 PelIO.cxx:145
 PelIO.cxx:146
 PelIO.cxx:147
 PelIO.cxx:148
 PelIO.cxx:149
 PelIO.cxx:150
 PelIO.cxx:151
 PelIO.cxx:152
 PelIO.cxx:153
 PelIO.cxx:154
 PelIO.cxx:155
 PelIO.cxx:156
 PelIO.cxx:157
 PelIO.cxx:158
 PelIO.cxx:159
 PelIO.cxx:160
 PelIO.cxx:161
 PelIO.cxx:162
 PelIO.cxx:163
 PelIO.cxx:164
 PelIO.cxx:165
 PelIO.cxx:166
 PelIO.cxx:167
 PelIO.cxx:168
 PelIO.cxx:169
 PelIO.cxx:170
 PelIO.cxx:171
 PelIO.cxx:172
 PelIO.cxx:173
 PelIO.cxx:174
 PelIO.cxx:175
 PelIO.cxx:176
 PelIO.cxx:177
 PelIO.cxx:178
 PelIO.cxx:179
 PelIO.cxx:180
 PelIO.cxx:181
 PelIO.cxx:182
 PelIO.cxx:183
 PelIO.cxx:184
 PelIO.cxx:185
 PelIO.cxx:186
 PelIO.cxx:187
 PelIO.cxx:188
 PelIO.cxx:189
 PelIO.cxx:190
 PelIO.cxx:191
 PelIO.cxx:192
 PelIO.cxx:193
 PelIO.cxx:194
 PelIO.cxx:195
 PelIO.cxx:196
 PelIO.cxx:197
 PelIO.cxx:198
 PelIO.cxx:199
 PelIO.cxx:200
 PelIO.cxx:201
 PelIO.cxx:202
 PelIO.cxx:203
 PelIO.cxx:204
 PelIO.cxx:205
 PelIO.cxx:206
 PelIO.cxx:207
 PelIO.cxx:208
 PelIO.cxx:209
 PelIO.cxx:210
 PelIO.cxx:211
 PelIO.cxx:212
 PelIO.cxx:213
 PelIO.cxx:214
 PelIO.cxx:215
 PelIO.cxx:216
 PelIO.cxx:217
 PelIO.cxx:218
 PelIO.cxx:219
 PelIO.cxx:220
 PelIO.cxx:221
 PelIO.cxx:222
 PelIO.cxx:223
 PelIO.cxx:224
 PelIO.cxx:225
 PelIO.cxx:226
 PelIO.cxx:227
 PelIO.cxx:228
 PelIO.cxx:229
 PelIO.cxx:230
 PelIO.cxx:231
 PelIO.cxx:232
 PelIO.cxx:233
 PelIO.cxx:234
 PelIO.cxx:235
 PelIO.cxx:236
 PelIO.cxx:237
 PelIO.cxx:238
 PelIO.cxx:239
 PelIO.cxx:240
 PelIO.cxx:241
 PelIO.cxx:242
 PelIO.cxx:243
 PelIO.cxx:244
 PelIO.cxx:245
 PelIO.cxx:246
 PelIO.cxx:247
 PelIO.cxx:248
 PelIO.cxx:249
 PelIO.cxx:250
 PelIO.cxx:251
 PelIO.cxx:252
 PelIO.cxx:253
 PelIO.cxx:254
 PelIO.cxx:255
 PelIO.cxx:256
 PelIO.cxx:257
 PelIO.cxx:258
 PelIO.cxx:259
 PelIO.cxx:260
 PelIO.cxx:261
 PelIO.cxx:262
 PelIO.cxx:263
 PelIO.cxx:264
 PelIO.cxx:265
 PelIO.cxx:266
 PelIO.cxx:267
 PelIO.cxx:268
 PelIO.cxx:269
 PelIO.cxx:270
 PelIO.cxx:271
 PelIO.cxx:272
 PelIO.cxx:273
 PelIO.cxx:274
 PelIO.cxx:275
 PelIO.cxx:276
 PelIO.cxx:277
 PelIO.cxx:278
 PelIO.cxx:279
 PelIO.cxx:280
 PelIO.cxx:281
 PelIO.cxx:282
 PelIO.cxx:283
 PelIO.cxx:284
 PelIO.cxx:285
 PelIO.cxx:286
 PelIO.cxx:287
 PelIO.cxx:288
 PelIO.cxx:289
 PelIO.cxx:290
 PelIO.cxx:291
 PelIO.cxx:292
 PelIO.cxx:293
 PelIO.cxx:294
 PelIO.cxx:295
 PelIO.cxx:296
 PelIO.cxx:297
 PelIO.cxx:298
 PelIO.cxx:299
 PelIO.cxx:300
 PelIO.cxx:301
 PelIO.cxx:302
 PelIO.cxx:303
 PelIO.cxx:304
 PelIO.cxx:305
 PelIO.cxx:306
 PelIO.cxx:307
 PelIO.cxx:308
 PelIO.cxx:309
 PelIO.cxx:310
 PelIO.cxx:311
 PelIO.cxx:312
 PelIO.cxx:313
 PelIO.cxx:314
 PelIO.cxx:315
 PelIO.cxx:316
 PelIO.cxx:317
 PelIO.cxx:318
 PelIO.cxx:319
 PelIO.cxx:320
 PelIO.cxx:321
 PelIO.cxx:322
 PelIO.cxx:323
 PelIO.cxx:324
 PelIO.cxx:325
 PelIO.cxx:326
 PelIO.cxx:327
 PelIO.cxx:328
 PelIO.cxx:329
 PelIO.cxx:330
 PelIO.cxx:331
 PelIO.cxx:332
 PelIO.cxx:333
 PelIO.cxx:334
 PelIO.cxx:335
 PelIO.cxx:336
 PelIO.cxx:337
 PelIO.cxx:338
 PelIO.cxx:339
 PelIO.cxx:340
 PelIO.cxx:341
 PelIO.cxx:342
 PelIO.cxx:343
 PelIO.cxx:344
 PelIO.cxx:345
 PelIO.cxx:346
 PelIO.cxx:347
 PelIO.cxx:348
 PelIO.cxx:349
 PelIO.cxx:350
 PelIO.cxx:351
 PelIO.cxx:352
 PelIO.cxx:353
 PelIO.cxx:354
 PelIO.cxx:355
 PelIO.cxx:356
 PelIO.cxx:357
 PelIO.cxx:358
 PelIO.cxx:359
 PelIO.cxx:360
 PelIO.cxx:361
 PelIO.cxx:362
 PelIO.cxx:363
 PelIO.cxx:364
 PelIO.cxx:365
 PelIO.cxx:366
 PelIO.cxx:367
 PelIO.cxx:368
 PelIO.cxx:369
 PelIO.cxx:370
 PelIO.cxx:371
 PelIO.cxx:372
 PelIO.cxx:373
 PelIO.cxx:374
 PelIO.cxx:375
 PelIO.cxx:376
 PelIO.cxx:377
 PelIO.cxx:378
 PelIO.cxx:379
 PelIO.cxx:380
 PelIO.cxx:381
 PelIO.cxx:382
 PelIO.cxx:383
 PelIO.cxx:384
 PelIO.cxx:385
 PelIO.cxx:386
 PelIO.cxx:387
 PelIO.cxx:388
 PelIO.cxx:389
 PelIO.cxx:390
 PelIO.cxx:391
 PelIO.cxx:392
 PelIO.cxx:393
 PelIO.cxx:394
 PelIO.cxx:395
 PelIO.cxx:396
 PelIO.cxx:397
 PelIO.cxx:398
 PelIO.cxx:399
 PelIO.cxx:400
 PelIO.cxx:401
 PelIO.cxx:402
 PelIO.cxx:403
 PelIO.cxx:404
 PelIO.cxx:405
 PelIO.cxx:406
 PelIO.cxx:407
 PelIO.cxx:408
 PelIO.cxx:409