diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index bbc2fde25..5539b1bd6 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -913,6 +913,8 @@ class Detector { void setDataStream(const defs::portPosition port, const bool enable, Positions pos = {}); + /* list of possible port positions */ + std::vector getPortPositionList() const; ///@} /** @name Receiver Configuration */ diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 20409f8a8..3cf8836ed 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1090,6 +1090,7 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) { } // also called by vetostream (for gotthard2) setNumberofUDPInterfaces_(n, pos); + pimpl->updateRxUDPDatastreamMetadata(); } void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { @@ -1325,6 +1326,11 @@ Result Detector::getDataStream(const defs::portPosition port, void Detector::setDataStream(const defs::portPosition port, const bool enable, Positions pos) { pimpl->Parallel(&Module::setDataStream, pos, port, enable); + pimpl->updateRxUDPDatastreamMetadata(); +} + +std::vector Detector::getPortPositionList() const { + return pimpl->getPortPositionList(); } // Receiver diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index b83e3a52e..34c69d868 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1644,6 +1644,42 @@ void DetectorImpl::verifyUniqueHost( } } +std::vector DetectorImpl::getPortPositionList() const { + switch (shm()->detType) { + case defs::JUNGFRAU: + case defs::MOENCH: + return std::vector{defs::TOP, defs::BOTTOM}; + case defs::EIGER: + return std::vector{defs::LEFT, defs::RIGHT}; + default: + throw RuntimeError("port Position does not exist for this detector"); + } +} + +void DetectorImpl::updateRxUDPDatastreamMetadata() { + auto detType = shm()->detType; + if (detType != defs::EIGER && detType != defs::JUNGFRAU && + detType != defs::MOENCH) + throw RuntimeError( + "Datastream enable not implemented for this detector"); + auto portList = getPortPositionList(); + if (portList.size() != 2) { + throw RuntimeError("Invalid port size. Expected 2."); + } + std::array, 2> results; + size_t i = 0; + for (const auto &port : portList) { + results[i] = Parallel(&Module::getDataStream, {}, port); + if (static_cast(results[i].size()) != size()) { + throw RuntimeError("udp datastream enable list does not match size " + "of module list"); + } + ++i; + } + + modules[0]->updateRxUDPDatastreamMetadata(results); +} + std::vector DetectorImpl::getRxROI(int module_id) const { if (shm()->detType == CHIPTESTBOARD || shm()->detType == defs::XILINX_CHIPTESTBOARD) { diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index d7fcc655d..3953a1200 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -310,6 +310,9 @@ class DetectorImpl : public virtual slsDetectorDefs { std::vector> verifyUniqueRxHost(const std::vector &names) const; + std::vector getPortPositionList() const; + void updateRxUDPDatastreamMetadata(); + defs::xy getPortGeometry() const; std::vector getRxROI(int module_id = -1) const; void setRxROI(const std::vector &args); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 79ae7b74c..32f3e42a4 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1434,6 +1434,41 @@ void Module::setDataStream(const portPosition port, const bool enable) { } } +void Module::updateRxUDPDatastreamMetadata( + const std::array, 2> &res) { + if (!shm()->useReceiverFlag) { + return; + } + LOG(logDEBUG) << "Updating UDP data stream enable in receiver (metadata)"; + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + + client.Send(F_RECEIVER_UDP_DATASTREAM_METADATA); + client.setFnum(F_RECEIVER_UDP_DATASTREAM_METADATA); + // ensure both port list size match + if (res[0].size() != res[1].size()) { + throw RuntimeError( + "Size Mismatch of udp datastream enable list for ports"); + } + // send udp data stream enable of all ports in all modules + auto nports = static_cast(res.size()); + auto nmods = static_cast(res[0].size()); + client.Send(nports); + client.Send(nmods); + for (const auto &r : res) { + // convert vector of bool to vector of int to send + std::vector tmp; + tmp.reserve(r.size()); + for (bool b : r) { + tmp.push_back(static_cast(b)); + } + client.Send(tmp); + } + if (client.Receive() == FAIL) { + throw ReceiverError("Receiver " + std::to_string(moduleIndex) + + " returned error: " + client.readErrorMessage()); + } +} + // Receiver Config bool Module::getUseReceiverFlag() const { return shm()->useReceiverFlag; } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index a27a3c1bc..6a2287a0c 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -281,6 +281,8 @@ class Module : public virtual slsDetectorDefs { void setTransmissionDelayRight(int value); bool getDataStream(const portPosition port) const; void setDataStream(const portPosition port, const bool enable); + void + updateRxUDPDatastreamMetadata(const std::array, 2> &res); /************************************************** * * diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index b495b5789..91e6c0d08 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -1095,6 +1095,10 @@ void Implementation::setNumberofUDPInterfaces(const int n) { // number of portrois should be equal to number of interfaces ResetRois(); + // reset udp data stream + udpDataStream[0] = true; + udpDataStream[1] = true; + // create threads for (int i = 0; i < generalData->numUDPInterfaces; ++i) { // listener and dataprocessor threads diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index 0acf62990..b41f16567 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -424,6 +424,7 @@ enum detFuncs { F_RECEIVER_GET_ROI_METADATA, F_SET_RECEIVER_READOUT_SPEED, F_RECEIVER_GET_UDP_DATASTREAM, + F_RECEIVER_UDP_DATASTREAM_METADATA, NUM_REC_FUNCTIONS }; @@ -844,6 +845,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_RECEIVER_GET_ROI_METADATA: return "F_RECEIVER_GET_ROI_METADATA"; case F_SET_RECEIVER_READOUT_SPEED: return "F_SET_RECEIVER_READOUT_SPEED"; case F_RECEIVER_GET_UDP_DATASTREAM: return "F_RECEIVER_GET_UDP_DATASTREAM"; + case F_RECEIVER_UDP_DATASTREAM_METADATA:return "F_RECEIVER_UDP_DATASTREAM_METADATA"; + case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function";