mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-18 07:47:12 +02:00
wip to parse vector of rois at command line
This commit is contained in:
@ -21,6 +21,7 @@ class Caller {
|
|||||||
UdpDestination getUdpEntry();
|
UdpDestination getUdpEntry();
|
||||||
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
|
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
|
||||||
void WrongNumberOfParameters(size_t expected);
|
void WrongNumberOfParameters(size_t expected);
|
||||||
|
std::vector<defs::ROI> parseRoiVector(const std::string &input);
|
||||||
|
|
||||||
template <typename V> std::string OutStringHex(const V &value) {
|
template <typename V> std::string OutStringHex(const V &value) {
|
||||||
if (value.equal())
|
if (value.equal())
|
||||||
|
@ -1739,13 +1739,12 @@ readout:
|
|||||||
PUT:
|
PUT:
|
||||||
function: startDetectorReadout
|
function: startDetectorReadout
|
||||||
|
|
||||||
# TODO
|
rx_clearroi:
|
||||||
#rx_clearroi:
|
inherit_actions: EXECUTE_SET_COMMAND_NOID
|
||||||
# inherit_actions: EXECUTE_SET_COMMAND_NOID
|
help: "\n\tResets Region of interest in receiver. Default is all channels/pixels enabled."
|
||||||
# help: "\n\tResets Region of interest in receiver. Default is all channels/pixels enabled."
|
actions:
|
||||||
# actions:
|
PUT:
|
||||||
# PUT:
|
function: clearRxROI
|
||||||
# function: clearRxROI
|
|
||||||
|
|
||||||
################# EXECUTE_SET_COMMAND ########################
|
################# EXECUTE_SET_COMMAND ########################
|
||||||
start:
|
start:
|
||||||
@ -2593,18 +2592,13 @@ rx_zmqip:
|
|||||||
PUT:
|
PUT:
|
||||||
argc: -1
|
argc: -1
|
||||||
|
|
||||||
#TODO
|
rx_roi:
|
||||||
#rx_roi:
|
is_description: true
|
||||||
# is_description: true
|
actions:
|
||||||
# actions:
|
GET:
|
||||||
# GET:
|
argc: 0
|
||||||
# argc: 0
|
PUT:
|
||||||
# PUT:
|
argc: -1
|
||||||
# args:
|
|
||||||
# - argc: 2
|
|
||||||
# arg_types: [ int, int ]
|
|
||||||
# - argc: 4
|
|
||||||
# arg_types: [ int, int, int, int ]
|
|
||||||
|
|
||||||
ratecorr:
|
ratecorr:
|
||||||
is_description: true
|
is_description: true
|
||||||
|
@ -988,13 +988,12 @@ class Detector {
|
|||||||
std::vector<defs::ROI> getRxROI() const;
|
std::vector<defs::ROI> getRxROI() const;
|
||||||
|
|
||||||
/** only at multi module level without gap pixels */
|
/** only at multi module level without gap pixels */
|
||||||
void setRxROI(const std::vector<defs::ROI>& args);
|
void setRxROI(const std::vector<defs::ROI> &args);
|
||||||
|
|
||||||
void clearRxROI();
|
void clearRxROI();
|
||||||
|
|
||||||
int getNumberOfUdpPortsInRxROI() const;
|
int getNumberOfUdpPortsInRxROI() const;
|
||||||
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
/** @name File */
|
/** @name File */
|
||||||
|
@ -10594,7 +10594,7 @@ std::string Caller::rx_arping(int action) {
|
|||||||
|
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
std::string Caller::rx_clearroi(int action) {
|
std::string Caller::rx_clearroi(int action) {
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
@ -10637,7 +10637,7 @@ std::string Caller::rx_clearroi(int action) {
|
|||||||
|
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
std::string Caller::rx_dbitoffset(int action) {
|
std::string Caller::rx_dbitoffset(int action) {
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
@ -21,6 +21,7 @@ class Caller {
|
|||||||
UdpDestination getUdpEntry();
|
UdpDestination getUdpEntry();
|
||||||
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
|
int GetLevelAndInsertIntoArgs(std::string levelSeparatedCommand);
|
||||||
void WrongNumberOfParameters(size_t expected);
|
void WrongNumberOfParameters(size_t expected);
|
||||||
|
std::vector<defs::ROI> parseRoiVector(const std::string &input);
|
||||||
|
|
||||||
template <typename V> std::string OutStringHex(const V &value) {
|
template <typename V> std::string OutStringHex(const V &value) {
|
||||||
if (value.equal())
|
if (value.equal())
|
||||||
@ -233,7 +234,7 @@ class Caller {
|
|||||||
std::string runclk(int action);
|
std::string runclk(int action);
|
||||||
std::string runtime(int action);
|
std::string runtime(int action);
|
||||||
std::string rx_arping(int action);
|
std::string rx_arping(int action);
|
||||||
//std::string rx_clearroi(int action);
|
std::string rx_clearroi(int action);
|
||||||
std::string rx_dbitlist(int action);
|
std::string rx_dbitlist(int action);
|
||||||
std::string rx_dbitoffset(int action);
|
std::string rx_dbitoffset(int action);
|
||||||
std::string rx_dbitreorder(int action);
|
std::string rx_dbitreorder(int action);
|
||||||
@ -251,7 +252,7 @@ class Caller {
|
|||||||
std::string rx_padding(int action);
|
std::string rx_padding(int action);
|
||||||
std::string rx_printconfig(int action);
|
std::string rx_printconfig(int action);
|
||||||
std::string rx_realudpsocksize(int action);
|
std::string rx_realudpsocksize(int action);
|
||||||
//std::string rx_roi(int action);
|
std::string rx_roi(int action);
|
||||||
std::string rx_silent(int action);
|
std::string rx_silent(int action);
|
||||||
std::string rx_start(int action);
|
std::string rx_start(int action);
|
||||||
std::string rx_status(int action);
|
std::string rx_status(int action);
|
||||||
@ -580,7 +581,7 @@ class Caller {
|
|||||||
{"runclk", &Caller::runclk},
|
{"runclk", &Caller::runclk},
|
||||||
{"runtime", &Caller::runtime},
|
{"runtime", &Caller::runtime},
|
||||||
{"rx_arping", &Caller::rx_arping},
|
{"rx_arping", &Caller::rx_arping},
|
||||||
//{"rx_clearroi", &Caller::rx_clearroi},
|
{"rx_clearroi", &Caller::rx_clearroi},
|
||||||
{"rx_dbitlist", &Caller::rx_dbitlist},
|
{"rx_dbitlist", &Caller::rx_dbitlist},
|
||||||
{"rx_dbitoffset", &Caller::rx_dbitoffset},
|
{"rx_dbitoffset", &Caller::rx_dbitoffset},
|
||||||
{"rx_dbitreorder", &Caller::rx_dbitreorder},
|
{"rx_dbitreorder", &Caller::rx_dbitreorder},
|
||||||
@ -598,7 +599,7 @@ class Caller {
|
|||||||
{"rx_padding", &Caller::rx_padding},
|
{"rx_padding", &Caller::rx_padding},
|
||||||
{"rx_printconfig", &Caller::rx_printconfig},
|
{"rx_printconfig", &Caller::rx_printconfig},
|
||||||
{"rx_realudpsocksize", &Caller::rx_realudpsocksize},
|
{"rx_realudpsocksize", &Caller::rx_realudpsocksize},
|
||||||
//{"rx_roi", &Caller::rx_roi},
|
{"rx_roi", &Caller::rx_roi},
|
||||||
{"rx_silent", &Caller::rx_silent},
|
{"rx_silent", &Caller::rx_silent},
|
||||||
{"rx_start", &Caller::rx_start},
|
{"rx_start", &Caller::rx_start},
|
||||||
{"rx_status", &Caller::rx_status},
|
{"rx_status", &Caller::rx_status},
|
||||||
|
@ -719,50 +719,124 @@ std::string Caller::rx_zmqip(int action) {
|
|||||||
}
|
}
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
/* TODO
|
|
||||||
std::string Caller::rx_roi(int action) {
|
std::string Caller::rx_roi(int action) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
if (action == defs::HELP_ACTION) {
|
if (action == defs::HELP_ACTION) {
|
||||||
os << "[xmin] [xmax] [ymin] [ymax]\n\tRegion of interest in "
|
os << "[xmin] [xmax] [ymin] [ymax]\n\tRegion of interest in "
|
||||||
"receiver.\n\tOnly allowed at multi module level and without gap "
|
"receiver.\n\t"
|
||||||
|
<< "For a list of rois, use '[' and '];' to distinguish between "
|
||||||
|
"rois and use comma inside the square brackets.\n\t"
|
||||||
|
<< "For example: [0, 100, 0, 100];[200, 300, 0, 100] will set two "
|
||||||
|
"rois.\n\t"
|
||||||
|
<< "Only allowed at multi module level and without gap "
|
||||||
"pixels."
|
"pixels."
|
||||||
<< '\n';
|
<< '\n';
|
||||||
} else if (action == defs::GET_ACTION) {
|
} else if (action == defs::GET_ACTION) {
|
||||||
if (!args.empty()) {
|
if (!args.empty()) {
|
||||||
WrongNumberOfParameters(0);
|
WrongNumberOfParameters(0);
|
||||||
}
|
}
|
||||||
if (det_id == -1) {
|
if (det_id != -1) {
|
||||||
auto t = det->getRxROI();
|
throw RuntimeError("Cannot execute receiver ROI at module level");
|
||||||
os << t << '\n';
|
|
||||||
} else {
|
} else {
|
||||||
auto t = det->getIndividualRxROIs(std::vector<int>{det_id});
|
auto t = det->getRxROI();
|
||||||
os << t << '\n';
|
// 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';
|
||||||
}
|
}
|
||||||
} else if (action == defs::PUT_ACTION) {
|
} else if (action == defs::PUT_ACTION) {
|
||||||
defs::ROI t;
|
std::vector<defs::ROI> rois;
|
||||||
// 2 or 4 arguments
|
|
||||||
if (args.size() != 2 && args.size() != 4) {
|
// Support multiple args with bracketed ROIs, or single arg with
|
||||||
WrongNumberOfParameters(2);
|
// semicolon-separated vector
|
||||||
}
|
bool isVectorInput =
|
||||||
if (args.size() == 2 || args.size() == 4) {
|
std::all_of(args.begin(), args.end(), [](const std::string &a) {
|
||||||
|
return a.find('[') != std::string::npos &&
|
||||||
|
a.find(']') != std::string::npos;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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.xmin = StringTo<int>(args[0]);
|
||||||
t.xmax = StringTo<int>(args[1]);
|
t.xmax = StringTo<int>(args[1]);
|
||||||
|
if (args.size() == 4) {
|
||||||
|
t.ymin = StringTo<int>(args[2]);
|
||||||
|
t.ymax = StringTo<int>(args[3]);
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (args.size() == 4) {
|
|
||||||
t.ymin = StringTo<int>(args[2]);
|
|
||||||
t.ymax = StringTo<int>(args[3]);
|
|
||||||
}
|
|
||||||
// only multi level
|
// only multi level
|
||||||
if (det_id != -1) {
|
if (det_id != -1) {
|
||||||
throw RuntimeError("Cannot execute receiver ROI at module level");
|
throw RuntimeError("Cannot execute receiver ROI at module level");
|
||||||
}
|
}
|
||||||
det->setRxROI(t);
|
|
||||||
os << t << '\n';
|
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';
|
||||||
} else {
|
} else {
|
||||||
throw RuntimeError("Unknown action");
|
throw RuntimeError("Unknown action");
|
||||||
}
|
}
|
||||||
return os.str();
|
return os.str();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
std::vector<defs::ROI> Caller::parseRoiVector(const std::string &input) {
|
||||||
|
std::vector<defs::ROI> rois;
|
||||||
|
std::stringstream ss(input);
|
||||||
|
std::string token;
|
||||||
|
|
||||||
|
while (std::getline(ss, token, ';')) {
|
||||||
|
token.erase(std::remove_if(token.begin(), token.end(), ::isspace),
|
||||||
|
token.end());
|
||||||
|
if (token.empty())
|
||||||
|
continue;
|
||||||
|
if (token.front() != '[' || token.back() != ']') {
|
||||||
|
throw RuntimeError("Each ROI must be enclosed in square brackets: "
|
||||||
|
"[xmin,xmax,ymin,ymax]");
|
||||||
|
}
|
||||||
|
token = token.substr(1, token.size() - 2); // remove brackets
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
std::stringstream inner(token);
|
||||||
|
std::string num;
|
||||||
|
while (std::getline(inner, num, ',')) {
|
||||||
|
parts.push_back(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.size() != 4) {
|
||||||
|
throw RuntimeError("ROI must have 4 comma-separated integers");
|
||||||
|
}
|
||||||
|
|
||||||
|
defs::ROI roi;
|
||||||
|
roi.xmin = StringTo<int>(parts[0]);
|
||||||
|
roi.xmax = StringTo<int>(parts[1]);
|
||||||
|
roi.ymin = StringTo<int>(parts[2]);
|
||||||
|
roi.ymax = StringTo<int>(parts[3]);
|
||||||
|
rois.emplace_back(roi);
|
||||||
|
}
|
||||||
|
return rois;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Caller::ratecorr(int action) {
|
std::string Caller::ratecorr(int action) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
if (action == defs::HELP_ACTION) {
|
if (action == defs::HELP_ACTION) {
|
||||||
|
@ -1367,12 +1367,10 @@ void Detector::setRxArping(bool value, Positions pos) {
|
|||||||
pimpl->Parallel(&Module::setRxArping, pos, value);
|
pimpl->Parallel(&Module::setRxArping, pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<defs::ROI> Detector::getRxROI() const {
|
std::vector<defs::ROI> Detector::getRxROI() const { return pimpl->getRxROI(); }
|
||||||
return pimpl->getRxROI();
|
|
||||||
}
|
|
||||||
|
|
||||||
// RxROIs can be set for all types except CTB. At multi level without gap pixels
|
// RxROIs can be set for all types except CTB. At multi level without gap pixels
|
||||||
void Detector::setRxROI(const std::vector<defs::ROI>& args) {
|
void Detector::setRxROI(const std::vector<defs::ROI> &args) {
|
||||||
pimpl->setRxROI(args);
|
pimpl->setRxROI(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1380,7 +1378,6 @@ void Detector::clearRxROI() { pimpl->clearRxROI(); }
|
|||||||
|
|
||||||
int Detector::getNumberOfUdpPortsInRxROI() const {
|
int Detector::getNumberOfUdpPortsInRxROI() const {
|
||||||
return pimpl->getNumberOfUdpPortsInRxROI();
|
return pimpl->getNumberOfUdpPortsInRxROI();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// File
|
// File
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
namespace sls {
|
namespace sls {
|
||||||
|
|
||||||
|
|
||||||
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update)
|
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update)
|
||||||
: detectorIndex(detector_index), shm(detector_index, -1),
|
: detectorIndex(detector_index), shm(detector_index, -1),
|
||||||
ctb_shm(detector_index, -1, CtbConfig::shm_tag()) {
|
ctb_shm(detector_index, -1, CtbConfig::shm_tag()) {
|
||||||
@ -536,7 +535,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
|||||||
bool quadEnable = false;
|
bool quadEnable = false;
|
||||||
// to flip image
|
// to flip image
|
||||||
bool eiger = false;
|
bool eiger = false;
|
||||||
std::array<int, 4> rxRoi {};//TODO: get roi from json header
|
std::array<int, 4> rxRoi{}; // TODO: get roi from json header
|
||||||
|
|
||||||
std::vector<bool> runningList(zmqSocket.size());
|
std::vector<bool> runningList(zmqSocket.size());
|
||||||
std::vector<bool> connectList(zmqSocket.size());
|
std::vector<bool> connectList(zmqSocket.size());
|
||||||
@ -1703,44 +1702,53 @@ std::vector<defs::ROI> DetectorImpl::getRxROI() const {
|
|||||||
throw RuntimeError("No Modules added");
|
throw RuntimeError("No Modules added");
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::vector<defs::ROI>{};
|
// return std::vector<defs::ROI>{};
|
||||||
//TODO
|
return rxRoiTemp;
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DetectorImpl::roisOverlap(const defs::ROI& a, const defs::ROI& b) {
|
bool DetectorImpl::roisOverlap(const defs::ROI &a, const defs::ROI &b) {
|
||||||
return !(a.xmax < b.xmin || a.xmin > b.xmax ||
|
return !(a.xmax < b.xmin || a.xmin > b.xmax || a.ymax < b.ymin ||
|
||||||
a.ymax < b.ymin || a.ymin > b.ymax);
|
a.ymin > b.ymax);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::validateROIs(const std::vector<defs::ROI>& rois) {
|
void DetectorImpl::validateROIs(const std::vector<defs::ROI> &rois) {
|
||||||
for (size_t i = 0; i < rois.size(); ++i) {
|
for (size_t i = 0; i < rois.size(); ++i) {
|
||||||
const auto& roi = rois[i];
|
const auto &roi = rois[i];
|
||||||
|
|
||||||
if (roi.noRoi()) {
|
if (roi.noRoi()) {
|
||||||
throw RuntimeError("Invalid Roi of size 0. Roi: " + ToString(roi));
|
throw RuntimeError("Invalid Roi of size 0. Roi: " + ToString(roi));
|
||||||
}
|
}
|
||||||
if (roi.completeRoi()) {
|
if (roi.completeRoi()) {
|
||||||
throw RuntimeError("Did you mean the clear roi command (API: "
|
throw RuntimeError("Did you mean the clear roi command (API: "
|
||||||
"clearRxROI, cmd: rx_clearroi) Roi: " + ToString(roi) + "?");
|
"clearRxROI, cmd: rx_clearroi) Roi: " +
|
||||||
|
ToString(roi) + "?");
|
||||||
}
|
}
|
||||||
if (roi.xmin > roi.xmax || roi.ymin > roi.ymax) {
|
if (roi.xmin > roi.xmax || roi.ymin > roi.ymax) {
|
||||||
throw RuntimeError(
|
throw RuntimeError(
|
||||||
"Invalid Roi. xmin/ymin exceeds xmax/ymax. Roi: " + ToString(roi));
|
"Invalid Roi. xmin/ymin exceeds xmax/ymax. Roi: " +
|
||||||
|
ToString(roi));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roi.xmin < 0 || roi.xmax >= shm()->numberOfChannels.x) {
|
if (roi.xmin < 0 || roi.xmax >= shm()->numberOfChannels.x) {
|
||||||
throw RuntimeError("ROI x-dimension outside detector bounds. Roi: " + ToString(roi));
|
throw RuntimeError(
|
||||||
|
"ROI x-dimension outside detector bounds. Roi: " +
|
||||||
|
ToString(roi));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is2D = (modules[0]->getNumberOfChannels().y > 1 ? true : false);
|
bool is2D = (modules[0]->getNumberOfChannels().y > 1 ? true : false);
|
||||||
if (is2D) {
|
if (is2D) {
|
||||||
if (roi.ymin < 0 || roi.ymax >= shm()->numberOfChannels.y) {
|
if (roi.ymin < 0 || roi.ymax >= shm()->numberOfChannels.y) {
|
||||||
throw RuntimeError("ROI y-dimension outside detector bounds. Roi: " + ToString(roi));
|
throw RuntimeError(
|
||||||
|
"ROI y-dimension outside detector bounds. Roi: " +
|
||||||
|
ToString(roi));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((roi.ymin != -1 && roi.ymin != 0) || (roi.ymax != -1 && roi.ymax != 0)) {
|
if ((roi.ymin != -1 && roi.ymin != 0) ||
|
||||||
throw RuntimeError("Invalid Y range for 1D detector: should be -1. Roi: " + ToString(roi));
|
(roi.ymax != -1 && roi.ymax != 0)) {
|
||||||
|
throw RuntimeError(
|
||||||
|
"Invalid Y range for 1D detector: should be -1. Roi: " +
|
||||||
|
ToString(roi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1753,7 +1761,7 @@ void DetectorImpl::validateROIs(const std::vector<defs::ROI>& rois) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::setRxROI(const std::vector<defs::ROI>& args) {
|
void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
|
||||||
if (shm()->detType == CHIPTESTBOARD ||
|
if (shm()->detType == CHIPTESTBOARD ||
|
||||||
shm()->detType == defs::XILINX_CHIPTESTBOARD) {
|
shm()->detType == defs::XILINX_CHIPTESTBOARD) {
|
||||||
throw RuntimeError("RxRoi not implemented for this Detector");
|
throw RuntimeError("RxRoi not implemented for this Detector");
|
||||||
@ -1764,15 +1772,15 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI>& args) {
|
|||||||
|
|
||||||
validateROIs(args);
|
validateROIs(args);
|
||||||
|
|
||||||
//TODO
|
rxRoiTemp = args;
|
||||||
|
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::clearRxROI() {
|
void DetectorImpl::clearRxROI() { rxRoiTemp.clear(); }
|
||||||
;// TODO: clear roi
|
|
||||||
}
|
|
||||||
|
|
||||||
int DetectorImpl::getNumberOfUdpPortsInRxROI() const {
|
int DetectorImpl::getNumberOfUdpPortsInRxROI() const {
|
||||||
return 0;// TODO
|
return 0; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::getBadChannels(const std::string &fname,
|
void DetectorImpl::getBadChannels(const std::string &fname,
|
||||||
|
@ -302,7 +302,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
verifyUniqueRxHost(const std::vector<std::string> &names) const;
|
verifyUniqueRxHost(const std::vector<std::string> &names) const;
|
||||||
|
|
||||||
std::vector<defs::ROI> getRxROI() const;
|
std::vector<defs::ROI> getRxROI() const;
|
||||||
void setRxROI(const std::vector<defs::ROI>& args);
|
void setRxROI(const std::vector<defs::ROI> &args);
|
||||||
void clearRxROI();
|
void clearRxROI();
|
||||||
int getNumberOfUdpPortsInRxROI() const;
|
int getNumberOfUdpPortsInRxROI() const;
|
||||||
|
|
||||||
@ -427,8 +427,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
void verifyUniqueHost(
|
void verifyUniqueHost(
|
||||||
bool isDet, std::vector<std::pair<std::string, uint16_t>> &hosts) const;
|
bool isDet, std::vector<std::pair<std::string, uint16_t>> &hosts) const;
|
||||||
|
|
||||||
bool roisOverlap(const defs::ROI& a, const defs::ROI& b);
|
bool roisOverlap(const defs::ROI &a, const defs::ROI &b);
|
||||||
void validateROIs(const std::vector<defs::ROI>& rois);
|
void validateROIs(const std::vector<defs::ROI> &rois);
|
||||||
|
|
||||||
const int detectorIndex{0};
|
const int detectorIndex{0};
|
||||||
SharedMemory<sharedDetector> shm{0, -1};
|
SharedMemory<sharedDetector> shm{0, -1};
|
||||||
@ -457,6 +457,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
|
|
||||||
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
||||||
void *pCallbackArg{nullptr};
|
void *pCallbackArg{nullptr};
|
||||||
|
|
||||||
|
std::vector<defs::ROI> rxRoiTemp;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sls
|
} // namespace sls
|
@ -301,9 +301,9 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
|
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
|
||||||
bool getRxArping() const;
|
bool getRxArping() const;
|
||||||
void setRxArping(bool enable);
|
void setRxArping(bool enable);
|
||||||
//defs::ROI getRxROI() const;
|
// defs::ROI getRxROI() const;
|
||||||
//void setRxROI(const slsDetectorDefs::ROI arg);
|
// void setRxROI(const slsDetectorDefs::ROI arg);
|
||||||
//void setRxROIMetadata(const slsDetectorDefs::ROI arg);
|
// void setRxROIMetadata(const slsDetectorDefs::ROI arg);
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* *
|
* *
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
target_sources(tests PRIVATE
|
target_sources(tests PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-Roi.cpp
|
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-rx.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller-rx.cpp
|
||||||
|
@ -494,6 +494,42 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
|
|||||||
REQUIRE_THROWS(caller.call("rx_roi", {"-1", "-1"}, -1, PUT));
|
REQUIRE_THROWS(caller.call("rx_roi", {"-1", "-1"}, -1, PUT));
|
||||||
REQUIRE_THROWS(
|
REQUIRE_THROWS(
|
||||||
caller.call("rx_roi", {"10", "15", "25", "30"}, -1, PUT));
|
caller.call("rx_roi", {"10", "15", "25", "30"}, -1, PUT));
|
||||||
|
// vector of rois
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
caller.call("rx_roi", {"[5, 10, -1, -1]; [25, 20, -1, -1]"}, -1,
|
||||||
|
PUT, oss);
|
||||||
|
REQUIRE(oss.str() ==
|
||||||
|
"rx_roi [5, 10, -1, -1]; [25, 20, -1, -1]\n");
|
||||||
|
}
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[5, 20, -1, -1; 25, 30 -1, -1]"}, -1, PUT));
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[5, 20, -1]; [25, 30 -1, -1]"}, -1, PUT));
|
||||||
|
// separated by space is allowed
|
||||||
|
REQUIRE_NOTHROW(caller.call(
|
||||||
|
"rx_roi", {"[5, 10, -1, -1]", "[25, 28, -1, -1]"}, -1, PUT));
|
||||||
|
REQUIRE_NOTHROW(caller.call("rx_roi",
|
||||||
|
{"[0, 10, -1, -1];[20, 30, -1, -1];[9, "
|
||||||
|
"10, -1, -1];[40, 50, -1, -1]"},
|
||||||
|
-1, PUT));
|
||||||
|
// overlapping rois
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[0, 10,-1, -1];[5, 15, -1, -1]"}, 0, PUT));
|
||||||
|
// xmin > xmax
|
||||||
|
REQUIRE_THROWS(caller.call("rx_roi", {"[12, 8, -1, -1]"}, 0, PUT));
|
||||||
|
// outside detector bounds
|
||||||
|
REQUIRE_THROWS(
|
||||||
|
caller.call("rx_roi", {"[95, 105, -1, -1]"}, 0, PUT));
|
||||||
|
// module level not allowed
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[5, 10, -1, -1]; [25, 28, -1, -1]"}, 0, PUT));
|
||||||
|
// square brackets missing
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
// 2d
|
// 2d
|
||||||
else {
|
else {
|
||||||
@ -521,6 +557,39 @@ TEST_CASE("rx_roi", "[.cmdcall]") {
|
|||||||
}
|
}
|
||||||
REQUIRE_THROWS(
|
REQUIRE_THROWS(
|
||||||
caller.call("rx_roi", {"-1", "-1", "-1", "-1"}, -1, PUT));
|
caller.call("rx_roi", {"-1", "-1", "-1", "-1"}, -1, PUT));
|
||||||
|
// vector of rois
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
caller.call("rx_roi", {"[5, 10, 20, 30]; [25, 28, 14, 15]"}, -1,
|
||||||
|
PUT, oss);
|
||||||
|
REQUIRE(oss.str() ==
|
||||||
|
"rx_roi [5, 10, 20, 30];[25, 28, 14, 15]\n");
|
||||||
|
}
|
||||||
|
// separated by space is allowed
|
||||||
|
REQUIRE_NOTHROW(caller.call(
|
||||||
|
"rx_roi", {"[5, 10, 20, 30]", "[25, 28, 14, 15]"}, -1, PUT));
|
||||||
|
REQUIRE_NOTHROW(caller.call("rx_roi",
|
||||||
|
{"[0, 10, 0, 10];[20, 30, 0, 10];[0, "
|
||||||
|
"10, 20, 30];[40, 50, 0, 10]"},
|
||||||
|
-1, PUT));
|
||||||
|
// overlapping rois
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[0, 10, 0, 10];[5, 15, 0, 10]"}, 0, PUT));
|
||||||
|
// xmin > xmax
|
||||||
|
REQUIRE_THROWS(caller.call("rx_roi", {"[12, 8, 0, 10]"}, 0, PUT));
|
||||||
|
// ymin > ymax
|
||||||
|
REQUIRE_THROWS(caller.call("rx_roi", {"[0, 10, 20, 5]"}, 0, PUT));
|
||||||
|
// outside detector bounds
|
||||||
|
REQUIRE_THROWS(caller.call("rx_roi", {"[95, 105, 0, 10]"}, 0, PUT));
|
||||||
|
// module level not allowed
|
||||||
|
REQUIRE_THROWS(caller.call(
|
||||||
|
"rx_roi", {"[5, 10, 20, 30]; [25, 28, 14, 15]"}, 0, PUT));
|
||||||
|
// square brackets missing
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i != det.size(); ++i) {
|
for (int i = 0; i != det.size(); ++i) {
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
#include "catch.hpp"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "DetectorImpl.h"
|
|
||||||
#include "sls/Detector.h"
|
|
||||||
#include "Module.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace sls {
|
|
||||||
|
|
||||||
TEST_CASE("ROI validation") {
|
|
||||||
DetectorImpl det(0, false, false);
|
|
||||||
det.addTestModule(slsDetectorDefs::JUNGFRAU);
|
|
||||||
std::cout << "size:"<< det.size() << std::endl;
|
|
||||||
DetectorImpl detector(0, false, false);
|
|
||||||
|
|
||||||
SECTION("Valid non-overlapping ROIs") {
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{0, 10, 0, 10},
|
|
||||||
{20, 30, 0, 10},
|
|
||||||
{0, 10, 20, 30},
|
|
||||||
{40, 50, 0, 10}
|
|
||||||
};
|
|
||||||
REQUIRE_NOTHROW(DetectorImplTestHelper::testValidateRois(detector, rois));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Overlapping ROIs should throw") {
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{0, 10, 0, 10},
|
|
||||||
{5, 15, 0, 10}
|
|
||||||
};
|
|
||||||
REQUIRE_THROWS_AS(DetectorImplTestHelper::testValidateRois(detector, rois),
|
|
||||||
sls::RuntimeError);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Invalid ROI (xmin > xmax)") {
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{12, 8, 0, 10}
|
|
||||||
};
|
|
||||||
REQUIRE_THROWS_AS(DetectorImplTestHelper::testValidateRois(detector, rois),
|
|
||||||
sls::RuntimeError);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Invalid ROI (ymin > ymax)") {
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{0, 10, 20, 5}
|
|
||||||
};
|
|
||||||
REQUIRE_THROWS_AS(DetectorImplTestHelper::testValidateRois(detector, rois),
|
|
||||||
sls::RuntimeError);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Invalid ROI (outside detector bounds)") {
|
|
||||||
// Assuming detector has 100x100 dimensions
|
|
||||||
detector.setNumberOfChannels({100, 100});
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{95, 105, 0, 10} // xmax out of bounds
|
|
||||||
};
|
|
||||||
REQUIRE_THROWS_AS(DetectorImplTestHelper::testValidateRois(detector, rois),
|
|
||||||
sls::RuntimeError);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Valid ROI for 1D detector") {
|
|
||||||
detector.setNumberOfChannels({100, 1});
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{10, 20, -1, -1}
|
|
||||||
};
|
|
||||||
REQUIRE_NOTHROW(DetectorImplTestHelper::testValidateRois(detector, rois));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Invalid Y for 1D detector") {
|
|
||||||
detector.setNumberOfChannels({100, 1});
|
|
||||||
std::vector<slsDetectorDefs::ROI> rois = {
|
|
||||||
{10, 20, 0, 10} // Y should be -1 for 1D
|
|
||||||
};
|
|
||||||
REQUIRE_THROWS_AS(DetectorImplTestHelper::testValidateRois(detector, rois),
|
|
||||||
sls::RuntimeError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace sls
|
|
@ -348,5 +348,23 @@ std::vector<T> StringTo(const std::vector<std::string> &strings) {
|
|||||||
result.push_back(StringTo<T>(s));
|
result.push_back(StringTo<T>(s));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
template <typename T>
|
||||||
|
std::string ToString(const std::vector<T> &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 <typename T>
|
||||||
|
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
|
||||||
|
return os << ToString(v);
|
||||||
|
}*/
|
||||||
|
|
||||||
} // namespace sls
|
} // namespace sls
|
||||||
|
Reference in New Issue
Block a user