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

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

View File

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

View File

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

View File

@ -1783,9 +1783,10 @@ void DetectorImpl::convertGlobalRoiToPortLevel(
throw RuntimeError("Only up to 2 ports per module supported."); throw RuntimeError("Only up to 2 ports per module supported.");
} }
if (numPorts != (int)portRois.size()) { if (numPorts != (int)portRois.size()) {
throw RuntimeError("Number of port ROIs does not match number of ports in module. Expected: " + throw RuntimeError("Number of port ROIs does not match number of ports "
std::to_string(numPorts) + ", got: " + "in module. Expected: " +
std::to_string(portRois.size())); std::to_string(numPorts) +
", got: " + std::to_string(portRois.size()));
} }
for (int port = 0; port < numPorts; ++port) { for (int port = 0; port < numPorts; ++port) {
@ -1812,20 +1813,22 @@ void DetectorImpl::convertGlobalRoiToPortLevel(
clipped.xmin = std::max(userRoi.xmin, portRoi.xmin) - portRoi.xmin; clipped.xmin = std::max(userRoi.xmin, portRoi.xmin) - portRoi.xmin;
clipped.xmax = std::min(userRoi.xmax, portRoi.xmax) - portRoi.xmin; clipped.xmax = std::min(userRoi.xmax, portRoi.xmax) - portRoi.xmin;
LOG(logDEBUG1) << "User ROI: " << ToString(userRoi) LOG(logDEBUG1) << "User ROI: " << ToString(userRoi)
<< ", Port ROI: " << ToString(portRoi) << " clipped roi:"<< ToString(clipped); << ", Port ROI: " << ToString(portRoi)
<< " clipped roi:" << ToString(clipped);
if (modSize.y > 1) { if (modSize.y > 1) {
clipped.ymin = std::max(userRoi.ymin, portRoi.ymin) - portRoi.ymin; clipped.ymin =
clipped.ymax = std::min(userRoi.ymax, portRoi.ymax) - portRoi.ymin; std::max(userRoi.ymin, portRoi.ymin) - portRoi.ymin;
clipped.ymax =
std::min(userRoi.ymax, portRoi.ymax) - portRoi.ymin;
} }
LOG(logDEBUG1) << "Clipped ROI for port " << port LOG(logDEBUG1) << "Clipped ROI for port " << port << ": "
<< ": " << ToString(clipped); << ToString(clipped);
// Check if port ROI already exists for this port // Check if port ROI already exists for this port
if (!portRois[port].completeRoi() && !portRois[port].noRoi()) { if (!portRois[port].completeRoi() && !portRois[port].noRoi()) {
throw RuntimeError( throw RuntimeError(
"Multiple ROIs specified for the same port " + "Multiple ROIs specified for the same port " +
std::to_string(port) + std::to_string(port) + " with ROI: " + ToString(userRoi));
" with ROI: " + ToString(userRoi));
} }
portRois[port] = clipped; portRois[port] = clipped;
} }
@ -1846,12 +1849,14 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
} }
validateROIs(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) { for (size_t iModule = 0; iModule < modules.size(); ++iModule) {
auto moduleGlobalRoi = getModuleROI(iModule); auto moduleGlobalRoi = getModuleROI(iModule);
LOG(logDEBUG1) << "Module " << iModule LOG(logDEBUG1) << "Module " << iModule
<< " Global ROI: " << ToString(moduleGlobalRoi); << " Global ROI: " << ToString(moduleGlobalRoi);
// at most 2 rois per module (for each port) // at most 2 rois per module (for each port)
std::vector<defs::ROI> portRois(nPortsPerModule); std::vector<defs::ROI> portRois(nPortsPerModule);
@ -1865,8 +1870,8 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
// print the rois for debugging // print the rois for debugging
LOG(logDEBUG1) << "Module " << iModule << " RxROIs:"; LOG(logDEBUG1) << "Module " << iModule << " RxROIs:";
for (size_t iPort = 0; iPort != portRois.size(); iPort++) { for (size_t iPort = 0; iPort != portRois.size(); iPort++) {
LOG(logDEBUG1) LOG(logDEBUG1) << " Port " << iPort << ": "
<< " Port " << iPort << ": " << ToString(portRois[iPort]); << ToString(portRois[iPort]);
} }
modules[iModule]->setRxROI(portRois); modules[iModule]->setRxROI(portRois);
} }
@ -1875,7 +1880,9 @@ void DetectorImpl::setRxROI(const std::vector<defs::ROI> &args) {
} }
void DetectorImpl::clearRxROI() { void DetectorImpl::clearRxROI() {
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) { 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));
} }

View File

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

View File

@ -1587,8 +1587,7 @@ std::vector<slsDetectorDefs::ROI> Module::getRxROIMetadata() const {
throw RuntimeError("Invalid number of ROI metadata: " + throw RuntimeError("Invalid number of ROI metadata: " +
std::to_string(size) + ". Min: 1."); std::to_string(size) + ". Min: 1.");
} }
LOG(logDEBUG1) << "ROI metadata of Receiver: " LOG(logDEBUG1) << "ROI metadata of Receiver: " << ToString(retval);
<< ToString(retval);
return retval; return retval;
} }

View File

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

View File

@ -227,8 +227,8 @@ std::string DataProcessor::CreateVirtualFile(
return masterFileUtility::CreateVirtualHDF5File( return masterFileUtility::CreateVirtualHDF5File(
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
modulePos, generalData->numUDPInterfaces, framesPerFile, modulePos, generalData->numUDPInterfaces, framesPerFile,
generalData->nPixelsX, ny, generalData->dynamicRange, generalData->nPixelsX, ny, generalData->dynamicRange, numFramesCaught,
numFramesCaught, numModX, numModY, dataFile->GetPDataType(), numModX, numModY, dataFile->GetPDataType(),
dataFile->GetParameterNames(), dataFile->GetParameterDataTypes(), dataFile->GetParameterNames(), dataFile->GetParameterDataTypes(),
hdf5LibMutex, gotthard25um, multiRoiMetadata); hdf5LibMutex, gotthard25um, multiRoiMetadata);
} }
@ -247,9 +247,9 @@ void DataProcessor::LinkFileInMaster(const std::string &masterFileName,
if (virtualFileName.empty()) { if (virtualFileName.empty()) {
fname = dataFile->GetFileName(); fname = dataFile->GetFileName();
} }
masterFileUtility::LinkHDF5FileInMaster(masterfname, fname, masterFileUtility::LinkHDF5FileInMaster(
dataFile->GetParameterNames(), masterfname, fname, dataFile->GetParameterNames(), silentMode,
silentMode, hdf5LibMutex, multiRoiMetadata.size()); hdf5LibMutex, multiRoiMetadata.size());
} }
#endif #endif

View File

@ -54,7 +54,7 @@ void DataStreamer::SetAdditionalJsonHeader(
} }
void DataStreamer::SetPortROI(ROI roi) { void DataStreamer::SetPortROI(ROI roi) {
if (roi.completeRoi()) {//TODO: just not send zmq if not in roi? if (roi.completeRoi()) { // TODO: just not send zmq if not in roi?
portRoi = portRoi =
ROI(0, generalData->nPixelsX - 1, 0, generalData->nPixelsY - 1); ROI(0, generalData->nPixelsX - 1, 0, generalData->nPixelsY - 1);
} else { } else {

View File

@ -166,7 +166,6 @@ void Implementation::setDetectorType(const detectorType d) {
SetLocalNetworkParameters(); SetLocalNetworkParameters();
SetupFifoStructure(); SetupFifoStructure();
// create threads // create threads
for (int i = 0; i < generalData->numUDPInterfaces; ++i) { for (int i = 0; i < generalData->numUDPInterfaces; ++i) {
@ -418,12 +417,11 @@ void Implementation::setPortROIs(const std::vector<defs::ROI> &args) {
if (it.completeRoi() || it.noRoi()) { if (it.completeRoi() || it.noRoi()) {
continue; // valid continue; // valid
} }
if (it.xmin < 0 || it.xmax < 0 || if (it.xmin < 0 || it.xmax < 0 || it.xmin >= nx || it.xmax >= nx) {
it.xmin >= nx || it.xmax >= nx) {
throw RuntimeError("Invalid ROIvx coordinates: " + ToString(it)); throw RuntimeError("Invalid ROIvx coordinates: " + ToString(it));
} }
if (ny > 1 && (it.ymin < 0 || it.ymax < 0 || if (ny > 1 &&
it.ymin >= ny || it.ymax >= ny)) { (it.ymin < 0 || it.ymax < 0 || it.ymin >= ny || it.ymax >= ny)) {
throw RuntimeError("Invalid ROI y coordinates: " + ToString(it)); throw RuntimeError("Invalid ROI y coordinates: " + ToString(it));
} }
} }

View File

@ -49,7 +49,8 @@ std::string CreateMasterBinaryFile(const std::string &filePath,
void LinkHDF5FileInMaster(std::string &masterFileName, void LinkHDF5FileInMaster(std::string &masterFileName,
std::string &dataFilename, std::string &dataFilename,
std::vector<std::string> parameterNames, std::vector<std::string> parameterNames,
const bool silentMode, std::mutex *hdf5LibMutex, size_t multiRoiSize) { const bool silentMode, std::mutex *hdf5LibMutex,
size_t multiRoiSize) {
std::lock_guard<std::mutex> lock(*hdf5LibMutex); std::lock_guard<std::mutex> lock(*hdf5LibMutex);
std::unique_ptr<H5::H5File> fd{nullptr}; std::unique_ptr<H5::H5File> fd{nullptr};
@ -74,11 +75,10 @@ void LinkHDF5FileInMaster(std::string &masterFileName,
if (multiRoiSize > 1) if (multiRoiSize > 1)
datasetname += ('_' + std::to_string(iRoi)); datasetname += ('_' + std::to_string(iRoi));
H5::DataSet dset = fd->openDataSet(datasetname); H5::DataSet dset = fd->openDataSet(datasetname);
std::string linkname = std::string linkname = std::string("/entry/data/") + datasetname;
std::string("/entry/data/") + datasetname;
if (H5Lcreate_external(dataFilename.c_str(), datasetname.c_str(), if (H5Lcreate_external(dataFilename.c_str(), datasetname.c_str(),
masterfd.getLocId(), linkname.c_str(), masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) { H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw RuntimeError( throw RuntimeError(
"Could not create link to data dataset in master"); "Could not create link to data dataset in master");
} }
@ -91,9 +91,9 @@ void LinkHDF5FileInMaster(std::string &masterFileName,
H5::DataSet pDset = fd->openDataSet(parameterDsetName.c_str()); H5::DataSet pDset = fd->openDataSet(parameterDsetName.c_str());
linkname = std::string("/entry/data/") + parameterDsetName; linkname = std::string("/entry/data/") + parameterDsetName;
if (H5Lcreate_external(dataFilename.c_str(), if (H5Lcreate_external(dataFilename.c_str(),
parameterDsetName.c_str(), parameterDsetName.c_str(),
masterfd.getLocId(), linkname.c_str(), masterfd.getLocId(), linkname.c_str(),
H5P_DEFAULT, H5P_DEFAULT) < 0) { H5P_DEFAULT, H5P_DEFAULT) < 0) {
throw RuntimeError( throw RuntimeError(
"Could not create link to parameter dataset in master"); "Could not create link to parameter dataset in master");
} }
@ -169,7 +169,8 @@ std::string CreateMasterHDF5File(const std::string &filePath,
return fileName; return fileName;
} }
defs::ROI GetGlobalPortRoi(const int iPort, const defs::xy portSize, const int numPortsY) { defs::ROI GetGlobalPortRoi(const int iPort, const defs::xy portSize,
const int numPortsY) {
defs::xy portPos = {(iPort / numPortsY), (iPort % numPortsY)}; defs::xy portPos = {(iPort / numPortsY), (iPort % numPortsY)};
const int xmin = portSize.x * portPos.x; const int xmin = portSize.x * portPos.x;
const int xmax = xmin + portSize.x - 1; const int xmax = xmin + portSize.x - 1;
@ -194,10 +195,10 @@ std::string CreateVirtualHDF5File(
const std::string &filePath, const std::string &fileNamePrefix, const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const int nPixelsX, const uint32_t maxFramesPerFile, const int nPixelsX, const int nPixelsY,
const int nPixelsY, const uint32_t dynamicRange, const uint32_t dynamicRange, const uint64_t numImagesCaught,
const uint64_t numImagesCaught, const int numModX, const int numModY, const int numModX, const int numModY, const H5::DataType dataType,
const H5::DataType dataType, const std::vector<std::string> parameterNames, const std::vector<std::string> parameterNames,
const std::vector<H5::DataType> parameterDataTypes, const std::vector<H5::DataType> parameterDataTypes,
std::mutex *hdf5LibMutex, bool gotthard25um, std::mutex *hdf5LibMutex, bool gotthard25um,
std::vector<defs::ROI> multiRoi) { std::vector<defs::ROI> multiRoi) {
@ -210,16 +211,17 @@ std::string CreateVirtualHDF5File(
// roi not allowed in 4 bit mode and with gotthard 2 mods // roi not allowed in 4 bit mode and with gotthard 2 mods
if (!completeRoi) { if (!completeRoi) {
if (dynamicRange == 4) { if (dynamicRange == 4) {
throw std::runtime_error("Skipping virtual hdf5 file since rx_roi is " throw std::runtime_error(
"enabled and it is in 4 bit mode."); "Skipping virtual hdf5 file since rx_roi is "
"enabled and it is in 4 bit mode.");
} }
if (gotthard25um && (numModX * numModY) == 2) { if (gotthard25um && (numModX * numModY) == 2) {
throw std::runtime_error("Skipping virtual hdf5 file since rx_roi is " throw std::runtime_error(
"enabled and there are 2 Gotthard 25um modules."); "Skipping virtual hdf5 file since rx_roi is "
"enabled and there are 2 Gotthard 25um modules.");
} }
} }
// virtual file name // virtual file name
std::ostringstream osfn; std::ostringstream osfn;
osfn << filePath << "/" << fileNamePrefix << "_virtual" osfn << filePath << "/" << fileNamePrefix << "_virtual"
@ -254,11 +256,12 @@ std::string CreateVirtualHDF5File(
auto currentRoi = multiRoi[iRoi]; auto currentRoi = multiRoi[iRoi];
defs::xy detectorSize = {nPixelsX * numModX, nPixelsY * numModY}; defs::xy detectorSize = {nPixelsX * numModX, nPixelsY * numModY};
if (completeRoi) { if (completeRoi) {
currentRoi = defs::ROI{0, detectorSize.x - 1, currentRoi =
0, detectorSize.y - 1}; defs::ROI{0, detectorSize.x - 1, 0, detectorSize.y - 1};
} }
if (multiRoi[iRoi].completeRoi()&& iRoi != 0) if (multiRoi[iRoi].completeRoi() && iRoi != 0)
throw RuntimeError("Cannot have complete roi and multiple rois"); throw RuntimeError(
"Cannot have complete roi and multiple rois");
// get detector shape and number of ports in roi // get detector shape and number of ports in roi
defs::xy portSize{nPixelsX, nPixelsY}; defs::xy portSize{nPixelsX, nPixelsY};
@ -276,7 +279,7 @@ std::string CreateVirtualHDF5File(
uint64_t nImages = numImagesCaught; uint64_t nImages = numImagesCaught;
int numFiles = numImagesCaught / maxFramesPerFile; int numFiles = numImagesCaught / maxFramesPerFile;
if (numImagesCaught % maxFramesPerFile) if (numImagesCaught % maxFramesPerFile)
++numFiles; ++numFiles;
hsize_t vdsDims[DATA_RANK] = {nImages, roiHeight, roiWidth}; hsize_t vdsDims[DATA_RANK] = {nImages, roiHeight, roiWidth};
hsize_t vdsDimsPara[VDS_PARA_RANK] = {nImages, nPortsInRoi}; hsize_t vdsDimsPara[VDS_PARA_RANK] = {nImages, nPortsInRoi};
@ -309,7 +312,9 @@ std::string CreateVirtualHDF5File(
hsize_t blockSizePara[VDS_PARA_RANK] = {nSrcFileImages, 1}; hsize_t blockSizePara[VDS_PARA_RANK] = {nSrcFileImages, 1};
// following recalculated for every readout // following recalculated for every readout
hsize_t blockSize[DATA_RANK] = {nSrcFileImages, static_cast<hsize_t>(nPixelsY), static_cast<hsize_t>(nPixelsX)}; hsize_t blockSize[DATA_RANK] = {nSrcFileImages,
static_cast<hsize_t>(nPixelsY),
static_cast<hsize_t>(nPixelsX)};
hsize_t startLocation[DATA_RANK] = {framesSaved, 0, 0}; hsize_t startLocation[DATA_RANK] = {framesSaved, 0, 0};
hsize_t startLocationPara[VDS_PARA_RANK] = {framesSaved, 0}; hsize_t startLocationPara[VDS_PARA_RANK] = {framesSaved, 0};
@ -318,8 +323,10 @@ std::string CreateVirtualHDF5File(
strideBetweenBlocks[2] = 2; strideBetweenBlocks[2] = 2;
} }
for (unsigned int iReadout = 0; iReadout < nTotalPorts; ++iReadout) { for (unsigned int iReadout = 0; iReadout < nTotalPorts;
auto globalPortRoi = GetGlobalPortRoi(iReadout, portSize, numModY); ++iReadout) {
auto globalPortRoi =
GetGlobalPortRoi(iReadout, portSize, numModY);
if (!globalPortRoi.overlap(currentRoi)) if (!globalPortRoi.overlap(currentRoi))
continue; continue;
@ -328,8 +335,8 @@ std::string CreateVirtualHDF5File(
int xmax = std::min(currentRoi.xmax, globalPortRoi.xmax); int xmax = std::min(currentRoi.xmax, globalPortRoi.xmax);
int ymin = std::max(currentRoi.ymin, globalPortRoi.ymin); int ymin = std::max(currentRoi.ymin, globalPortRoi.ymin);
int ymax = std::min(currentRoi.ymax, globalPortRoi.ymax); int ymax = std::min(currentRoi.ymax, globalPortRoi.ymax);
hsize_t portRoiHeight = ymax - ymin + 1; hsize_t portRoiHeight = ymax - ymin + 1;
hsize_t portRoiWidth = xmax - xmin + 1; hsize_t portRoiWidth = xmax - xmin + 1;
// recalculating start location and block size // recalculating start location and block size
if (!gotthard25um) { if (!gotthard25um) {
@ -338,7 +345,8 @@ std::string CreateVirtualHDF5File(
blockSize[1] = portRoiHeight; blockSize[1] = portRoiHeight;
blockSize[2] = portRoiWidth; blockSize[2] = portRoiWidth;
} }
// interleaving for g2 (startLocation is 0 and 1) (g2 had no roi) // interleaving for g2 (startLocation is 0 and 1) (g2 had no
// roi)
else { else {
++startLocation[2]; ++startLocation[2];
} }
@ -369,13 +377,15 @@ std::string CreateVirtualHDF5File(
} }
// source dataspace // source dataspace
hsize_t srcDims[DATA_RANK] = {nSrcFileImages, portRoiHeight, portRoiWidth}; hsize_t srcDims[DATA_RANK] = {nSrcFileImages, portRoiHeight,
hsize_t srcDimsMax[DATA_RANK] = {H5S_UNLIMITED, portRoiHeight, portRoiWidth};
portRoiWidth}; hsize_t srcDimsMax[DATA_RANK] = {
H5S_UNLIMITED, portRoiHeight, portRoiWidth};
H5::DataSpace srcDataSpace(DATA_RANK, srcDims, srcDimsMax); H5::DataSpace srcDataSpace(DATA_RANK, srcDims, srcDimsMax);
hsize_t srcDimsPara[PARA_RANK] = {nSrcFileImages}; hsize_t srcDimsPara[PARA_RANK] = {nSrcFileImages};
hsize_t srcDimsMaxPara[PARA_RANK] = {H5S_UNLIMITED}; hsize_t srcDimsMaxPara[PARA_RANK] = {H5S_UNLIMITED};
H5::DataSpace srcDataSpacePara(PARA_RANK, srcDimsPara, srcDimsMaxPara); H5::DataSpace srcDataSpacePara(PARA_RANK, srcDimsPara,
srcDimsMaxPara);
// temporary fixfor corner case bug: // temporary fixfor corner case bug:
// (framescaught not multiple of framesperfile, // (framescaught not multiple of framesperfile,
// virtual parameter datasets error loading (bad scalar // virtual parameter datasets error loading (bad scalar

View File

@ -21,7 +21,8 @@ std::string CreateMasterBinaryFile(const std::string &filePath,
void LinkHDF5FileInMaster(std::string &masterFileName, void LinkHDF5FileInMaster(std::string &masterFileName,
std::string &dataFilename, std::string &dataFilename,
std::vector<std::string> parameterNames, std::vector<std::string> parameterNames,
const bool silentMode, std::mutex *hdf5LibMutex, size_t multiRoiSize); const bool silentMode, std::mutex *hdf5LibMutex,
size_t multiRoiSize);
std::string CreateMasterHDF5File(const std::string &filePath, std::string CreateMasterHDF5File(const std::string &filePath,
const std::string &fileNamePrefix, const std::string &fileNamePrefix,
@ -29,17 +30,18 @@ std::string CreateMasterHDF5File(const std::string &filePath,
const bool overWriteEnable, const bool overWriteEnable,
const bool silentMode, MasterAttributes *attr, const bool silentMode, MasterAttributes *attr,
std::mutex *hdf5LibMutex); std::mutex *hdf5LibMutex);
defs::ROI GetGlobalPortRoi(const int iPort, const defs::xy portSize, const int numPortsY); defs::ROI GetGlobalPortRoi(const int iPort, const defs::xy portSize,
const int numPortsY);
int GetNumPortsInRoi(const defs::ROI roi, const defs::xy portSize); int GetNumPortsInRoi(const defs::ROI roi, const defs::xy portSize);
std::string CreateVirtualHDF5File( std::string CreateVirtualHDF5File(
const std::string &filePath, const std::string &fileNamePrefix, const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const int nPixelsX, const uint32_t maxFramesPerFile, const int nPixelsX, const int nPixelsY,
const int nPixelsY, const uint32_t dynamicRange, const uint32_t dynamicRange, const uint64_t numImagesCaught,
const uint64_t numImagesCaught, const int numModX, const int numModY, const int numModX, const int numModY, const H5::DataType dataType,
const H5::DataType dataType, const std::vector<std::string> parameterNames, const std::vector<std::string> parameterNames,
const std::vector<H5::DataType> parameterDataTypes, const std::vector<H5::DataType> parameterDataTypes,
std::mutex *hdf5LibMutex, bool gotthard25um, std::mutex *hdf5LibMutex, bool gotthard25um,
std::vector<defs::ROI> multiRoi); std::vector<defs::ROI> multiRoi);

View File

@ -349,5 +349,4 @@ std::vector<T> StringTo(const std::vector<std::string> &strings) {
return result; return result;
} }
} // namespace sls } // namespace sls

View File

@ -230,12 +230,8 @@ class slsDetectorDefs {
ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){}; ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){};
ROI(int xmin, int xmax, int ymin, int ymax) ROI(int xmin, int xmax, int ymin, int ymax)
: xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax){}; : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax){};
constexpr int width() const { constexpr int width() const { return (xmax - xmin + 1); }
return (xmax - xmin + 1); constexpr int height() const { return (ymax - ymin + 1); }
}
constexpr int height() const {
return (ymax - ymin + 1);
}
constexpr std::array<int, 4> getIntArray() const { constexpr std::array<int, 4> getIntArray() const {
return std::array<int, 4>({xmin, xmax, ymin, ymax}); return std::array<int, 4>({xmin, xmax, ymin, ymax});
} }
@ -252,7 +248,7 @@ class slsDetectorDefs {
ymin = 0; ymin = 0;
ymax = 0; ymax = 0;
} }
constexpr bool overlap(const ROI & other) const { constexpr bool overlap(const ROI &other) const {
return ((xmin <= other.xmax && xmax >= other.xmin) && return ((xmin <= other.xmax && xmax >= other.xmin) &&
(ymin <= other.ymax && ymax >= other.ymin)); (ymin <= other.ymax && ymax >= other.ymin));
} }