mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-11 12:27:14 +02:00
Rx roi (#428)
* roi structure expanded to have ymin and ymax * compile with 'detector roi' * wip * wip, rx_roi, rx_clearroi * wip rxroi * rxroi wip * wip rxroi * merge fix * wip * rx_roi works, impl wip, test * tests in, impl left * wip, rxroi impl * wip, rxroi impl * wip * setrx_Roi works, getrx_roi, wip * rx_roi impl done * wip, rxroi * wip, getrx_roi rxr ports * fix ports * wip * wip * fix positions on server side * wip * numports wip * wip * jungfrau top inner interface row increment * x, y detpos, wip * removed eiger row indices flipping in gui (bottom flipping maintained) * wip * wip, jungfrau numinterfaces2 * jungfrau virtual works * eiger, jungfrau, g2 virtual server works * eiger positions fix, wip * binaries in * minor printout * binaries in * merge fix * merge fix * removing getposition * setrxroi wip * set upto port * get messed, wip * roi multi to module works, wip * wip * roi dont return -1 * added rxroi metadata in master file * added rxroifromshm, not yet in detector * rx roi in gui with box, also for gap pixels (gappixels for jungfrau mess) * fix for segfault in gui with detaching roi box in gui * wip * m3 gui: slave timing modes should be discarded when squashing * fixed m3 virtual data, and fixed counters in gui asthetics * m3 roi works * wip, g2 * wip * handling g225um boards, and showing roi for gainplot as well * udpate python functions * fix for 1d and a2d roi written * fixed actual roi written to file * no virtual hdf5 when handling rx roi * test * minor * binarie in
This commit is contained in:
@ -899,6 +899,16 @@ class Detector {
|
||||
* every minute. Useful in 10G mode. */
|
||||
void setRxArping(bool value, Positions pos = {});
|
||||
|
||||
/** at module level */
|
||||
Result<defs::ROI> getIndividualRxROIs(Positions pos) const;
|
||||
|
||||
defs::ROI getRxROI() const;
|
||||
|
||||
/** only at multi module level without gap pixels */
|
||||
void setRxROI(const defs::ROI value);
|
||||
|
||||
void clearRxROI();
|
||||
|
||||
///@}
|
||||
|
||||
/** @name File */
|
||||
|
@ -9,27 +9,12 @@
|
||||
*/
|
||||
class detectorData {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param progress progress index
|
||||
* @param fname file name prefix
|
||||
* @param x number of detector channels (1D detector) or dimension in x (2D
|
||||
* detector)
|
||||
* @param y dimension in y (2D detector)
|
||||
* @param d pointer to data in char* format
|
||||
* @param dbytes number of bytes of image pointed to by cval pointer
|
||||
* @param dr dynamic range or bits per pixel
|
||||
* @param fIndex file index
|
||||
* @param complete true if complete image, else missing packets
|
||||
*/
|
||||
detectorData(double progress, std::string fname, int x, int y, char *d,
|
||||
int dbytes, int dr, uint64_t fIndex, bool complete)
|
||||
: progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x),
|
||||
ny(y), data(d), databytes(dbytes), dynamicRange(dr),
|
||||
completeImage(complete){};
|
||||
detectorData(double progressIndex, std::string fileName, int nx, int ny, char *data, int databytes, int dynamicRange, uint64_t fileIndex, bool completeImage)
|
||||
: progressIndex(progressIndex), fileName(fileName), fileIndex(fileIndex), nx(nx), ny(ny), data(data), 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) {};
|
||||
/**
|
||||
* Destructor
|
||||
* data has to be deleted by caller
|
||||
*/
|
||||
~detectorData(){};
|
||||
@ -60,8 +45,9 @@ class detectorData {
|
||||
uint64_t fileIndex;
|
||||
int nx;
|
||||
int ny;
|
||||
char *data;
|
||||
char *data{nullptr};
|
||||
int databytes;
|
||||
int dynamicRange;
|
||||
bool completeImage;
|
||||
std::array<int,4> rxRoi{{-1, -1, -1, -1}};
|
||||
};
|
||||
|
@ -354,7 +354,7 @@ std::string CmdProxy::DetectorSize(int action) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getDetectorSize();
|
||||
os << "[" << t.x << ", " << t.y << "]\n";
|
||||
os << t << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
@ -1056,7 +1056,7 @@ std::string CmdProxy::TemperatureValues(int action) {
|
||||
std::string CmdProxy::Dac(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
|
||||
|
||||
if (action == defs::HELP_ACTION) {
|
||||
if (args.size() == 0) {
|
||||
os << GetHelpDac(std::to_string(0)) << '\n';
|
||||
@ -1082,7 +1082,7 @@ std::string CmdProxy::Dac(int action) {
|
||||
WrongNumberOfParameters(1); // This prints slightly wrong
|
||||
|
||||
defs::dacIndex dacIndex{};
|
||||
//TODO! Remove if
|
||||
// TODO! Remove if
|
||||
if (type == defs::CHIPTESTBOARD && !is_int(args[0])) {
|
||||
dacIndex = det->getDacIndex(args[0]);
|
||||
} else {
|
||||
@ -1152,7 +1152,8 @@ std::string CmdProxy::DacList(const int action) {
|
||||
"names. Cannot change them.");
|
||||
}
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError("Cannot configure dacnames at module level");
|
||||
throw sls::RuntimeError(
|
||||
"Cannot configure dacnames at module level");
|
||||
}
|
||||
if (args.size() != 18) {
|
||||
WrongNumberOfParameters(18);
|
||||
@ -1646,6 +1647,51 @@ std::string CmdProxy::ReceiverHostname(int action) {
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::Rx_ROI(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[xmin] [xmax] [ymin] [ymax]\n\tRegion of interest in "
|
||||
"receiver.\n\tOnly allowed at multi module level and without gap pixels."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
if (det_id == -1) {
|
||||
auto t = det->getRxROI();
|
||||
os << t << '\n';
|
||||
} else {
|
||||
auto t = det->getIndividualRxROIs(std::vector<int>{det_id});
|
||||
os << t << '\n';
|
||||
}
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
defs::ROI t;
|
||||
// 2 or 4 arguments
|
||||
if (args.size() != 2 && args.size() != 4) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
if (args.size() == 2 || args.size() == 4) {
|
||||
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]);
|
||||
}
|
||||
// only multi level
|
||||
if (det_id != -1) {
|
||||
throw RuntimeError("Cannot execute receiver ROI at module level");
|
||||
}
|
||||
det->setRxROI(t);
|
||||
os << t << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/* File */
|
||||
|
||||
/* ZMQ Streaming Parameters (Receiver<->Client) */
|
||||
@ -1898,9 +1944,7 @@ std::string CmdProxy::ROI(int action) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getROI(std::vector<int>{det_id});
|
||||
for (auto &it : t) {
|
||||
os << '[' << it.xmin << ", " << it.xmax << "] \n";
|
||||
}
|
||||
os << t << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (det_id == -1 && det->size() > 1) {
|
||||
throw sls::RuntimeError("Cannot execute ROI at multi module level");
|
||||
@ -1910,28 +1954,7 @@ std::string CmdProxy::ROI(int action) {
|
||||
}
|
||||
defs::ROI t(StringTo<int>(args[0]), StringTo<int>(args[1]));
|
||||
det->setROI(t, det_id);
|
||||
os << '[' << t.xmin << ", " << t.xmax << "]\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::ClearROI(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "\n\t[Gotthard] Resets Region of interest in detector. All "
|
||||
"channels enabled. Default is all channels enabled."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
det->clearROI(std::vector<int>{det_id});
|
||||
os << "[-1, -1]\n";
|
||||
os << t << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
@ -2101,9 +2124,8 @@ std::string CmdProxy::VetoStreaming(int action) {
|
||||
os << "[none|lll|10gbe|...]\n\t[Gotthard2] Enable or disable the 2 "
|
||||
"veto streaming interfaces available. Can include more than one "
|
||||
"interface. \n\tDefault: none. lll (low latency link) is the "
|
||||
"default "
|
||||
"interface to work with. \n\t10GbE is for debugging and also "
|
||||
"enables second interface in receiver for listening to veto "
|
||||
"default interface to work with. \n\t10GbE is for debugging and "
|
||||
"also enables second interface in receiver for listening to veto "
|
||||
"packets (writes a separate file if writing enabled). Also "
|
||||
"restarts client and receiver zmq sockets if zmq streaming "
|
||||
"enabled."
|
||||
@ -2294,9 +2316,9 @@ std::string CmdProxy::GateDelay(int action) {
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
if (cmd == "gatedelay") {
|
||||
os << "[duration] [(optional unit) "
|
||||
"ns|us|ms|s]\n\t[Mythen3] Gate Delay of all gate signals in "
|
||||
"auto and trigger mode (internal gating)."
|
||||
os << "[duration] [(optional unit) ns|us|ms|s]\n\t[Mythen3] Gate "
|
||||
"Delay of all gate signals in auto and trigger mode "
|
||||
"(internal gating)."
|
||||
<< '\n';
|
||||
} else if (cmd == "gatedelay1") {
|
||||
os << "[n_value]\n\t[Mythen3] Gate Delay of gate signal 1 in auto "
|
||||
@ -2807,11 +2829,11 @@ std::string CmdProxy::AdditionalJsonHeader(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[key1] [value1] [key2] [value2]...[keyn] [valuen]"
|
||||
"\n\tAdditional json header to be streamed out from receiver via "
|
||||
"zmq. Default is empty. Max 20 characters for each key/value. "
|
||||
"Use only if to be processed by an intermediate user process "
|
||||
"listening to receiver zmq packets. Empty value deletes header. "
|
||||
os << "[key1] [value1] [key2] [value2]...[keyn] [valuen]\n\tAdditional "
|
||||
"json header to be streamed out from receiver via zmq. Default "
|
||||
"is empty. Max 20 characters for each key/value. Use only if to "
|
||||
"be processed by an intermediate user process listening to "
|
||||
"receiver zmq packets. Empty value deletes header. "
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (!args.empty()) {
|
||||
@ -2921,10 +2943,10 @@ std::string CmdProxy::UpdateDetectorServer(int action) {
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[server_name with full "
|
||||
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Copies detector server via TCP (without tftp). Makes "
|
||||
"a symbolic link with a shorter name (without vx.x.x). Then, "
|
||||
"detector controller reboots (except "
|
||||
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3][Gotthard2] "
|
||||
"Copies detector server via TCP (without tftp). Makes a symbolic "
|
||||
"link with a shorter name (without vx.x.x). Then, detector "
|
||||
"controller reboots (except "
|
||||
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
||||
"to the link, which is effective after a reboot."
|
||||
<< '\n';
|
||||
@ -2947,11 +2969,9 @@ std::string CmdProxy::UpdateKernel(int action) {
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[kernel_name with full "
|
||||
"path]\n\t[Jungfrau][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Advanced Command!! You could damage the detector. "
|
||||
"Please use"
|
||||
" with caution.\n\tUpdates the kernel image. Then, detector "
|
||||
"controller "
|
||||
"path]\n\t[Jungfrau][Ctb][Moench][Mythen3][Gotthard2] Advanced "
|
||||
"Command!! You could damage the detector. Please use with "
|
||||
"caution.\n\tUpdates the kernel image. Then, detector controller "
|
||||
"reboots with new kernel."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
@ -2972,16 +2992,15 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "\n\tWithout tftp: [server_name (incl fullpath)] "
|
||||
"[fname.pof (incl full path)] "
|
||||
"This does not use tftp."
|
||||
"\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
|
||||
"firmware, detector server, deletes old server, creates the symbolic link and then "
|
||||
"reboots detector controller. \n\t\t[Mythen3][Gotthard2] will "
|
||||
"require a script to start up the shorter named server link at "
|
||||
"start up. \n\t\tserver_name is full path name of detector server "
|
||||
"binary"
|
||||
"\n\t\tfname is full path of programming file"
|
||||
os << "\n\tWithout tftp: [server_name (incl fullpath)] [fname.pof "
|
||||
"(incl full path)] This does not use "
|
||||
"tftp.\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
|
||||
"firmware, detector server, deletes old server, creates the "
|
||||
"symbolic link and then reboots detector controller. "
|
||||
"\n\t\t[Mythen3][Gotthard2] will require a script to start up "
|
||||
"the shorter named server link at start up. \n\t\tserver_name is "
|
||||
"full path name of detector server binary\n\t\tfname is full "
|
||||
"path of programming file"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
@ -2989,14 +3008,13 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
|
||||
int fpos = args.size() - 1;
|
||||
if (args[fpos].find(".pof") == std::string::npos &&
|
||||
args[fpos].find(".rbf") == std::string::npos) {
|
||||
throw sls::RuntimeError("Programming file must be a pof/rbf file.");
|
||||
}
|
||||
det->updateFirmwareAndServer(args[0], args[1],
|
||||
std::vector<int>{det_id});
|
||||
std::vector<int>{det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
@ -3039,8 +3057,7 @@ std::string CmdProxy::AdcRegister(int action) {
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[address] [value]\n\t[Jungfrau][Ctb][Moench][Gotthard] Writes "
|
||||
"to an adc "
|
||||
"register in hex. Advanced user Function!"
|
||||
"to an adc register in hex. Advanced user Function!"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get.");
|
||||
|
@ -743,11 +743,10 @@ class CmdProxy {
|
||||
|
||||
/* Pattern */
|
||||
/* Moench */
|
||||
|
||||
|
||||
/* Advanced */
|
||||
{"copydetectorserver", "updatedetectorserver"},
|
||||
|
||||
|
||||
/* Insignificant */
|
||||
{"nframes", "framecounter"},
|
||||
{"now", "runtime"},
|
||||
@ -910,6 +909,8 @@ class CmdProxy {
|
||||
{"rx_lastclient", &CmdProxy::rx_lastclient},
|
||||
{"rx_threads", &CmdProxy::rx_threads},
|
||||
{"rx_arping", &CmdProxy::rx_arping},
|
||||
{"rx_roi", &CmdProxy::Rx_ROI},
|
||||
{"rx_clearroi", &CmdProxy::rx_clearroi},
|
||||
|
||||
/* File */
|
||||
{"fformat", &CmdProxy::fformat},
|
||||
@ -965,7 +966,7 @@ class CmdProxy {
|
||||
|
||||
/* Gotthard Specific */
|
||||
{"roi", &CmdProxy::ROI},
|
||||
{"clearroi", &CmdProxy::ClearROI},
|
||||
{"clearroi", &CmdProxy::clearroi},
|
||||
{"exptimel", &CmdProxy::exptimel},
|
||||
|
||||
/* Gotthard2 Specific */
|
||||
@ -1150,6 +1151,7 @@ class CmdProxy {
|
||||
std::string UDPDestinationIP2(int action);
|
||||
/* Receiver Config */
|
||||
std::string ReceiverHostname(int action);
|
||||
std::string Rx_ROI(int action);
|
||||
/* File */
|
||||
/* ZMQ Streaming Parameters (Receiver<->Client) */
|
||||
std::string ZMQHWM(int action);
|
||||
@ -1164,7 +1166,6 @@ class CmdProxy {
|
||||
std::string TemperatureEvent(int action);
|
||||
/* Gotthard Specific */
|
||||
std::string ROI(int action);
|
||||
std::string ClearROI(int action);
|
||||
/* Gotthard2 Specific */
|
||||
std::string InjectChannel(int action);
|
||||
std::string VetoPhoton(int action);
|
||||
@ -1766,6 +1767,11 @@ class CmdProxy {
|
||||
"the interface it is "
|
||||
"listening to every minute. Useful in 10G mode.");
|
||||
|
||||
EXECUTE_SET_COMMAND_NOID(
|
||||
rx_clearroi, clearRxROI,
|
||||
"Resets Region of interest in receiver. Default is all "
|
||||
"channels/pixels enabled.");
|
||||
|
||||
/* File */
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
@ -2001,6 +2007,10 @@ class CmdProxy {
|
||||
"[(optional unit) ns|us|ms|s]\n\t[Gotthard] Exposure time "
|
||||
"left for current frame. ");
|
||||
|
||||
EXECUTE_SET_COMMAND(clearroi, clearROI,
|
||||
"[Gotthard] Resets Region of interest in detector. All "
|
||||
"channels enabled. Default is all channels enabled.");
|
||||
|
||||
/* Gotthard2 Specific */
|
||||
INTEGER_COMMAND_SET_NOID_GET_ID(
|
||||
bursts, getNumberOfBursts, setNumberOfBursts, StringTo<int64_t>,
|
||||
|
@ -38,7 +38,7 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
|
||||
|
||||
if (detectorShm.exists()) {
|
||||
detectorShm.openSharedMemory(false);
|
||||
numDetectors = detectorShm()->numberOfModules;
|
||||
numDetectors = detectorShm()->totalNumberOfModules;
|
||||
detectorShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
@ -1211,6 +1211,16 @@ void Detector::setRxArping(bool value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setRxArping, pos, value);
|
||||
}
|
||||
|
||||
Result<defs::ROI> Detector::getIndividualRxROIs(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getRxROI, pos);
|
||||
}
|
||||
|
||||
defs::ROI Detector::getRxROI() const { return pimpl->getRxROI(); }
|
||||
|
||||
void Detector::setRxROI(const defs::ROI value) { pimpl->setRxROI(value); }
|
||||
|
||||
void Detector::clearRxROI() { pimpl->clearRxROI(); }
|
||||
|
||||
// File
|
||||
|
||||
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
|
||||
@ -1777,7 +1787,7 @@ Detector::getVetoAlgorithm(const defs::streamingInterface interface,
|
||||
void Detector::setVetoAlgorithm(const defs::vetoAlgorithm alg,
|
||||
defs::streamingInterface interface,
|
||||
Positions pos) {
|
||||
LOG(logINFOBLUE) << "alg:" << ToString(alg)
|
||||
LOG(logDEBUG) << "alg:" << ToString(alg)
|
||||
<< " interface:" << ToString(interface);
|
||||
pimpl->Parallel(&Module::setVetoAlgorithm, pos, alg, interface);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
|
||||
|
||||
if (detectorShm.exists()) {
|
||||
detectorShm.openSharedMemory(false);
|
||||
numModules = detectorShm()->numberOfModules;
|
||||
numModules = detectorShm()->totalNumberOfModules;
|
||||
detectorShm.removeSharedMemory();
|
||||
}
|
||||
|
||||
@ -161,10 +161,10 @@ void DetectorImpl::initSharedMemory(bool verify) {
|
||||
|
||||
void DetectorImpl::initializeDetectorStructure() {
|
||||
shm()->shmversion = DETECTOR_SHMVERSION;
|
||||
shm()->numberOfModules = 0;
|
||||
shm()->totalNumberOfModules = 0;
|
||||
shm()->detType = GENERIC;
|
||||
shm()->numberOfModule.x = 0;
|
||||
shm()->numberOfModule.y = 0;
|
||||
shm()->numberOfModules.x = 0;
|
||||
shm()->numberOfModules.y = 0;
|
||||
shm()->numberOfChannels.x = 0;
|
||||
shm()->numberOfChannels.y = 0;
|
||||
shm()->acquiringFlag = false;
|
||||
@ -172,6 +172,10 @@ void DetectorImpl::initializeDetectorStructure() {
|
||||
shm()->gapPixels = false;
|
||||
// zmqlib default
|
||||
shm()->zmqHwm = -1;
|
||||
shm()->rx_roi.xmin = -1;
|
||||
shm()->rx_roi.xmax = -1;
|
||||
shm()->rx_roi.ymin = -1;
|
||||
shm()->rx_roi.ymax = -1;
|
||||
}
|
||||
|
||||
void DetectorImpl::initializeMembers(bool verify) {
|
||||
@ -179,7 +183,7 @@ void DetectorImpl::initializeMembers(bool verify) {
|
||||
zmqSocket.clear();
|
||||
|
||||
// get objects from single det shared memory (open)
|
||||
for (int i = 0; i < shm()->numberOfModules; i++) {
|
||||
for (int i = 0; i < shm()->totalNumberOfModules; i++) {
|
||||
try {
|
||||
modules.push_back(
|
||||
sls::make_unique<Module>(detectorIndex, i, verify));
|
||||
@ -246,7 +250,7 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
|
||||
|
||||
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
|
||||
// this check is there only to allow the previous detsizechan command
|
||||
if (shm()->numberOfModules != 0) {
|
||||
if (shm()->totalNumberOfModules != 0) {
|
||||
LOG(logWARNING) << "There are already module(s) in shared memory."
|
||||
"Freeing Shared memory now.";
|
||||
bool initialChecks = shm()->initialChecks;
|
||||
@ -305,7 +309,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
|
||||
auto pos = modules.size();
|
||||
modules.emplace_back(
|
||||
sls::make_unique<Module>(type, detectorIndex, pos, false));
|
||||
shm()->numberOfModules = modules.size();
|
||||
shm()->totalNumberOfModules = modules.size();
|
||||
modules[pos]->setControlPort(port);
|
||||
modules[pos]->setStopPort(port + 1);
|
||||
modules[pos]->setHostname(host, shm()->initialChecks);
|
||||
@ -328,9 +332,8 @@ void DetectorImpl::addModule(const std::string &hostname) {
|
||||
void DetectorImpl::updateDetectorSize() {
|
||||
LOG(logDEBUG) << "Updating Detector Size: " << size();
|
||||
|
||||
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels();
|
||||
|
||||
if (det_size.x == 0 || det_size.y == 0) {
|
||||
const slsDetectorDefs::xy modSize = modules[0]->getNumberOfChannels();
|
||||
if (modSize.x == 0 || modSize.y == 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Module size for x or y dimensions is 0. Unable to proceed in "
|
||||
"updating detector size. ");
|
||||
@ -338,39 +341,39 @@ void DetectorImpl::updateDetectorSize() {
|
||||
|
||||
int maxx = shm()->numberOfChannels.x;
|
||||
int maxy = shm()->numberOfChannels.y;
|
||||
int ndetx = 0, ndety = 0;
|
||||
int nModx = 0, nMody = 0;
|
||||
// 1d, add modules along x axis
|
||||
if (det_size.y == 1) {
|
||||
if (modSize.y == 1) {
|
||||
if (maxx == 0) {
|
||||
maxx = det_size.x * size();
|
||||
maxx = modSize.x * size();
|
||||
}
|
||||
ndetx = maxx / det_size.x;
|
||||
ndety = size() / ndetx;
|
||||
if ((maxx % det_size.x) > 0) {
|
||||
++ndety;
|
||||
nModx = maxx / modSize.x;
|
||||
nMody = size() / nModx;
|
||||
if ((maxx % modSize.x) > 0) {
|
||||
++nMody;
|
||||
}
|
||||
}
|
||||
// 2d, add modules along y axis (due to eiger top/bottom)
|
||||
else {
|
||||
if (maxy == 0) {
|
||||
maxy = det_size.y * size();
|
||||
maxy = modSize.y * size();
|
||||
}
|
||||
ndety = maxy / det_size.y;
|
||||
ndetx = size() / ndety;
|
||||
if ((maxy % det_size.y) > 0) {
|
||||
++ndetx;
|
||||
nMody = maxy / modSize.y;
|
||||
nModx = size() / nMody;
|
||||
if ((maxy % modSize.y) > 0) {
|
||||
++nModx;
|
||||
}
|
||||
}
|
||||
|
||||
shm()->numberOfModule.x = ndetx;
|
||||
shm()->numberOfModule.y = ndety;
|
||||
shm()->numberOfChannels.x = det_size.x * ndetx;
|
||||
shm()->numberOfChannels.y = det_size.y * ndety;
|
||||
shm()->numberOfModules.x = nModx;
|
||||
shm()->numberOfModules.y = nMody;
|
||||
shm()->numberOfChannels.x = modSize.x * nModx;
|
||||
shm()->numberOfChannels.y = modSize.y * nMody;
|
||||
|
||||
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
|
||||
<< shm()->numberOfModule.x
|
||||
<< shm()->numberOfModules.x
|
||||
<< "\n\tNumber of Modules in Y direction:"
|
||||
<< shm()->numberOfModule.y
|
||||
<< shm()->numberOfModules.y
|
||||
<< "\n\tNumber of Channels in X direction:"
|
||||
<< shm()->numberOfChannels.x
|
||||
<< "\n\tNumber of Channels in Y direction:"
|
||||
@ -378,7 +381,7 @@ void DetectorImpl::updateDetectorSize() {
|
||||
|
||||
for (auto &module : modules) {
|
||||
if (module->getUpdateMode() == 0) {
|
||||
module->updateNumberOfModule(shm()->numberOfModule);
|
||||
module->updateNumberOfModule(shm()->numberOfModules);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -386,7 +389,7 @@ void DetectorImpl::updateDetectorSize() {
|
||||
int DetectorImpl::size() const { return modules.size(); }
|
||||
|
||||
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
|
||||
return shm()->numberOfModule;
|
||||
return shm()->numberOfModules;
|
||||
}
|
||||
|
||||
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
|
||||
@ -412,7 +415,7 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
|
||||
if (size() && modules[0]->getQuad()) {
|
||||
break;
|
||||
}
|
||||
if (shm()->numberOfModule.y % 2 != 0) {
|
||||
if (shm()->numberOfModules.y % 2 != 0) {
|
||||
throw RuntimeError("Gap pixels can only be used "
|
||||
"for full modules.");
|
||||
}
|
||||
@ -495,6 +498,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
bool quadEnable = false;
|
||||
// to flip image
|
||||
bool eiger = false;
|
||||
std::array<int, 4> rxRoi = shm()->rx_roi.getIntArray();
|
||||
|
||||
std::vector<bool> runningList(zmqSocket.size());
|
||||
std::vector<bool> connectList(zmqSocket.size());
|
||||
@ -571,7 +575,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
// shape
|
||||
nPixelsX = zHeader.npixelsx;
|
||||
nPixelsY = zHeader.npixelsy;
|
||||
// module shape (port)
|
||||
// port geometry
|
||||
nX = zHeader.ndetx;
|
||||
nY = zHeader.ndety;
|
||||
nDetPixelsX = nX * nPixelsX;
|
||||
@ -668,6 +672,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
<< "\n\t databytes: " << multisize
|
||||
<< "\n\t dynamicRange: " << dynamicRange;
|
||||
|
||||
|
||||
// send data to callback
|
||||
if (data) {
|
||||
char *callbackImage = multiframe.get();
|
||||
@ -691,7 +696,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
thisData = new detectorData(currentProgress, currentFileName,
|
||||
nDetActualPixelsX, nDetActualPixelsY,
|
||||
callbackImage, imagesize, dynamicRange,
|
||||
currentFileIndex, completeImage);
|
||||
currentFileIndex, completeImage, rxRoi);
|
||||
try {
|
||||
dataReady(
|
||||
thisData, currentFrameIndex,
|
||||
@ -1094,9 +1099,6 @@ int DetectorImpl::acquire() {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// We need this to handle Mythen3 synchronization
|
||||
auto detector_type = Parallel(&Module::getDetectorType, {}).squash();
|
||||
|
||||
try {
|
||||
struct timespec begin, end;
|
||||
clock_gettime(CLOCK_REALTIME, &begin);
|
||||
@ -1174,6 +1176,7 @@ int DetectorImpl::acquire() {
|
||||
}
|
||||
|
||||
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
|
||||
// handle Mythen3 synchronization
|
||||
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
|
||||
std::vector<int> master;
|
||||
std::vector<int> slaves;
|
||||
@ -1425,6 +1428,218 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue,
|
||||
Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett);
|
||||
}
|
||||
|
||||
defs::xy DetectorImpl::getPortGeometry() const {
|
||||
defs::xy portGeometry(1, 1);
|
||||
switch (shm()->detType) {
|
||||
case EIGER:
|
||||
portGeometry.x = modules[0]->getNumberofUDPInterfacesFromShm();
|
||||
break;
|
||||
case JUNGFRAU:
|
||||
portGeometry.y = modules[0]->getNumberofUDPInterfacesFromShm();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return portGeometry;
|
||||
}
|
||||
|
||||
defs::xy DetectorImpl::calculatePosition(int moduleIndex,
|
||||
defs::xy geometry) const {
|
||||
defs::xy pos{};
|
||||
int maxYMods = shm()->numberOfModules.y;
|
||||
pos.y = (moduleIndex % maxYMods) * geometry.y;
|
||||
pos.x = (moduleIndex / maxYMods) * geometry.x;
|
||||
return pos;
|
||||
}
|
||||
|
||||
defs::ROI DetectorImpl::getRxROI() const {
|
||||
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
|
||||
throw RuntimeError("RxRoi not implemented for this Detector");
|
||||
}
|
||||
if (modules.size() == 0) {
|
||||
throw RuntimeError("No Modules added");
|
||||
}
|
||||
// complete detector in roi
|
||||
auto t = Parallel(&Module::getRxROI, {});
|
||||
if (t.equal() && t.front().completeRoi()) {
|
||||
LOG(logDEBUG) << "no roi";
|
||||
return defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1);
|
||||
}
|
||||
|
||||
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
|
||||
bool is2D = (numChansPerMod.y > 1 ? true : false);
|
||||
defs::xy geometry = getPortGeometry();
|
||||
|
||||
defs::ROI retval{};
|
||||
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
|
||||
|
||||
defs::ROI moduleRoi = modules[iModule]->getRxROI();
|
||||
if (moduleRoi.noRoi()) {
|
||||
LOG(logDEBUG) << iModule << ": no roi";
|
||||
} else {
|
||||
// expand complete roi
|
||||
if (moduleRoi.completeRoi()) {
|
||||
moduleRoi.xmin = 0;
|
||||
moduleRoi.xmax = numChansPerMod.x;
|
||||
if (is2D) {
|
||||
moduleRoi.ymin = 0;
|
||||
moduleRoi.ymax = numChansPerMod.y;
|
||||
}
|
||||
}
|
||||
LOG(logDEBUG) << iModule << ": " << moduleRoi;
|
||||
|
||||
// get roi at detector level
|
||||
defs::xy pos = calculatePosition(iModule, geometry);
|
||||
defs::ROI moduleFullRoi{};
|
||||
moduleFullRoi.xmin = numChansPerMod.x * pos.x + moduleRoi.xmin;
|
||||
moduleFullRoi.xmax = numChansPerMod.x * pos.x + moduleRoi.xmax;
|
||||
if (is2D) {
|
||||
moduleFullRoi.ymin = numChansPerMod.y * pos.y + moduleRoi.ymin;
|
||||
moduleFullRoi.ymax = numChansPerMod.y * pos.y + moduleRoi.ymax;
|
||||
}
|
||||
LOG(logDEBUG) << iModule << ": (full roi)" << moduleFullRoi;
|
||||
|
||||
// get min and max
|
||||
if (retval.xmin == -1 || moduleFullRoi.xmin < retval.xmin) {
|
||||
LOG(logDEBUG) << iModule << ": xmin updated";
|
||||
retval.xmin = moduleFullRoi.xmin;
|
||||
}
|
||||
if (retval.xmax == -1 || moduleFullRoi.xmax > retval.xmax) {
|
||||
LOG(logDEBUG) << iModule << ": xmax updated";
|
||||
retval.xmax = moduleFullRoi.xmax;
|
||||
}
|
||||
if (retval.ymin == -1 || moduleFullRoi.ymin < retval.ymin) {
|
||||
LOG(logDEBUG) << iModule << ": ymin updated";
|
||||
retval.ymin = moduleFullRoi.ymin;
|
||||
}
|
||||
if (retval.ymax == -1 || moduleFullRoi.ymax > retval.ymax) {
|
||||
LOG(logDEBUG) << iModule << ": ymax updated";
|
||||
retval.ymax = moduleFullRoi.ymax;
|
||||
}
|
||||
}
|
||||
LOG(logDEBUG) << iModule << ": (retval): " << retval;
|
||||
}
|
||||
if (retval.ymin == -1) {
|
||||
retval.ymin = 0;
|
||||
retval.ymax = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void DetectorImpl::setRxROI(const defs::ROI arg) {
|
||||
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
|
||||
throw RuntimeError("RxRoi not implemented for this Detector");
|
||||
}
|
||||
if (modules.size() == 0) {
|
||||
throw RuntimeError("No Modules added");
|
||||
}
|
||||
if (arg.noRoi()) {
|
||||
throw RuntimeError("Invalid Roi of size 0.");
|
||||
}
|
||||
if (arg.completeRoi()) {
|
||||
throw RuntimeError("Did you mean the clear roi command (API: clearRxROI, cmd: rx_clearroi)?");
|
||||
}
|
||||
if (arg.xmin > arg.xmax || arg.ymin > arg.ymax) {
|
||||
throw RuntimeError("Invalid Receiver Roi. xmin/ymin exceeds xmax/ymax.");
|
||||
}
|
||||
|
||||
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
|
||||
bool is2D = (numChansPerMod.y > 1 ? true : false);
|
||||
defs::xy geometry = getPortGeometry();
|
||||
|
||||
if (!is2D && ((arg.ymin != -1 && arg.ymin != 0) || (arg.ymax != -1 && arg.ymax != 0))) {
|
||||
throw RuntimeError("Invalid Receiver roi. Cannot set 2d roi for a 1d detector.");
|
||||
}
|
||||
|
||||
if (arg.xmin < 0 || arg.xmax >= shm()->numberOfChannels.x || (is2D && (arg.ymin < 0 || arg.ymax >= shm()->numberOfChannels.y))) {
|
||||
throw RuntimeError("Invalid Receiver Roi. Outside detector range.");
|
||||
}
|
||||
|
||||
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
|
||||
// default init = complete roi
|
||||
defs::ROI moduleRoi{};
|
||||
|
||||
// incomplete roi
|
||||
if (!arg.completeRoi()) {
|
||||
// multi module Gotthard2
|
||||
if (shm()->detType == GOTTHARD2 && size() > 1) {
|
||||
moduleRoi.xmin = arg.xmin / 2;
|
||||
moduleRoi.xmax = arg.xmax / 2;
|
||||
if (iModule == 0) {
|
||||
// all should be even
|
||||
if (arg.xmin % 2 != 0) {
|
||||
++moduleRoi.xmin;
|
||||
}
|
||||
} else if (iModule == 1) {
|
||||
// all should be odd
|
||||
if (arg.xmax % 2 == 0) {
|
||||
--moduleRoi.xmax;
|
||||
}
|
||||
} else {
|
||||
throw RuntimeError("Cannot have more than 2 modules for a Gotthard2 detector");
|
||||
}
|
||||
} else {
|
||||
// get module limits
|
||||
defs::xy pos = calculatePosition(iModule, geometry);
|
||||
defs::ROI moduleFullRoi{};
|
||||
moduleFullRoi.xmin = numChansPerMod.x * pos.x;
|
||||
moduleFullRoi.xmax = numChansPerMod.x * (pos.x + 1) - 1;
|
||||
if (is2D) {
|
||||
moduleFullRoi.ymin = numChansPerMod.y * pos.y;
|
||||
moduleFullRoi.ymax = numChansPerMod.y * (pos.y + 1) - 1;
|
||||
}
|
||||
|
||||
// no roi
|
||||
if (arg.xmin > moduleFullRoi.xmax ||
|
||||
arg.xmax < moduleFullRoi.xmin ||
|
||||
(is2D && (arg.ymin > moduleFullRoi.ymax ||
|
||||
arg.ymax < moduleFullRoi.ymin))) {
|
||||
moduleRoi.setNoRoi();
|
||||
}
|
||||
// incomplete module roi
|
||||
else if (arg.xmin > moduleFullRoi.xmin ||
|
||||
arg.xmax < moduleFullRoi.xmax ||
|
||||
(is2D && (arg.ymin > moduleFullRoi.ymin ||
|
||||
arg.ymax < moduleFullRoi.ymax))) {
|
||||
moduleRoi.xmin = (arg.xmin <= moduleFullRoi.xmin)
|
||||
? 0
|
||||
: (arg.xmin % numChansPerMod.x);
|
||||
moduleRoi.xmax = (arg.xmax >= moduleFullRoi.xmax)
|
||||
? numChansPerMod.x - 1
|
||||
: (arg.xmax % numChansPerMod.x);
|
||||
if (is2D) {
|
||||
moduleRoi.ymin = (arg.ymin <= moduleFullRoi.ymin)
|
||||
? 0
|
||||
: (arg.ymin % numChansPerMod.y);
|
||||
moduleRoi.ymax = (arg.ymax >= moduleFullRoi.ymax)
|
||||
? numChansPerMod.y - 1
|
||||
: (arg.ymax % numChansPerMod.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
modules[iModule]->setRxROI(moduleRoi);
|
||||
}
|
||||
// updating shm rx_roi for gui purposes
|
||||
shm()->rx_roi = arg;
|
||||
|
||||
// metadata
|
||||
if (arg.completeRoi()) {
|
||||
modules[0]->setRxROIMetadata(defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1));
|
||||
} else {
|
||||
modules[0]->setRxROIMetadata(arg);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorImpl::clearRxROI() {
|
||||
Parallel(&Module::setRxROI, {}, defs::ROI{});
|
||||
shm()->rx_roi.xmin = -1;
|
||||
shm()->rx_roi.ymin = -1;
|
||||
shm()->rx_roi.xmax = -1;
|
||||
shm()->rx_roi.ymax = -1;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> DetectorImpl::getCtbDacNames() const {
|
||||
return ctb_shm()->getDacNames();
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
|
||||
#include "CtbConfig.h"
|
||||
class ZmqSocket;
|
||||
class detectorData;
|
||||
@ -20,7 +19,7 @@ class detectorData;
|
||||
#include <vector>
|
||||
|
||||
#define DETECTOR_SHMAPIVERSION 0x190809
|
||||
#define DETECTOR_SHMVERSION 0x201007
|
||||
#define DETECTOR_SHMVERSION 0x220505
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
|
||||
#include <future>
|
||||
@ -51,14 +50,14 @@ struct sharedDetector {
|
||||
/** last time stamp when accessing the shared memory */
|
||||
char lastDate[SHORT_STRING_LENGTH];
|
||||
|
||||
int numberOfModules;
|
||||
int totalNumberOfModules;
|
||||
slsDetectorDefs::detectorType detType;
|
||||
|
||||
/** END OF FIXED PATTERN
|
||||
* -----------------------------------------------*/
|
||||
|
||||
/** Number of modules operated at once */
|
||||
slsDetectorDefs::xy numberOfModule;
|
||||
slsDetectorDefs::xy numberOfModules;
|
||||
|
||||
/** max number of channels for complete detector*/
|
||||
slsDetectorDefs::xy numberOfChannels;
|
||||
@ -68,6 +67,8 @@ struct sharedDetector {
|
||||
bool gapPixels;
|
||||
/** high water mark of listening tcp port (only data) */
|
||||
int zmqHwm;
|
||||
/** in shm for gui purposes */
|
||||
defs::ROI rx_roi{};
|
||||
};
|
||||
|
||||
class DetectorImpl : public virtual slsDetectorDefs {
|
||||
@ -302,11 +303,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
Positions pos = {});
|
||||
void setDefaultDac(defs::dacIndex index, int defaultValue,
|
||||
defs::detectorSettings sett, Positions pos);
|
||||
|
||||
defs::ROI getRxROI() const;
|
||||
void setRxROI(const defs::ROI arg);
|
||||
void clearRxROI();
|
||||
|
||||
std::vector<std::string> getCtbDacNames() const;
|
||||
std::string getCtbDacName(defs::dacIndex i) const;
|
||||
void setCtbDacNames(const std::vector<std::string>& names);
|
||||
void setCtbDacNames(const std::vector<std::string> &names);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -389,6 +392,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int kbhit();
|
||||
|
||||
defs::xy getPortGeometry() const;
|
||||
defs::xy calculatePosition(int moduleIndex, defs::xy geometry) const;
|
||||
|
||||
const int detectorIndex{0};
|
||||
sls::SharedMemory<sharedDetector> shm{0, -1};
|
||||
sls::SharedMemory<CtbConfig> ctb_shm{0, -1, CtbConfig::shm_tag()};
|
||||
|
@ -1410,6 +1410,19 @@ void Module::setRxArping(bool enable) {
|
||||
sendToReceiver(F_SET_RECEIVER_ARPING, static_cast<int>(enable), nullptr);
|
||||
}
|
||||
|
||||
defs::ROI Module::getRxROI() const {
|
||||
return sendToReceiver<slsDetectorDefs::ROI>(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::setRxROIMetadata(const slsDetectorDefs::ROI arg) {
|
||||
sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI_METADATA, arg, nullptr);
|
||||
}
|
||||
|
||||
// File
|
||||
slsDetectorDefs::fileFormat Module::getFileFormat() const {
|
||||
return sendToReceiver<fileFormat>(F_GET_RECEIVER_FILE_FORMAT);
|
||||
@ -1837,7 +1850,7 @@ void Module::setROI(slsDetectorDefs::ROI arg) {
|
||||
}
|
||||
sendToDetector(F_SET_ROI, arg, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
sendToReceiver(F_RECEIVER_SET_ROI, arg, nullptr);
|
||||
sendToReceiver(F_RECEIVER_SET_DETECTOR_ROI, arg, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,6 +290,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
std::array<pid_t, NUM_RX_THREAD_IDS> 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);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
|
@ -440,6 +440,79 @@ TEST_CASE("rx_arping", "[.cmd][.rx]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rx_roi", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) {
|
||||
REQUIRE_THROWS(proxy.Call("rx_roi", {"5", "10"}, -1, PUT));
|
||||
} else {
|
||||
auto prev_val = det.getRxROI();
|
||||
defs::xy detsize = det.getDetectrSize();
|
||||
|
||||
// 1d
|
||||
if (det_type == defs::GOTTHARD || det_type == defs::GOTTHARD2 ||
|
||||
det_type == defs::MYTHEN3) {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_roi", {"5", "10"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_roi [5, 10]\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_roi", {"10", "15"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_roi [10, 15]\n");
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("rx_roi", {"-1", "-1"}, -1, PUT));
|
||||
REQUIRE_THROWS(proxy.Call("rx_roi", {"10", "15", "25", "30"}, -1, PUT));
|
||||
}
|
||||
// 2d
|
||||
else {
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_roi", {"10", "15", "1", "5"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_roi [10, 15, 1, 5]\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_roi", {"10", "22", "18", "19"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_roi [10, 22, 18, 19]\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_roi", {"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, ") + std::to_string(detsize.x - 5) + std::string(", ") + std::to_string(detsize.y - 5) + std::string(", 1]\n"));
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("rx_roi", {"-1", "-1", "-1", "-1"}, -1, PUT));
|
||||
}
|
||||
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxROI(prev_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rx_clearroi", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
|
||||
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) {
|
||||
REQUIRE_THROWS(proxy.Call("rx_clearroi", {}, -1, PUT));
|
||||
} else {
|
||||
auto prev_val = det.getRxROI();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_clearroi", {}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_clearroi successful\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxROI(prev_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* File */
|
||||
|
||||
TEST_CASE("fformat", "[.cmd]") {
|
||||
|
Reference in New Issue
Block a user