Rev 197 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 195 | f9daq | 1 | /******************************************************************** |
| 2 | DRS.h, S.Ritt, M. Schneebeli - PSI |
||
| 3 | |||
| 4 | $Id: DRS.h 21309 2014-04-11 14:51:29Z ritt $ |
||
| 5 | |||
| 6 | ********************************************************************/ |
||
| 7 | #ifndef DRS_H |
||
| 8 | #define DRS_H |
||
| 9 | #include <stdio.h> |
||
| 10 | #include <string.h> |
||
| 11 | #include "averager.h" |
||
| 12 | |||
| 13 | #ifdef HAVE_LIBUSB |
||
| 14 | # ifndef HAVE_USB |
||
| 15 | # define HAVE_USB |
||
| 16 | # endif |
||
| 17 | #endif |
||
| 18 | |||
| 19 | #ifdef HAVE_USB |
||
| 20 | # include "musbstd.h" |
||
| 21 | #endif // HAVE_USB |
||
| 22 | |||
| 23 | #ifdef HAVE_VME |
||
| 24 | # include <mvmestd.h> |
||
| 25 | #endif // HAVE_VME |
||
| 26 | |||
| 27 | /* disable "deprecated" warning */ |
||
| 28 | #ifdef _MSC_VER |
||
| 29 | #pragma warning(disable: 4996) |
||
| 30 | #endif |
||
| 31 | |||
| 32 | #ifndef NULL |
||
| 33 | #define NULL 0 |
||
| 34 | #endif |
||
| 35 | |||
| 36 | int drs_kbhit(); |
||
| 37 | unsigned int millitime(); |
||
| 38 | |||
| 39 | /* transport mode */ |
||
| 40 | #define TR_VME 1 |
||
| 41 | #define TR_USB 2 |
||
| 42 | #define TR_USB2 3 |
||
| 43 | |||
| 44 | /* address types */ |
||
| 45 | #ifndef T_CTRL |
||
| 46 | #define T_CTRL 1 |
||
| 47 | #define T_STATUS 2 |
||
| 48 | #define T_RAM 3 |
||
| 49 | #define T_FIFO 4 |
||
| 50 | #endif |
||
| 51 | |||
| 52 | /*---- Register addresses ------------------------------------------*/ |
||
| 53 | |||
| 54 | #define REG_CTRL 0x00000 /* 32 bit control reg */ |
||
| 55 | #define REG_DAC_OFS 0x00004 |
||
| 56 | #define REG_DAC0 0x00004 |
||
| 57 | #define REG_DAC1 0x00006 |
||
| 58 | #define REG_DAC2 0x00008 |
||
| 59 | #define REG_DAC3 0x0000A |
||
| 60 | #define REG_DAC4 0x0000C |
||
| 61 | #define REG_DAC5 0x0000E |
||
| 62 | #define REG_DAC6 0x00010 |
||
| 63 | #define REG_DAC7 0x00012 |
||
| 64 | #define REG_CHANNEL_CONFIG 0x00014 // low byte |
||
| 65 | #define REG_CONFIG 0x00014 // high byte |
||
| 66 | #define REG_CHANNEL_MODE 0x00016 |
||
| 67 | #define REG_ADCCLK_PHASE 0x00016 |
||
| 68 | #define REG_FREQ_SET_HI 0x00018 // DRS2 |
||
| 69 | #define REG_FREQ_SET_LO 0x0001A // DRS2 |
||
| 70 | #define REG_TRG_DELAY 0x00018 // DRS4 |
||
| 71 | #define REG_FREQ_SET 0x0001A // DRS4 |
||
| 72 | #define REG_TRIG_DELAY 0x0001C |
||
| 73 | #define REG_LMK_MSB 0x0001C // DRS4 Mezz |
||
| 74 | #define REG_CALIB_TIMING 0x0001E // DRS2 |
||
| 75 | #define REG_EEPROM_PAGE_EVAL 0x0001E // DRS4 Eval |
||
| 76 | #define REG_EEPROM_PAGE_MEZZ 0x0001A // DRS4 Mezz |
||
| 77 | #define REG_TRG_CONFIG 0x0001C // DRS4 Eval4 |
||
| 78 | #define REG_LMK_LSB 0x0001E // DRS4 Mezz |
||
| 79 | #define REG_WARMUP 0x00020 // DRS4 Mezz |
||
| 80 | #define REG_COOLDOWN 0x00022 // DRS4 Mezz |
||
| 81 | #define REG_READ_POINTER 0x00026 // DRS4 Mezz |
||
| 82 | |||
| 83 | #define REG_MAGIC 0x00000 |
||
| 84 | #define REG_BOARD_TYPE 0x00002 |
||
| 85 | #define REG_STATUS 0x00004 |
||
| 86 | #define REG_RDAC_OFS 0x0000E |
||
| 87 | #define REG_RDAC0 0x00008 |
||
| 88 | #define REG_STOP_CELL0 0x00008 |
||
| 89 | #define REG_RDAC1 0x0000A |
||
| 90 | #define REG_STOP_CELL1 0x0000A |
||
| 91 | #define REG_RDAC2 0x0000C |
||
| 92 | #define REG_STOP_CELL2 0x0000C |
||
| 93 | #define REG_RDAC3 0x0000E |
||
| 94 | #define REG_STOP_CELL3 0x0000E |
||
| 95 | #define REG_RDAC4 0x00000 |
||
| 96 | #define REG_RDAC5 0x00002 |
||
| 97 | #define REG_STOP_WSR0 0x00010 |
||
| 98 | #define REG_STOP_WSR1 0x00011 |
||
| 99 | #define REG_STOP_WSR2 0x00012 |
||
| 100 | #define REG_STOP_WSR3 0x00013 |
||
| 101 | #define REG_RDAC6 0x00014 |
||
| 102 | #define REG_RDAC7 0x00016 |
||
| 103 | #define REG_EVENTS_IN_FIFO 0x00018 |
||
| 104 | #define REG_EVENT_COUNT 0x0001A |
||
| 105 | #define REG_FREQ1 0x0001C |
||
| 106 | #define REG_FREQ2 0x0001E |
||
| 107 | #define REG_WRITE_POINTER 0x0001E |
||
| 108 | #define REG_TEMPERATURE 0x00020 |
||
| 109 | #define REG_TRIGGER_BUS 0x00022 |
||
| 110 | #define REG_SERIAL_BOARD 0x00024 |
||
| 111 | #define REG_VERSION_FW 0x00026 |
||
| 112 | #define REG_SCALER0 0x00028 |
||
| 113 | #define REG_SCALER1 0x0002C |
||
| 114 | #define REG_SCALER2 0x00030 |
||
| 115 | #define REG_SCALER3 0x00034 |
||
| 116 | #define REG_SCALER4 0x00038 |
||
| 117 | #define REG_SCALER5 0x0003C |
||
| 118 | |||
| 119 | /*---- Control register bit definitions ----------------------------*/ |
||
| 120 | |||
| 121 | #define BIT_START_TRIG (1<<0) // write a "1" to start domino wave |
||
| 122 | #define BIT_REINIT_TRIG (1<<1) // write a "1" to stop & reset DRS |
||
| 123 | #define BIT_SOFT_TRIG (1<<2) // write a "1" to stop and read data to RAM |
||
| 124 | #define BIT_EEPROM_WRITE_TRIG (1<<3) // write a "1" to write into serial EEPROM |
||
| 125 | #define BIT_EEPROM_READ_TRIG (1<<4) // write a "1" to read from serial EEPROM |
||
| 126 | #define BIT_MULTI_BUFFER (1<<16) // Use multi buffering when "1" |
||
| 127 | #define BIT_DMODE (1<<17) // (*DRS2*) 0: single shot, 1: circular |
||
| 128 | #define BIT_ADC_ACTIVE (1<<17) // (*DRS4*) 0: stop ADC when running, 1: ADC always clocked |
||
| 129 | #define BIT_LED (1<<18) // 1=on, 0=blink during readout |
||
| 130 | #define BIT_TCAL_EN (1<<19) // switch on (1) / off (0) for 33 MHz calib signal |
||
| 131 | #define BIT_TCAL_SOURCE (1<<20) |
||
| 132 | #define BIT_REFCLK_SOURCE (1<<20) |
||
| 133 | #define BIT_FREQ_AUTO_ADJ (1<<21) // DRS2/3 |
||
| 134 | #define BIT_TRANSP_MODE (1<<21) // DRS4 |
||
| 135 | #define BIT_ENABLE_TRIGGER1 (1<<22) // External LEMO/FP/TRBUS trigger |
||
| 136 | #define BIT_LONG_START_PULSE (1<<23) // (*DRS2*) 0:short start pulse (>0.8GHz), 1:long start pulse (<0.8GHz) |
||
| 137 | #define BIT_READOUT_MODE (1<<23) // (*DRS3*,*DRS4*) 0:start from first bin, 1:start from domino stop |
||
| 138 | #define BIT_DELAYED_START (1<<24) // DRS2: start domino wave 400ns after soft trigger, used for waveform |
||
| 139 | // generator startup |
||
| 140 | #define BIT_NEG_TRIGGER (1<<24) // DRS4: use high-to-low trigger if set |
||
| 141 | #define BIT_ACAL_EN (1<<25) // connect DRS to inputs (0) or to DAC6 (1) |
||
| 142 | #define BIT_TRIGGER_DELAYED (1<<26) // select delayed trigger from trigger bus |
||
| 143 | #define BIT_ADCCLK_INVERT (1<<26) // invert ADC clock |
||
| 144 | #define BIT_REFCLK_EXT (1<<26) // use external MMCX CLKIN refclk |
||
| 145 | #define BIT_DACTIVE (1<<27) // keep domino wave running during readout |
||
| 146 | #define BIT_STANDBY_MODE (1<<28) // put chip in standby mode |
||
| 147 | #define BIT_TR_SOURCE1 (1<<29) // trigger source selection bits |
||
| 148 | #define BIT_DECIMATION (1<<29) // drop all odd samples (DRS4 mezz.) |
||
| 149 | #define BIT_TR_SOURCE2 (1<<30) // trigger source selection bits |
||
| 150 | #define BIT_ENABLE_TRIGGER2 (1<<31) // analog threshold (internal) trigger |
||
| 151 | |||
| 152 | /* DRS4 configuration register bit definitions */ |
||
| 153 | #define BIT_CONFIG_DMODE (1<<8) // 0: single shot, 1: circular |
||
| 154 | #define BIT_CONFIG_PLLEN (1<<9) // write a "1" to enable the internal PLL |
||
| 155 | #define BIT_CONFIG_WSRLOOP (1<<10) // write a "1" to connect WSROUT to WSRIN internally |
||
| 156 | |||
| 157 | /*---- Status register bit definitions -----------------------------*/ |
||
| 158 | |||
| 159 | #define BIT_RUNNING (1<<0) // one if domino wave running or readout in progress |
||
| 160 | #define BIT_NEW_FREQ1 (1<<1) // one if new frequency measurement available |
||
| 161 | #define BIT_NEW_FREQ2 (1<<2) |
||
| 162 | #define BIT_PLL_LOCKED0 (1<<1) // 1 if PLL has locked (DRS4 evaluation board only) |
||
| 163 | #define BIT_PLL_LOCKED1 (1<<2) // 1 if PLL DRS4 B has locked (DRS4 mezzanine board only) |
||
| 164 | #define BIT_PLL_LOCKED2 (1<<3) // 1 if PLL DRS4 C has locked (DRS4 mezzanine board only) |
||
| 165 | #define BIT_PLL_LOCKED3 (1<<4) // 1 if PLL DRS4 D has locked (DRS4 mezzanine board only) |
||
| 166 | #define BIT_SERIAL_BUSY (1<<5) // 1 if EEPROM operation in progress |
||
| 167 | #define BIT_LMK_LOCKED (1<<6) // 1 if PLL of LMK chip has locked (DRS4 mezzanine board only) |
||
| 168 | #define BIT_2048_MODE (1<<7) // 1 if 2048-bin mode has been soldered |
||
| 169 | |||
| 170 | enum DRSBoardConstants { |
||
| 171 | kNumberOfChannelsMax = 10, |
||
| 172 | kNumberOfCalibChannelsV3 = 10, |
||
| 173 | kNumberOfCalibChannelsV4 = 8, |
||
| 174 | kNumberOfBins = 1024, |
||
| 175 | kNumberOfChipsMax = 4, |
||
| 176 | kFrequencyCacheSize = 10, |
||
| 177 | kBSplineOrder = 4, |
||
| 178 | kPreCaliculatedBSplines = 1000, |
||
| 179 | kPreCaliculatedBSplineGroups = 5, |
||
| 180 | kNumberOfADCBins = 4096, |
||
| 181 | kBSplineXMinOffset = 20, |
||
| 182 | kMaxNumberOfClockCycles = 100, |
||
| 183 | }; |
||
| 184 | |||
| 185 | enum DRSErrorCodes { |
||
| 186 | kSuccess = 0, |
||
| 187 | kInvalidTriggerSignal = -1, |
||
| 188 | kWrongChannelOrChip = -2, |
||
| 189 | kInvalidTransport = -3, |
||
| 190 | kZeroSuppression = -4, |
||
| 191 | kWaveNotAvailable = -5 |
||
| 192 | }; |
||
| 193 | |||
| 194 | /*---- callback class ----*/ |
||
| 195 | |||
| 196 | class DRSCallback |
||
| 197 | { |
||
| 198 | public: |
||
| 199 | virtual void Progress(int value) = 0; |
||
| 200 | virtual ~DRSCallback() {}; |
||
| 201 | }; |
||
| 202 | |||
| 203 | /*------------------------*/ |
||
| 204 | |||
| 205 | class DRSBoard; |
||
| 206 | |||
| 207 | class ResponseCalibration { |
||
| 208 | protected: |
||
| 209 | |||
| 210 | class CalibrationData { |
||
| 211 | public: |
||
| 212 | class CalibrationDataChannel { |
||
| 213 | public: |
||
| 214 | unsigned char fLimitGroup[kNumberOfBins]; //! |
||
| 215 | float fMin[kNumberOfBins]; //! |
||
| 216 | float fRange[kNumberOfBins]; //! |
||
| 217 | short fOffset[kNumberOfBins]; //! |
||
| 218 | short fGain[kNumberOfBins]; //! |
||
| 219 | unsigned short fOffsetADC[kNumberOfBins]; //! |
||
| 220 | short *fData[kNumberOfBins]; //! |
||
| 221 | unsigned char *fLookUp[kNumberOfBins]; //! |
||
| 222 | unsigned short fLookUpOffset[kNumberOfBins]; //! |
||
| 223 | unsigned char fNumberOfLookUpPoints[kNumberOfBins]; //! |
||
| 224 | float *fTempData; //! |
||
| 225 | |||
| 226 | private: |
||
| 227 | CalibrationDataChannel(const CalibrationDataChannel &c); // not implemented |
||
| 228 | CalibrationDataChannel &operator=(const CalibrationDataChannel &rhs); // not implemented |
||
| 229 | |||
| 230 | public: |
||
| 231 | CalibrationDataChannel(int numberOfGridPoints) |
||
| 232 | :fTempData(new float[numberOfGridPoints]) { |
||
| 233 | int i; |
||
| 234 | for (i = 0; i < kNumberOfBins; i++) { |
||
| 235 | fData[i] = new short[numberOfGridPoints]; |
||
| 236 | } |
||
| 237 | memset(fLimitGroup, 0, sizeof(fLimitGroup)); |
||
| 238 | memset(fMin, 0, sizeof(fMin)); |
||
| 239 | memset(fRange, 0, sizeof(fRange)); |
||
| 240 | memset(fOffset, 0, sizeof(fOffset)); |
||
| 241 | memset(fGain, 0, sizeof(fGain)); |
||
| 242 | memset(fOffsetADC, 0, sizeof(fOffsetADC)); |
||
| 243 | memset(fLookUp, 0, sizeof(fLookUp)); |
||
| 244 | memset(fLookUpOffset, 0, sizeof(fLookUpOffset)); |
||
| 245 | memset(fNumberOfLookUpPoints, 0, sizeof(fNumberOfLookUpPoints)); |
||
| 246 | } |
||
| 247 | ~CalibrationDataChannel() { |
||
| 248 | int i; |
||
| 249 | delete fTempData; |
||
| 250 | for (i = 0; i < kNumberOfBins; i++) { |
||
| 251 | delete fData[i]; |
||
| 252 | delete fLookUp[i]; |
||
| 253 | } |
||
| 254 | } |
||
| 255 | }; |
||
| 256 | |||
| 257 | bool fRead; //! |
||
| 258 | CalibrationDataChannel *fChannel[10]; //! |
||
| 259 | unsigned char fNumberOfGridPoints; //! |
||
| 260 | int fHasOffsetCalibration; //! |
||
| 261 | float fStartTemperature; //! |
||
| 262 | float fEndTemperature; //! |
||
| 263 | int *fBSplineOffsetLookUp[kNumberOfADCBins]; //! |
||
| 264 | float **fBSplineLookUp[kNumberOfADCBins]; //! |
||
| 265 | float fMin; //! |
||
| 266 | float fMax; //! |
||
| 267 | unsigned char fNumberOfLimitGroups; //! |
||
| 268 | static float fIntRevers[2 * kBSplineOrder - 2]; |
||
| 269 | |||
| 270 | private: |
||
| 271 | CalibrationData(const CalibrationData &c); // not implemented |
||
| 272 | CalibrationData &operator=(const CalibrationData &rhs); // not implemented |
||
| 273 | |||
| 274 | public: |
||
| 275 | CalibrationData(int numberOfGridPoints); |
||
| 276 | ~CalibrationData(); |
||
| 277 | static int CalculateBSpline(int nGrid, float value, float *bsplines); |
||
| 278 | void PreCalculateBSpline(); |
||
| 279 | void DeletePreCalculatedBSpline(); |
||
| 280 | }; |
||
| 281 | |||
| 282 | // General Fields |
||
| 283 | DRSBoard *fBoard; |
||
| 284 | |||
| 285 | double fPrecision; |
||
| 286 | |||
| 287 | // Fields for creating the Calibration |
||
| 288 | bool fInitialized; |
||
| 289 | bool fRecorded; |
||
| 290 | bool fFitted; |
||
| 291 | bool fOffset; |
||
| 292 | bool fCalibrationValid[2]; |
||
| 293 | |||
| 294 | int fNumberOfPointsLowVolt; |
||
| 295 | int fNumberOfPoints; |
||
| 296 | int fNumberOfMode2Bins; |
||
| 297 | int fNumberOfSamples; |
||
| 298 | int fNumberOfGridPoints; |
||
| 299 | int fNumberOfXConstPoints; |
||
| 300 | int fNumberOfXConstGridPoints; |
||
| 301 | double fTriggerFrequency; |
||
| 302 | int fShowStatistics; |
||
| 303 | FILE *fCalibFile; |
||
| 304 | |||
| 305 | int fCurrentLowVoltPoint; |
||
| 306 | int fCurrentPoint; |
||
| 307 | int fCurrentSample; |
||
| 308 | int fCurrentFitChannel; |
||
| 309 | int fCurrentFitBin; |
||
| 310 | |||
| 311 | float *fResponseX[10][kNumberOfBins]; |
||
| 312 | float *fResponseY; |
||
| 313 | unsigned short **fWaveFormMode3[10]; |
||
| 314 | unsigned short **fWaveFormMode2[10]; |
||
| 315 | short **fWaveFormOffset[10]; |
||
| 316 | unsigned short **fWaveFormOffsetADC[10]; |
||
| 317 | unsigned short *fSamples; |
||
| 318 | int *fSampleUsed; |
||
| 319 | |||
| 320 | float *fPntX[2]; |
||
| 321 | float *fPntY[2]; |
||
| 322 | float *fUValues[2]; |
||
| 323 | float *fRes[kNumberOfBins]; |
||
| 324 | float *fResX[kNumberOfBins]; |
||
| 325 | |||
| 326 | double *fXXFit; |
||
| 327 | double *fYYFit; |
||
| 328 | double *fWWFit; |
||
| 329 | double *fYYFitRes; |
||
| 330 | double *fYYSave; |
||
| 331 | double *fXXSave; |
||
| 332 | double fGainMin; |
||
| 333 | double fGainMax; |
||
| 334 | |||
| 335 | float **fStatisticsApprox; |
||
| 336 | float **fStatisticsApproxExt; |
||
| 337 | |||
| 338 | // Fields for applying the Calibration |
||
| 339 | CalibrationData *fCalibrationData[kNumberOfChipsMax]; |
||
| 340 | |||
| 341 | private: |
||
| 342 | ResponseCalibration(const ResponseCalibration &c); // not implemented |
||
| 343 | ResponseCalibration &operator=(const ResponseCalibration &rhs); // not implemented |
||
| 344 | |||
| 345 | public: |
||
| 346 | ResponseCalibration(DRSBoard* board); |
||
| 347 | ~ResponseCalibration(); |
||
| 348 | |||
| 349 | void SetCalibrationParameters(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, |
||
| 350 | int numberOfSamples, int numberOfGridPoints, int numberOfXConstPoints, |
||
| 351 | int numberOfXConstGridPoints, double triggerFrequency, int showStatistics = 0); |
||
| 352 | void ResetCalibration(); |
||
| 353 | bool RecordCalibrationPoints(int chipNumber); |
||
| 354 | bool RecordCalibrationPointsV3(int chipNumber); |
||
| 355 | bool RecordCalibrationPointsV4(int chipNumber); |
||
| 356 | bool FitCalibrationPoints(int chipNumber); |
||
| 357 | bool FitCalibrationPointsV3(int chipNumber); |
||
| 358 | bool FitCalibrationPointsV4(int chipNumber); |
||
| 359 | bool OffsetCalibration(int chipNumber); |
||
| 360 | bool OffsetCalibrationV3(int chipNumber); |
||
| 361 | bool OffsetCalibrationV4(int chipNumber); |
||
| 362 | double GetTemperature(unsigned int chipIndex); |
||
| 363 | |||
| 364 | bool WriteCalibration(unsigned int chipIndex); |
||
| 365 | bool WriteCalibrationV3(unsigned int chipIndex); |
||
| 366 | bool WriteCalibrationV4(unsigned int chipIndex); |
||
| 367 | bool ReadCalibration(unsigned int chipIndex); |
||
| 368 | bool ReadCalibrationV3(unsigned int chipIndex); |
||
| 369 | bool ReadCalibrationV4(unsigned int chipIndex); |
||
| 370 | bool Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform, |
||
| 371 | int triggerCell, float threshold, bool offsetCalib); |
||
| 372 | bool SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, |
||
| 373 | unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel); |
||
| 374 | bool IsRead(int chipIndex) const { return fCalibrationValid[chipIndex]; } |
||
| 375 | double GetPrecision() const { return fPrecision; }; |
||
| 376 | |||
| 377 | double GetOffsetAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fOffset[bin]; }; |
||
| 378 | double GetGainAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fGain[bin]; }; |
||
| 379 | double GetMeasPointXAt(int ip) const { return fXXSave[ip]; }; |
||
| 380 | double GetMeasPointYAt(int ip) const { return fYYSave[ip]; }; |
||
| 381 | |||
| 382 | protected: |
||
| 383 | void InitFields(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, int numberOfSamples, |
||
| 384 | int numberOfGridPoints, int numberOfXConstPoints, int numberOfXConstGridPoints, |
||
| 385 | double triggerFrequency, int showStatistics); |
||
| 386 | void DeleteFields(); |
||
| 387 | void CalibrationTrigger(int mode, double voltage); |
||
| 388 | void CalibrationStart(double voltage); |
||
| 389 | |||
| 390 | static float GetValue(float *coefficients, float u, int n); |
||
| 391 | static int Approx(float *p, float *uu, int np, int nu, float *coef); |
||
| 392 | static void LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt); |
||
| 393 | static int LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n); |
||
| 394 | static void Housholder(int lpivot, int l1, int m, float **u, int iU1, int iU2, float *up, float **c, int iC1, |
||
| 395 | int iC2, int ice, int ncv); |
||
| 396 | |||
| 397 | static int MakeDir(const char *path); |
||
| 398 | static void Average(int method,float *samples,int numberOfSamples,float &mean,float &error,float sigmaBoundary); |
||
| 399 | }; |
||
| 400 | |||
| 401 | |||
| 402 | class DRSBoard { |
||
| 403 | protected: |
||
| 404 | class TimeData { |
||
| 405 | public: |
||
| 406 | class FrequencyData { |
||
| 407 | public: |
||
| 408 | int fFrequency; |
||
| 409 | double fBin[kNumberOfBins]; |
||
| 410 | }; |
||
| 411 | |||
| 412 | enum { |
||
| 413 | kMaxNumberOfFrequencies = 4000 |
||
| 414 | }; |
||
| 415 | int fChip; |
||
| 416 | int fNumberOfFrequencies; |
||
| 417 | FrequencyData *fFrequency[kMaxNumberOfFrequencies]; |
||
| 418 | |||
| 419 | private: |
||
| 420 | TimeData(const TimeData &c); // not implemented |
||
| 421 | TimeData &operator=(const TimeData &rhs); // not implemented |
||
| 422 | |||
| 423 | public: |
||
| 424 | TimeData() |
||
| 425 | :fChip(0) |
||
| 426 | ,fNumberOfFrequencies(0) { |
||
| 427 | } |
||
| 428 | ~TimeData() { |
||
| 429 | int i; |
||
| 430 | for (i = 0; i < fNumberOfFrequencies; i++) { |
||
| 431 | delete fFrequency[i]; |
||
| 432 | } |
||
| 433 | } |
||
| 434 | }; |
||
| 435 | |||
| 436 | public: |
||
| 437 | // DAC channels (CMC Version 1 : DAC_COFSA,DAC_COFSB,DAC_DRA,DAC_DSA,DAC_TLEVEL,DAC_ACALIB,DAC_DSB,DAC_DRB) |
||
| 438 | unsigned int fDAC_COFSA; |
||
| 439 | unsigned int fDAC_COFSB; |
||
| 440 | unsigned int fDAC_DRA; |
||
| 441 | unsigned int fDAC_DSA; |
||
| 442 | unsigned int fDAC_TLEVEL; |
||
| 443 | unsigned int fDAC_ACALIB; |
||
| 444 | unsigned int fDAC_DSB; |
||
| 445 | unsigned int fDAC_DRB; |
||
| 446 | // DAC channels (CMC Version 2+3 : DAC_COFS,DAC_DSA,DAC_DSB,DAC_TLEVEL,DAC_ADCOFS,DAC_CLKOFS,DAC_ACALIB) |
||
| 447 | unsigned int fDAC_COFS; |
||
| 448 | unsigned int fDAC_ADCOFS; |
||
| 449 | unsigned int fDAC_CLKOFS; |
||
| 450 | // DAC channels (CMC Version 4 : DAC_ROFS_1,DAC_DSA,DAC_DSB,DAC_ROFS_2,DAC_ADCOFS,DAC_ACALIB,DAC_INOFS,DAC_BIAS) |
||
| 451 | unsigned int fDAC_ROFS_1; |
||
| 452 | unsigned int fDAC_ROFS_2; |
||
| 453 | unsigned int fDAC_INOFS; |
||
| 454 | unsigned int fDAC_BIAS; |
||
| 455 | // DAC channels (USB EVAL1 (fBoardType 5) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS) |
||
| 456 | // DAC channels (USB EVAL3 (fBoardType 7) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS) |
||
| 457 | unsigned int fDAC_CMOFS; |
||
| 458 | unsigned int fDAC_CALN; |
||
| 459 | unsigned int fDAC_CALP; |
||
| 460 | unsigned int fDAC_ONOFS; |
||
| 461 | // DAC channels (DRS4 MEZZ1 (fBoardType 6) : DAC_ONOFS,DAC_CMOFSP,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_CMOFSN,DAC_ROFS_1) |
||
| 462 | unsigned int fDAC_CMOFSP; |
||
| 463 | unsigned int fDAC_CMOFSN; |
||
| 464 | // DAC channels (DRS4 EVAL4 (fBoardType 8) : DAC_ONOFS,DAC_TLEVEL4,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL1,DAC_TLEVEL2,DAC_TLEVEL3) |
||
| 465 | unsigned int fDAC_TLEVEL1; |
||
| 466 | unsigned int fDAC_TLEVEL2; |
||
| 467 | unsigned int fDAC_TLEVEL3; |
||
| 468 | unsigned int fDAC_TLEVEL4; |
||
| 469 | |||
| 470 | protected: |
||
| 471 | // Fields for DRS |
||
| 472 | int fDRSType; |
||
| 473 | int fBoardType; |
||
| 474 | int fNumberOfChips; |
||
| 475 | int fNumberOfChannels; |
||
| 476 | int fRequiredFirmwareVersion; |
||
| 477 | int fFirmwareVersion; |
||
| 478 | int fBoardSerialNumber; |
||
| 479 | int fHasMultiBuffer; |
||
| 480 | unsigned int fTransport; |
||
| 481 | unsigned int fCtrlBits; |
||
| 482 | int fNumberOfReadoutChannels; |
||
| 483 | int fReadoutChannelConfig; |
||
| 484 | int fADCClkPhase; |
||
| 485 | bool fADCClkInvert; |
||
| 486 | double fExternalClockFrequency; |
||
| 487 | #ifdef HAVE_USB |
||
| 488 | MUSB_INTERFACE *fUsbInterface; |
||
| 489 | #endif |
||
| 490 | #ifdef HAVE_VME |
||
| 491 | MVME_INTERFACE *fVmeInterface; |
||
| 492 | mvme_addr_t fBaseAddress; |
||
| 493 | #endif |
||
| 494 | int fSlotNumber; |
||
| 495 | double fNominalFrequency; |
||
| 496 | double fTrueFrequency; |
||
| 497 | double fTCALFrequency; |
||
| 498 | double fRefClock; |
||
| 499 | int fMultiBuffer; |
||
| 500 | int fDominoMode; |
||
| 501 | int fDominoActive; |
||
| 502 | int fADCActive; |
||
| 503 | int fChannelConfig; |
||
| 504 | int fChannelCascading; |
||
| 505 | int fChannelDepth; |
||
| 506 | int fWSRLoop; |
||
| 507 | int fReadoutMode; |
||
| 508 | unsigned short fReadPointer; |
||
| 509 | int fNMultiBuffer; |
||
| 510 | int fTriggerEnable1; |
||
| 511 | int fTriggerEnable2; |
||
| 512 | int fTriggerSource; |
||
| 513 | int fTriggerDelay; |
||
| 514 | double fTriggerDelayNs; |
||
| 515 | int fSyncDelay; |
||
| 516 | int fDelayedStart; |
||
| 517 | int fTranspMode; |
||
| 518 | int fDecimation; |
||
| 519 | unsigned short fStopCell[4]; |
||
| 520 | unsigned char fStopWSR[4]; |
||
| 521 | unsigned short fTriggerBus; |
||
| 522 | double fROFS; |
||
| 523 | double fRange; |
||
| 524 | double fCommonMode; |
||
| 525 | int fAcalMode; |
||
| 526 | int fbkAcalMode; |
||
| 527 | double fAcalVolt; |
||
| 528 | double fbkAcalVolt; |
||
| 529 | int fTcalFreq; |
||
| 530 | int fbkTcalFreq; |
||
| 531 | int fTcalLevel; |
||
| 532 | int fbkTcalLevel; |
||
| 533 | int fTcalPhase; |
||
| 534 | int fTcalSource; |
||
| 535 | int fRefclk; |
||
| 536 | |||
| 537 | unsigned char fWaveforms[kNumberOfChipsMax * kNumberOfChannelsMax * 2 * kNumberOfBins]; |
||
| 538 | |||
| 539 | // Fields for Calibration |
||
| 540 | int fMaxChips; |
||
| 541 | char fCalibDirectory[1000]; |
||
| 542 | |||
| 543 | // Fields for Response Calibration old method |
||
| 544 | ResponseCalibration *fResponseCalibration; |
||
| 545 | |||
| 546 | // Fields for Calibration new method |
||
| 547 | bool fVoltageCalibrationValid; |
||
| 548 | double fCellCalibratedRange; |
||
| 549 | double fCellCalibratedTemperature; |
||
| 550 | unsigned short fCellOffset[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
| 551 | unsigned short fCellOffset2[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
| 552 | double fCellGain[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
| 553 | |||
| 554 | double fTimingCalibratedFrequency; |
||
| 555 | double fCellDT[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; |
||
| 556 | |||
| 557 | // Fields for Time Calibration |
||
| 558 | TimeData **fTimeData; |
||
| 559 | int fNumberOfTimeData; |
||
| 560 | |||
| 561 | // General debugging flag |
||
| 562 | int fDebug; |
||
| 563 | |||
| 564 | // Fields for wave transfer |
||
| 565 | bool fWaveTransferred[kNumberOfChipsMax * kNumberOfChannelsMax]; |
||
| 566 | |||
| 567 | // Waveform Rotation |
||
| 568 | int fTriggerStartBin; // Start Bin of the trigger |
||
| 569 | |||
| 570 | private: |
||
| 571 | DRSBoard(const DRSBoard &c); // not implemented |
||
| 572 | DRSBoard &operator=(const DRSBoard &rhs); // not implemented |
||
| 573 | |||
| 574 | public: |
||
| 575 | // Public Methods |
||
| 576 | #ifdef HAVE_USB |
||
| 577 | DRSBoard(MUSB_INTERFACE * musb_interface, int usb_slot); |
||
| 578 | #endif |
||
| 579 | #ifdef HAVE_VME |
||
| 580 | DRSBoard(MVME_INTERFACE * mvme_interface, mvme_addr_t base_address, int slot_number); |
||
| 581 | |||
| 582 | MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; |
||
| 583 | #endif |
||
| 584 | ~DRSBoard(); |
||
| 585 | |||
| 586 | int SetBoardSerialNumber(unsigned short serialNumber); |
||
| 587 | int GetBoardSerialNumber() const { return fBoardSerialNumber; } |
||
| 588 | int HasMultiBuffer() const { return fHasMultiBuffer; } |
||
| 589 | int GetFirmwareVersion() const { return fFirmwareVersion; } |
||
| 590 | int GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; } |
||
| 591 | int GetDRSType() const { return fDRSType; } |
||
| 592 | int GetBoardType() const { return fBoardType; } |
||
| 593 | int GetNumberOfChips() const { return fNumberOfChips; } |
||
| 594 | // channel : Flash ADC index |
||
| 595 | // readout channel : VME readout index |
||
| 596 | // input : Input on board |
||
| 597 | int GetNumberOfChannels() const { return fNumberOfChannels; } |
||
| 598 | int GetChannelDepth() const { return fChannelDepth; } |
||
| 599 | int GetChannelCascading() const { return fChannelCascading; } |
||
| 600 | inline int GetNumberOfReadoutChannels() const; |
||
| 601 | inline int GetWaveformBufferSize() const; |
||
| 602 | inline int GetNumberOfInputs() const; |
||
| 603 | inline int GetNumberOfCalibInputs() const; |
||
| 604 | inline int GetClockChannel() const; |
||
| 605 | inline int GetTriggerChannel() const; |
||
| 606 | inline int GetClockInput() const { return Channel2Input(GetClockChannel()); } |
||
| 607 | inline int GetTriggerInput() const { return fDRSType < 4 ? Channel2Input(GetTriggerChannel()) : -1; } |
||
| 608 | inline int Channel2Input(int channel) const; |
||
| 609 | inline int Channel2ReadoutChannel(int channel) const; |
||
| 610 | inline int Input2Channel(int input, int ind = 0) const; |
||
| 611 | inline int Input2ReadoutChannel(int input, int ind = 0) const; |
||
| 612 | inline int ReadoutChannel2Channel(int readout) const; |
||
| 613 | inline int ReadoutChannel2Input(int readout) const; |
||
| 614 | |||
| 615 | inline bool IsCalibChannel(int ch) const; |
||
| 616 | inline bool IsCalibInput(int input) const; |
||
| 617 | int GetSlotNumber() const { return fSlotNumber; } |
||
| 618 | int InitFPGA(void); |
||
| 619 | int Write(int type, unsigned int addr, void *data, int size); |
||
| 620 | int Read(int type, void *data, unsigned int addr, int size); |
||
| 621 | int GetTransport() const { return fTransport; } |
||
| 622 | void RegisterTest(void); |
||
| 623 | int RAMTest(int flag); |
||
| 624 | int ChipTest(); |
||
| 625 | unsigned int GetCtrlReg(void); |
||
| 626 | unsigned short GetConfigReg(void); |
||
| 627 | unsigned int GetStatusReg(void); |
||
| 628 | void SetLED(int state); |
||
| 629 | int SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels); |
||
| 630 | void SetADCClkPhase(int phase, bool invert); |
||
| 631 | void SetWarmup(unsigned int ticks); |
||
| 632 | void SetCooldown(unsigned int ticks); |
||
| 633 | int GetReadoutChannelConfig() { return fReadoutChannelConfig; } |
||
| 634 | void SetNumberOfChannels(int nChannels); |
||
| 635 | int EnableTrigger(int flag1, int flag2); |
||
| 636 | int GetTriggerEnable(int i) { return i?fTriggerEnable2:fTriggerEnable1; } |
||
| 637 | int SetDelayedTrigger(int flag); |
||
| 638 | int SetTriggerDelayPercent(int delay); |
||
| 639 | int SetTriggerDelayNs(int delay); |
||
| 640 | int GetTriggerDelay() { return fTriggerDelay; } |
||
| 641 | double GetTriggerDelayNs() { return fTriggerDelayNs; } |
||
| 642 | int SetSyncDelay(int ticks); |
||
| 643 | int SetTriggerLevel(double value); |
||
| 644 | int SetIndividualTriggerLevel(int channel, double voltage); |
||
| 645 | int SetTriggerPolarity(bool negative); |
||
| 646 | int SetTriggerSource(int source); |
||
| 647 | int GetTriggerSource() { return fTriggerSource; } |
||
| 648 | int SetDelayedStart(int flag); |
||
| 649 | int SetTranspMode(int flag); |
||
| 650 | int SetStandbyMode(int flag); |
||
| 651 | int SetDecimation(int flag); |
||
| 652 | int GetDecimation() { return fDecimation; } |
||
| 653 | int IsBusy(void); |
||
| 654 | int IsEventAvailable(void); |
||
| 655 | int IsPLLLocked(void); |
||
| 656 | int IsLMKLocked(void); |
||
| 657 | int IsNewFreq(unsigned char chipIndex); |
||
| 658 | int SetDAC(unsigned char channel, double value); |
||
| 659 | int ReadDAC(unsigned char channel, double *value); |
||
| 660 | int GetRegulationDAC(double *value); |
||
| 661 | int StartDomino(); |
||
| 662 | int StartClearCycle(); |
||
| 663 | int FinishClearCycle(); |
||
| 664 | int Reinit(); |
||
| 665 | int Init(); |
||
| 666 | void SetDebug(int debug) { fDebug = debug; } |
||
| 667 | int Debug() { return fDebug; } |
||
| 668 | int SetDominoMode(unsigned char mode); |
||
| 669 | int SetDominoActive(unsigned char mode); |
||
| 670 | int SetReadoutMode(unsigned char mode); |
||
| 671 | int SoftTrigger(void); |
||
| 672 | int ReadFrequency(unsigned char chipIndex, double *f); |
||
| 673 | int SetFrequency(double freq, bool wait); |
||
| 674 | double VoltToFreq(double volt); |
||
| 675 | double FreqToVolt(double freq); |
||
| 676 | double GetNominalFrequency() const { return fNominalFrequency; } |
||
| 677 | double GetTrueFrequency(); |
||
| 678 | int RegulateFrequency(double freq); |
||
| 679 | int SetExternalClockFrequency(double frequencyMHz); |
||
| 680 | double GetExternalClockFrequency(); |
||
| 681 | int SetMultiBuffer(int flag); |
||
| 682 | int IsMultiBuffer() { return fMultiBuffer; } |
||
| 683 | void ResetMultiBuffer(void); |
||
| 684 | int GetMultiBufferRP(void); |
||
| 685 | int SetMultiBufferRP(unsigned short rp); |
||
| 686 | int GetMultiBufferWP(void); |
||
| 687 | void IncrementMultiBufferRP(void); |
||
| 688 | void SetVoltageOffset(double offset1, double offset2); |
||
| 689 | int SetInputRange(double center); |
||
| 690 | double GetInputRange(void) { return fRange; } |
||
| 691 | double GetCalibratedInputRange(void) { return fCellCalibratedRange; } |
||
| 692 | double GetCalibratedTemperature(void) { return fCellCalibratedTemperature; } |
||
| 693 | double GetCalibratedFrequency(void) { return fTimingCalibratedFrequency; } |
||
| 694 | int TransferWaves(int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); |
||
| 695 | int TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); |
||
| 696 | int TransferWaves(int firstChannel, int lastChannel); |
||
| 697 | int TransferWaves(unsigned char *p, int firstChannel, int lastChannel); |
||
| 698 | int DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, |
||
| 699 | unsigned short *waveform); |
||
| 700 | int DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform); |
||
| 701 | int GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform, |
||
| 702 | bool responseCalib = false, int triggerCell = -1, int wsr = -1, bool adjustToClock = false, |
||
| 703 | float threshold = 0, bool offsetCalib = true); |
||
| 704 | int GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform, |
||
| 705 | bool responseCalib = false, int triggerCell = -1, int wsr = -1, bool adjustToClock = false, |
||
| 706 | float threshold = 0, bool offsetCalib = true); |
||
| 707 | int GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false, |
||
| 708 | int triggerCell = -1, int wsr = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); |
||
| 709 | int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib, |
||
| 710 | int triggerCell = -1, int wsr = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); |
||
| 711 | int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform); |
||
| 712 | int GetRawWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform, bool adjustToClock = false); |
||
| 713 | int GetRawWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel, |
||
| 714 | unsigned short *waveform, bool adjustToClock = false); |
||
| 715 | bool IsTimingCalibrationValid(void); |
||
| 716 | bool IsVoltageCalibrationValid(void) { return fVoltageCalibrationValid; } |
||
| 717 | int GetTime(unsigned int chipIndex, int channelIndex, double freq, int tc, float *time, bool tcalibrated=true, bool rotated=true); |
||
| 718 | int GetTime(unsigned int chipIndex, int channelIndex, int tc, float *time, bool tcalibrated=true, bool rotated=true); |
||
| 719 | int GetTimeCalibration(unsigned int chipIndex, int channelIndex, int mode, float *time, bool force=false); |
||
| 720 | int GetTriggerCell(unsigned int chipIndex); |
||
| 721 | int GetStopCell(unsigned int chipIndex); |
||
| 722 | unsigned char GetStopWSR(unsigned int chipIndex); |
||
| 723 | int GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex); |
||
| 724 | void TestDAC(int channel); |
||
| 725 | void MeasureSpeed(); |
||
| 726 | void InteractSpeed(); |
||
| 727 | void MonitorFrequency(); |
||
| 728 | int TestShift(int n); |
||
| 729 | int EnableAcal(int mode, double voltage); |
||
| 730 | int GetAcalMode() { return fAcalMode; } |
||
| 731 | double GetAcalVolt() { return fAcalVolt; } |
||
| 732 | int EnableTcal(int freq, int level=0, int phase=0); |
||
| 733 | int SelectClockSource(int source); |
||
| 734 | int SetRefclk(int source); |
||
| 735 | int GetRefclk() { return fRefclk; } |
||
| 736 | int GetTcalFreq() { return fTcalFreq; } |
||
| 737 | int GetTcalLevel() { return fTcalLevel; } |
||
| 738 | int GetTcalPhase() { return fTcalPhase; } |
||
| 739 | int GetTcalSource() { return fTcalSource; } |
||
| 740 | int SetCalibVoltage(double value); |
||
| 741 | int SetCalibTiming(int t1, int t2); |
||
| 742 | double GetTemperature(); |
||
| 743 | int Is2048ModeCapable(); |
||
| 744 | int GetTriggerBus(); |
||
| 745 | unsigned int GetScaler(int channel); |
||
| 746 | int ReadEEPROM(unsigned short page, void *buffer, int size); |
||
| 747 | int WriteEEPROM(unsigned short page, void *buffer, int size); |
||
| 748 | bool HasCorrectFirmware(); |
||
| 749 | int ConfigureLMK(double sampFreq, bool freqChange, int calFreq, int calPhase); |
||
| 750 | |||
| 751 | bool InitTimeCalibration(unsigned int chipIndex); |
||
| 752 | void SetCalibrationDirectory(const char *calibrationDirectoryPath); |
||
| 753 | void GetCalibrationDirectory(char *calibrationDirectoryPath); |
||
| 754 | |||
| 755 | ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; } |
||
| 756 | |||
| 757 | double GetPrecision() const { return fResponseCalibration ? fResponseCalibration->GetPrecision() : 0.1; } |
||
| 758 | int CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform, |
||
| 759 | short *waveform, bool responseCalib, int triggerCell, bool adjustToClock, |
||
| 760 | float threshold, bool offsetCalib); |
||
| 761 | |||
| 762 | static void LinearRegression(double *x, double *y, int n, double *a, double *b); |
||
| 763 | |||
| 764 | void ReadSingleWaveform(int nChips, int nChan, |
||
| 765 | unsigned short wfu[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins], bool rotated); |
||
| 766 | int AverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); |
||
| 767 | int RobustAverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); |
||
| 768 | int CalibrateVolt(DRSCallback *pcb); |
||
| 769 | int AnalyzePeriod(Averager *ave, int iIter, int nIter, int channel, float wf[kNumberOfBins], int tCell, double cellDV[kNumberOfBins], double cellDT[kNumberOfBins]); |
||
| 770 | int AnalyzeSlope(Averager *ave, int iIter, int nIter, int channel, float wf[kNumberOfBins], int tCell, double cellDV[kNumberOfBins], double cellDT[kNumberOfBins]); |
||
| 771 | int CalibrateTiming(DRSCallback *pcb); |
||
| 772 | static void RemoveSymmetricSpikes(short **wf, int nwf, |
||
| 773 | short diffThreshold, int spikeWidth, |
||
| 774 | short maxPeakToPeak, short spikeVoltage, |
||
| 775 | int nTimeRegionThreshold); |
||
| 776 | protected: |
||
| 777 | // Protected Methods |
||
| 778 | void ConstructBoard(); |
||
| 779 | void ReadSerialNumber(); |
||
| 780 | void ReadCalibration(void); |
||
| 781 | |||
| 782 | TimeData *GetTimeCalibration(unsigned int chipIndex, bool reinit = false); |
||
| 783 | |||
| 784 | int GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period); |
||
| 785 | }; |
||
| 786 | |||
| 787 | int DRSBoard::GetNumberOfReadoutChannels() const |
||
| 788 | { |
||
| 789 | return (fDRSType == 4 && fReadoutChannelConfig == 4) ? 5 : fNumberOfChannels; |
||
| 790 | } |
||
| 791 | |||
| 792 | int DRSBoard::GetWaveformBufferSize() const |
||
| 793 | { |
||
| 794 | int nbin=0; |
||
| 795 | if (fDRSType < 4) { |
||
| 796 | nbin = fNumberOfChips * fNumberOfChannels * kNumberOfBins; |
||
| 797 | } else { |
||
| 798 | if (fBoardType == 6) { |
||
| 799 | if (fDecimation) { |
||
| 800 | nbin = fNumberOfChips * (4 * kNumberOfBins + kNumberOfBins / 2); |
||
| 801 | } else { |
||
| 802 | nbin = fNumberOfChips * 5 * kNumberOfBins; |
||
| 803 | } |
||
| 804 | } else if (fBoardType == 7 || fBoardType == 8 || fBoardType == 9) |
||
| 805 | nbin = fNumberOfChips * fNumberOfChannels * kNumberOfBins; |
||
| 806 | } |
||
| 807 | return nbin * static_cast<int>(sizeof(short int)); |
||
| 808 | } |
||
| 809 | |||
| 810 | int DRSBoard::GetNumberOfInputs() const |
||
| 811 | { |
||
| 812 | // return number of input channels excluding clock and trigger channels. |
||
| 813 | if (fDRSType < 4) { |
||
| 814 | return fNumberOfChannels - 2; |
||
| 815 | } else { |
||
| 816 | return fNumberOfChannels / 2; |
||
| 817 | } |
||
| 818 | } |
||
| 819 | int DRSBoard::GetNumberOfCalibInputs() const |
||
| 820 | { |
||
| 821 | return (fDRSType < 4) ? 2 : 1; |
||
| 822 | } |
||
| 823 | int DRSBoard::GetClockChannel() const |
||
| 824 | { |
||
| 825 | return fDRSType < 4 ? 9 : 8; |
||
| 826 | } |
||
| 827 | int DRSBoard::GetTriggerChannel() const |
||
| 828 | { |
||
| 829 | return fDRSType < 4 ? 8 : -1; |
||
| 830 | } |
||
| 831 | |||
| 832 | int DRSBoard::Channel2Input(int channel) const |
||
| 833 | { |
||
| 834 | return (fDRSType < 4) ? channel : channel / 2; |
||
| 835 | } |
||
| 836 | int DRSBoard::Channel2ReadoutChannel(int channel) const |
||
| 837 | { |
||
| 838 | if (fDRSType < 4) { |
||
| 839 | return channel; |
||
| 840 | } else { |
||
| 841 | if (fReadoutChannelConfig == 4) { |
||
| 842 | return channel / 2; |
||
| 843 | } else { |
||
| 844 | return channel; |
||
| 845 | } |
||
| 846 | } |
||
| 847 | } |
||
| 848 | int DRSBoard::Input2Channel(int input, int ind) const |
||
| 849 | { |
||
| 850 | if (fChannelCascading == 1) { |
||
| 851 | return (fDRSType < 4) ? input : (input * 2 + ind); |
||
| 852 | } else { |
||
| 853 | if (input == 4) { // clock |
||
| 854 | return 8; |
||
| 855 | } else { |
||
| 856 | return input; |
||
| 857 | } |
||
| 858 | } |
||
| 859 | } |
||
| 860 | int DRSBoard::Input2ReadoutChannel(int input, int ind) const |
||
| 861 | { |
||
| 862 | if (fDRSType < 4) { |
||
| 863 | return input; |
||
| 864 | } else { |
||
| 865 | if (fReadoutChannelConfig == 4) { |
||
| 866 | return input; |
||
| 867 | } else { |
||
| 868 | return (input * 2 + ind); |
||
| 869 | } |
||
| 870 | } |
||
| 871 | } |
||
| 872 | int DRSBoard::ReadoutChannel2Channel(int readout) const |
||
| 873 | { |
||
| 874 | if (fDRSType < 4) { |
||
| 875 | return readout; |
||
| 876 | } else { |
||
| 877 | if (fReadoutChannelConfig == 4) { |
||
| 878 | return readout * 2; |
||
| 879 | } else { |
||
| 880 | return readout; |
||
| 881 | } |
||
| 882 | } |
||
| 883 | } |
||
| 884 | int DRSBoard::ReadoutChannel2Input(int readout) const |
||
| 885 | { |
||
| 886 | if (fDRSType < 4) { |
||
| 887 | return readout; |
||
| 888 | } else { |
||
| 889 | if (fReadoutChannelConfig == 4) { |
||
| 890 | return readout; |
||
| 891 | } else { |
||
| 892 | return readout / 2; |
||
| 893 | } |
||
| 894 | } |
||
| 895 | } |
||
| 896 | bool DRSBoard::IsCalibChannel(int ch) const |
||
| 897 | { |
||
| 898 | // return if it is clock or trigger channel |
||
| 899 | if (fDRSType < 4) |
||
| 900 | return ch == GetClockChannel() || ch == GetTriggerChannel(); |
||
| 901 | else |
||
| 902 | return ch == GetClockChannel(); |
||
| 903 | } |
||
| 904 | bool DRSBoard::IsCalibInput(int input) const |
||
| 905 | { |
||
| 906 | // return if it is clock or trigger channel |
||
| 907 | int ch = Input2Channel(input); |
||
| 908 | if (fDRSType < 4) |
||
| 909 | return ch == GetClockChannel() || ch == GetTriggerChannel(); |
||
| 910 | else |
||
| 911 | return ch == GetClockChannel(); |
||
| 912 | } |
||
| 913 | |||
| 914 | class DRS { |
||
| 915 | protected: |
||
| 916 | // constants |
||
| 917 | enum { |
||
| 918 | kMaxNumberOfBoards = 40 |
||
| 919 | }; |
||
| 920 | |||
| 921 | protected: |
||
| 922 | DRSBoard *fBoard[kMaxNumberOfBoards]; |
||
| 923 | int fNumberOfBoards; |
||
| 924 | char fError[256]; |
||
| 925 | #ifdef HAVE_VME |
||
| 926 | MVME_INTERFACE *fVmeInterface; |
||
| 927 | #endif |
||
| 928 | |||
| 929 | private: |
||
| 930 | DRS(const DRS &c); // not implemented |
||
| 931 | DRS &operator=(const DRS &rhs); // not implemented |
||
| 932 | |||
| 933 | public: |
||
| 934 | // Public Methods |
||
| 935 | DRS(); |
||
| 936 | ~DRS(); |
||
| 937 | |||
| 938 | DRSBoard *GetBoard(int i) { return fBoard[i]; } |
||
| 939 | void SetBoard(int i, DRSBoard *b); |
||
| 940 | DRSBoard **GetBoards() { return fBoard; } |
||
| 941 | int GetNumberOfBoards() const { return fNumberOfBoards; } |
||
| 942 | bool GetError(char *str, int size); |
||
| 943 | void SortBoards(); |
||
| 944 | |||
| 945 | #ifdef HAVE_VME |
||
| 946 | MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; |
||
| 947 | #endif |
||
| 948 | }; |
||
| 949 | |||
| 950 | #endif // DRS_H |