From 28792ea7e7aea8d993a9170015e7adc8d24e20ea Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 24 Jun 2025 09:39:28 +0200 Subject: [PATCH] switched to vector instead of std::array>, which prints extra [-1, -1] when theres only 1 udp interface --- slsDetectorSoftware/include/sls/Detector.h | 2 +- slsDetectorSoftware/src/Detector.cpp | 4 +- slsDetectorSoftware/src/DetectorImpl.cpp | 30 +++++++---- slsDetectorSoftware/src/DetectorImpl.h | 5 +- slsDetectorSoftware/src/Module.cpp | 52 ++++++++++++++++--- slsDetectorSoftware/src/Module.h | 4 +- .../tests/Caller/test-Caller-rx.cpp | 8 +-- slsReceiverSoftware/src/ClientInterface.cpp | 19 +++++-- slsReceiverSoftware/src/DataStreamer.cpp | 2 +- slsReceiverSoftware/src/Implementation.cpp | 40 ++++++++++---- slsReceiverSoftware/src/Implementation.h | 6 +-- 11 files changed, 127 insertions(+), 45 deletions(-) diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index b0a261e94..10a3acba6 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -993,7 +993,7 @@ class Detector { std::vector getRxROI() const; /** Returns port level ROIs. Max 2 ports and hence max 2 elements per readout */ - Result> getRxROI(int module_id) const; + std::vector getRxROI(int module_id) const; /** only at multi module level without gap pixels. At most, 1 ROI per UDP port */ void setRxROI(const std::vector &args); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index a274f06f7..b2d70937c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1387,8 +1387,8 @@ std::vector Detector::getRxROI() const { return pimpl->getRxROI(); } -Result> Detector::getRxROI(int module_id) const { - return pimpl->Parallel(&Module::getRxROI, {module_id}); +std::vector Detector::getRxROI(int module_id) const { + return pimpl->getRxROI(module_id); } // RxROIs can be set for all types except CTB. At multi level without gap pixels diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 66d4b7a73..5cb2744b5 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1667,8 +1667,7 @@ void DetectorImpl::verifyUniqueHost( } } -std::vector DetectorImpl::getRxROI() const { - +std::vector DetectorImpl::getRxROI(int module_id) const { if (shm()->detType == CHIPTESTBOARD || shm()->detType == defs::XILINX_CHIPTESTBOARD) { throw RuntimeError("RxRoi not implemented for this Detector"); @@ -1677,6 +1676,14 @@ std::vector DetectorImpl::getRxROI() const { throw RuntimeError("No Modules added"); } + // individual module rois + if (module_id >= 0) { + if (module_id >= (int)modules.size()) + throw RuntimeError("Invalid module index " + std::to_string(module_id) + ". Out of bounds."); + return modules[module_id]->getRxROI(); + } + + // multi roi // return std::vector{}; return rxRoiTemp; // TODO @@ -1792,13 +1799,18 @@ defs::ROI DetectorImpl::getModuleROI(int moduleIndex) const { void DetectorImpl::convertGlobalRoiToPortLevel( const defs::ROI &userRoi, const defs::ROI &moduleRoi, - std::array &portRois) const { + std::vector &portRois) const { const defs::xy modSize = modules[0]->getNumberOfChannels(); const defs::xy geometry = getPortGeometry(); const int numPorts = geometry.x * geometry.y; if (numPorts > 2) { throw RuntimeError("Only up to 2 ports per module supported."); } + if (numPorts != (int)portRois.size()) { + throw RuntimeError("Number of port ROIs does not match number of ports in module. Expected: " + + std::to_string(numPorts) + ", got: " + + std::to_string(portRois.size())); + } for (int port = 0; port < numPorts; ++port) { defs::ROI portRoi = moduleRoi; @@ -1849,12 +1861,13 @@ void DetectorImpl::setRxROI(const std::vector &args) { } validateROIs(args); + int nPortsPerModule = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).tsquash("Inconsistent number of udp ports set up per module"); for (size_t iModule = 0; iModule < modules.size(); ++iModule) { auto moduleGlobalRoi = getModuleROI(iModule); // at most 2 rois per module (for each port) - std::array portRois{}; + std::vector portRois(nPortsPerModule); for (const auto &arg : args) { if (roisOverlap(arg, moduleGlobalRoi)) { @@ -1863,7 +1876,7 @@ void DetectorImpl::setRxROI(const std::vector &args) { } // print the rois for debugging LOG(logINFOBLUE) << "Module " << iModule << " RxROIs:"; - for (size_t iPort = 0; iPort != 2; iPort++) { + for (size_t iPort = 0; iPort != portRois.size(); iPort++) { LOG(logINFOBLUE) << " Port " << iPort << ": " << ToString(portRois[iPort]); } @@ -1876,15 +1889,12 @@ void DetectorImpl::setRxROI(const std::vector &args) { void DetectorImpl::clearRxROI() { rxRoiTemp.clear(); + int nPortsPerModule = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).tsquash("Inconsistent number of udp ports set up per module"); for (size_t iModule = 0; iModule < modules.size(); ++iModule) { - modules[iModule]->setRxROI(std::array{}); + modules[iModule]->setRxROI(std::vector(nPortsPerModule)); } } -int DetectorImpl::getNumberOfUdpPortsInRxROI() const { - return 0; // TODO -} - void DetectorImpl::getBadChannels(const std::string &fname, Positions pos) const { auto res = Parallel(&Module::getBadChannels, pos); diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index a43707c0c..45d95e4cf 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -302,10 +302,9 @@ class DetectorImpl : public virtual slsDetectorDefs { verifyUniqueRxHost(const std::vector &names) const; defs::xy getPortGeometry() const; - std::vector getRxROI() const; + std::vector getRxROI(int module_id = -1) const; void setRxROI(const std::vector &args); void clearRxROI(); - int getNumberOfUdpPortsInRxROI() const; void getBadChannels(const std::string &fname, Positions pos) const; void setBadChannels(const std::string &fname, Positions pos); @@ -433,7 +432,7 @@ class DetectorImpl : public virtual slsDetectorDefs { defs::ROI getModuleROI(int moduleIndex) const; void convertGlobalRoiToPortLevel( const defs::ROI &userRoi, const defs::ROI &moduleRoi, - std::array &portRois) const; + std::vector &portRois) const; const int detectorIndex{0}; SharedMemory shm{0, -1}; diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 12b8be264..6ee96af9e 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1521,12 +1521,50 @@ void Module::setRxArping(bool enable) { sendToReceiver(F_SET_RECEIVER_ARPING, static_cast(enable), nullptr); } -std::array Module::getRxROI() const { - return sendToReceiver>(F_RECEIVER_GET_RECEIVER_ROI); +std::vector Module::getRxROI() const { + LOG(logDEBUG1) << "Getting receiver ROI for Module " << moduleIndex; + // check number of ports + if (!shm()->useReceiverFlag) { + throw RuntimeError("No receiver to get ROI."); + } + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + client.Send(F_RECEIVER_GET_RECEIVER_ROI); + client.setFnum(F_RECEIVER_GET_RECEIVER_ROI); + auto nPorts = client.Receive(); + std::vector retval(nPorts); + if (nPorts > 0) + client.Receive(retval); + if (nPorts > shm()->numUDPInterfaces) { + throw RuntimeError("Invalid number of rois: " + std::to_string(nPorts) + ". Max: " + std::to_string(shm()->numUDPInterfaces)); + } + LOG(logDEBUG1) << "ROI of Receiver" << moduleIndex << ": " + << ToString(retval); + return retval; } -void Module::setRxROI(const std::array &portRois) { - sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI, portRois, nullptr); +void Module::setRxROI(const std::vector &portRois) { + LOG(logDEBUG) << "Sending to receiver " << moduleIndex + << " [roi: " << ToString(portRois) << ']'; + if (!shm()->useReceiverFlag) { + throw RuntimeError("No receiver to set ROI."); + } + if ((int)portRois.size() > shm()->numUDPInterfaces) { + throw RuntimeError("Invalid number of ROIs: " + + std::to_string(portRois.size()) + + ". Max: " + std::to_string(shm()->numUDPInterfaces)); + } + // check number of ports + auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + client.Send(F_RECEIVER_SET_RECEIVER_ROI); + client.setFnum(F_RECEIVER_SET_RECEIVER_ROI); + int size = static_cast(portRois.size()); + client.Send(size); + if (size > 0) + client.Send(portRois); + if (client.Receive() == FAIL) { + throw ReceiverError("Receiver " + std::to_string(moduleIndex) + + " returned error: " + client.readErrorMessage()); + } } void Module::setRxROIMetadata(const std::vector &args) { @@ -1535,8 +1573,10 @@ void Module::setRxROIMetadata(const std::vector &args) { auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); receiver.Send(F_RECEIVER_SET_RECEIVER_ROI_METADATA); receiver.setFnum(F_RECEIVER_SET_RECEIVER_ROI_METADATA); - receiver.Send(static_cast(args.size())); - receiver.Send(args); + int size = static_cast(args.size()); + receiver.Send(size); + if (size > 0) + receiver.Send(args); if (receiver.Receive() == FAIL) { throw ReceiverError("Receiver " + std::to_string(moduleIndex) + " returned error: " + receiver.readErrorMessage()); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 47284fec0..86516cbb5 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -301,8 +301,8 @@ class Module : public virtual slsDetectorDefs { std::array getReceiverThreadIds() const; bool getRxArping() const; void setRxArping(bool enable); - std::array getRxROI() const; - void setRxROI(const std::array &portRois); + std::vector getRxROI() const; + void setRxROI(const std::vector &portRois); void setRxROIMetadata(const std::vector &args); /************************************************** diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp index 3576b4d40..9b0a42997 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -619,11 +619,11 @@ TEST_CASE("rx_roi", "[.cmdcall]") { caller.call("rx_roi", {}, 0, GET, oss1)); // eiger returns 2 values for 2 ports per module if (det_type == defs::EIGER) { - REQUIRE(oss1.str() == "rx_roi [[[" + stringMin + ", " + std::to_string(portSize.x - 1) + ", 20, 30], [" + std::to_string(portSize.x) + ", " + stringMax + ", 20, 30]]]\n"); + REQUIRE(oss1.str() == "rx_roi [[" + stringMin + ", " + std::to_string(portSize.x - 1) + ", 20, 30], [" + std::to_string(portSize.x) + ", " + stringMax + ", 20, 30]]\n"); } // others return only 1 roi per module (1 port per module) else { - REQUIRE(oss1.str() == "rx_roi [[[" + stringMin + ", " + std::to_string(portSize.x - 1) + "20, 30]]]\n"); + REQUIRE(oss1.str() == "rx_roi [[" + stringMin + ", " + std::to_string(portSize.x - 1) + "20, 30]]\n"); } } } @@ -655,11 +655,11 @@ TEST_CASE("rx_roi", "[.cmdcall]") { caller.call("rx_roi", {}, 0, GET, oss1)); // non-eiger with 2 interfaces returns 2 values for 2 ports per module if (numinterfaces == 2) { - REQUIRE(oss1.str() == "rx_roi [[[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [20, 30, " + std::to_string(portSize.y) + ", " + stringMax + "]]]\n"); + REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [20, 30, " + std::to_string(portSize.y) + ", " + stringMax + "]]\n"); } // others return only 1 roi per module (1 port per module) else { - REQUIRE(oss1.str() == "rx_roi [[[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [-1, -1]]]\n"); + REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "]]\n"); } } } diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index cee0b7f87..37611ad5d 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -1695,11 +1695,24 @@ int ClientInterface::set_arping(Interface &socket) { int ClientInterface::get_receiver_roi(Interface &socket) { auto retvals = impl()->getPortROIs(); LOG(logDEBUG1) << "Receiver roi retval:" << ToString(retvals); - return socket.sendResult(retvals); + auto size = static_cast(retvals.size()); + socket.Send(size); + if (size > 0) + socket.Send(retvals); + return OK; } int ClientInterface::set_receiver_roi(Interface &socket) { - auto args = socket.Receive>(); + auto roiSize = socket.Receive(); + std::vector args(roiSize); + if (roiSize > 0) { + socket.Receive(args); + } + if (roiSize > impl()->getNumberofUDPInterfaces()) { + throw RuntimeError("Invalid number of ROIs received: " + + std::to_string(roiSize) + ". Max: " + + std::to_string(impl()->getNumberofUDPInterfaces())); + } if (detType == CHIPTESTBOARD || detType == XILINX_CHIPTESTBOARD) functionNotImplemented(); LOG(logDEBUG1) << "Set Receiver ROI: " << ToString(args); @@ -1716,7 +1729,7 @@ int ClientInterface::set_receiver_roi(Interface &socket) { int ClientInterface::set_receiver_roi_metadata(Interface &socket) { auto roiSize = socket.Receive(); - LOG(logDEBUG) << "Number of ReceiverROI metadata: " << roiSize; + LOG(logDEBUG1) << "Number of ReceiverROI metadata: " << roiSize; std::vector rois(roiSize); if (roiSize > 0) { socket.Receive(rois); diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index f2f6a4b9e..e971dae30 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -54,7 +54,7 @@ void DataStreamer::SetAdditionalJsonHeader( } void DataStreamer::SetPortROI(ROI roi) { - if (roi.completeRoi()) { + if (roi.completeRoi()) {//TODO: just not send zmq if not in roi? portRoi = ROI(0, generalData->nPixelsX - 1, 0, generalData->nPixelsY - 1); } else { diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index bb3372443..ffffb7d05 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -184,7 +184,7 @@ void Implementation::SetupListener(int i) { listener[i]->SetUdpPortNumber(udpPortNum[i]); listener[i]->SetEthernetInterface(eth[i]); listener[i]->SetActivate(activated); - listener[i]->SetIsOutsideRoi(portRois[i].noRoi()); + listener[i]->SetIsOutsideRoi(i >= (int)portRois.size()); listener[i]->SetDetectorDatastream(detectorDataStream[i]); listener[i]->SetSilentMode(silentMode); } @@ -194,7 +194,12 @@ void Implementation::SetupDataProcessor(int i) { dataProcessor[i]->SetGeneralData(generalData); dataProcessor[i]->SetUdpPortNumber(udpPortNum[i]); dataProcessor[i]->SetActivate(activated); - dataProcessor[i]->SetPortROI(portRois[i]); + if (i >= (int)portRois.size()) { + ROI roi{0, 0, 0, 0}; + dataProcessor[i]->SetPortROI(roi); + } else { + dataProcessor[i]->SetPortROI(portRois[i]); + } dataProcessor[i]->SetDataStreamEnable(dataStreamEnable); dataProcessor[i]->SetStreamingFrequency(streamingFrequency); dataProcessor[i]->SetStreamingTimerInMs(streamingTimerInMs); @@ -216,7 +221,12 @@ void Implementation::SetupDataStreamer(int i) { dataStreamer[i]->SetFlipRows(flipRows); dataStreamer[i]->SetNumberofPorts(numPorts); dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames); - dataStreamer[i]->SetPortROI(portRois[i]); + if (i >= (int)portRois.size()) { + ROI roi{0, 0, 0, 0}; + dataStreamer[i]->SetPortROI(roi); + } else { + dataStreamer[i]->SetPortROI(portRois[i]); + } } slsDetectorDefs::xy Implementation::getDetectorSize() const { @@ -395,19 +405,29 @@ void Implementation::setArping(const bool i, } } -std::array Implementation::getPortROIs() const { +std::vector Implementation::getPortROIs() const { return portRois; } -void Implementation::setPortROIs(const std::array &args) { +void Implementation::setPortROIs(const std::vector &args) { portRois = args; for (size_t i = 0; i != listener.size(); ++i) - listener[i]->SetIsOutsideRoi(portRois[i].noRoi()); + listener[i]->SetIsOutsideRoi(i >= portRois.size()); for (size_t i = 0; i != dataProcessor.size(); ++i) - dataProcessor[i]->SetPortROI(portRois[i]); + if (i >= portRois.size()) { + ROI roi{0, 0, 0, 0}; + dataProcessor[i]->SetPortROI(roi); + } else { + dataProcessor[i]->SetPortROI(portRois[i]); + } for (size_t i = 0; i != dataStreamer.size(); ++i) { - dataStreamer[i]->SetPortROI(portRois[i]); + if (i >= portRois.size()) { + ROI roi{0, 0, 0, 0}; + dataStreamer[i]->SetPortROI(roi); + } else { + dataStreamer[i]->SetPortROI(portRois[i]); + } } LOG(logINFO) << "Rois (per port): " << ToString(portRois); } @@ -710,7 +730,7 @@ void Implementation::stopReceiver() { } else if (!detectorDataStream[i]) { summary = (i == 0 ? "\n\tDeactivated Left Port" : "\n\tDeactivated Right Port"); - } else if (portRois[i].noRoi()) { + } else if (i >= (int)portRois.size()) { summary = "\n\tNo Roi on Port[" + std::to_string(i) + ']'; } else { std::ostringstream os; @@ -881,7 +901,7 @@ void Implementation::StartMasterWriter() { masterAttributes.framePadding = framePadding; masterAttributes.scanParams = scanParams; masterAttributes.totalFrames = numberOfTotalFrames; - // complete ROI + // complete ROI (for each port TODO?) if (multiRoiMetadata.empty()) { int nTotalPixelsX = (generalData->nPixelsX * numPorts.x); int nTotalPixelsY = (generalData->nPixelsY * numPorts.y); diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 2d663b85b..6f25287fd 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -58,8 +58,8 @@ class Implementation : private virtual slsDetectorDefs { bool getArping() const; pid_t getArpingProcessId() const; void setArping(const bool i, const std::vector ips); - std::array getPortROIs() const; - void setPortROIs(const std::array &args); + std::vector getPortROIs() const; + void setPortROIs(const std::vector &args); void setMultiROIMetadata(const std::vector &args); /************************************************** @@ -307,7 +307,7 @@ class Implementation : private virtual slsDetectorDefs { bool framePadding{true}; pid_t parentThreadId; pid_t tcpThreadId; - std::array portRois{}; + std::vector portRois{}; std::vector multiRoiMetadata{}; // file parameters