This commit is contained in:
maliakal_d 2020-07-17 17:33:43 +02:00
parent 546bef5e5a
commit b7cb341ee3
15 changed files with 212 additions and 176 deletions

View File

@ -112,7 +112,7 @@
#define CONFIG_DYNAMIC_RANGE_OFST (4) #define CONFIG_DYNAMIC_RANGE_OFST (4)
#define CONFIG_DYNAMIC_RANGE_MSK (0x00000003 << CONFIG_DYNAMIC_RANGE_OFST) #define CONFIG_DYNAMIC_RANGE_MSK (0x00000003 << CONFIG_DYNAMIC_RANGE_OFST)
#define CONFIG_DYNAMIC_RANGE_1_VAL ((0x0 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK) #define CONFIG_DYNAMIC_RANGE_1_VAL ((0x0 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
#define CONFIG_DYNAMIC_RANGE_4_VAL ((0x1 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK) #define CONFIG_DYNAMIC_RANGE_8_VAL ((0x1 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
#define CONFIG_DYNAMIC_RANGE_16_VAL ((0x2 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK) #define CONFIG_DYNAMIC_RANGE_16_VAL ((0x2 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
#define CONFIG_DYNAMIC_RANGE_24_VAL ((0x3 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK) #define CONFIG_DYNAMIC_RANGE_24_VAL ((0x3 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
@ -149,6 +149,8 @@
#define PKT_CONFIG_NRXR_MAX_MSK (0x0000003F << PKT_CONFIG_NRXR_MAX_OFST) #define PKT_CONFIG_NRXR_MAX_MSK (0x0000003F << PKT_CONFIG_NRXR_MAX_OFST)
#define PKT_CONFIG_RXR_START_ID_OFST (8) #define PKT_CONFIG_RXR_START_ID_OFST (8)
#define PKT_CONFIG_RXR_START_ID_MSK (0x0000003F << PKT_CONFIG_RXR_START_ID_OFST) #define PKT_CONFIG_RXR_START_ID_MSK (0x0000003F << PKT_CONFIG_RXR_START_ID_OFST)
#define PKT_CONFIG_1G_INTERFACE_OFST (16)
#define PKT_CONFIG_1G_INTERFACE_MSK (0x00000001 << PKT_CONFIG_1G_INTERFACE_OFST)
/* Module Coordinates Register */ /* Module Coordinates Register */
#define COORD_0_REG (0x02 * REG_OFFSET + BASE_PKT) #define COORD_0_REG (0x02 * REG_OFFSET + BASE_PKT)

View File

@ -531,16 +531,15 @@ int setDynamicRange(int dr) {
if (dr > 0) { if (dr > 0) {
uint32_t regval = 0; uint32_t regval = 0;
switch (dr) { switch (dr) {
case 1: /*case 1: TODO:Not implemented in firmware yet
regval = CONFIG_DYNAMIC_RANGE_1_VAL; regval = CONFIG_DYNAMIC_RANGE_1_VAL;
break; break;*/
case 4: case 8:
regval = CONFIG_DYNAMIC_RANGE_4_VAL; regval = CONFIG_DYNAMIC_RANGE_8_VAL;
break; break;
case 16: case 16:
regval = CONFIG_DYNAMIC_RANGE_16_VAL; regval = CONFIG_DYNAMIC_RANGE_16_VAL;
break; break;
case 24:
case 32: case 32:
regval = CONFIG_DYNAMIC_RANGE_24_VAL; regval = CONFIG_DYNAMIC_RANGE_24_VAL;
break; break;
@ -555,10 +554,10 @@ int setDynamicRange(int dr) {
uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK; uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK;
switch (regval) { switch (regval) {
case CONFIG_DYNAMIC_RANGE_1_VAL: /*case CONFIG_DYNAMIC_RANGE_1_VAL: TODO:Not implemented in firmware yet
return 1; return 1;*/
case CONFIG_DYNAMIC_RANGE_4_VAL: case CONFIG_DYNAMIC_RANGE_8_VAL:
return 4; return 8;
case CONFIG_DYNAMIC_RANGE_16_VAL: case CONFIG_DYNAMIC_RANGE_16_VAL:
return 16; return 16;
case CONFIG_DYNAMIC_RANGE_24_VAL: case CONFIG_DYNAMIC_RANGE_24_VAL:
@ -2038,7 +2037,6 @@ void *start_timer(void *arg) {
int numFrames = (getNumFrames() * getNumTriggers()); int numFrames = (getNumFrames() * getNumTriggers());
int64_t expUs = getGatePeriod() / 1000; int64_t expUs = getGatePeriod() / 1000;
// int dr = setDynamicRange(-1);
int imagesize = calculateDataBytes(); int imagesize = calculateDataBytes();
int dataSize = imagesize / PACKETS_PER_FRAME; int dataSize = imagesize / PACKETS_PER_FRAME;
int packetSize = dataSize + sizeof(sls_detector_header); int packetSize = dataSize + sizeof(sls_detector_header);
@ -2046,6 +2044,34 @@ void *start_timer(void *arg) {
// Generate data // Generate data
char imageData[imagesize]; char imageData[imagesize];
memset(imageData, 0, imagesize); memset(imageData, 0, imagesize);
{
int dr = setDynamicRange(-1);
int numCounters = __builtin_popcount(getCounterMask());
int nchannels = NCHAN_1_COUNTER * NCHIP * numCounters;
switch (dr) {
/*case 1: // TODO: Not implemented in firmware yet
break;*/
case 8:
for (int i = 0; i < nchannels; ++i) {
*((uint8_t *)(imageData + i)) = (uint8_t)i;
}
break;
case 16:
for (int i = 0; i < nchannels; ++i) {
*((uint16_t *)(imageData + i * sizeof(uint16_t))) = (uint16_t)i;
}
break;
case 32:
for (int i = 0; i < nchannels; ++i) {
*((uint32_t *)(imageData + i * sizeof(uint32_t))) =
((uint32_t)i & 0xFFFFFF); // 24 bit
}
break;
default:
break;
}
}
for (int i = 0; i < imagesize; i += sizeof(uint8_t)) { for (int i = 0; i < imagesize; i += sizeof(uint8_t)) {
*((uint8_t *)(imageData + i)) = i; *((uint8_t *)(imageData + i)) = i;
} }
@ -2282,13 +2308,7 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
int calculateDataBytes() { int calculateDataBytes() {
int numCounters = __builtin_popcount(getCounterMask()); int numCounters = __builtin_popcount(getCounterMask());
int dr = setDynamicRange(-1); int dr = setDynamicRange(-1);
int databytes = NCHAN_1_COUNTER * NCHIP * numCounters * return (NCHAN_1_COUNTER * NCHIP * numCounters * ((double)dr / 8.00));
((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 0.5 : // 4 bit
0.125))); // 1 bit
return databytes;
} }
int getTotalNumberOfChannels() { int getTotalNumberOfChannels() {

View File

@ -27,7 +27,7 @@
#define DEFAULT_PATTERN_FILE ("DefaultPattern.txt") #define DEFAULT_PATTERN_FILE ("DefaultPattern.txt")
#define DEFAULT_INTERNAL_GATES (1) #define DEFAULT_INTERNAL_GATES (1)
#define DEFAULT_EXTERNAL_GATES (1) #define DEFAULT_EXTERNAL_GATES (1)
#define DEFAULT_DYNAMIC_RANGE (24) #define DEFAULT_DYNAMIC_RANGE (32)
#define DEFAULT_NUM_FRAMES (1) #define DEFAULT_NUM_FRAMES (1)
#define DEFAULT_NUM_CYCLES (1) #define DEFAULT_NUM_CYCLES (1)
#define DEFAULT_GATE_WIDTH (100 * 1000 * 1000) // ns #define DEFAULT_GATE_WIDTH (100 * 1000 * 1000) // ns

View File

@ -2684,10 +2684,13 @@ int set_dynamic_range(int file_des) {
// check dr // check dr
switch (dr) { switch (dr) {
case GET_FLAG: case GET_FLAG:
#ifdef MYTHEN3D /*#ifdef MYTHEN3D TODO:Not implemented in firmware yet
case 32: case 1:
#elif EIGERD #endif*/
#ifdef EIGERD
case 4: case 4:
#endif
#if defined(EIGERD) || defined(MYTHEN3D)
case 8: case 8:
case 16: case 16:
case 32: case 32:
@ -2698,6 +2701,11 @@ int set_dynamic_range(int file_des) {
#endif #endif
retval = setDynamicRange(dr); retval = setDynamicRange(dr);
LOG(logDEBUG1, ("Dynamic range: %d\n", retval)); LOG(logDEBUG1, ("Dynamic range: %d\n", retval));
if (retval == -1) {
ret = FAIL;
sprintf(mess, "Could not get dynamic range.\n");
LOG(logERROR, (mess));
}
validate(dr, retval, "set dynamic range", DEC); validate(dr, retval, "set dynamic range", DEC);
break; break;
default: default:

View File

@ -203,6 +203,16 @@ class Detector {
* [Gotthard2] only in continuous mode */ * [Gotthard2] only in continuous mode */
Result<ns> getDelayAfterTriggerLeft(Positions pos = {}) const; Result<ns> getDelayAfterTriggerLeft(Positions pos = {}) const;
Result<int> getDynamicRange(Positions pos = {}) const;
/**
* [Eiger] Options: 4, 8, 16, 32
* [Mythen3] Options: 8, 16, 32
* [Eiger] If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to
* 1
*/
void setDynamicRange(int value);
Result<defs::timingMode> getTimingMode(Positions pos = {}) const; Result<defs::timingMode> getTimingMode(Positions pos = {}) const;
/** /**
@ -736,15 +746,6 @@ class Detector {
* * * *
* ************************************************/ * ************************************************/
Result<int> getDynamicRange(Positions pos = {}) const;
/**
* [Eiger]
* Options: 4, 8, 16, 32
* If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to 1
*/
void setDynamicRange(int value);
/** [Eiger] in 32 bit mode */ /** [Eiger] in 32 bit mode */
Result<ns> getSubExptime(Positions pos = {}) const; Result<ns> getSubExptime(Positions pos = {}) const;

View File

@ -487,6 +487,37 @@ std::string CmdProxy::Exptime(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::DynamicRange(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[value]\n\tDynamic Range or number of bits per "
"pixel in detector.\n\t"
"[Eiger] Options: 4, 8, 16, 32\n\t"
"[Mythen3] Options: 8, 16, 32"
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getDynamicRange({det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (det_id != -1) {
throw sls::RuntimeError(
"Cannot execute dynamic range at module level");
}
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->setDynamicRange(StringTo<int>(args[0]));
os << args.front() << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::Speed(int action) { std::string CmdProxy::Speed(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
@ -1196,35 +1227,6 @@ std::string CmdProxy::ReceiveHostname(int action) {
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */ /* Eiger Specific */
std::string CmdProxy::DynamicRange(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[4|8|16|32]\n\t[Eiger] Dynamic Range or number of bits per "
"pixel in detector."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getDynamicRange({det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (det_id != -1) {
throw sls::RuntimeError(
"Cannot execute dynamic range at module level");
}
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->setDynamicRange(StringTo<int>(args[0]));
os << args.front() << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::Threshold(int action) { std::string CmdProxy::Threshold(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';

View File

@ -643,6 +643,7 @@ class CmdProxy {
{"triggersl", &CmdProxy::triggersl}, {"triggersl", &CmdProxy::triggersl},
{"delayl", &CmdProxy::delayl}, {"delayl", &CmdProxy::delayl},
{"periodl", &CmdProxy::periodl}, {"periodl", &CmdProxy::periodl},
{"dr", &CmdProxy::DynamicRange},
{"timing", &CmdProxy::timing}, {"timing", &CmdProxy::timing},
{"speed", &CmdProxy::Speed}, {"speed", &CmdProxy::Speed},
{"adcphase", &CmdProxy::Adcphase}, {"adcphase", &CmdProxy::Adcphase},
@ -814,7 +815,6 @@ class CmdProxy {
{"zmqip", &CmdProxy::zmqip}, {"zmqip", &CmdProxy::zmqip},
/* Eiger Specific */ /* Eiger Specific */
{"dr", &CmdProxy::DynamicRange},
{"subexptime", &CmdProxy::subexptime}, {"subexptime", &CmdProxy::subexptime},
{"subdeadtime", &CmdProxy::subdeadtime}, {"subdeadtime", &CmdProxy::subdeadtime},
{"threshold", &CmdProxy::Threshold}, {"threshold", &CmdProxy::Threshold},
@ -996,6 +996,7 @@ class CmdProxy {
/* acquisition parameters */ /* acquisition parameters */
std::string Acquire(int action); std::string Acquire(int action);
std::string Exptime(int action); std::string Exptime(int action);
std::string DynamicRange(int action);
std::string Speed(int action); std::string Speed(int action);
std::string Adcphase(int action); std::string Adcphase(int action);
std::string Dbitphase(int action); std::string Dbitphase(int action);
@ -1021,7 +1022,6 @@ class CmdProxy {
/* File */ /* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */ /* Eiger Specific */
std::string DynamicRange(int action);
std::string Threshold(int action); std::string Threshold(int action);
std::string ThresholdNoTb(int action); std::string ThresholdNoTb(int action);
std::string TrimEnergies(int action); std::string TrimEnergies(int action);
@ -1785,9 +1785,11 @@ class CmdProxy {
"[nth frame]\n\tStream out every nth frame. Default is 1. 0 means " "[nth frame]\n\tStream out every nth frame. Default is 1. 0 means "
"streaming every 200 ms and discarding frames in this interval."); "streaming every 200 ms and discarding frames in this interval.");
INTEGER_COMMAND( INTEGER_COMMAND(rx_zmqstartfnum, getRxZmqStartingFrame,
rx_zmqstartfnum, getRxZmqStartingFrame, setRxZmqStartingFrame, StringTo<int>, setRxZmqStartingFrame, StringTo<int>,
"[fnum]\n\tThe starting frame index to stream out. 0 by default, which streams the first frame in an acquisition, and then depending on the rx zmq frequency/ timer"); "[fnum]\n\tThe starting frame index to stream out. 0 by "
"default, which streams the first frame in an acquisition, "
"and then depending on the rx zmq frequency/ timer");
INTEGER_COMMAND( INTEGER_COMMAND(
rx_zmqport, getRxZmqPort, setRxZmqPort, StringTo<int>, rx_zmqport, getRxZmqPort, setRxZmqPort, StringTo<int>,

View File

@ -273,6 +273,14 @@ Result<ns> Detector::getPeriodLeft(Positions pos) const {
return pimpl->Parallel(&Module::getPeriodLeft, pos); return pimpl->Parallel(&Module::getPeriodLeft, pos);
} }
Result<int> Detector::getDynamicRange(Positions pos) const {
return pimpl->Parallel(&Module::getDynamicRange, pos);
}
void Detector::setDynamicRange(int value) {
pimpl->Parallel(&Module::setDynamicRange, {}, value);
}
Result<defs::timingMode> Detector::getTimingMode(Positions pos) const { Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
return pimpl->Parallel(&Module::getTimingMode, pos); return pimpl->Parallel(&Module::getTimingMode, pos);
} }
@ -1022,14 +1030,6 @@ void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
// Eiger Specific // Eiger Specific
Result<int> Detector::getDynamicRange(Positions pos) const {
return pimpl->Parallel(&Module::getDynamicRange, pos);
}
void Detector::setDynamicRange(int value) {
pimpl->Parallel(&Module::setDynamicRange, {}, value);
}
Result<ns> Detector::getSubExptime(Positions pos) const { Result<ns> Detector::getSubExptime(Positions pos) const {
return pimpl->Parallel(&Module::getSubExptime, pos); return pimpl->Parallel(&Module::getSubExptime, pos);
} }

View File

@ -259,6 +259,38 @@ int64_t Module::getPeriodLeft() const {
return sendToDetectorStop<int64_t>(F_GET_PERIOD_LEFT); return sendToDetectorStop<int64_t>(F_GET_PERIOD_LEFT);
} }
int Module::getDynamicRange() {
return sendToDetector<int>(F_SET_DYNAMIC_RANGE, GET_FLAG);
}
void Module::setDynamicRange(int n) {
int prev_val = n;
if (shm()->myDetectorType == EIGER) {
prev_val = getDynamicRange();
}
auto retval = sendToDetector<int>(F_SET_DYNAMIC_RANGE, n);
if (shm()->useReceiverFlag) {
int arg = retval;
sendToReceiver<int>(F_SET_RECEIVER_DYNAMIC_RANGE, arg);
}
// changes in dr
if (n != prev_val) {
// update speed for usability
if (n == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
setClockDivider(RUN_CLOCK, 2);
} else if (prev_val == 32) {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of "
<< n;
setClockDivider(RUN_CLOCK, 0);
}
updateRateCorrection();
}
}
slsDetectorDefs::timingMode Module::getTimingMode() { slsDetectorDefs::timingMode Module::getTimingMode() {
return sendToDetector<timingMode>(F_SET_TIMING_MODE, GET_FLAG); return sendToDetector<timingMode>(F_SET_TIMING_MODE, GET_FLAG);
} }
@ -1017,38 +1049,6 @@ void Module::setClientStreamingIP(const sls::IpAddr ip) {
// Eiger Specific // Eiger Specific
int Module::getDynamicRange() {
return sendToDetector<int>(F_SET_DYNAMIC_RANGE, GET_FLAG);
}
void Module::setDynamicRange(int n) {
int prev_val = n;
if (shm()->myDetectorType == EIGER) {
prev_val = getDynamicRange();
}
auto retval = sendToDetector<int>(F_SET_DYNAMIC_RANGE, n);
if (shm()->useReceiverFlag) {
int arg = retval;
sendToReceiver<int>(F_SET_RECEIVER_DYNAMIC_RANGE, arg);
}
// changes in dr
if (n != prev_val) {
// update speed for usability
if (n == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
setClockDivider(RUN_CLOCK, 2);
} else if (prev_val == 32) {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of "
<< n;
setClockDivider(RUN_CLOCK, 0);
}
updateRateCorrection();
}
}
int64_t Module::getSubExptime() { int64_t Module::getSubExptime() {
return sendToDetector<int64_t>(F_GET_SUB_EXPTIME); return sendToDetector<int64_t>(F_GET_SUB_EXPTIME);
} }

View File

@ -125,6 +125,8 @@ class Module : public virtual slsDetectorDefs {
int64_t getNumberOfTriggersLeft() const; int64_t getNumberOfTriggersLeft() const;
int64_t getDelayAfterTriggerLeft() const; int64_t getDelayAfterTriggerLeft() const;
int64_t getPeriodLeft() const; int64_t getPeriodLeft() const;
int getDynamicRange();
void setDynamicRange(int n);
timingMode getTimingMode(); timingMode getTimingMode();
void setTimingMode(timingMode value); void setTimingMode(timingMode value);
int getClockDivider(int clkIndex); int getClockDivider(int clkIndex);
@ -290,8 +292,6 @@ class Module : public virtual slsDetectorDefs {
* Eiger Specific * * Eiger Specific *
* * * *
* ************************************************/ * ************************************************/
int getDynamicRange();
void setDynamicRange(int n);
int64_t getSubExptime(); int64_t getSubExptime();
void setSubExptime(int64_t value); void setSubExptime(int64_t value);
int64_t getSubDeadTime(); int64_t getSubDeadTime();

View File

@ -315,47 +315,6 @@ TEST_CASE("txndelay_right", "[.cmd][.new]") {
/* Eiger Specific */ /* Eiger Specific */
TEST_CASE("dr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto dr = det.getDynamicRange().squash();
std::array<int, 4> vals{4, 8, 16, 32};
for (const auto val : vals) {
std::ostringstream oss1, oss2;
proxy.Call("dr", {std::to_string(val)}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr " + std::to_string(val) + '\n');
proxy.Call("dr", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "dr " + std::to_string(val) + '\n');
}
det.setDynamicRange(dr);
} else if (det_type == defs::MYTHEN3) {
// not updated in firmware to support anything other than 32 at the
// moment
std::ostringstream oss1, oss2;
proxy.Call("dr", {"32"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr 32\n");
proxy.Call("dr", {"32"}, -1, PUT, oss2);
REQUIRE(oss2.str() == "dr 32\n");
REQUIRE_THROWS(proxy.Call("dr", {"4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"8"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"16"}, -1, PUT));
} else {
// For the other detectors we should get an error message
// except for dr 16
REQUIRE_THROWS(proxy.Call("dr", {"4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"8"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"32"}, -1, PUT));
std::ostringstream oss1, oss2;
proxy.Call("dr", {"16"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr 16\n");
proxy.Call("dr", {"16"}, -1, PUT, oss2);
REQUIRE(oss2.str() == "dr 16\n");
}
}
TEST_CASE("subexptime", "[.cmd][.new]") { TEST_CASE("subexptime", "[.cmd][.new]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -451,6 +451,48 @@ TEST_CASE("periodl", "[.cmd][.new]") {
} }
} }
TEST_CASE("dr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto dr = det.getDynamicRange().squash();
std::array<int, 4> vals{4, 8, 16, 32};
for (const auto val : vals) {
std::ostringstream oss1, oss2;
proxy.Call("dr", {std::to_string(val)}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr " + std::to_string(val) + '\n');
proxy.Call("dr", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "dr " + std::to_string(val) + '\n');
}
det.setDynamicRange(dr);
} else if (det_type == defs::MYTHEN3) {
auto dr = det.getDynamicRange().squash();
// not updated in firmware to support dr 1
std::array<int, 3> vals{8, 16, 32};
for (const auto val : vals) {
std::ostringstream oss1, oss2;
proxy.Call("dr", {std::to_string(val)}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr " + std::to_string(val) + '\n');
proxy.Call("dr", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "dr " + std::to_string(val) + '\n');
}
det.setDynamicRange(dr);
} else {
// For the other detectors we should get an error message
// except for dr 16
REQUIRE_THROWS(proxy.Call("dr", {"4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"8"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("dr", {"32"}, -1, PUT));
std::ostringstream oss1, oss2;
proxy.Call("dr", {"16"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dr 16\n");
proxy.Call("dr", {"16"}, -1, PUT, oss2);
REQUIRE(oss2.str() == "dr 16\n");
}
}
TEST_CASE("timing", "[.cmd][.new]") { TEST_CASE("timing", "[.cmd][.new]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -727,21 +727,28 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting dynamic range: " << dr; LOG(logDEBUG1) << "Setting dynamic range: " << dr;
bool exists = false; bool exists = false;
switch (myDetectorType) { switch (dr) {
case EIGER: case 16:
if (dr == 4 || dr == 8 || dr == 16 || dr == 32) { exists = true;
break;
/*case 1: //TODO: Not yet implemented in firmware
if (myDetectorType == MYTHEN3) {
exists = true; exists = true;
} }
break; break;
case MYTHEN3: */
if (dr == 1 || dr == 4 || dr == 16 || dr == 32) { case 4:
if (myDetectorType == EIGER) {
exists = true;
}
break;
case 8:
case 32:
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
exists = true; exists = true;
} }
break; break;
default: default:
if (dr == 16) {
exists = true;
}
break; break;
} }
if (!exists) { if (!exists) {

View File

@ -449,11 +449,7 @@ class Mythen3Data : public GeneralData {
ncounters = n; ncounters = n;
nPixelsX = NCHAN * ncounters; nPixelsX = NCHAN * ncounters;
LOG(logINFO) << "nPixelsX: " << nPixelsX; LOG(logINFO) << "nPixelsX: " << nPixelsX;
imageSize = nPixelsX * nPixelsY * imageSize = nPixelsX * nPixelsY * ((double)dr / 8.00);
((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 0.5 : // 4 bit
0.125))); // 1 bit
dataSize = imageSize / packetsPerFrame; dataSize = imageSize / packetsPerFrame;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
LOG(logINFO) << "PacketSize: " << packetSize; LOG(logINFO) << "PacketSize: " << packetSize;
@ -465,11 +461,7 @@ class Mythen3Data : public GeneralData {
* @param tgEnable (discarded, of no value to mythen3) * @param tgEnable (discarded, of no value to mythen3)
*/ */
void SetDynamicRange(int dr, bool tgEnable) { void SetDynamicRange(int dr, bool tgEnable) {
imageSize = nPixelsX * nPixelsY * imageSize = nPixelsX * nPixelsY * ((double)dr / 8.00);
((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 0.5 : // 4 bit
0.125))); // 1 bit
dataSize = imageSize / packetsPerFrame; dataSize = imageSize / packetsPerFrame;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
LOG(logINFO) << "PacketSize: " << packetSize; LOG(logINFO) << "PacketSize: " << packetSize;

View File

@ -293,9 +293,10 @@ void Implementation::setDetectorType(const detectorType d) {
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
&masterFileWriteEnable, &dataStreamEnable, &dynamicRange, &masterFileWriteEnable, &dataStreamEnable, &dynamicRange,
&streamingFrequency, &streamingTimerInMs, &streamingStartFnum, &framePadding, &streamingFrequency, &streamingTimerInMs, &streamingStartFnum,
&activated, &deactivatedPaddingEnable, &silentMode, &quadEnable, &framePadding, &activated, &deactivatedPaddingEnable,
&ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
&ctbAnalogDataBytes));
} catch (...) { } catch (...) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
@ -1018,10 +1019,10 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, i, myDetectorType, fifo_ptr, &fileFormatType,
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency, &streamingTimerInMs, &streamingStartFnum, &dynamicRange, &streamingFrequency, &streamingTimerInMs,
&framePadding, &activated, &deactivatedPaddingEnable, &streamingStartFnum, &framePadding, &activated,
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &deactivatedPaddingEnable, &silentMode, &quadEnable,
&ctbAnalogDataBytes)); &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes));
dataProcessor[i]->SetGeneralData(generalData); dataProcessor[i]->SetGeneralData(generalData);
} catch (...) { } catch (...) {
listener.clear(); listener.clear();