
#ifndef DRS_H
#define DRS_H

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <algorithm>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include "mxml.h"
#include "strlcpy.h"

// Concurrent Technologies VME single board computer
#ifdef CT_VME 
#include "rcc_error/rcc_error.h"   // Error reporting
#include "vme_rcc/vme_rcc.h"       // VME access
#include "cmem_rcc/cmem_rcc.h"     // Allocation of contiguous memory
#include "rcc_time_stamp/tstamp.h" // Time stamp library
#endif

// Struck VME interface
#ifdef STRUCK_VME
#include "mvmestd.h"
#endif

// Control register bit definitions 
#define BIT_START_TRIG        (1<<0)    // Write a "1" to start domino wave
#define BIT_REINIT_TRIG       (1<<1)    // Write a "1" to stop & reset DRS
#define BIT_SOFT_TRIG         (1<<2)    // Write a "1" to stop and read data to RAM
#define BIT_FLASH_TRIG        (1<<3)    // Write a "1" to write DAC0 & DAC1 into serial EEPROM
#define BIT_AUTOSTART        (1<<16)
#define BIT_DMODE            (1<<17)    // 0: single shot, 1: circular
#define BIT_LED              (1<<18)    // 1=on, 0=blink during readout
#define BIT_TCAL_EN          (1<<19)    // Switch on (1) / off (0) for 33 MHz calib signal
#define BIT_ZERO_SUPP        (1<<20)
#define BIT_FREQ_AUTO_ADJ    (1<<21)
#define BIT_ENABLE_TRIGGER   (1<<22)
#define BIT_LONG_START_PULSE (1<<23)    // (*DRS2*) 0:short start pulse (> 0.8 GHz), 1:long start pulse (< 0.8 GHz)
#define BIT_READOUT_MODE     (1<<23)    // (*DRS3*) 0:start from first bin, 1:start from domino stop
#define BIT_DELAYED_START    (1<<24)    // Start domino wave 400 ns after soft trigger, used for waveform
                                        // Generator startup
#define BIT_ACAL_EN          (1<<25)    // Connect DRS to inputs (0) or to DAC6 (1)
#define BIT_TRIGGER_DELAYED  (1<<26)    // Select delayed trigger from trigger bus
#define BIT_DACTIVE          (1<<27)    // Keep domino wave running during readout

// Status register bit definitions 
#define BIT_RUNNING           (1<<0)    // One if domino wave running or readout in progress
#define BIT_NEW_FREQ1         (1<<1)    // One if new frequency measurement available
#define BIT_NEW_FREQ2         (1<<2)

enum DRSBoardConstants {
  kNumberOfChannels            =   10,
  kNumberOfCalibChannels       =   10,
  kNumberOfBins                = 1024,
  kNumberOfChips               =    2,
  kFrequencyCacheSize          =   10,
  kBSplineOrder                =    4,
  kPreCaliculatedBSplines      = 1000,
  kPreCaliculatedBSplineGroups =    5,
  kNumberOfADCBins             = 4096,
  kBSplineXMinOffset           =   20,
  kMaxNumberOfClockCycles      =  100,
};

enum DRSErrorCodes {
  kSuccess                     =  0,
  kInvalidTriggerSignal        = -1,
  kWrongChannelOrChip          = -2,
  kInvalidTransport            = -3,
  kZeroSuppression             = -4,
  kWaveNotAvailable            = -5
};

class DRSBoard;


class ResponseCalibration {
 protected:
  
  class CalibrationData {
  public:
    class CalibrationDataChannel {
    public:
      unsigned char   fLimitGroup[kNumberOfBins];           //!
      float           fMin[kNumberOfBins];                  //!
      float           fRange[kNumberOfBins];                //!
      short           fOffset[kNumberOfBins];               //!
      short           fGain[kNumberOfBins];                 //!
      unsigned short  fOffsetADC[kNumberOfBins];            //!
      short          *fData[kNumberOfBins];                 //!
      unsigned char  *fLookUp[kNumberOfBins];               //!
      unsigned short  fLookUpOffset[kNumberOfBins];         //!
      unsigned char   fNumberOfLookUpPoints[kNumberOfBins]; //!
      float          *fTempData;                            //!
      
    private:
      CalibrationDataChannel(const CalibrationDataChannel &c);              // Not implemented
      CalibrationDataChannel &operator=(const CalibrationDataChannel &rhs); // Not implemented
      
    public:
      CalibrationDataChannel(int numberOfGridPoints)
	:fTempData(new float[numberOfGridPoints]) {
	int i;
	for (i = 0; i < kNumberOfBins; i++) {
	  fData[i] = new short[numberOfGridPoints];
	  fLookUp[i] = NULL;
	}
      }
      ~CalibrationDataChannel() {
	int i;
	delete fTempData;
	for (i = 0; i < kNumberOfBins; i++) {
	  delete fData[i];
	  delete fLookUp[i];
	}
      }
    };
    
    bool                    fRead;                                  //!
    CalibrationDataChannel *fChannel[kNumberOfCalibChannels];       //!
    unsigned char           fNumberOfGridPoints;                    //!
    int                     fHasOffsetCalibration;                  //!
    float                   fStartTemperature;                      //!
    float                   fEndTemperature;                        //!
    int                    *fBSplineOffsetLookUp[kNumberOfADCBins]; //!
    float                 **fBSplineLookUp[kNumberOfADCBins];       //!
    float                   fMin;                                   //!
    float                   fMax;                                   //!
    unsigned char           fNumberOfLimitGroups;                   //!
    static float            fIntRevers[2 * kBSplineOrder - 2];
    
  private:
    CalibrationData(const CalibrationData &c);              // Not implemented
    CalibrationData &operator=(const CalibrationData &rhs); // Not implemented
    
  public:
    CalibrationData(int numberOfGridPoints);
    ~CalibrationData();
    static int CalculateBSpline(int nGrid, float value, float *bsplines);
    void       PreCalculateBSpline();
    void       DeletePreCalculatedBSpline();
  };
  
  // General Fields
  DRSBoard        *fBoard;
  
  double           fPrecision;
  
  // Fields for creating the Calibration
  bool             fInitialized;
  bool             fRecorded;
  bool             fFitted;
  bool             fOffset;
  bool             fCalibrationValid[2];
  
  int              fNumberOfPointsLowVolt;
  int              fNumberOfPoints;
  int              fNumberOfMode2Bins;
  int              fNumberOfSamples;
  int              fNumberOfGridPoints;
  int              fNumberOfXConstPoints;
  int              fNumberOfXConstGridPoints;
  double           fTriggerFrequency;
  int              fShowStatistics;
  FILE            *fCalibFile;
  
  int              fCurrentLowVoltPoint;
  int              fCurrentPoint;
  int              fCurrentSample;
  int              fCurrentFitChannel;
  int              fCurrentFitBin;
  
  float           *fResponseX[kNumberOfCalibChannels][kNumberOfBins];
  float           *fResponseY;
  unsigned short **fWaveFormMode3[kNumberOfCalibChannels];
  unsigned short **fWaveFormMode2[kNumberOfCalibChannels];
  short          **fWaveFormOffset[kNumberOfCalibChannels];
  unsigned short **fWaveFormOffsetADC[kNumberOfCalibChannels]; // Is this used?
  unsigned short  *fSamples;
  int             *fSampleUsed;
  
  float           *fPntX[2];
  float           *fPntY[2];
  float           *fUValues[2];
  float           *fRes[kNumberOfBins];
  float           *fResX[kNumberOfBins];
  
  double          *fXXFit;
  double          *fYYFit;
  double          *fWWFit;
  double          *fYYFitRes;
  double          *fYYSave;
  double          *fXXSave;
  
  float          **fStatisticsApprox;
  float          **fStatisticsApproxExt;
  
  // Fields for applying the Calibration
  CalibrationData *fCalibrationData[kNumberOfChips];
  
 private:
  ResponseCalibration(const ResponseCalibration &c);              // Not implemented
  ResponseCalibration &operator=(const ResponseCalibration &rhs); // Not implemented
  
 public:
  ResponseCalibration(DRSBoard* board);
  ~ResponseCalibration();
  
  void   SetCalibrationParameters(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins,
				  int numberOfSamples, int numberOfGridPoints, int numberOfXConstPoints,
				  int numberOfXConstGridPoints, double triggerFrequency, int showStatistics = 0);
  void   ResetCalibration();
  bool   RecordCalibrationPoints(int chipNumber);
  bool   RecordCalibrationPointsV3(int chipNumber);
  bool   RecordCalibrationPointsV4(int chipNumber);
  bool   FitCalibrationPoints(int chipNumber);
  bool   FitCalibrationPointsV3(int chipNumber);
  bool   FitCalibrationPointsV4(int chipNumber);
  bool   OffsetCalibration(int chipNumber);
  double GetTemperature(unsigned int chipIndex);
  
  bool   WriteCalibration(unsigned int chipIndex);
  bool   WriteCalibrationV3(unsigned int chipIndex);
  bool   WriteCalibrationV4(unsigned int chipIndex);
  bool   ReadCalibration(unsigned int chipIndex);
  bool   ReadCalibrationV3(unsigned int chipIndex);
  bool   ReadCalibrationV4(unsigned int chipIndex);
  bool   Calibrate(unsigned int chipIndex, unsigned int channel, float *adcWaveform,
		   float *uWaveform, float threshold);
  bool   Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform,
		   int triggerCell, float threshold);
  bool   SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform,
			   unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel);
  bool   IsRead(int chipIndex) const { return fCalibrationValid[chipIndex]; }
  double GetPrecision() const { return fPrecision; };
  
  double GetOffsetAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fOffset[bin]; };
  double GetGainAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fGain[bin]; };
  double GetMeasPointXAt(int ip) const { return fXXSave[ip]; };
  double GetMeasPointYAt(int ip) const { return fYYSave[ip]; };
  
 protected:
  void   InitFields(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, int numberOfSamples,
		    int numberOfGridPoints, int numberOfXConstPoints, int numberOfXConstGridPoints,
		    double triggerFrequency, int showStatistics);
  void   DeleteFields();
  void   CalibrationTrigger(int mode, double voltage);
  void   CalibrationStart(double voltage);
  
  static float  GetValue(float *coefficients, float u, int n);
  static int    Approx(float *p, float *uu, int np, int nu, float *coef);
  static void   LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt);
  static int    LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n);
  static void   Housholder(int lpivot, int l1, int m, float **u, int iU1, int iU2, float *up, float **c, int iC1,
			   int iC2, int ice, int ncv);
  
  static int    MakeDir(const char *path);
  static void   Average(int method,float *samples,int numberOfSamples,float &mean,float &error,float sigmaBoundary);
};



class DRSBoard {
 protected:
  class TimeData {
  public:
    class FrequencyData {
    public:
      int    fFrequency;
      double fBin[kNumberOfBins];
    };
    
    enum {
      kMaxNumberOfFrequencies = 4000
    };
    int            fChip;
    int            fNumberOfFrequencies;
    FrequencyData *fFrequency[kMaxNumberOfFrequencies];
    
  private:
    TimeData(const TimeData &c);              // Not implemented
    TimeData &operator=(const TimeData &rhs); // Not implemented
    
  public:
    TimeData()
      :fChip(0)
      ,fNumberOfFrequencies(0) {
    }
    ~TimeData() {
      int i;
      for (i = 0; i < fNumberOfFrequencies; i++) {
	delete fFrequency[i];
      }
    }
  };
  
 public:
  // DAC channels (CMC Version 1 : DAC_COFSA,DAC_COFSB,DAC_DRA,DAC_DSA,DAC_TLEVEL,DAC_ACALIB,DAC_DSB,DAC_DRB)
  unsigned int         fDAC_COFSA;
  unsigned int         fDAC_COFSB;
  unsigned int         fDAC_DRA;
  unsigned int         fDAC_DSA;
  unsigned int         fDAC_TLEVEL;
  unsigned int         fDAC_ACALIB;
  unsigned int         fDAC_DSB;
  unsigned int         fDAC_DRB;
  // DAC channels (CMC Version 2+3 : DAC_COFS,DAC_DSA,DAC_DSB,DAC_TLEVEL,DAC_ADCOFS,DAC_CLKOFS,DAC_ACALIB)
  unsigned int         fDAC_COFS;
  unsigned int         fDAC_ADCOFS;
  unsigned int         fDAC_CLKOFS;
  // DAC channels (CMC Version 4 : DAC_ROFS_1,DAC_DSA,DAC_DSB,DAC_ROFS_2,DAC_ADCOFS,DAC_ACALIB,DAC_INOFS,DAC_BIAS)
  unsigned int         fDAC_ROFS_1;
  unsigned int         fDAC_ROFS_2;
  unsigned int         fDAC_INOFS;
  unsigned int         fDAC_BIAS;
 
 protected:
  // Fields for DRS
  int                  fRequiredFirmwareVersion;
  int                  fFirmwareVersion;
  int                  fChipVersion;
  int                  fBoardVersion;
  int                  fCMCSerialNumber;
  unsigned int         fTransport;
  unsigned int         fCtrlBits;
  int                  fNumberOfReadoutChannels;
  double               fExternalClockFrequency;

  // VME
#ifdef CT_VME 
  VME_ErrorCode_t          ErrorCode;
  VME_BlockTransferList_t  BLT_List;
  
  char                 ErrorString[VME_MAXSTRING];
  
  int                  CMEM_SegIdentifier; 

  unsigned long        PCIAddress;        // Physical address of contiguous buffer
  unsigned long        VirtualAddress;    // Virtual address of contiguous buffer  

  unsigned int         fBaseAddress;
  unsigned int         fBoardAddress;
  int                  fMasterMapping;
#endif
#ifdef STRUCK_VME
  mvme_addr_t          fBaseAddress;
  MVME_INTERFACE      *fVMEInterface;
#endif

  int                  fSlotNumber;
  double               fFrequency;
  int                  fDominoMode;
  int                  fReadoutMode;
  int                  fTriggerEnable;
  int                  fDelayedStart;
  int                  fTriggerCell;
  
#ifdef STRUCK_VME
  unsigned char        fWaveforms[kNumberOfChips * kNumberOfChannels * 2 * kNumberOfBins];
#endif
#ifdef CT_VME
  unsigned long        fWaveforms[kNumberOfChannels * kNumberOfBins]; 
#endif
  
  // Fields for Calibration
  int                  fMaxChips;
  char                 fCalibDirectory[1000];
  
  // Fields for Response Calibration
  ResponseCalibration *fResponseCalibration;
  
  // Fields for Time Calibration
  TimeData           **fTimeData;
  int                  fNumberOfTimeData;
  
  // General debugging flag
  int                  fDebug;
  
  // Fields for wave transfer
  bool                 fWaveTransferred[kNumberOfChips * kNumberOfChannels];
  
  // Waveform Rotation
  int                  fTriggerStartBin; // Start bin of the trigger
  bool                 kRotateWave;
  
 private:
  DRSBoard(const DRSBoard &c);              // Not implemented
  DRSBoard &operator=(const DRSBoard &rhs); // Not implemented
  
 public:
  
  ~DRSBoard();
  
  void         SetCMCSerialNumber(unsigned int serialNumber) { fCMCSerialNumber = serialNumber; }
  int          GetCMCSerialNumber() const { return fCMCSerialNumber; }
  int          GetFirmwareVersion() const { return fFirmwareVersion; }
  int          GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; }
  int          GetChipVersion() const { return fChipVersion; }
  int          GetCMCVersion() const { return fBoardVersion; }
  
  // VME
  int          GetSlotNumber() const { return fSlotNumber; }

#ifdef CT_VME 
  unsigned int GetBaseAddress() const {return fBaseAddress; }
  unsigned int GetBoardAddress() const {return fBoardAddress; }
#endif

  int          Read(int type, void *data, unsigned int addr, int size);
  int          Write(int type, unsigned int addr, void *data, int size);

#ifdef CT_VME 
  int          AllocateSegmentCMEM(unsigned int SegSize, int *CMEM_SegIdentifier);
  int          AssignPhysicalSegAddressCMEM(int CMEM_SegIdentifier, unsigned long* PCIAddress);
  int          AssignVirtualSegAddressCMEM(int CMEM_SegIdentifier, unsigned long* VirtualAddress);
  int          FreeSegmentCMEM(int CMEM_SegIdentifier);
#endif

  void         RegisterTest(void);
  int          RAMTest(int flag);
  unsigned int GetCtrlReg(void);
  unsigned int GetStatusReg(void);
  
  void         SetLED(int state);
  
  void         SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels);
  void         SetNumberOfChannels(int nChannels);
  int          EnableTrigger(int mode);
  int          SetDelayedStart(int flag);
  int          IsBusy(void);
  int          IsNewFreq(unsigned char chipIndex);
  int          SetDAC(unsigned char channel, double value);
  int          ReadDAC(unsigned char channel, double *value);
  int          GetRegulationDAC(double *value);
  
  int          StartDomino();
  int          Reinit();
  int          Init();
  
  void         SetDebug(int debug) { fDebug = debug; }
  
  int          SetDominoMode(unsigned char mode);
  
  int          SetDominoActive(unsigned char mode);
  int          SetReadoutMode(unsigned char mode);
  
  int          SoftTrigger(void);
  int          ReadFrequency(unsigned char chipIndex, double *f);
  int          SetFrequency(double freq);
  double       VoltToFreq(double volt);
  double       FreqToVolt(double freq);
  double       GetFrequency() const { return fFrequency; }
  
  int          RegulateFrequency(double freq);
  int          SetExternalClockFrequency(double frequencyMHz);
  double       GetExternalClockFrequency();
  
  void         SetVoltageOffset(double offset1, double offset2);


  int          TestRead(unsigned int n, int type);
 
  int          TransferWaves(int numberOfChannels = kNumberOfChips * kNumberOfChannels);
  int          TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChips * kNumberOfChannels);
  int          TransferWaves(unsigned char *p, int firstChannel, int lastChannel);
  int          TransferWaves(unsigned long *p, int numberOfChannels = kNumberOfChips * kNumberOfChannels);
  int          TransferWaves(unsigned long *p, int firstChannel, int lastChannel);
  int          TransferWaves(int firstChannel, int lastChannel);

  int          DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
  			  unsigned short *waveform);
  int          DecodeWave(unsigned long *waveforms, unsigned int chipIndex, unsigned char channel,
			  unsigned short *waveform);
  int          DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform);

  int          GetWave(unsigned long *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform, 
		       bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false, 
		       float threshold = 0);
  int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform,
		       bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
		       float threshold = 0);
  int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform,
		       bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
		       float threshold = 0);
  int          GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false,
		       int triggerCell = -1, bool adjustToClock = false, float threshold = 0);
  int          GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib = false,
		       int triggerCell = -1, bool adjustToClock = false, float threshold = 0);
  int          GetADCWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform);
  int          GetADCWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel,
  		  unsigned short *waveform);
  int          GetADCWave(unsigned long *waveforms,unsigned int chipIndex, unsigned char channel,
  		  unsigned short *waveform);
  
  void         RotateWave(int triggerCell, short *waveform);  
  void         RotateWave(int triggerCell, float *waveform);  
  void         SetRotation(bool r) {kRotateWave = r;}

  int          GetTime(unsigned int chipIndex, int frequencyMHz, float *time, int triggerCell);
  int          GetTriggerCell(unsigned int chipIndex);
  int          GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex);
  int          GetTriggerCell(unsigned long *waveforms,unsigned int chipIndex);
  int          GetTriggerCell(float *waveform);

  void         TestDAC(int channel);
  void         MeasureSpeed();
  void         InteractSpeed();
  void         MonitorFrequency();
  int          EnableTcal(int flag);
  int          EnableAcal(int mode, double voltage);
  int          SetCalibVoltage(double value);
  int          SetCalibTiming(int t1, int t2);
  double       GetTemperature();
  int          GetTriggerBus();
  int          FlashEEPROM(unsigned short serial_cmc);
  bool         HasCorrectFirmware();
  
  bool         InitTimeCalibration(unsigned int chipIndex);
  void         SetCalibrationDirectory(const char *calibrationDirectoryPath);
  void         GetCalibrationDirectory(char *calibrationDirectoryPath);
  
  ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; }
  
  int          GetStoredTriggerCell() const { return fTriggerCell; }
  double       GetPrecision() const { return fResponseCalibration->GetPrecision(); }
  int          CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform,
				 short *waveform, bool responseCalib, int triggerCell, bool adjustToClock,
				 float threshold);
  
  static void  LinearRegression(double *x, double *y, int n, double *a, double *b);
  
 protected:
  // Protected methods
  void         ConstructBoard();
  void         ReadSerialNumber();
  
  
  TimeData    *GetTimeCalibration(unsigned int chipIndex, bool reinit = false);
  
  int          GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period);
  
 public:
  
#ifdef CT_VME 
  DRSBoard(int MasterMapping, unsigned int BaseAddress, unsigned int BoardAddress, int SlotNumber);
#endif

#ifdef STRUCK_VME
  DRSBoard(MVME_INTERFACE * MVME_Interface, mvme_addr_t BaseAddress, int SlotNumber);
  MVME_INTERFACE *GetVMEInterface() const { return fVMEInterface; };
#endif

  void PrintBinary32(unsigned int i);
  long int GetMicroSeconds();
  
};



class DRS {
  
 protected:
  enum {
    kMaxNumberOfBoards = 40
  };
  
 protected:
  
  DRSBoard        *fBoard[kMaxNumberOfBoards];
  
#ifdef CT_VME 
  VME_MasterMap_t  MasterMap;
  VME_ErrorCode_t  ErrorCode;
  
  char             ErrorString[VME_MAXSTRING];
  
  int              MasterMapping[kMaxNumberOfBoards];
#endif

  int              fNumberOfBoards;
  
#ifdef STRUCK_VME
  MVME_INTERFACE *fVMEInterface;
#endif
 

 private:
  DRS(const DRS &c);              // Not implemented
  DRS &operator=(const DRS &rhs); // Not implemented
  

#ifdef CT_VME 
  int OpenVME();
  int MasterMapVME(int* MMap);
  int MasterUnMapVME(int MMap);
  int CloseVME();
  
  int OpenCMEM();
  int CloseCMEM();
#endif

  int First_VME_Slot; 
  int Last_VME_Slot;  
  
 public:
  // Public Methods
  DRS();
  ~DRS();
  
  DRSBoard        *GetBoard(int i) { return fBoard[i]; }
  DRSBoard       **GetBoards() { return fBoard; }
  int              GetNumberOfBoards() const { return fNumberOfBoards; }

#ifdef STRUCK_VME
   MVME_INTERFACE *GetVMEInterface() const { return fVMEInterface; };
#endif

  void             InitialScan();
  void             SetFirstVMESlot(int s) { First_VME_Slot = s; }
  void             SetLastVMESlot(int s) { Last_VME_Slot = s; }
  int              GetFirstVMESlot() { return First_VME_Slot; }
  int              GetLastVMESlot() { return Last_VME_Slot; }
};

#endif   // DRS_H
