/*
$Id: EventDataToHistogramBase.hh 2110 2010-04-07 04:35:47Z jisuzuki $
 */

#ifndef EVENTDATATOHISTOGRAMBASE
#define EVENTDATATOHISTOGRAMBASE

#include "Header.hh"
#include "GslHistogram.hh"
#include "ElementContainer.hh"
#include "ElementContainerMatrix.hh"
#include "ElementContainerArray.hh"

class EventDataToHistogramBase{
private:

protected:
  UInt4 NumOfPixel;
  UInt4 NumOfPsd;
  UInt4 CheckFlag;

  std::vector<Double> *a, *b, *c;
  std::vector<GslHistogram*> *gslhist;
  unsigned long long int CurrentPulseId, StartPulseId, EndPulseId;
  Double *Range;
  Double ClockToMicrosec( UInt4 Clock );
  void Decode_T0Data( const UChar *data, UInt4 *CrateId, UInt4 *ModuleId,
                      UInt8 *PulseId );
  void Decode_EventData( const UChar *data, UInt4 *psd_num, UInt4 *k,
                         UInt4 *ph_l, UInt4 *ph_r, UInt4 *tof );
  void Decode_TimeStampData( const UChar *data, UInt4 *t1, UInt4 *t2, UInt4 *t3,
                             UInt4 *t4, UInt4 *t5, Double *t6 );


public:
  EventDataToHistogramBase( );
  EventDataToHistogramBase( UInt4 _NumOfPsd, UInt4 _NumOfPixel );
  // Set the number of psd-s and pixels.
  // The second argument is total number
  // of pixels handled by this class.

  virtual ~EventDataToHistogramBase();

  UInt4 _CrateId, _ModuleId, _psd_num, _ph_l, _ph_r, _tof;
  UInt8 _PulseId;
  UInt4 _k, _t1, _t2, _t3, _t4, _t5;
  Double _t6;

  void Allocate( UInt4 _NumOfPsd, UInt4 _NumOfPixel );

  virtual UInt4 PutPsdId( UInt4 DaqChannel, UInt4 module, UInt4 psd )=0;
  // Returns PSD-ID

  virtual UInt4 PutPixelId( UInt4 PsdId, UInt4 PixelPosition )=0;
  // Returns pixel-id.
  // The first and second arguments are the return value of
  // PutPsdId(...) and PutPixelPosition(...).

  UInt4 PutPixelPosition( UInt4 PsdId, UInt4 pl, UInt4 pr );
  // Returns pixel position.
  // This method will be implemented or improved by DAQ-team.

  void SetPsdParam( UInt4 PsdId, Double A, Double B, Double C );
  // Set psd parameters used in PutPixelPosition(...).

  void SetTofBin( UInt4 PixelId, std::vector<Double> tof );
  void SetTofBin( UInt4 PixelId, Double *tof, UInt4 Size );
  // Set bin widths of histograms.

  void SetTofBin_DeltaT_Const( UInt4 PixelId,
                               Double Ini, Double Fin,
                               Double DeltaT );
  // Set bin widths of histograms.
  // Histogram bins are defined with the relationship dt = DeltaT.

  void SetTofBin_DeltaToverT_Const( UInt4 PixelId,
                                    Double Ini, Double Fin,
                                    Double DeltaToverT );
  // Set bin widths of histograms.
  // The second and fourth argument should not be 0.0 and 2.0.
  // Histogram bins are defined with the relationship dT/T = DeltaToverT.

  void Increment( UInt4 DaqChannel, UChar* data, UInt4 size );
  // Event data is input and histogram will be updated with this method.

  GslHistogram *PutGslHistogram( UInt4 PixelId ){ return (*gslhist)[ PixelId ]; }
  // Histogram data will be extracted with this method.

  std::vector<GslHistogram*> *PutGslHistogramVec(){ return gslhist; }

  std::vector<Double> PutHist( UInt4 PixelId )
    { return (*gslhist)[ PixelId ]->PutHistogram(); }

  Double PutSum( UInt4 PixelId )
  { return PutGslHistogram(PixelId)->PutHistogramSum();}

  std::vector<Double> PutBin( UInt4 PixelId ){ return (*gslhist)[ PixelId ]->PutBin(); }
  void Reset();

  virtual Double TimeFocParamC0( UInt4 _pixelid ){ return 0.0; }
  virtual Double TimeFocParamC1( UInt4 _pixelid ){ return 1.0; }

  //unsigned long long int PutStartPulseId(){   return StartPulseId; }
  //unsigned long long int PutEndPulseId(){     return EndPulseId; }
  //unsigned long long int PutCurrentPulseId(){ return CurrentPulseId; }

  ElementContainerMatrix  PutElementContainerMatrix(  std::vector<UInt4> NumObElements );
  ElementContainerMatrix *PutElementContainerMatrixP( std::vector<UInt4> NumObElements );

};

#endif


/*
//#include <stdlib.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <list>
#include <string>
//#include <math.h>
#include <fstream>
//#include <stdio.h>
//#include <stdarg.h>
//#include <ctype.h>

//using namespace std;

typedef char               Char;
typedef unsigned char      UChar;
typedef short              Int2;
typedef unsigned short     UInt2;
typedef int                Int4;
typedef unsigned int       UInt4;
typedef long long          Int8;
typedef unsigned long long UInt8;
typedef double             Double;
typedef float              Float;
typedef bool               Bool;

int main(){

  UInt4 Number = 100000;
  UChar *array = new UChar [ Number ];

  FILE *fin;
  fin = fopen( "121410/run071214102418/psdsitcp16.dat", "r" );
  fread( array, sizeof(Char), Number, fin );
  fclose( fin );

  for( UInt4 i=0; i<1000; i++ ){

    UInt4 index = i * 8;

    if( *( array + index ) == 91 ){ // if T0 data

      UInt4 ModuleId = (UInt4)( array[index+4] );
      unsigned long long int PulseId = ( array[index+5] ) * 256 * 256 +
                                       ( array[index+6] ) * 256 +
                                       ( array[index+7] );

      std::printf( "%d\t%d\t%d\n", i, ModuleId, PulseId );
    }


    if( *( array + index ) == 90 ){ // if event data

      UInt4 psd_num = (UInt4)( array[index+1] & 0x7 );
      UInt4 k = (UInt4)( array[index+6] )/16;
      UInt4 ph_l = (UInt4)( array[index+5] ) * 16 + k;
      UInt4 ph_r = (UInt4)( array[index+7] )
                 + 256 * ( (UInt4( array[index+6] ) )-k*16 );

      UInt4 tof = (UInt4)( array[index+2] << 16 )
                + (UInt4)( array[index+3] << 8 )
                + (UInt4)( array[index+4]);


      //std::printf( "%d\t%d\t%d\t%d\t%d\n", index, psd_num, ph_l, ph_r, tof );
    }

    if( *( array + index ) == 92 ){ // if time data
      UInt4 t1 = (UInt4)( array[index+1] );
      UInt4 t2 = (UInt4)( array[index+2] );
      UInt4 t3 = (UInt4)( array[index+3] );
      UInt4 t4 = (UInt4)( array[index+4] );
      UInt4 t5 = (UInt4)( array[index+5] );
      UInt4 t6 = (UInt4)( array[index+6] );
      UInt4 t7 = (UInt4)( array[index+7] );
      std::printf( "%d\t%d\t%d\t%d\t%d\t%d\t%f\n",
                   i, t1, t2, t3, t4, t5,(float)t6 + (float)t7/256.0);
    }
  }

  return 0;
}

 */

