format
All checks were successful
Build on RHEL9 / build (push) Successful in 2m57s
Build on RHEL8 / build (push) Successful in 5m0s

This commit is contained in:
2025-06-30 12:32:05 +02:00
parent cbd0aed8e5
commit 5d31d86b83
13 changed files with 205 additions and 156 deletions

View File

@@ -992,7 +992,8 @@ class Detector {
/** Returns multi level ROIs */
std::vector<defs::ROI> getRxROI() const;
/** Returns port level ROIs. Max 2 ports and hence max 2 elements per readout */
/** Returns port level ROIs. Max 2 ports and hence max 2 elements per
* readout */
std::vector<defs::ROI> getRxROI(int module_id) const;
/** only at multi module level without gap pixels. At most, 1 ROI per UDP

View File

@@ -1383,9 +1383,7 @@ void Detector::setRxArping(bool value, Positions pos) {
pimpl->Parallel(&Module::setRxArping, pos, value);
}
std::vector<defs::ROI> Detector::getRxROI() const {
return pimpl->getRxROI();
}
std::vector<defs::ROI> Detector::getRxROI() const { return pimpl->getRxROI(); }
std::vector<defs::ROI> Detector::getRxROI(int module_id) const {
return pimpl->getRxROI(module_id);
@@ -1398,7 +1396,6 @@ void Detector::setRxROI(const std::vector<defs::ROI> &args) {
void Detector::clearRxROI() { pimpl->clearRxROI(); }
// File
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {

View File

@@ -1676,7 +1676,7 @@ std::vector<defs::ROI> DetectorImpl::getRxROI(int module_id) const {
}
if (module_id >= (int)modules.size()) {
throw RuntimeError("Invalid module id: " + std::to_string(module_id));
}
}
if (module_id >= 0) {
return modules[module_id]->getRxROI();
}
@@ -1783,9 +1783,10 @@ void DetectorImpl::convertGlobalRoiToPortLevel(
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()));
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) {
@@ -1812,20 +1813,22 @@ void DetectorImpl::convertGlobalRoiToPortLevel(
clipped.xmin = std::max(userRoi.xmin, portRoi.xmin) - portRoi.xmin;
clipped.xmax = std::min(userRoi.xmax, portRoi.xmax) - portRoi.xmin;
LOG(logDEBUG1) << "User ROI: " << ToString(userRoi)
<< ", Port ROI: " << ToString(portRoi) << " clipped roi:"<< ToString(clipped);
<< ", Port ROI: " << ToString(portRoi)
<< " clipped roi:" << ToString(clipped);
if (modSize.y > 1) {
clipped.ymin = std::max(userRoi.ymin, portRoi.ymin) - portRoi.ymin;
clipped.ymax = std::min(userRoi.ymax, portRoi.ymax) - portRoi.ymin;
clipped.ymin =
std::max(userRoi.ymin, portRoi.ymin) - portRoi.ymin;
clipped.ymax =
std::min(userRoi.ymax, portRoi.ymax) - portRoi.ymin;
}
LOG(logDEBUG1) << "Clipped ROI for port " << port
<< ": " << ToString(clipped);
LOG(logDEBUG1) << "Clipped ROI for port " << port << ": "
<< ToString(clipped);
// Check if port ROI already exists for this port
if (!portRois[port].completeRoi() && !portRois[port].noRoi()) {
throw RuntimeError(
"Multiple ROIs specified for the same port " +
std::to_string(port) +
" with ROI: " + ToString(userRoi));
std::to_string(port) + " with ROI: " + ToString(userRoi));
}
portRois[port] = clipped;
}
@@ -1846,12 +1849,14 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
}
validateROIs(args);
int nPortsPerModule = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).tsquash("Inconsistent number of udp ports set up per module");
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);
LOG(logDEBUG1) << "Module " << iModule
<< " Global ROI: " << ToString(moduleGlobalRoi);
<< " Global ROI: " << ToString(moduleGlobalRoi);
// at most 2 rois per module (for each port)
std::vector<defs::ROI> portRois(nPortsPerModule);
@@ -1865,8 +1870,8 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
// print the rois for debugging
LOG(logDEBUG1) << "Module " << iModule << " RxROIs:";
for (size_t iPort = 0; iPort != portRois.size(); iPort++) {
LOG(logDEBUG1)
<< " Port " << iPort << ": " << ToString(portRois[iPort]);
LOG(logDEBUG1) << " Port " << iPort << ": "
<< ToString(portRois[iPort]);
}
modules[iModule]->setRxROI(portRois);
}
@@ -1874,10 +1879,12 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
modules[0]->setRxROIMetadata(args);
}
void DetectorImpl::clearRxROI() {
int nPortsPerModule = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).tsquash("Inconsistent number of udp ports set up per module");
void DetectorImpl::clearRxROI() {
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::vector<defs::ROI>(nPortsPerModule));
modules[iModule]->setRxROI(std::vector<defs::ROI>(nPortsPerModule));
}
modules[0]->setRxROIMetadata(std::vector<defs::ROI>(1));
}

View File

@@ -428,9 +428,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
void validateROIs(const std::vector<defs::ROI> &rois);
defs::xy calculatePosition(int moduleIndex) const;
defs::ROI getModuleROI(int moduleIndex) const;
void convertGlobalRoiToPortLevel(
const defs::ROI &userRoi, const defs::ROI &moduleRoi,
std::vector<defs::ROI> &portRois) const;
void convertGlobalRoiToPortLevel(const defs::ROI &userRoi,
const defs::ROI &moduleRoi,
std::vector<defs::ROI> &portRois) const;
const int detectorIndex{0};
SharedMemory<sharedDetector> shm{0, -1};

View File

@@ -1526,7 +1526,7 @@ std::vector<defs::ROI> Module::getRxROI() const {
// 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);
@@ -1561,12 +1561,12 @@ void Module::setRxROI(const std::vector<defs::ROI> &portRois) {
client.setFnum(F_RECEIVER_SET_RECEIVER_ROI);
int size = static_cast<int>(portRois.size());
client.Send(size);
if (size > 0)
if (size > 0)
client.Send(portRois);
if (client.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
}
std::vector<slsDetectorDefs::ROI> Module::getRxROIMetadata() const {
@@ -1587,8 +1587,7 @@ std::vector<slsDetectorDefs::ROI> Module::getRxROIMetadata() const {
throw RuntimeError("Invalid number of ROI metadata: " +
std::to_string(size) + ". Min: 1.");
}
LOG(logDEBUG1) << "ROI metadata of Receiver: "
<< ToString(retval);
LOG(logDEBUG1) << "ROI metadata of Receiver: " << ToString(retval);
return retval;
}

View File

@@ -7,8 +7,8 @@
#include "sls/sls_detector_defs.h"
#include "test-Caller-global.h"
#include <sstream>
#include <filesystem>
#include <sstream>
#include "sls/versionAPI.h"
#include "tests/globals.h"
@@ -502,8 +502,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
{"[95," + std::to_string(detsize.x + 5) + ", -1, -1]"}, -1,
PUT));
// module level not allowed
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 10, -1, -1]"}, 0, PUT));
REQUIRE_THROWS(caller.call("rx_roi", {"[5, 10, -1, -1]"}, 0, PUT));
// vector of rois
// square brackets missing
@@ -518,18 +517,23 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
if (det.size() == 2) {
auto moduleSize = det.getModuleSize()[0];
std::string stringMin = std::to_string(moduleSize.x);
std::string stringMax = std::to_string(moduleSize.x + 1);
std::string stringMin = std::to_string(moduleSize.x);
std::string stringMax = std::to_string(moduleSize.x + 1);
// separated by space is allowed
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[5, 10, -1, -1]", "[" + stringMin + ", " + stringMax + ", -1, -1]"}, -1, PUT));
"rx_roi",
{"[5, 10, -1, -1]",
"[" + stringMin + ", " + stringMax + ", -1, -1]"},
-1, PUT));
std::ostringstream oss;
// separated by semicolon is allowed
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");
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");
// verify individual roi
{
@@ -537,12 +541,14 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
stringMax = std::to_string(moduleSize.x + 50);
std::ostringstream oss, oss1;
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[" + stringMin + ", " + stringMax + "]"}, -1, PUT, oss));
REQUIRE(oss.str() ==
"rx_roi [[" + stringMin + ", " + stringMax + "]]\n");
REQUIRE_NOTHROW(
caller.call("rx_roi", {}, 0, GET, oss1));
REQUIRE(oss1.str() == "rx_roi [[" + stringMin + ", " + std::to_string(moduleSize.x - 1) + "]]\n");
"rx_roi", {"[" + stringMin + ", " + stringMax + "]"},
-1, PUT, oss));
REQUIRE(oss.str() == "rx_roi [[" + stringMin + ", " +
stringMax + "]]\n");
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss1));
REQUIRE(oss1.str() == "rx_roi [[" + stringMin + ", " +
std::to_string(moduleSize.x - 1) +
"]]\n");
}
}
}
@@ -587,8 +593,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
{"[95, 100, 0, " + std::to_string(detsize.y + 5) + "]"}, -1,
PUT));
// module level not allowed
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 10, 20, 30]"}, 0, PUT));
REQUIRE_THROWS(caller.call("rx_roi", {"[5, 10, 20, 30]"}, 0, PUT));
// vector of rois
// square brackets missing
@@ -603,24 +608,29 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
REQUIRE_THROWS(caller.call(
"rx_roi", {"[0, 10, 0, 10];[0, 10, 9, 11]"}, -1, PUT));
int numinterfaces = det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces");
"inconsistent number of interfaces");
// multiple ports horizontally
if (det_type == defs::EIGER || (det.size() == 2 && det.getModuleGeometry().x > 1)) {
std::string stringMin = std::to_string(portSize.x);
std::string stringMax = std::to_string(portSize.x + 1);
if (det_type == defs::EIGER ||
(det.size() == 2 && det.getModuleGeometry().x > 1)) {
std::string stringMin = std::to_string(portSize.x);
std::string stringMax = std::to_string(portSize.x + 1);
// separated by space is allowed
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[5, 10, 20, 30]", "[" + stringMin + ", " + stringMax + ", 20, 30]"}, -1, PUT));
"rx_roi",
{"[5, 10, 20, 30]",
"[" + stringMin + ", " + stringMax + ", 20, 30]"},
-1, PUT));
std::ostringstream oss;
// separated by semicolon is allowed
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");
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");
// verify individual roi
{
@@ -628,36 +638,52 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
stringMax = std::to_string(portSize.x + delta);
std::ostringstream oss, oss1;
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[" + stringMin + ", " + stringMax + ", 20, 30]"}, -1, PUT, oss));
REQUIRE(oss.str() == "rx_roi [[" + stringMin + ", " + stringMax + ", 20, 30]]\n");
REQUIRE_NOTHROW(
caller.call("rx_roi", {}, 0, GET, oss1));
"rx_roi",
{"[" + stringMin + ", " + stringMax + ", 20, 30]"}, -1,
PUT, oss));
REQUIRE(oss.str() == "rx_roi [[" + stringMin + ", " +
stringMax + ", 20, 30]]\n");
REQUIRE_NOTHROW(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], [0, " + std::to_string(delta) + ", 20, 30]]\n");
REQUIRE(oss1.str() ==
"rx_roi [[" + stringMin + ", " +
std::to_string(portSize.x - 1) +
", 20, 30], [0, " + std::to_string(delta) +
", 20, 30]]\n");
}
// others return only 1 roi per module (1 port per module)
// 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");
}
}
}
// multiple ports vertically
if (((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) && (numinterfaces == 2)) ||
(det.size() == 2 && det.getModuleGeometry().y > 1)) {
std::string stringMin = std::to_string(portSize.y);
std::string stringMax = std::to_string(portSize.y + 1);
if (((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) &&
(numinterfaces == 2)) ||
(det.size() == 2 && det.getModuleGeometry().y > 1)) {
std::string stringMin = std::to_string(portSize.y);
std::string stringMax = std::to_string(portSize.y + 1);
// separated by space is allowed
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[5, 10, 20, 30]", "[25, 28, " + stringMin + ", " + stringMax + "]"}, -1, PUT));
REQUIRE_NOTHROW(
caller.call("rx_roi",
{"[5, 10, 20, 30]", "[25, 28, " + stringMin +
", " + stringMax + "]"},
-1, PUT));
std::ostringstream oss;
// separated by semicolon is allowed
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");
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");
// verify individual roi
{
@@ -665,22 +691,37 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
stringMax = std::to_string(portSize.y + delta);
std::ostringstream oss, oss1;
REQUIRE_NOTHROW(caller.call(
"rx_roi", {"[ 20, 30, " + stringMin + ", " + stringMax + "]"}, -1, PUT, oss));
REQUIRE(oss.str() == "rx_roi [[20, 30, " + stringMin + ", " + stringMax + "]]\n");
REQUIRE_NOTHROW(
caller.call("rx_roi", {}, 0, GET, oss1));
// non-eiger with 2 interfaces returns 2 values for 2 ports per module
if ((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) && (numinterfaces == 2)) {
REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "], [20, 30, 0, " + std::to_string(delta) + "]]\n");
"rx_roi",
{"[ 20, 30, " + stringMin + ", " + stringMax + "]"}, -1,
PUT, oss));
REQUIRE(oss.str() == "rx_roi [[20, 30, " + stringMin +
", " + stringMax + "]]\n");
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss1));
// non-eiger with 2 interfaces returns 2 values for 2 ports
// per module
if ((det_type == defs::JUNGFRAU ||
det_type == defs::MOENCH) &&
(numinterfaces == 2)) {
REQUIRE(oss1.str() ==
"rx_roi [[20, 30, " + stringMin + ", " +
std::to_string(portSize.y - 1) +
"], [20, 30, 0, " + std::to_string(delta) +
"]]\n");
}
// others return only 1 roi per module (1 port per module)
// others return only 1 roi per module (1 port per module)
else {
// (eiger 2 ports)
if (det_type == defs::EIGER) {
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) +
"], [-1, -1]]\n");
} else {
REQUIRE(oss1.str() == "rx_roi [[20, 30, " + stringMin + ", " + std::to_string(portSize.y - 1) + "]]\n");
REQUIRE(oss1.str() ==
"rx_roi [[20, 30, " + stringMin + ", " +
std::to_string(portSize.y - 1) +
"]]\n");
}
}
}
@@ -700,7 +741,7 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
"inconsistent file index values in test");
auto prev_fname = det.getFileNamePrefix().tsquash(
"inconsistent file name prefix values in test");
det.setFileWrite(true);
det.setFilePath("/tmp");
det.setFileNamePrefix("test");
@@ -736,7 +777,6 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
}
}
TEST_CASE("rx_clearroi", "[.cmdcall]") {
Detector det;
Caller caller(&det);