Merge pull request #388 from slsdetectorgroup/eiger12

eiger 12 bit mode
This commit is contained in:
Dhanya Thattil 2022-03-16 16:50:41 +01:00 committed by GitHub
commit c9769579e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 431 additions and 127 deletions

View File

@ -39,6 +39,7 @@ This document describes the differences between v7.0.0 and v6.x.x
- current frame index points to listened frame index (not processed index)
- when in discard partial frames or empty mode, the frame number doesnt increase by 1, it increases to that number (so its faster)
- file write disabled by default
- eiger 12 bit mode
- start non blocking acquisition at modular level
- hostname cmd failed when connecting to servers in update mode (ctb, moench, jungfrau, eiger)
- missingpackets signed (negative => extra packets)

View File

@ -287,7 +287,7 @@ class Detector(CppDetectorApi):
Note
-----
[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n
[Mythen3] Options: 8, 16, 32 \n
[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16
"""

View File

@ -97,6 +97,11 @@
<string>65535</string>
</property>
</item>
<item>
<property name="text">
<string>4095</string>
</property>
</item>
<item>
<property name="text">
<string>255</string>

View File

@ -69,5 +69,11 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
enum { DYNAMIC, FORCE_SWITCH_G1, FORCE_SWITCH_G2, FIX_G1, FIX_G2, FIX_G0 };
bool isVisibleFixG0{false};
enum { DYNAMICRANGE_32, DYNAMICRANGE_16, DYNAMICRANGE_8, DYNAMICRANGE_4 };
enum {
DYNAMICRANGE_32,
DYNAMICRANGE_16,
DYNAMICRANGE_12,
DYNAMICRANGE_8,
DYNAMICRANGE_4
};
};

View File

@ -1064,6 +1064,8 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
// mythen3 / gotthard2 debugging
int discardBits = numDiscardBits;
uint16_t temp = 0;
uint8_t *src = (uint8_t *)source;
switch (dr) {
case 4:
@ -1083,6 +1085,19 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
}
break;
case 12:
for (ichan = 0; ichan < size; ++ichan) {
temp = (*src++ & 0xFF);
temp |= ((*src & 0xF) << 8u);
dest[ichan] = (double)temp;
++ichan;
temp = ((*src++ & 0xF0) >> 4u);
temp |= ((*src++ & 0xFF) << 4u);
dest[ichan] = (double)temp;
}
break;
case 16:
if (detType == slsDetectorDefs::JUNGFRAU ||
detType == slsDetectorDefs::GOTTHARD2) {

View File

@ -60,13 +60,19 @@ void qTabSettings::SetupWidgetWindow() {
QStandardItemModel *model =
qobject_cast<QStandardItemModel *>(comboDynamicRange->model());
if (model) {
QModelIndex index;
QStandardItem *item;
index =
model->index(DYNAMICRANGE_4, comboDynamicRange->modelColumn(),
int dr = DYNAMICRANGE_4;
for (int i = 0; i != 2; ++i) {
// disable dr 4
QModelIndex index =
model->index(dr, comboDynamicRange->modelColumn(),
comboDynamicRange->rootModelIndex());
item = model->itemFromIndex(index);
item->setEnabled(false);
// disable dr 12
dr = DYNAMICRANGE_12;
}
}
} else if (detType == slsDetectorDefs::EIGER) {
lblDynamicRange->setEnabled(true);
@ -305,6 +311,9 @@ void qTabSettings::GetDynamicRange() {
case 16:
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_16);
break;
case 12:
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_12);
break;
case 8:
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_8);
break;
@ -333,6 +342,9 @@ void qTabSettings::SetDynamicRange(int index) {
case DYNAMICRANGE_16:
det->setDynamicRange(16);
break;
case DYNAMICRANGE_12:
det->setDynamicRange(12);
break;
case DYNAMICRANGE_8:
det->setDynamicRange(8);
break;

View File

@ -702,8 +702,16 @@ void resetPeripheral() {
}
/* set parameters - dr, adcenablemask */
int setDynamicRange(int dr) {
if (dr == 16)
return OK;
return FAIL;
}
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
int getDynamicRange(int *retval) {
*retval = DYNAMIC_RANGE;
return OK;
}
int setADCEnableMask(uint32_t mask) {
if (mask == 0u) {

View File

@ -862,11 +862,17 @@ void Beb_ResetFrameNumber() {
}
int Beb_SetUpTransferParameters(short the_bit_mode) {
if (the_bit_mode != 4 && the_bit_mode != 8 && the_bit_mode != 16 &&
the_bit_mode != 32)
return 0;
switch (the_bit_mode) {
case 4:
case 8:
case 12:
case 16:
case 32:
Beb_bit_mode = the_bit_mode;
return 1;
default:
return 0;
}
}
int Beb_StopAcquisition() {

View File

@ -931,7 +931,10 @@ unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec) {
int Feb_Control_PrepareForAcquisition() {
LOG(logINFOBLUE, ("Preparing for Acquisition\n"));
Feb_Control_PrintAcquisitionSetup();
if (!Feb_Control_PrintAcquisitionSetup()) {
LOG(logERROR, ("Could not prepare acquisition\n"));
return 0;
}
if (Feb_Control_Reset() == STATUS_ERROR) {
LOG(logERROR, ("Trouble reseting daq or data stream\n"));
@ -988,20 +991,26 @@ int Feb_Control_PrepareForAcquisition() {
return 1;
}
void Feb_Control_PrintAcquisitionSetup() {
int Feb_Control_PrintAcquisitionSetup() {
time_t rawtime;
time(&rawtime);
struct tm *timeinfo = localtime(&rawtime);
LOG(logINFO,
("Starting an exposure: (%s)"
int dr = 0;
if (!Feb_Control_GetDynamicRange(&dr)) {
LOG(logERROR, ("Could not print acquisition set up\n"));
return 0;
}
LOG(logINFO, ("Starting an exposure: (%s)"
"\t Dynamic range nbits: %d\n"
"\t Trigger mode: 0x%x\n"
"\t Number of exposures: %d\n"
"\t Exsposure time (if used): %f seconds.\n"
"\t Exsposure period (if used): %f seconds.\n\n",
asctime(timeinfo), Feb_Control_GetDynamicRange(),
Feb_Control_triggerMode, Feb_Control_GetNExposures(),
Feb_Control_exposure_time_in_sec, Feb_Control_exposure_period_in_sec));
asctime(timeinfo), dr, Feb_Control_triggerMode,
Feb_Control_GetNExposures(), Feb_Control_exposure_time_in_sec,
Feb_Control_exposure_period_in_sec));
return 1;
}
int Feb_Control_StartAcquisition() {
@ -1169,49 +1178,106 @@ int Feb_Control_SoftwareTrigger(int block) {
}
// parameters
int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo) {
int Feb_Control_SetDynamicRange(int dr) {
static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM |
DAQ_STATIC_BIT_CHIP_TEST |
DAQ_STATIC_BIT_ROTEST;
if (four_eight_sixteen_or_thirtytwo == 4) {
switch (dr) {
case 4:
Feb_Control_staticBits =
DAQ_STATIC_BIT_M4 |
(Feb_Control_staticBits &
everything_but_bit_mode); // leave test bits in currernt state
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
} else if (four_eight_sixteen_or_thirtytwo == 8) {
break;
case 8:
Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits &
everything_but_bit_mode);
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
} else if (four_eight_sixteen_or_thirtytwo == 16) {
break;
case 12:
case 16:
Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits &
everything_but_bit_mode);
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
} else if (four_eight_sixteen_or_thirtytwo == 32) {
// disable 16 bit conversion if 12 bit mode (enable if 16 bit)
if (!Feb_Control_Disable16bitConversion(dr == 12))
return 0;
break;
case 32:
Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits &
everything_but_bit_mode);
Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING;
} else {
LOG(logERROR, ("dynamic range (%d) not valid, not setting bit mode.\n",
four_eight_sixteen_or_thirtytwo));
break;
default:
LOG(logERROR,
("dynamic range (%d) not valid, not setting bit mode.\n", dr));
LOG(logINFO, ("Set dynamic range int must equal 4,8 16, or 32.\n"));
return 0;
}
LOG(logINFO,
("Dynamic range set to %d\n", four_eight_sixteen_or_thirtytwo));
LOG(logINFO, ("Dynamic range set to %d\n", dr));
return 1;
}
unsigned int Feb_Control_GetDynamicRange() {
if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING)
return 32;
else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits)
return 4;
else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits)
return 8;
int Feb_Control_GetDynamicRange(int *retval) {
if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) {
*retval = 32;
} else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits) {
*retval = 4;
} else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits) {
*retval = 8;
} else {
int disable16 = 0;
if (!Feb_Control_Get16bitConversionDisabled(&disable16)) {
LOG(logERROR, ("Could not get dynamic range (12 or 16 bit)\n"));
return 0;
}
if (disable16) {
*retval = 12;
} else {
*retval = 16;
}
}
return 16;
return 1;
}
int Feb_Control_Disable16bitConversion(int disable) {
LOG(logINFO, ("%s 16 bit expansion\n", disable ? "Disabling" : "Enabling"));
unsigned int regval = 0;
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, &regval)) {
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
(disable ? "disable" : "enable")));
return 0;
}
if (disable) {
regval |= DAQ_REG_HRDWRE_DSBL_16BIT_MSK;
} else {
regval &= ~DAQ_REG_HRDWRE_DSBL_16BIT_MSK;
}
if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) {
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
(disable ? "disable" : "enable")));
return 0;
}
return 1;
}
int Feb_Control_Get16bitConversionDisabled(int *ret) {
unsigned int regval = 0;
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, &regval)) {
LOG(logERROR, ("Could not get 16 bit expansion (bit mode)\n"));
return 0;
}
if (regval & DAQ_REG_HRDWRE_DSBL_16BIT_MSK) {
*ret = 1;
} else {
*ret = 0;
}
return 1;
}
int Feb_Control_SetReadoutSpeed(unsigned int readout_speed) {
@ -1554,7 +1620,10 @@ int Feb_Control_SetChipSignalsToTrimQuad(int enable) {
regval &= ~(DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK);
}
return Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval);
if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) {
LOG(logERROR, ("Could not set chip signals to trim quad\n"));
return 0;
}
}
return 1;
}
@ -1604,7 +1673,7 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
for (int iloop = 0; iloop < 2; ++iloop) {
if (run[iloop]) {
LOG(logINFO,
LOG(logDEBUG1,
("Writing 0x%x to %s 0x%x\n", data, side[iloop], actualOffset));
if (!Feb_Interface_WriteRegister(addr[iloop], actualOffset, data, 0,
0)) {
@ -1612,6 +1681,18 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
side[iloop], actualOffset));
return 0;
}
uint32_t regVal = 0;
if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset,
&regVal)) {
LOG(logERROR, ("Could not read %s register\n", addr[iloop]));
return 0;
}
if (regVal != data) {
LOG(logERROR,
("Could not write %s register. Write 0x%x, read 0x%x\n",
addr[iloop], data, regVal));
return 0;
}
}
}
@ -1648,8 +1729,8 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
side[iloop], actualOffset));
return 0;
}
LOG(logINFO, ("Read 0x%x from %s 0x%x\n", value[iloop], side[iloop],
actualOffset));
LOG(logDEBUG1, ("Read 0x%x from %s 0x%x\n", value[iloop],
side[iloop], actualOffset));
*retval = value[iloop];
// if not the other (left, not right OR right, not left), return the
// value
@ -1824,7 +1905,11 @@ int64_t Feb_Control_Get_RateTable_Period_in_nsec() {
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec) {
// period = exptime if 16bit, period = subexptime if 32 bit
int dr = Feb_Control_GetDynamicRange();
int dr = 0;
if (!Feb_Control_GetDynamicRange(&dr)) {
LOG(logERROR, ("Could not set rate correction tau\n"));
return 0;
}
double period_in_sec =
(double)(Feb_Control_GetSubFrameExposureTime()) / (double)1e9;
if (dr == 16)

View File

@ -55,7 +55,7 @@ int Feb_Control_ResetChipPartially();
int Feb_Control_SendBitModeToBebServer();
unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec);
int Feb_Control_PrepareForAcquisition();
void Feb_Control_PrintAcquisitionSetup();
int Feb_Control_PrintAcquisitionSetup();
int Feb_Control_StartAcquisition();
int Feb_Control_StopAcquisition();
int Feb_Control_IsReadyForTrigger(int *readyForTrigger);
@ -63,8 +63,10 @@ int Feb_Control_SendSoftwareTrigger();
int Feb_Control_SoftwareTrigger(int block);
// parameters
int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo);
unsigned int Feb_Control_GetDynamicRange();
int Feb_Control_SetDynamicRange(int dr);
int Feb_Control_GetDynamicRange(int *retval);
int Feb_Control_Disable16bitConversion(int disable);
int Feb_Control_Get16bitConversionDisabled();
int Feb_Control_SetReadoutSpeed(unsigned int readout_speed);
int Feb_Control_SetReadoutMode(unsigned int readout_mode);
int Feb_Control_SetTriggerMode(unsigned int trigger_mode);

View File

@ -29,6 +29,8 @@
#define DAQ_REG_HRDWRE_OW_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_MASTER_OFST)
#define DAQ_REG_HRDWRE_MASTER_OFST (4)
#define DAQ_REG_HRDWRE_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_MASTER_OFST)
#define DAQ_REG_HRDWRE_DSBL_16BIT_OFST (5)
#define DAQ_REG_HRDWRE_DSBL_16BIT_MSK (0x00000001 << DAQ_REG_HRDWRE_DSBL_16BIT_OFST)
#define DAQ_REG_HRDWRE_PROGRAM_OFST (30)
#define DAQ_REG_HRDWRE_PROGRAM_MSK (0x00000001 << DAQ_REG_HRDWRE_PROGRAM_OFST)
#define DAQ_REG_HRDWRE_M8_OFST (31)

View File

@ -821,10 +821,12 @@ int readRegister(uint32_t offset, uint32_t *retval) {
/* set parameters - dr, roi */
int setDynamicRange(int dr) {
// setting dr
if (dr > 0) {
LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr));
#ifndef VIRTUAL
if (dr <= 0) {
return FAIL;
}
#ifdef VIRTUAL
LOG(logINFO, ("Setting dynamic range: %d\n", dr));
#else
sharedMemory_lockLocalLink();
if (Feb_Control_SetDynamicRange(dr)) {
if (!Beb_SetUpTransferParameters(dr)) {
@ -836,14 +838,21 @@ int setDynamicRange(int dr) {
sharedMemory_unlockLocalLink();
#endif
eiger_dynamicrange = dr;
}
// getting dr
#ifndef VIRTUAL
return OK;
}
int getDynamicRange(int *retval) {
#ifdef VIRTUAL
*retval = eiger_dynamicrange;
#else
sharedMemory_lockLocalLink();
eiger_dynamicrange = Feb_Control_GetDynamicRange();
if (!Feb_Control_GetDynamicRange(retval)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
#endif
return eiger_dynamicrange;
return OK;
}
/* parameters - readout */
@ -1158,6 +1167,7 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, set M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
@ -1170,6 +1180,7 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
@ -1179,6 +1190,7 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
@ -1923,7 +1935,8 @@ int setRateCorrection(
else if (custom_tau_in_nsec == -1)
custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
int dr = Feb_Control_GetDynamicRange();
int dr = eiger_dynamicrange;
// get period = subexptime if 32bit , else period = exptime if 16 bit
int64_t actual_period =
Feb_Control_GetSubFrameExposureTime(); // already in nsec
@ -2321,7 +2334,7 @@ void *start_timer(void *arg) {
const int maxRows = MAX_ROWS_PER_READOUT;
const int packetsPerFrame = (maxPacketsPerFrame * readNRows) / maxRows;
LOG(logDEBUG1,
LOG(logDEBUG,
(" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n "
"packetsize:%d\n maxnumpackes:%d\n npixelsx:%d\n databytes:%d\n",
dr, bytesPerPixel, tgEnable, datasize, packetsize, maxPacketsPerFrame,
@ -2338,11 +2351,13 @@ void *start_timer(void *arg) {
npixels /= 2;
}
LOG(logDEBUG1,
("pixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket));
("npixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket));
uint8_t *src = (uint8_t *)imageData;
for (int i = 0; i < npixels; ++i) {
if (i > 0 && i % pixelsPerPacket == 0) {
++pixelVal;
}
switch (dr) {
case 4:
*((uint8_t *)(imageData + i)) =
@ -2357,6 +2372,30 @@ void *start_timer(void *arg) {
*((uint8_t *)(imageData + i)) =
eiger_virtual_test_mode ? 0xFE : (uint8_t)pixelVal;
break;
case 12:
if (eiger_virtual_test_mode) {
// first 12 bit pixel
// first 8 byte
*src++ = 0xFE;
// second 12bit pixel
++i;
// second 8 byte
*src++ = 0xEF;
// third byte
*src++ = 0xFF;
} else {
// first 12 bit pixel
// first 8 byte
*src++ = (uint8_t)(i & 0xFF);
// second 8 byte (first nibble)
*src = (uint8_t)((i++ >> 8u) & 0xF);
// second 12bit pixel
// second 8 byte (second nibble)
*src++ |= ((uint8_t)(i & 0xF) << 4u);
// third byte
*src++ = (uint8_t)((i >> 4u) & 0xFF);
}
break;
case 16:
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
eiger_virtual_test_mode ? 0xFFE : (uint16_t)pixelVal;
@ -2433,9 +2472,27 @@ void *start_timer(void *arg) {
// fill data
int dstOffset = sizeof(sls_detector_header);
int dstOffset2 = sizeof(sls_detector_header);
{
for (int psize = 0; psize < datasize; psize += npixelsx) {
if (dr == 12) {
// multiple of 768,1024,4096
int copysize = 256;
for (int psize = 0; psize < datasize; psize += copysize) {
memcpy(packetData + dstOffset, imageData + srcOffset,
copysize);
memcpy(packetData2 + dstOffset2, imageData + srcOffset2,
copysize);
srcOffset += copysize;
srcOffset2 += copysize;
dstOffset += copysize;
dstOffset2 += copysize;
// reached 1 row (quarter module)
if ((srcOffset % npixelsx) == 0) {
srcOffset += npixelsx;
srcOffset2 += npixelsx;
}
}
} else {
for (int psize = 0; psize < datasize; psize += npixelsx) {
if (dr == 32 && tgEnable == 0) {
memcpy(packetData + dstOffset,
imageData + srcOffset, npixelsx / 2);
@ -2733,9 +2790,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
int calculateDataBytes() {
if (send_to_ten_gig)
return setDynamicRange(-1) * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE;
return eiger_dynamicrange * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE;
else
return setDynamicRange(-1) * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE;
return eiger_dynamicrange * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE;
}
int getTotalNumberOfChannels() {

View File

@ -5,7 +5,7 @@
#define LINKED_SERVER_NAME "eigerDetectorServer"
#define REQUIRED_FIRMWARE_VERSION (29)
#define REQUIRED_FIRMWARE_VERSION (30)
// virtual ones renamed for consistency
// real ones keep previous name for compatibility (already in production)
#ifdef VIRTUAL

View File

@ -952,7 +952,16 @@ void resetPeripheral() {
/* set parameters - dr, roi */
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
int setDynamicRange(int dr) {
if (dr == 16)
return OK;
return FAIL;
}
int getDynamicRange(int *retval) {
*retval = DYNAMIC_RANGE;
return OK;
}
/* parameters - timer */
void setNumFrames(int64_t val) {

View File

@ -788,7 +788,16 @@ void setMasterSlaveConfiguration() {
/* set parameters - dr, roi */
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
int setDynamicRange(int dr) {
if (dr == 16)
return OK;
return FAIL;
}
int getDynamicRange(int *retval) {
*retval = DYNAMIC_RANGE;
return OK;
}
int setROI(ROI arg) {

View File

@ -796,7 +796,16 @@ void resetPeripheral() {
/* set parameters - dr, roi */
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
int setDynamicRange(int dr) {
if (dr == 16)
return OK;
return FAIL;
}
int getDynamicRange(int *retval) {
*retval = DYNAMIC_RANGE;
return OK;
}
void setADCInvertRegister(uint32_t val) {
LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val));

View File

@ -706,7 +706,16 @@ void resetPeripheral() {
/* set parameters - dr, adcenablemask */
int setDynamicRange(int dr) { return DYNAMIC_RANGE; }
int setDynamicRange(int dr) {
if (dr == 16)
return OK;
return FAIL;
}
int getDynamicRange(int *retval) {
*retval = DYNAMIC_RANGE;
return OK;
}
int setADCEnableMask(uint32_t mask) {
if (mask == 0u) {

View File

@ -729,7 +729,9 @@ void resetPeripheral() {
/* set parameters - dr, roi */
int setDynamicRange(int dr) {
if (dr > 0) {
if (dr <= 0) {
return FAIL;
}
uint32_t regval = 0;
switch (dr) {
/*case 1: TODO:Not implemented in firmware yet
@ -752,23 +754,29 @@ int setDynamicRange(int dr) {
bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK);
bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval);
updatePacketizing();
}
return OK;
}
int getDynamicRange(int *retval) {
uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK;
switch (regval) {
/*case CONFIG_DYNAMIC_RANGE_1_VAL: TODO:Not implemented in firmware yet
return 1;*/
case CONFIG_DYNAMIC_RANGE_8_VAL:
return 8;
*retval = 8;
break;
case CONFIG_DYNAMIC_RANGE_16_VAL:
return 16;
*retval = 16;
break;
case CONFIG_DYNAMIC_RANGE_24_VAL:
return 32;
*retval = 32;
break;
default:
LOG(logERROR, ("Invalid dynamic range %d read back\n",
regval >> CONFIG_DYNAMIC_RANGE_OFST));
return -1;
return FAIL;
}
return OK;
}
/* set parameters - readout */
@ -1091,7 +1099,8 @@ void updatePacketizing() {
// 10g
if (tgEnable) {
const int dr = setDynamicRange(-1);
int dr = 0;
getDynamicRange(&dr);
packetsPerFrame = 1;
if (dr == 32 && ncounters > 1) {
packetsPerFrame = 2;
@ -2202,7 +2211,8 @@ void *start_timer(void *arg) {
const int imageSize = calculateDataBytes();
const int tgEnable = enableTenGigabitEthernet(-1);
const int dr = setDynamicRange(-1);
int dr = 0;
getDynamicRange(&dr);
int ncounters = __builtin_popcount(getCounterMask());
int dataSize = 0;
int packetsPerFrame = 0;
@ -2523,7 +2533,8 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
int calculateDataBytes() {
int numCounters = __builtin_popcount(getCounterMask());
int dr = setDynamicRange(-1);
int dr = 0;
getDynamicRange(&dr);
return (NCHAN_1_COUNTER * NCHIP * numCounters * ((double)dr / 8.00));
}

View File

@ -173,6 +173,7 @@ void setMasterSlaveConfiguration();
// parameters - dr, roi
int setDynamicRange(int dr);
int getDynamicRange(int *retval);
#ifdef GOTTHARDD
int setROI(ROI arg);
ROI getROI();

View File

@ -2815,6 +2815,9 @@ int set_dynamic_range(int file_des) {
#endif
#if defined(EIGERD) || defined(MYTHEN3D)
case 8:
#ifdef EIGERD
case 12:
#endif
case 16:
case 32:
#endif
@ -2822,14 +2825,25 @@ int set_dynamic_range(int file_des) {
defined(MOENCHD) || defined(GOTTHARD2D)
case 16:
#endif
retval = setDynamicRange(dr);
LOG(logDEBUG1, ("Dynamic range: %d\n", retval));
if (retval == -1) {
ret = FAIL;
sprintf(mess, "Could not get dynamic range.\n");
if (dr >= 0) {
ret = setDynamicRange(dr);
if (ret == FAIL) {
sprintf(mess, "Could not set dynamic range to %d\n", dr);
LOG(logERROR, (mess));
}
}
// get
if (ret == OK) {
ret = getDynamicRange(&retval);
if (ret == FAIL) {
strcpy(mess, "Could not get dynamic range\n");
LOG(logERROR, (mess));
} else {
LOG(logDEBUG1, ("Dynamic range: %d\n", retval));
validate(&ret, mess, dr, retval, "set dynamic range", DEC);
}
}
break;
default:
modeNotImplemented("Dynamic range", dr);
@ -4650,11 +4664,17 @@ int set_read_n_rows(int file_des) {
LOG(logERROR, (mess));
} else {
#ifdef EIGERD
int dr = setDynamicRange(GET_FLAG);
int dr = 0;
ret = getDynamicRange(&dr);
int isTenGiga = enableTenGigabitEthernet(GET_FLAG);
unsigned int maxnl = MAX_ROWS_PER_READOUT;
unsigned int maxnp = (isTenGiga ? 4 : 16) * dr;
if ((arg * maxnp) % maxnl) {
// get dr fail
if (ret == FAIL) {
strcpy(mess,
"Could not read n rows (failed to get dynamic range)\n");
LOG(logERROR, (mess));
} else if ((arg * maxnp) % maxnl) {
ret = FAIL;
sprintf(mess,
"Could not set number of rows to %d. For %d bit "
@ -4862,6 +4882,7 @@ int is_udp_configured() {
LOG(logWARNING, ("%s", configureMessage));
return FAIL;
}
// virtual: no check (can be eth name: lo, ip: 127.0.0.1)
#ifndef VIRTUAL
if (udpDetails[i].dstmac == 0) {
sprintf(configureMessage,
@ -7111,7 +7132,10 @@ int get_receiver_parameters(int file_des) {
}
// dynamic range
i32 = setDynamicRange(GET_FLAG);
ret = getDynamicRange(&i32);
if (ret == FAIL) {
i32 = 0;
}
n += sendData(file_des, &i32, sizeof(i32), INT32);
if (n < 0)
return printSocketReadError();

View File

@ -284,7 +284,7 @@ class Detector {
Result<int> getDynamicRange(Positions pos = {}) const;
/**
* [Eiger] Options: 4, 8, 16, 32. If i is 32, also sets clkdivider to 2,
* [Eiger] Options: 4, 8, 12, 16, 32. If i is 32, also sets clkdivider to 2,
* else sets clkdivider to 1 \n [Mythen3] Options: 8, 16, 32 \n
* [Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16
*/

View File

@ -1109,7 +1109,6 @@ class CmdProxy {
/* acquisition parameters */
std::string Acquire(int action);
std::string Exptime(int action);
std::string DynamicRange(int action);
std::string ReadoutSpeed(int action);
std::string Adcphase(int action);
std::string Dbitphase(int action);
@ -1328,7 +1327,7 @@ class CmdProxy {
dr, getDynamicRange, setDynamicRange, StringTo<int>,
"[value]\n\tDynamic Range or number of bits per "
"pixel in detector.\n\t"
"[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets "
"[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets "
"clkdivider to 2, else to 0.\n\t"
"[Mythen3] Options: 8, 16, 32\n\t"
"[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16");

View File

@ -387,7 +387,7 @@ void Detector::setDynamicRange(int value) {
std::vector<int> Detector::getDynamicRangeList() const {
switch (getDetectorType().squash()) {
case defs::EIGER:
return std::vector<int>{4, 8, 16, 32};
return std::vector<int>{4, 8, 12, 16, 32};
case defs::MYTHEN3:
return std::vector<int>{8, 16, 32};
default:

View File

@ -716,6 +716,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
break;
*/
case 4:
case 12:
if (detType == EIGER) {
exists = true;
}

View File

@ -112,6 +112,7 @@ void HDF5DataFile::CreateFirstHDF5DataFile(
udpPortNumber_ = udpPortNumber;
switch (dynamicRange_) {
case 12:
case 16:
dataType_ = PredType::STD_U16LE;
break;
@ -248,8 +249,30 @@ void HDF5DataFile::WriteToFile(char *buffer, const int buffersize,
WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer));
}
void HDF5DataFile::Convert12to16Bit(uint16_t *dst, uint8_t *src) {
for (int i = 0; i < EIGER_NUM_PIXELS; ++i) {
*dst = (uint16_t)(*src++ & 0xFF);
*dst++ |= (uint16_t)((*src & 0xF) << 8u);
++i;
*dst = (uint16_t)((*src++ & 0xF0) >> 4u);
*dst++ |= (uint16_t)((*src++ & 0xFF) << 4u);
}
}
void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
char *buffer) {
// expand 12 bit to 16 bits
char *revBuffer = buffer;
if (dynamicRange_ == 12) {
revBuffer = (char *)malloc(EIGER_16_BIT_IMAGE_SIZE);
if (revBuffer == nullptr) {
throw sls::RuntimeError("Could not allocate memory for 12 bit to "
"16 bit conversion in object " +
std::to_string(index_));
}
Convert12to16Bit((uint16_t *)revBuffer, (uint8_t *)buffer);
}
std::lock_guard<std::mutex> lock(*hdf5Lib_);
uint64_t nDimx =
@ -266,9 +289,15 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start);
DataSpace memspace(2, dims2);
dataSet_->write(buffer, dataType_, memspace, *dataSpace_);
dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_);
memspace.close();
if (dynamicRange_ == 12) {
free(revBuffer);
}
} catch (const Exception &error) {
if (dynamicRange_ == 12) {
free(revBuffer);
}
LOG(logERROR) << "Could not write to file in object " << index_;
error.printErrorStack();
throw sls::RuntimeError("Could not write to file in object " +

View File

@ -35,6 +35,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
private:
void CreateFile();
void Convert12to16Bit(uint16_t *dst, uint8_t *src);
void WriteDataFile(const uint64_t currentFrameNumber, char *buffer);
void WriteParameterDatasets(const uint64_t currentFrameNumber,
sls_receiver_header *rheader);
@ -72,4 +73,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
int detIndex_{0};
int numUnitsPerReadout_{0};
uint32_t udpPortNumber_{0};
static const int EIGER_NUM_PIXELS{256 * 2 * 256};
static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2};
};