/******************************************************************** DRS.h, S.Ritt, M. Schneebeli - PSI $Id: DRS.h 14473 2009-10-25 18:44:22Z sawada $ ********************************************************************/ #ifndef DRS_H #define DRS_H #include #include #ifdef HAVE_LIBUSB # ifndef HAVE_USB # define HAVE_USB # endif #endif #ifdef HAVE_USB # include #endif // HAVE_USB #ifdef HAVE_VME # include #endif // HAVE_VME /* disable "deprecated" warning */ #ifdef _MSC_VER #pragma warning(disable: 4996) #endif #ifndef NULL #define NULL 0 #endif /* transport mode */ #define TR_VME 1 #define TR_USB 2 #define TR_USB2 3 /* address types */ #ifndef T_CTRL #define T_CTRL 1 #define T_STATUS 2 #define T_RAM 3 #define T_FIFO 4 #endif /*---- Register addresses ------------------------------------------*/ #define REG_CTRL 0x00000 /* 32 bit control reg */ #define REG_DAC_OFS 0x00004 #define REG_DAC0 0x00004 #define REG_DAC1 0x00006 #define REG_DAC2 0x00008 #define REG_DAC3 0x0000A #define REG_DAC4 0x0000C #define REG_DAC5 0x0000E #define REG_DAC6 0x00010 #define REG_DAC7 0x00012 #define REG_CHANNEL_CONFIG 0x00014 // low byte #define REG_CONFIG 0x00014 // high byte #define REG_CHANNEL_MODE 0x00016 #define REG_ADCCLK_PHASE 0x00016 #define REG_FREQ_SET_HI 0x00018 // DRS2 #define REG_FREQ_SET_LO 0x0001A // DRS2 #define REG_TRG_DELAY 0x00018 // DRS4 #define REG_FREQ_SET 0x0001A // DRS4 #define REG_TRIG_DELAY 0x0001C #define REG_LMK_MSB 0x0001C // DRS4 Mezz #define REG_CALIB_TIMING 0x0001E // DRS2 #define REG_EEPROM_PAGE_EVAL 0x0001E // DRS4 Eval #define REG_EEPROM_PAGE_MEZZ 0x0001A // DRS4 Mezz #define REG_LMK_LSB 0x0001E // DRS4 Mezz #define REG_WARMUP 0x00020 // DRS4 Mezz #define REG_COOLDOWN 0x00022 // DRS4 Mezz #define REG_MAGIC 0x00000 #define REG_BOARD_TYPE 0x00002 #define REG_STATUS 0x00004 #define REG_RDAC_OFS 0x0000E #define REG_RDAC0 0x00008 #define REG_STOP_CELL0 0x00008 #define REG_RDAC1 0x0000A #define REG_STOP_CELL1 0x0000A #define REG_RDAC2 0x0000C #define REG_STOP_CELL2 0x0000C #define REG_RDAC3 0x0000E #define REG_STOP_CELL3 0x0000E #define REG_RDAC4 0x00000 #define REG_RDAC5 0x00002 #define REG_RDAC6 0x00014 #define REG_RDAC7 0x00016 #define REG_EVENTS_IN_FIFO 0x00018 #define REG_EVENT_COUNT 0x0001A #define REG_FREQ1 0x0001C #define REG_FREQ2 0x0001E #define REG_TEMPERATURE 0x00020 #define REG_TRIGGER_BUS 0x00022 #define REG_SERIAL_BOARD 0x00024 #define REG_VERSION_FW 0x00026 /*---- 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_EEPROM_WRITE_TRIG (1<<3) // write a "1" to write into serial EEPROM #define BIT_EEPROM_READ_TRIG (1<<4) // write a "1" to read from serial EEPROM #define BIT_AUTOSTART (1<<16) #define BIT_DMODE (1<<17) // (*DRS2*) 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_TCAL_SOURCE (1<<20) #define BIT_REFCLK_SOURCE (1<<20) #define BIT_FREQ_AUTO_ADJ (1<<21) // DRS2/3 #define BIT_TRANSP_MODE (1<<21) // DRS4 #define BIT_ENABLE_TRIGGER1 (1<<22) // External LEMO/FP/TRBUS trigger #define BIT_LONG_START_PULSE (1<<23) // (*DRS2*) 0:short start pulse (>0.8GHz), 1:long start pulse (<0.8GHz) #define BIT_READOUT_MODE (1<<23) // (*DRS3*,*DRS4*) 0:start from first bin, 1:start from domino stop #define BIT_DELAYED_START (1<<24) // DRS2: start domino wave 400ns after soft trigger, used for waveform // generator startup #define BIT_NEG_TRIGGER (1<<24) // DRS4: use high-to-low trigger if set #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_ADCCLK_INVERT (1<<26) // invert ADC clock #define BIT_DACTIVE (1<<27) // keep domino wave running during readout #define BIT_STANDBY_MODE (1<<28) // put chip in standby mode #define BIT_TR_SOURCE1 (1<<29) // trigger source selection bits #define BIT_TR_SOURCE2 (1<<30) // trigger source selection bits #define BIT_ENABLE_TRIGGER2 (1<<31) // analog threshold (internal) trigger /* DRS4 configuration register bit definitions */ #define BIT_CONFIG_DMODE (1<<8) // 0: single shot, 1: circular #define BIT_CONFIG_PLLEN (1<<9) // write a "1" to enable the internal PLL #define BIT_CONFIG_WSRLOOP (1<<10) // write a "1" to connect WSROUT to WSRIN internally /*---- 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) #define BIT_PLL_LOCKED0 (1<<1) // 1 if PLL has locked (DRS4 evaluation board only) #define BIT_PLL_LOCKED1 (1<<2) // 1 if PLL DRS4 B has locked (DRS4 mezzanine board only) #define BIT_PLL_LOCKED2 (1<<3) // 1 if PLL DRS4 C has locked (DRS4 mezzanine board only) #define BIT_PLL_LOCKED3 (1<<4) // 1 if PLL DRS4 D has locked (DRS4 mezzanine board only) #define BIT_SERIAL_BUSY (1<<5) // 1 if EEPROM operation in progress #define BIT_LMK_LOCKED (1<<6) // 1 if PLL of LMK chip has locked (DRS4 mezzanine board only) enum DRSBoardConstants { kNumberOfChannelsMax = 10, kNumberOfCalibChannelsV3 = 10, kNumberOfCalibChannelsV4 = 8, kNumberOfBins = 1024, kNumberOfChipsMax = 4, 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 }; /*---- callback class ----*/ class DRSCallback { public: virtual void Progress(int value) = 0; virtual ~DRSCallback() {}; }; /*------------------------*/ 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]; } memset(fLimitGroup, 0, sizeof(fLimitGroup)); memset(fMin, 0, sizeof(fMin)); memset(fRange, 0, sizeof(fRange)); memset(fOffset, 0, sizeof(fOffset)); memset(fGain, 0, sizeof(fGain)); memset(fOffsetADC, 0, sizeof(fOffsetADC)); memset(fLookUp, 0, sizeof(fLookUp)); memset(fLookUpOffset, 0, sizeof(fLookUpOffset)); memset(fNumberOfLookUpPoints, 0, sizeof(fNumberOfLookUpPoints)); } ~CalibrationDataChannel() { int i; delete fTempData; for (i = 0; i < kNumberOfBins; i++) { delete fData[i]; delete fLookUp[i]; } } }; bool fRead; //! CalibrationDataChannel *fChannel[10]; //! 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[10][kNumberOfBins]; float *fResponseY; unsigned short **fWaveFormMode3[10]; unsigned short **fWaveFormMode2[10]; short **fWaveFormOffset[10]; unsigned short **fWaveFormOffsetADC[10]; 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; double fGainMin; double fGainMax; float **fStatisticsApprox; float **fStatisticsApproxExt; // Fields for applying the Calibration CalibrationData *fCalibrationData[kNumberOfChipsMax]; 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); bool OffsetCalibrationV3(int chipNumber); bool OffsetCalibrationV4(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 offsetCalib); bool Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform, int triggerCell, float threshold, bool offsetCalib); 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; // DAC channels (USB EVAL1 (Version 5) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS) unsigned int fDAC_CMOFS; unsigned int fDAC_CALN; unsigned int fDAC_CALP; unsigned int fDAC_ONOFS; // DAC channels (DRS4 MEZZ1 (Version 6) : DAC_ONOFS,DAC_CMOFSP,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_CMOFSN,DAC_ROFS_1) unsigned int fDAC_CMOFSP; unsigned int fDAC_CMOFSN; protected: // Fields for DRS int fDRSType; int fBoardType; int fNumberOfChips; int fNumberOfChannels; int fRequiredFirmwareVersion; int fFirmwareVersion; int fBoardSerialNumber; unsigned int fTransport; unsigned int fCtrlBits; int fNumberOfReadoutChannels; int fReadoutChannelConfig; int fADCClkPhase; bool fADCClkInvert; double fExternalClockFrequency; #ifdef HAVE_USB MUSB_INTERFACE *fUsbInterface; #endif #ifdef HAVE_VME MVME_INTERFACE *fVmeInterface; mvme_addr_t fBaseAddress; #endif int fSlotNumber; double fFrequency; double fTCALFrequency; double fRefClock; int fDominoMode; int fDominoActive; int fChannelConfig; int fWSRLoop; int fReadoutMode; int fTriggerEnable1; int fTriggerEnable2; int fTriggerSource; int fTriggerDelay; int fSyncDelay; int fDelayedStart; int fTranspMode; unsigned short fStopCell[4]; double fROFS; double fRange; double fCommonMode; int fAcalMode; int fbkAcalMode; double fAcalVolt; double fbkAcalVolt; int fTcalFreq; int fbkTcalFreq; int fTcalLevel; int fbkTcalLevel; int fTcalPhase; int fTcalSource; unsigned char fWaveforms[kNumberOfChipsMax * kNumberOfChannelsMax * 2 * kNumberOfBins]; // Fields for Calibration int fMaxChips; char fCalibDirectory[1000]; // Fields for Response Calibration old method ResponseCalibration *fResponseCalibration; // Fields for Calibration new method bool fCellCalibrationValid; double fCellCalibratedRange; unsigned short fCellOffset[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; unsigned short fCellOffset2[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; double fCellGain[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; bool fTimingCalibrationValid; double fTimingCalibratedFrequency; double fCellT[kNumberOfChipsMax][kNumberOfBins]; signed short fCellDT[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; // Fields for Time Calibration TimeData **fTimeData; int fNumberOfTimeData; // General debugging flag int fDebug; // Fields for wave transfer bool fWaveTransferred[kNumberOfChipsMax * kNumberOfChannelsMax]; // Waveform Rotation int fTriggerStartBin; // Start Bin of the trigger private: DRSBoard(const DRSBoard &c); // not implemented DRSBoard &operator=(const DRSBoard &rhs); // not implemented public: // Public Methods #ifdef HAVE_USB DRSBoard(MUSB_INTERFACE * musb_interface, int usb_slot); #endif #ifdef HAVE_VME DRSBoard(MVME_INTERFACE * mvme_interface, mvme_addr_t base_address, int slot_number); MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; #endif ~DRSBoard(); int SetBoardSerialNumber(unsigned short serialNumber); int GetBoardSerialNumber() const { return fBoardSerialNumber; } int GetFirmwareVersion() const { return fFirmwareVersion; } int GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; } int GetDRSType() const { return fDRSType; } int GetBoardType() const { return fBoardType; } int GetNumberOfChips() const { return fNumberOfChips; } // channel : Flash ADC index // readout channel : VME readout index // input : Input on board int GetNumberOfChannels() const { return fNumberOfChannels; } inline int GetNumberOfReadoutChannels() const; inline int GetNumberOfInputs() const; inline int GetNumberOfCalibInputs() const; inline int GetClockChannel() const; inline int GetTriggerChannel() const; inline int GetClockInput() const { return Channel2Input(GetClockChannel()); } inline int GetTriggerInput() const { return fDRSType < 4 ? Channel2Input(GetTriggerChannel()) : -1; } inline int Channel2Input(int channel) const; inline int Channel2ReadoutChannel(int channel) const; inline int Input2Channel(int input, int ind = 0) const; inline int Input2ReadoutChannel(int input, int ind = 0) const; inline int ReadoutChannel2Channel(int readout) const; inline int ReadoutChannel2Input(int readout) const; inline bool IsCalibChannel(int ch) const; inline bool IsCalibInput(int input) const; int GetSlotNumber() const { return fSlotNumber; } int InitFPGA(void); int Write(int type, unsigned int addr, void *data, int size); int Read(int type, void *data, unsigned int addr, int size); int GetTransport() const { return fTransport; } void RegisterTest(void); int RAMTest(int flag); int ChipTest(); unsigned int GetCtrlReg(void); unsigned short GetConfigReg(void); unsigned int GetStatusReg(void); void SetLED(int state); void SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels); void SetADCClkPhase(int phase, bool invert); void SetWarmup(unsigned int ticks); void SetCooldown(unsigned int ticks); int GetReadoutChannelConfig() { return fReadoutChannelConfig; } void SetNumberOfChannels(int nChannels); int EnableTrigger(int flag1, int flag2); int GetTriggerEnable(int i) { return i?fTriggerEnable2:fTriggerEnable1; } int SetDelayedTrigger(int flag); int SetTriggerDelay(int delay); int SetSyncDelay(int ticks); int GetTriggerDelay() { return fTriggerDelay; } int SetTriggerLevel(double value, bool negative); int SetTriggerSource(int source); int GetTriggerSource() { return fTriggerSource; } int SetDelayedStart(int flag); int SetTranspMode(int flag); int SetStandbyMode(int flag); int IsBusy(void); int IsPLLLocked(void); int IsLMKLocked(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 StartClearCycle(); int FinishClearCycle(); int Reinit(); int Init(); void SetDebug(int debug) { fDebug = debug; } int Debug() { return fDebug; } 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, bool wait); 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 SetInputRange(double center); double GetInputRange(void) { return fRange; } double GetCalibratedInputRange(void) { return fCellCalibratedRange; } double GetCalibratedFrequency(void) { return fTimingCalibratedFrequency; } int TransferWaves(int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); int TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); int TransferWaves(int firstChannel, int lastChannel); int TransferWaves(unsigned char *p, int firstChannel, int lastChannel); int DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, unsigned short *waveform); int DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform); 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, bool offsetCalib = true); 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, bool offsetCalib = true); int GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib, int triggerCell = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform); int GetRawWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform, bool adjustToClock = false); int GetRawWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel, unsigned short *waveform, bool adjustToClock = false); int GetTime(unsigned int chipIndex, double freq, float *time, bool tcalibrated=true, bool rotated=true); int GetTime(unsigned int chipIndex, float *time, bool tcalibrated=true, bool rotated=true); int GetTriggerCell(unsigned int chipIndex); int GetStopCell(unsigned int chipIndex); int GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex); void TestDAC(int channel); void MeasureSpeed(); void InteractSpeed(); void MonitorFrequency(); int TestShift(int n); int EnableAcal(int mode, double voltage); int GetAcalMode() { return fAcalMode; } double GetAcalVolt() { return fAcalVolt; } int EnableTcal(int freq, int level=0, int phase=0); int SelectClockSource(int source); int SetRefclk(int source); int GetTcalFreq() { return fTcalFreq; } int GetTcalLevel() { return fTcalLevel; } int GetTcalPhase() { return fTcalPhase; } int GetTcalSource() { return fTcalSource; } int SetCalibVoltage(double value); int SetCalibTiming(int t1, int t2); double GetTemperature(); int GetTriggerBus(); int ReadEEPROM(unsigned short page, void *buffer, int size); int WriteEEPROM(unsigned short page, void *buffer, int size); bool HasCorrectFirmware(); int ConfigureLMK(double sampFreq, bool freqChange, int calFreq, int calPhase); bool InitTimeCalibration(unsigned int chipIndex); void SetCalibrationDirectory(const char *calibrationDirectoryPath); void GetCalibrationDirectory(char *calibrationDirectoryPath); ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; } double GetPrecision() const { return fResponseCalibration ? fResponseCalibration->GetPrecision() : 0.1; } int CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform, short *waveform, bool responseCalib, int triggerCell, bool adjustToClock, float threshold, bool offsetCalib); static void LinearRegression(double *x, double *y, int n, double *a, double *b); void ReadSingleWaveform(int nChips, int nChan, unsigned short wfu[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins], bool rotated); int AverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); int RobustAverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); int CalibrateVolt(DRSCallback *pcb); int AnalyzeWF(int nIter, float wf[kNumberOfBins], int tCell, double cellT[kNumberOfBins]); int CalibrateTiming(DRSCallback *pcb); bool IsCalibrationValid() { return fCellCalibrationValid; } bool IsTimingCalibrationValid() { return fTimingCalibrationValid; } static void RemoveSymmetricSpikes(short **wf, int nwf, short diffThreshold, int spikeWidth, short maxPeakToPeak, short spikeVoltage, int nTimeRegionThreshold); protected: // Protected Methods void ConstructBoard(); void ReadSerialNumber(); void ReadCalibration(void); TimeData *GetTimeCalibration(unsigned int chipIndex, bool reinit = false); int GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period); }; int DRSBoard::GetNumberOfReadoutChannels() const { return (fDRSType == 4 && fReadoutChannelConfig == 4) ? 5 : fNumberOfChannels; } int DRSBoard::GetNumberOfInputs() const { // return number of input channels excluding clock and trigger channels. if (fDRSType < 4) { return fNumberOfChannels - 2; } else { return fNumberOfChannels / 2; } } int DRSBoard::GetNumberOfCalibInputs() const { return (fDRSType < 4) ? 2 : 1; } int DRSBoard::GetClockChannel() const { return fDRSType < 4 ? 9 : 8; } int DRSBoard::GetTriggerChannel() const { return fDRSType < 4 ? 8 : -1; } int DRSBoard::Channel2Input(int channel) const { return (fDRSType < 4) ? channel : channel / 2; } int DRSBoard::Channel2ReadoutChannel(int channel) const { if (fDRSType < 4) { return channel; } else { if (fReadoutChannelConfig == 4) { return channel / 2; } else { return channel; } } } int DRSBoard::Input2Channel(int input, int ind) const { return (fDRSType < 4) ? input : (input * 2 + ind); } int DRSBoard::Input2ReadoutChannel(int input, int ind) const { if (fDRSType < 4) { return input; } else { if (fReadoutChannelConfig == 4) { return input; } else { return (input * 2 + ind); } } } int DRSBoard::ReadoutChannel2Channel(int readout) const { if (fDRSType < 4) { return readout; } else { if (fReadoutChannelConfig == 4) { return readout * 2; } else { return readout; } } } int DRSBoard::ReadoutChannel2Input(int readout) const { if (fDRSType < 4) { return readout; } else { if (fReadoutChannelConfig == 4) { return readout; } else { return readout / 2; } } } bool DRSBoard::IsCalibChannel(int ch) const { // return if it is clock or trigger channel if (fDRSType < 4) return ch == GetClockChannel() || ch == GetTriggerChannel(); else return ch == GetClockChannel(); } bool DRSBoard::IsCalibInput(int input) const { // return if it is clock or trigger channel int ch = Input2Channel(input); if (fDRSType < 4) return ch == GetClockChannel() || ch == GetTriggerChannel(); else return ch == GetClockChannel(); } class DRS { protected: // constants enum { kMaxNumberOfBoards = 40 }; protected: DRSBoard *fBoard[kMaxNumberOfBoards]; int fNumberOfBoards; char fError[256]; #ifdef HAVE_VME MVME_INTERFACE *fVmeInterface; #endif private: DRS(const DRS &c); // not implemented DRS &operator=(const DRS &rhs); // not implemented public: // Public Methods DRS(); ~DRS(); DRSBoard *GetBoard(int i) { return fBoard[i]; } DRSBoard **GetBoards() { return fBoard; } int GetNumberOfBoards() const { return fNumberOfBoards; } bool GetError(char *str, int size); #ifdef HAVE_VME MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; #endif }; #endif // DRS_H