mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-05-01 10:20:04 +02:00
txdelay for all modules (#584)
* setting txdelay for all modules for eiger, jungfrau and m3 * added txdelay in python and renamed txndelay_ to txdelay_ * call in parallel
This commit is contained in:
parent
928d778fb1
commit
61c31ed44a
@ -127,6 +127,7 @@ This document describes the differences between v7.0.0 and v6.x.x
|
||||
- gui nios temperature added
|
||||
- detector header change (bunchid, reserved, debug, roundRnumber) ->detSpec1 - 4
|
||||
-ctb and moench (allowing all clkdivs (totaldiv was a float instead of int))
|
||||
- txndelay_ ->txdelay_ (also for python), txdelay = delay for all with step
|
||||
- hardwareversion
|
||||
- jungfrau connected moduleid to detid_jungfrau.txt on board
|
||||
|
||||
|
@ -627,25 +627,46 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@property
|
||||
@element
|
||||
def txndelay_frame(self):
|
||||
def txdelay(self):
|
||||
"""
|
||||
[Eiger][Jungfrau][Mythen3] Set transmission delay for all modules in the detector using the step size provided.
|
||||
|
||||
Note
|
||||
----
|
||||
Sets up the following for every module:\n
|
||||
\t\t[Eiger] txdelay_left to (2 * mod_index * n_delay), \n
|
||||
\t\t[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay) and \n
|
||||
\t\t[Eiger] txdelay_frame to (2 *num_modules * n_delay) \n
|
||||
\t\t[Jungfrau][Mythen3] txdelay_frame to (num_modules * n_delay)\n\n
|
||||
Please refer txdelay_left, txdelay_right and txdelay_frame for details.
|
||||
"""
|
||||
return self.getTransmissionDelay()
|
||||
|
||||
@txdelay.setter
|
||||
def txdelay(self, args):
|
||||
ut.set_using_dict(self.setTransmissionDelay, args)
|
||||
|
||||
@property
|
||||
@element
|
||||
def txdelay_frame(self):
|
||||
"""
|
||||
[Eiger][Jungfrau][Mythen3] Transmission delay of first udp packet being streamed out of the module.\n
|
||||
|
||||
Note
|
||||
----
|
||||
[Jungfrau] [0-31] Each value represents 1 ms. \n
|
||||
[Eiger] Additional delay to txndelay_left and txndelay_right. Each value represents 10ns. Typical value is 50000. \n
|
||||
[Eiger] Additional delay to txdelay_left and txdelay_right. Each value represents 10ns. Typical value is 50000. \n
|
||||
[Mythen3] [0-16777215] Each value represents 8 ns (125 MHz clock), max is 134 ms.
|
||||
"""
|
||||
return self.getTransmissionDelayFrame()
|
||||
|
||||
@txndelay_frame.setter
|
||||
def txndelay_frame(self, args):
|
||||
@txdelay_frame.setter
|
||||
def txdelay_frame(self, args):
|
||||
ut.set_using_dict(self.setTransmissionDelayFrame, args)
|
||||
|
||||
@property
|
||||
@element
|
||||
def txndelay_left(self):
|
||||
def txdelay_left(self):
|
||||
"""[Eiger] Transmission delay of first packet in an image being streamed out of the module's left UDP port.
|
||||
|
||||
Note
|
||||
@ -654,13 +675,13 @@ class Detector(CppDetectorApi):
|
||||
"""
|
||||
return self.getTransmissionDelayLeft()
|
||||
|
||||
@txndelay_left.setter
|
||||
def txndelay_left(self, args):
|
||||
@txdelay_left.setter
|
||||
def txdelay_left(self, args):
|
||||
ut.set_using_dict(self.setTransmissionDelayLeft, args)
|
||||
|
||||
@property
|
||||
@element
|
||||
def txndelay_right(self):
|
||||
def txdelay_right(self):
|
||||
"""
|
||||
[Eiger] Transmission delay of first packet in an image being streamed out of the module's right UDP port.
|
||||
|
||||
@ -670,8 +691,8 @@ class Detector(CppDetectorApi):
|
||||
"""
|
||||
return self.getTransmissionDelayRight()
|
||||
|
||||
@txndelay_right.setter
|
||||
def txndelay_right(self, args):
|
||||
@txdelay_right.setter
|
||||
def txdelay_right(self, args):
|
||||
ut.set_using_dict(self.setTransmissionDelayRight, args)
|
||||
|
||||
@property
|
||||
|
@ -783,6 +783,12 @@ void init_det(py::module &m) {
|
||||
(void (Detector::*)(int, sls::Positions)) &
|
||||
Detector::setTransmissionDelayRight,
|
||||
py::arg(), py::arg() = Positions{});
|
||||
CppDetectorApi.def("getTransmissionDelay",
|
||||
(int (Detector::*)() const) &
|
||||
Detector::getTransmissionDelay);
|
||||
CppDetectorApi.def(
|
||||
"setTransmissionDelay",
|
||||
(void (Detector::*)(int)) & Detector::setTransmissionDelay, py::arg());
|
||||
CppDetectorApi.def("getUseReceiverFlag",
|
||||
(Result<bool>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getUseReceiverFlag,
|
||||
|
@ -835,6 +835,20 @@ class Detector {
|
||||
* port
|
||||
*/
|
||||
void setTransmissionDelayRight(int value, Positions pos = {});
|
||||
|
||||
/** [Eiger][Jungfrau] */
|
||||
int getTransmissionDelay() const;
|
||||
|
||||
/**
|
||||
* [Eiger][Jungfrau][Mythen3] Set transmission delay for all modules in the
|
||||
* detector using the step size provided.Sets up \n\t\t[Eiger] txdelay_left
|
||||
* to (2 * mod_index * n_delay), \n\t\t[Eiger] txdelay_right to ((2 *
|
||||
* mod_index + 1) * n_delay) and \n\t\t[Eiger] txdelay_frame to (2
|
||||
* *num_modules * n_delay) \n\t\t[Jungfrau][Mythen3] txdelay_frame to
|
||||
* (num_modules * n_delay) \nfor every module.
|
||||
*/
|
||||
void setTransmissionDelay(int step);
|
||||
|
||||
///@}
|
||||
|
||||
/** @name Receiver Configuration */
|
||||
|
@ -1705,6 +1705,42 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::TransmissionDelay(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[n_delay]\n\t[Eiger][Jungfrau][Mythen3] Set transmission delay "
|
||||
"for all modules in the detector using the step size "
|
||||
"provided.Sets up \n\t\t[Eiger] txdelay_left to (2 * mod_index * "
|
||||
"n_delay), \n\t\t[Eiger] txdelay_right to ((2 * mod_index + 1) * "
|
||||
"n_delay) and \n\t\t[Eiger] txdelay_frame to (2 *num_modules * "
|
||||
"n_delay) \n\t\t[Jungfrau][Mythen3] txdelay_frame to "
|
||||
"(num_modules * n_delay) \nfor every module."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (det_id != -1) {
|
||||
throw RuntimeError("Cannot execute this at module level");
|
||||
}
|
||||
if (args.size() != 0) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getTransmissionDelay();
|
||||
os << OutString(t) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (det_id != -1) {
|
||||
throw RuntimeError("Cannot execute this at module level");
|
||||
}
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
det->setTransmissionDelay(StringTo<int>(args[0]));
|
||||
os << args.front() << '\n';
|
||||
} else {
|
||||
throw RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/* Receiver Config */
|
||||
std::string CmdProxy::ReceiverHostname(int action) {
|
||||
std::ostringstream os;
|
||||
|
@ -697,6 +697,9 @@ class CmdProxy {
|
||||
{"rx_udpport", "udp_dstport"},
|
||||
{"rx_udpport2", "udp_dstport2"},
|
||||
{"flowcontrol_10g", "flowcontrol10g"},
|
||||
{"txndelay_frame", "txdelay_frame"},
|
||||
{"txndelay_left", "txdelay_left"},
|
||||
{"txndelay_right", "txdelay_right"},
|
||||
|
||||
/* Receiver Config */
|
||||
{"r_silent", "rx_silent"},
|
||||
@ -893,9 +896,10 @@ class CmdProxy {
|
||||
{"rx_printconfig", &CmdProxy::rx_printconfig},
|
||||
{"tengiga", &CmdProxy::tengiga},
|
||||
{"flowcontrol10g", &CmdProxy::flowcontrol10g},
|
||||
{"txndelay_frame", &CmdProxy::txndelay_frame},
|
||||
{"txndelay_left", &CmdProxy::txndelay_left},
|
||||
{"txndelay_right", &CmdProxy::txndelay_right},
|
||||
{"txdelay_frame", &CmdProxy::txdelay_frame},
|
||||
{"txdelay_left", &CmdProxy::txdelay_left},
|
||||
{"txdelay_right", &CmdProxy::txdelay_right},
|
||||
{"txdelay", &CmdProxy::TransmissionDelay},
|
||||
|
||||
/* Receiver Config */
|
||||
{"rx_hostname", &CmdProxy::ReceiverHostname},
|
||||
@ -1158,6 +1162,7 @@ class CmdProxy {
|
||||
std::string UDPSourceIP2(int action);
|
||||
std::string UDPDestinationIP(int action);
|
||||
std::string UDPDestinationIP2(int action);
|
||||
std::string TransmissionDelay(int action);
|
||||
/* Receiver Config */
|
||||
std::string ReceiverHostname(int action);
|
||||
std::string Rx_ROI(int action);
|
||||
@ -1689,24 +1694,24 @@ class CmdProxy {
|
||||
"[0, 1]\n\t[Eiger][Jungfrau] 10GbE Flow Control.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
txndelay_frame, getTransmissionDelayFrame, setTransmissionDelayFrame,
|
||||
txdelay_frame, getTransmissionDelayFrame, setTransmissionDelayFrame,
|
||||
StringTo<int>,
|
||||
"[n_delay]\n\t[Eiger][Jungfrau][Mythen3] Transmission delay of first "
|
||||
"udp packet being streamed out of the module.\n\t[Jungfrau] [0-31] "
|
||||
"Each value represents 1 ms\n\t[Eiger] Additional delay to "
|
||||
"txndelay_left and txndelay_right. Each value represents 10ns. Typical "
|
||||
"txdelay_left and txdelay_right. Each value represents 10ns. Typical "
|
||||
"value is 50000.\n\t[Mythen3] [0-16777215] Each value represents 8 ns "
|
||||
"(125 MHz clock), max is 134 ms.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
txndelay_left, getTransmissionDelayLeft, setTransmissionDelayLeft,
|
||||
txdelay_left, getTransmissionDelayLeft, setTransmissionDelayLeft,
|
||||
StringTo<int>,
|
||||
"[n_delay]\n\t[Eiger] Transmission delay of first packet in an image "
|
||||
"being streamed out of the module's left UDP port. Each value "
|
||||
"represents 10ns. Typical value is 50000.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
txndelay_right, getTransmissionDelayRight, setTransmissionDelayRight,
|
||||
txdelay_right, getTransmissionDelayRight, setTransmissionDelayRight,
|
||||
StringTo<int>,
|
||||
"[n_delay]\n\t[Eiger] Transmission delay of first packet in an image "
|
||||
"being streamed out of the module's right UDP port. Each value "
|
||||
|
@ -1120,6 +1120,14 @@ void Detector::setTransmissionDelayRight(int value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setTransmissionDelayRight, pos, value);
|
||||
}
|
||||
|
||||
int Detector::getTransmissionDelay() const {
|
||||
return pimpl->getTransmissionDelay();
|
||||
}
|
||||
|
||||
void Detector::setTransmissionDelay(int step) {
|
||||
pimpl->setTransmissionDelay(step);
|
||||
}
|
||||
|
||||
// Receiver
|
||||
|
||||
Result<bool> Detector::getUseReceiverFlag(Positions pos) const {
|
||||
|
@ -431,6 +431,89 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
|
||||
shm()->gapPixels = enable;
|
||||
}
|
||||
|
||||
int DetectorImpl::getTransmissionDelay() const {
|
||||
bool eiger = false;
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case MYTHEN3:
|
||||
break;
|
||||
case EIGER:
|
||||
eiger = true;
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError(
|
||||
"Transmission delay is not implemented for the this detector.");
|
||||
}
|
||||
if (!eiger && size() <= 1) {
|
||||
throw RuntimeError(
|
||||
"Cannot get intermodule transmission delays with just one module");
|
||||
}
|
||||
int step = 0;
|
||||
if (eiger) {
|
||||
// between left and right
|
||||
step = modules[0]->getTransmissionDelayRight();
|
||||
} else {
|
||||
// between first and second
|
||||
step = modules[1]->getTransmissionDelayFrame();
|
||||
}
|
||||
for (int i = 0; i != size(); ++i) {
|
||||
if (eiger) {
|
||||
if ((modules[i]->getTransmissionDelayLeft() != (2 * i * step)) ||
|
||||
(modules[i]->getTransmissionDelayRight() !=
|
||||
((2 * i + 1) * step)) ||
|
||||
(modules[i]->getTransmissionDelayFrame() !=
|
||||
(2 * size() * step))) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (modules[i]->getTransmissionDelayFrame() != (i * step)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return step;
|
||||
}
|
||||
|
||||
void DetectorImpl::setTransmissionDelay(int step) {
|
||||
bool eiger = false;
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case MYTHEN3:
|
||||
break;
|
||||
case EIGER:
|
||||
eiger = true;
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError(
|
||||
"Transmission delay is not implemented for the this detector.");
|
||||
}
|
||||
|
||||
//using a asyc+future directly (instead of Parallel) to pass different values
|
||||
std::vector<std::future<void>> futures;
|
||||
for (int i = 0; i != size(); ++i) {
|
||||
if (eiger) {
|
||||
futures.push_back(std::async(std::launch::async,
|
||||
&Module::setTransmissionDelayLeft,
|
||||
modules[i].get(), 2 * i * step));
|
||||
futures.push_back(std::async(std::launch::async,
|
||||
&Module::setTransmissionDelayRight,
|
||||
modules[i].get(), (2 * i + 1) * step));
|
||||
futures.push_back(std::async(std::launch::async,
|
||||
&Module::setTransmissionDelayFrame,
|
||||
modules[i].get(), 2 * size() * step));
|
||||
|
||||
} else {
|
||||
futures.push_back(std::async(std::launch::async,
|
||||
&Module::setTransmissionDelayFrame,
|
||||
modules[i].get(), i * step));
|
||||
}
|
||||
}
|
||||
|
||||
//wait for calls to complete
|
||||
for (auto &f : futures)
|
||||
f.get();
|
||||
}
|
||||
|
||||
int DetectorImpl::destroyReceivingDataSockets() {
|
||||
LOG(logINFO) << "Going to destroy data sockets";
|
||||
// close socket
|
||||
|
@ -237,11 +237,10 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* Sets maximum number of channels of all sls modules */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/** [Eiger][Jungfrau] */
|
||||
bool getGapPixelsinCallback() const;
|
||||
/** [Eiger][Jungfrau] */
|
||||
void setGapPixelsinCallback(const bool enable);
|
||||
|
||||
int getTransmissionDelay() const;
|
||||
void setTransmissionDelay(int step);
|
||||
bool getDataStreamingToClient();
|
||||
void setDataStreamingToClient(bool enable);
|
||||
int getClientStreamingHwm() const;
|
||||
|
@ -2672,7 +2672,7 @@ TEST_CASE("txndelay_frame", "[.cmd]") {
|
||||
det_type == defs::MYTHEN3) {
|
||||
auto prev_val = det.getTransmissionDelayFrame();
|
||||
auto val = 5000;
|
||||
if (det_type == defs::JUNGFRAU) {
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::MYTHEN3) {
|
||||
val = 5;
|
||||
}
|
||||
std::string sval = std::to_string(val);
|
||||
@ -2691,6 +2691,62 @@ TEST_CASE("txndelay_frame", "[.cmd]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("txdelay", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::EIGER || det_type == defs::JUNGFRAU ||
|
||||
det_type == defs::MYTHEN3) {
|
||||
Result<int> prev_left, prev_right;
|
||||
bool eiger = false;
|
||||
if (det_type == defs::EIGER) {
|
||||
eiger = true;
|
||||
prev_left = det.getTransmissionDelayLeft();
|
||||
prev_right = det.getTransmissionDelayRight();
|
||||
}
|
||||
auto prev_frame = det.getTransmissionDelayFrame();
|
||||
auto val = 5000;
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::MYTHEN3) {
|
||||
val = 5;
|
||||
}
|
||||
std::string sval = std::to_string(val);
|
||||
{
|
||||
std::ostringstream oss1, oss2;
|
||||
proxy.Call("txdelay", {sval}, -1, PUT, oss1);
|
||||
REQUIRE(oss1.str() == "txdelay " + sval + "\n");
|
||||
proxy.Call("txdelay", {}, -1, GET, oss2);
|
||||
REQUIRE(oss2.str() == "txdelay " + sval + "\n");
|
||||
}
|
||||
// test other mods
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
if (eiger) {
|
||||
REQUIRE(det.getTransmissionDelayLeft({i}).squash(-1) ==
|
||||
(3 * i * val));
|
||||
REQUIRE(det.getTransmissionDelayRight({i}).squash(-1) ==
|
||||
((3 * i + 1) * val));
|
||||
REQUIRE(det.getTransmissionDelayFrame({i}).squash(-1) ==
|
||||
((3 * i + 2) * val));
|
||||
} else {
|
||||
REQUIRE(det.getTransmissionDelayFrame({i}).squash(-1) ==
|
||||
(i * val));
|
||||
}
|
||||
}
|
||||
// not a module level command
|
||||
REQUIRE_THROWS(proxy.Call("txdelay", {"5"}, 0, PUT));
|
||||
REQUIRE_THROWS(proxy.Call("txdelay", {}, 0, GET));
|
||||
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
if (eiger) {
|
||||
det.setTransmissionDelayLeft(prev_left[i]);
|
||||
det.setTransmissionDelayRight(prev_right[i]);
|
||||
}
|
||||
det.setTransmissionDelayFrame(prev_frame[i]);
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("txdelay", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
/* ZMQ Streaming Parameters (Receiver<->Client) */
|
||||
|
||||
TEST_CASE("zmqport", "[.cmd]") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user