fix merge formatting and refactoring
All checks were successful
Build on RHEL9 / build (push) Successful in 2m52s
Build on RHEL8 / build (push) Successful in 4m54s

This commit is contained in:
2025-07-02 14:10:02 +02:00
31 changed files with 406 additions and 394 deletions

View File

@@ -22,6 +22,7 @@ class Caller {
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
void WrongNumberOfParameters(size_t expected);
std::vector<defs::ROI> parseRoiVector(const std::string &input);
defs::ROI parseRoi(const std::vector<std::string> &args);
template <typename V> std::string OutStringHex(const V &value) {
if (value.equal())

View File

@@ -2193,20 +2193,6 @@ return 0
}
__rx_roi() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "4" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "5" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__rx_silent() {

View File

@@ -2117,20 +2117,6 @@ return 0
}
__rx_roi() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "4" ]]; then
FCN_RETURN=""
fi
if [[ "${cword}" == "5" ]]; then
FCN_RETURN=""
fi
fi
return 0
}
__rx_silent() {

View File

@@ -8831,25 +8831,8 @@ rx_roi:
store_result_in_t: true
PUT:
args:
- arg_types:
- int
- int
argc: 2
cast_input: []
check_det_id: false
convert_det_id: true
function: ''
input: []
input_types: []
output: []
require_det_id: false
store_result_in_t: false
- arg_types:
- int
- int
- int
- int
argc: 4
- arg_types: []
argc: -1
cast_input: []
check_det_id: false
convert_det_id: true

View File

@@ -989,14 +989,13 @@ class Detector {
* every minute. Useful in 10G mode. */
void setRxArping(bool value, Positions pos = {});
/** Returns multi level ROIs */
std::vector<defs::ROI> getRxROI() const;
/** If module_id is -1, returns multi level ROIs. Else it returns port
* level ROIs. Max 2 ports and hence max 2 elements per readout */
std::vector<defs::ROI> getRxROI(int module_id = -1) const;
/** 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
* port. Setting number of udp interfaces will clear the roi */
/** only at multi module level without gap pixels. If more than 1 ROI per
* UDP port, it will throw. Setting number of udp interfaces will clear the
* roi. Cannot be set for CTB or Xilinx CTB */
void setRxROI(const std::vector<defs::ROI> &args);
void clearRxROI();

View File

@@ -19,14 +19,6 @@ class detectorData {
databytes(databytes), dynamicRange(dynamicRange),
completeImage(completeImage){};
detectorData(double progressIndex, std::string fileName, int nx, int ny,
char *data, int databytes, int dynamicRange,
uint64_t fileIndex, bool completeImage,
std::array<int, 4> rxRoi)
: progressIndex(progressIndex), fileName(fileName),
fileIndex(fileIndex), nx(nx), ny(ny), data(data),
databytes(databytes), dynamicRange(dynamicRange),
completeImage(completeImage), rxRoi(rxRoi){};
/**
* data has to be deleted by caller
*/
@@ -62,7 +54,6 @@ class detectorData {
int databytes;
int dynamicRange;
bool completeImage;
std::array<int, 4> rxRoi{{-1, -1, -1, -1}};
};
} // namespace sls

View File

@@ -22,6 +22,7 @@ class Caller {
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
void WrongNumberOfParameters(size_t expected);
std::vector<defs::ROI> parseRoiVector(const std::string &input);
defs::ROI parseRoi(const std::vector<std::string> &args);
template <typename V> std::string OutStringHex(const V &value) {
if (value.equal())

View File

@@ -723,70 +723,70 @@ std::string Caller::rx_zmqip(int action) {
std::string Caller::rx_roi(int action) {
std::ostringstream os;
std::string helpMessage =
std::string("[xmin] [xmax] [ymin] [ymax]\n\tRegion of interest in "
"receiver.\n\t") +
"For a list of rois, use '[' and ']; ' to distinguish between "
"rois and use comma inside the square brackets.\n\t If one fails to "
"use space after semicolon, please use quotes" +
"For example: [0,100,0,100]; [200,300,0,100] will set two "
"rois.or '[0,100,0,100];[200,300,0,100]' when the vector is a single "
"string\n\n\t" +
"Only allowed to set at multi module level and without gap "
"ixels.\n\n\t" +
"One can get rx_roi also at port level, by specifying the module id "
"and it will return the roi for each port.\n"
"Setting number of udp interfaces will clear the rx_roi\n";
std::string("[xmin] [xmax] [ymin] [ymax]\n") +
"\tDefines a single region of interest (ROI) in the receiver.\n"
"\tFor example, to set a single ROI: 0 100 20 30\n\n"
"\tTo specify multiple ROIs, use square brackets between ROIs and "
"commas inside for each ROI. \n"
"\tInside each bracket, no spaces allowed.\n\n"
"\tIf you use semicolon (along with '['and ']' to separate rois), \n"
"\tenclose the entire list in quotes.\n"
"\tExamples:\n"
"\t [0,100,0,100] [200,300,0,100]\n"
"\t \"[0,100,0,100];[200,300,0,100]\"\n\n"
"\tNotes:\n"
"\t- ROIs can only be set at the multi-module level.\n"
"\t- ROIs coordinates assume no gap pixels, even if they are enabled "
"in gui.\n"
"\t- To retrieve ROIs per port, specify the module ID when using the "
"get command.\n"
"\t- Use the command 'rx_clearroi' to clear all ROIs.\n"
"\t- Changing the number of UDP interfaces will automatically clear "
"the current ROIs.\n\n"
"\t- Cannot be set for CTB or Xilinx CTB.\n";
if (action == defs::HELP_ACTION) {
os << helpMessage;
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
if (det_id != -1) {
auto t = det->getRxROI(det_id);
os << ToString(t) << '\n';
} else {
auto t = det->getRxROI();
os << ToString(t) << '\n';
}
auto t = det->getRxROI(det_id);
os << ToString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
std::vector<defs::ROI> rois;
if (det_id != -1) {
throw RuntimeError("Cannot set receiver ROI at module level");
}
// Support multiple args with bracketed ROIs, or single arg with
// semicolon-separated vector
// semicolon-separated vector in quotes
bool isVectorInput =
std::all_of(args.begin(), args.end(), [](const std::string &a) {
return a.find('[') != std::string::npos &&
a.find(']') != std::string::npos;
});
std::vector<defs::ROI> rois;
try {
// previous format: 2 or 4 separate args
if ((args.size() == 2 || args.size() == 4) && !isVectorInput) {
defs::ROI t;
t.xmin = StringTo<int>(args[0]);
t.xmax = StringTo<int>(args[1]);
if (args.size() == 4) {
t.ymin = StringTo<int>(args[2]);
t.ymax = StringTo<int>(args[3]);
}
// single roi in previous format: [xmin,xmax,ymin,ymax]
if (!isVectorInput) {
auto t = parseRoi(args);
rois.emplace_back(t);
} else {
if (!isVectorInput)
WrongNumberOfParameters(2);
else {
for (const auto &arg : args) {
auto subRois = parseRoiVector(arg);
rois.insert(rois.end(), subRois.begin(), subRois.end());
}
}
// multiple roi or single roi with brackets
// multiple roi: multiple args with bracketed ROIs, or single arg
// with semicolon-bracketed Rois in quotes
else {
for (const auto &arg : args) {
auto subRois = parseRoiVector(arg);
rois.insert(rois.end(), subRois.begin(), subRois.end());
}
}
} catch (const std::exception &e) {
throw RuntimeError("Could not parse ROI: " + helpMessage);
}
// only multi level
if (det_id != -1) {
throw RuntimeError("Cannot execute receiver ROI at module level");
throw RuntimeError("Could not parse ROI: Did you use spaces inside "
"the brackets? Use sls_detector_help " +
cmd + " to get the right syntax expected.");
}
det->setRxROI(rois);
@@ -802,16 +802,19 @@ std::vector<defs::ROI> Caller::parseRoiVector(const std::string &input) {
std::stringstream ss(input);
std::string token;
while (std::getline(ss, token, ';')) {
token.erase(std::remove_if(token.begin(), token.end(), ::isspace),
token.end());
while (std::getline(ss, token, ']')) {
// remove spaces and semicolons
token.erase(
std::remove_if(token.begin(), token.end(),
[](char c) { return std::isspace(c) || c == ';'; }),
token.end());
if (token.empty())
continue;
if (token.front() != '[' || token.back() != ']') {
if (token.front() != '[') {
throw RuntimeError("Each ROI must be enclosed in square brackets: "
"[xmin,xmax,ymin,ymax]");
}
token = token.substr(1, token.size() - 2); // remove brackets
token = token.substr(1, token.size() - 1); // remove brackets
std::vector<std::string> parts;
std::stringstream inner(token);
std::string num;
@@ -819,22 +822,28 @@ std::vector<defs::ROI> Caller::parseRoiVector(const std::string &input) {
parts.push_back(num);
}
if (parts.size() != 2 && parts.size() != 4) {
throw RuntimeError("ROI must have 2 or 4 comma-separated integers");
}
defs::ROI roi;
roi.xmin = StringTo<int>(parts[0]);
roi.xmax = StringTo<int>(parts[1]);
if (parts.size() == 4) {
roi.ymin = StringTo<int>(parts[2]);
roi.ymax = StringTo<int>(parts[3]);
}
auto roi = parseRoi(parts);
rois.emplace_back(roi);
}
return rois;
}
defs::ROI Caller::parseRoi(const std::vector<std::string> &parts) {
if (parts.size() != 2 && parts.size() != 4) {
throw RuntimeError(
"Could not parse ROI. A ROI must have 2 or 4 integers");
}
defs::ROI roi;
roi.xmin = StringTo<int>(parts[0]);
roi.xmax = StringTo<int>(parts[1]);
if (parts.size() == 4) {
roi.ymin = StringTo<int>(parts[2]);
roi.ymax = StringTo<int>(parts[3]);
}
return roi;
}
std::string Caller::ratecorr(int action) {
std::ostringstream os;
if (action == defs::HELP_ACTION) {

View File

@@ -1384,22 +1384,16 @@ 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(int module_id) const {
return pimpl->getRxROI(module_id);
}
// RxROIs can be set for all types except CTB. At multi level without gap pixels
void Detector::setRxROI(const std::vector<defs::ROI> &args) {
pimpl->setRxROI(args);
}
void Detector::clearRxROI() { pimpl->clearRxROI(); }
// File
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {

View File

@@ -535,7 +535,6 @@ void DetectorImpl::readFrameFromReceiver() {
bool quadEnable = false;
// to flip image
bool eiger = false;
std::array<int, 4> rxRoi{}; // TODO: get roi from json header
std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size());
@@ -732,7 +731,7 @@ void DetectorImpl::readFrameFromReceiver() {
thisData = new detectorData(currentProgress, currentFileName,
nDetActualPixelsX, nDetActualPixelsY,
callbackImage, imagesize, dynamicRange,
currentFileIndex, completeImage, rxRoi);
currentFileIndex, completeImage);
try {
dataReady(
thisData, currentFrameIndex,
@@ -1677,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();
}
@@ -1813,16 +1812,17 @@ void DetectorImpl::convertGlobalRoiToPortLevel(
clipped.xmin = std::max(userRoi.xmin, portRoi.xmin) - portRoi.xmin;
clipped.xmax = std::min(userRoi.xmax, portRoi.xmax) - portRoi.xmin;
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;
}
// Check if port ROI already exists for this port (from another user roi)
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;
}
@@ -1843,7 +1843,9 @@ 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);
@@ -1856,17 +1858,18 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
convertGlobalRoiToPortLevel(arg, moduleGlobalRoi, portRois);
}
}
modules[iModule]->setRxROI(portRois);
}
// metadata
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

@@ -2769,22 +2769,8 @@ int InferAction::rx_realudpsocksize() {
int InferAction::rx_roi() {
if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 2) {
return slsDetectorDefs::PUT_ACTION;
}
if (args.size() == 4) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
throw RuntimeError("sls_detector is disabled for command: rx_roi. Use "
"sls_detector_get or sls_detector_put");
}
int InferAction::rx_silent() {

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,34 +502,41 @@ 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
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, -1, -1; 25, 30, -1, -1]"}, -1, PUT));
"rx_roi", {"[5, 20, -1, -1]; 25, 30, -1, -1]"}, -1, PUT));
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, -1, -1]; [25, 30, -1, -1"}, -1, PUT));
// invalid roi, 4 parts expected
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, -1]; [25, 30, -1, -1]"}, -1, PUT));
"rx_roi", {"[5, 20, -1] [25, 30, -1, -1]"}, -1, PUT));
// overlapping rois
REQUIRE_THROWS(caller.call(
"rx_roi", {"[0, 10,-1, -1];[5, 15, -1, -1]"}, -1, PUT));
"rx_roi", {"[0, 10,-1, -1] [5, 15, -1, -1]"}, -1, PUT));
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");
// separated by semicolon with quotes is allowed (skips
// cmdParser)
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 +544,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,40 +596,47 @@ 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
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, 20, 30; 25, 30, 14, 15]"}, -1, PUT));
"rx_roi", {"[5, 20, 20, 30]; 25, 30, 14, 15]"}, -1, PUT));
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, 20, 30]; [25, 30, 14, 15"}, -1, PUT));
// invalid roi, 4 parts expected
REQUIRE_THROWS(caller.call(
"rx_roi", {"[5, 20, 20]; [25, 30, 14, 15]"}, -1, PUT));
"rx_roi", {"[5, 20, 20] [25, 30, 14, 15]"}, -1, PUT));
// overlapping rois
REQUIRE_THROWS(caller.call(
"rx_roi", {"[0, 10, 0, 10];[5, 15, 0, 10]"}, -1, PUT));
"rx_roi", {"[0, 10, 0, 10] [5, 15, 0, 10]"}, -1, PUT));
REQUIRE_THROWS(caller.call(
"rx_roi", {"[0, 10, 0, 10];[0, 10, 9, 11]"}, -1, PUT));
"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");
// separated by semicolon with quotes is allowed (skips
// cmdParser)
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 +644,53 @@ 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");
// separated by semicolon is allowed with quotes (skips
// cmdParser)
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 +698,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 +748,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 +784,6 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
}
}
TEST_CASE("rx_clearroi", "[.cmdcall]") {
Detector det;
Caller caller(&det);