diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index aaca367ec..b0a261e94 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -989,15 +989,17 @@ class Detector { * every minute. Useful in 10G mode. */ void setRxArping(bool value, Positions pos = {}); + /** Returns multi level ROIs */ std::vector getRxROI() const; - /** only at multi module level without gap pixels */ + /** Returns port level ROIs. Max 2 ports and hence max 2 elements per readout */ + Result> 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); void clearRxROI(); - int getNumberOfUdpPortsInRxROI() const; - ///@} /** @name File */ diff --git a/slsDetectorSoftware/src/CallerSpecial.cpp b/slsDetectorSoftware/src/CallerSpecial.cpp index bb0cfdf2f..9ceb3803a 100644 --- a/slsDetectorSoftware/src/CallerSpecial.cpp +++ b/slsDetectorSoftware/src/CallerSpecial.cpp @@ -739,14 +739,7 @@ std::string Caller::rx_roi(int action) { throw RuntimeError("Cannot execute receiver ROI at module level"); } else { auto t = det->getRxROI(); - // os << ToString(t) << '\n'; - for (const auto &r : t) { - os << r << ';'; - } - if (!t.empty()) { - os.seekp(-1, std::ios_base::end); // remove trailing ; - } - os << '\n'; + os << ToString(t) << '\n'; } } else if (action == defs::PUT_ACTION) { std::vector rois; @@ -789,14 +782,7 @@ std::string Caller::rx_roi(int action) { } det->setRxROI(rois); - // os << ToString(rois) << '\n'; - for (const auto &r : rois) { - os << r << ';'; - } - //if (!rois.empty()) { - // os.seekp(-1, std::ios_base::end); // remove trailing ; - //} - os << '\n'; + os << ToString(rois) << '\n'; } else { throw RuntimeError("Unknown action"); } diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 960b84654..a274f06f7 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1383,7 +1383,13 @@ void Detector::setRxArping(bool value, Positions pos) { pimpl->Parallel(&Module::setRxArping, pos, value); } -std::vector Detector::getRxROI() const { return pimpl->getRxROI(); } +std::vector Detector::getRxROI() const { + return pimpl->getRxROI(); +} + +Result> Detector::getRxROI(int module_id) const { + return pimpl->Parallel(&Module::getRxROI, {module_id}); +} // RxROIs can be set for all types except CTB. At multi level without gap pixels void Detector::setRxROI(const std::vector &args) { @@ -1392,9 +1398,6 @@ void Detector::setRxROI(const std::vector &args) { void Detector::clearRxROI() { pimpl->clearRxROI(); } -int Detector::getNumberOfUdpPortsInRxROI() const { - return pimpl->getNumberOfUdpPortsInRxROI(); -} // File diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 7e405d7a8..1fa906dc3 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1791,7 +1791,7 @@ defs::ROI DetectorImpl::getModuleROI(int moduleIndex) const { void DetectorImpl::convertGlobalRoiToPortLevel( const defs::ROI &userRoi, const defs::ROI &moduleRoi, - std::vector> &portRois) const { + std::array &portRois) const { const defs::xy modSize = modules[0]->getNumberOfChannels(); const defs::xy geometry = getPortGeometry(); const int numPorts = geometry.x * geometry.y; @@ -1827,16 +1827,13 @@ void DetectorImpl::convertGlobalRoiToPortLevel( } // Check if port ROI already exists for this port - for (const auto &m : portRois) { - if (m.find(port) != m.end()) { - throw RuntimeError( - "Multiple ROIs specified for the same port " + - std::to_string(port) + - " with ROI: " + ToString(userRoi)); - } + if (!portRois[port].completeRoi()) { + throw RuntimeError( + "Multiple ROIs specified for the same port " + + std::to_string(port) + + " with ROI: " + ToString(userRoi)); } - - portRois.push_back({{port, clipped}}); + portRois[port] = clipped; } } } @@ -1856,7 +1853,7 @@ void DetectorImpl::setRxROI(const std::vector &args) { auto moduleGlobalRoi = getModuleROI(iModule); // at most 2 rois per module (for each port) - std::vector> portRois; + std::array portRois{}; for (const auto &arg : args) { if (roisOverlap(arg, moduleGlobalRoi)) { @@ -1865,18 +1862,23 @@ void DetectorImpl::setRxROI(const std::vector &args) { } // print the rois for debugging LOG(logINFOBLUE) << "Module " << iModule << " RxROIs:"; - for (const auto &portRoi : portRois) { - for (const auto &roi : portRoi) { - LOG(logINFOBLUE) - << " Port " << roi.first << ": " << ToString(roi.second); - } + for (size_t iPort = 0; iPort != 2; iPort++) { + LOG(logINFOBLUE) + << " Port " << iPort << ": " << ToString(portRois[iPort]); } - // modules[iModule]->setRxROIs(portRois); TODO + modules[iModule]->setRxROI(portRois); } rxRoiTemp = args; + // metadata + modules[0]->setRxROIMetadata(args); } -void DetectorImpl::clearRxROI() { rxRoiTemp.clear(); } +void DetectorImpl::clearRxROI() { + rxRoiTemp.clear(); + for (size_t iModule = 0; iModule < modules.size(); ++iModule) { + modules[iModule]->setRxROI(std::array{}); + } +} int DetectorImpl::getNumberOfUdpPortsInRxROI() const { return 0; // TODO diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index 4d82088b7..a43707c0c 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -433,7 +433,7 @@ class DetectorImpl : public virtual slsDetectorDefs { defs::ROI getModuleROI(int moduleIndex) const; void convertGlobalRoiToPortLevel( const defs::ROI &userRoi, const defs::ROI &moduleRoi, - std::vector> &portRois) const; + std::array &portRois) const; const int detectorIndex{0}; SharedMemory shm{0, -1}; diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 47f4ffe79..25af1c403 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1520,20 +1520,29 @@ bool Module::getRxArping() const { void Module::setRxArping(bool enable) { sendToReceiver(F_SET_RECEIVER_ARPING, static_cast(enable), nullptr); } -/* -defs::ROI Module::getRxROI() const { - return sendToReceiver(F_RECEIVER_GET_RECEIVER_ROI); + +std::array Module::getRxROI() const { + return sendToReceiver>(F_RECEIVER_GET_RECEIVER_ROI); } -void Module::setRxROI(const slsDetectorDefs::ROI arg) { - LOG(logDEBUG) << moduleIndex << ": " << arg; - sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI, arg, nullptr); +void Module::setRxROI(std::array portRois) { + /*LOG(logDEBUG) << "Sending to receiver " << moduleIndex << " [rx roi: " << ToString(portRois) + << ']'; + auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + receiver.Send(F_RECEIVER_SET_RECEIVER_ROI); + receiver.setFnum(F_RECEIVER_SET_RECEIVER_ROI); + receiver.Send(portRois); + if (receiver.Receive() == FAIL) { + throw ReceiverError("Receiver " + std::to_string(moduleIndex) + + " returned error: " + receiver.readErrorMessage()); + }*/ + sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI, portRois, nullptr); } -void Module::setRxROIMetadata(const slsDetectorDefs::ROI arg) { +void Module::setRxROIMetadata(const std::vector &arg) { sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI_METADATA, arg, nullptr); } -*/ + // File slsDetectorDefs::fileFormat Module::getFileFormat() const { return sendToReceiver(F_GET_RECEIVER_FILE_FORMAT); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index c84fa378b..ca79f44d7 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -301,9 +301,9 @@ class Module : public virtual slsDetectorDefs { std::array getReceiverThreadIds() const; bool getRxArping() const; void setRxArping(bool enable); - // defs::ROI getRxROI() const; - // void setRxROI(const slsDetectorDefs::ROI arg); - // void setRxROIMetadata(const slsDetectorDefs::ROI arg); + std::array getRxROI() const; + void setRxROI(const std::array 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 aff9ef607..72d4c23a0 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -482,12 +482,12 @@ TEST_CASE("rx_roi", "[.cmdcall]") { { std::ostringstream oss; caller.call("rx_roi", {"5", "10"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_roi [5, 10]\n"); + REQUIRE(oss.str() == "rx_roi [[5, 10]]\n"); } { std::ostringstream oss; caller.call("rx_roi", {"10", "15"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_roi [10, 15]\n"); + REQUIRE(oss.str() == "rx_roi [[10, 15]]\n"); } REQUIRE_THROWS(caller.call("rx_roi", {"0", "0"}, -1, PUT)); REQUIRE_THROWS(caller.call("rx_roi", {"-1", "-1"}, -1, PUT)); @@ -526,7 +526,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") { REQUIRE_NOTHROW(caller.call( "rx_roi", {"[5, 10, -1, -1];[" + stringMin + ", " + stringMax + ", -1, -1]"}, -1, PUT, oss)); REQUIRE(oss.str() == - "rx_roi [5, 10];[" + stringMin + ", " + stringMax + "]\n"); + "rx_roi [[5, 10], [" + stringMin + ", " + stringMax + "]]\n"); } } @@ -535,12 +535,12 @@ TEST_CASE("rx_roi", "[.cmdcall]") { { std::ostringstream oss; caller.call("rx_roi", {"10", "15", "1", "5"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_roi [10, 15, 1, 5]\n"); + REQUIRE(oss.str() == "rx_roi [[10, 15, 1, 5]]\n"); } { std::ostringstream oss; caller.call("rx_roi", {"10", "22", "18", "19"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_roi [10, 22, 18, 19]\n"); + REQUIRE(oss.str() == "rx_roi [[10, 22, 18, 19]]\n"); } { std::ostringstream oss; @@ -548,11 +548,11 @@ TEST_CASE("rx_roi", "[.cmdcall]") { {"1", std::to_string(detsize.x - 5), "1", std::to_string(detsize.y - 5)}, -1, PUT, oss); - REQUIRE(oss.str() == std::string("rx_roi [1, ") + + REQUIRE(oss.str() == std::string("rx_roi [[1, ") + std::to_string(detsize.x - 5) + std::string(", 1, ") + std::to_string(detsize.y - 5) + - std::string("]\n")); + std::string("]]\n")); } REQUIRE_THROWS( caller.call("rx_roi", {"0", "0", "0", "0"}, -1, PUT)); @@ -600,7 +600,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") { REQUIRE_NOTHROW(caller.call( "rx_roi", {"[5, 10, 20, 30];[" + stringMin + ", " + stringMax + ", 20, 30]"}, -1, PUT, oss)); REQUIRE(oss.str() == - "rx_roi [5, 10, 20, 30];[" + stringMin + ", " + stringMax + ", 20, 30]\n"); + "rx_roi [[5, 10, 20, 30], [" + stringMin + ", " + stringMax + ", 20, 30]]\n"); } if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH) { // 2 interfaces or 2 modules @@ -622,7 +622,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") { REQUIRE_NOTHROW(caller.call( "rx_roi", {"[5, 10, 20, 30];[25, 28, " + stringMin + ", " + stringMax + "]"}, -1, PUT, oss)); REQUIRE(oss.str() == - "rx_roi [5, 10, 20, 30];[25, 28, " + stringMin + ", " + stringMax + "]\n"); + "rx_roi [[5, 10, 20, 30], [25, 28, " + stringMin + ", " + stringMax + "]]\n"); } } } diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index 55d6b628b..71d9a1190 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -348,23 +348,6 @@ std::vector StringTo(const std::vector &strings) { result.push_back(StringTo(s)); return result; } -/* -template -std::string ToString(const std::vector &vec) { - std::ostringstream oss; - oss << "["; - for (size_t i = 0; i < vec.size(); ++i) { - oss << vec[i]; - if (i != vec.size() - 1) - oss << ", "; - } - oss << "]"; - return oss.str(); -}*/ -/*template -std::ostream &operator<<(std::ostream &os, const std::vector &v) { - return os << ToString(v); -}*/ } // namespace sls