Add rx_streamdummyheader command (#1442)
Build and Deploy on local RHEL9 / build (push) Successful in 2m1s
Build on RHEL9 docker image / build (push) Successful in 3m49s
Build on RHEL8 docker image / build (push) Successful in 5m1s
Build and Deploy on local RHEL8 / build (push) Successful in 5m6s
Run Simulator Tests on local RHEL9 / build (push) Successful in 18m17s
Run Simulator Tests on local RHEL8 / build (push) Successful in 21m56s

* add rx_restream_stop command. This allows to send a ZMQ dummy header any time user wants to do so. For example this allows to pre-configure the ZMQ processing software before the acquisition begins. Therefore, the dummy header was adapted in order to contain the fields stored in the receiver.

* renamed command, changed inherit, moved commands to zmq related section

* update filename in restreamstop

* renamed helper function, sorted header fields alphabetically

* fixed fnametostream set

* renamed functions, add SetFileName method, format JSON parameters order

* added python bindings and formatting (does nothing really)

* renamed restream stop functions to stream dummy

* checkout .github files from ed8c885

* release notes

---------

Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
This commit is contained in:
2026-06-01 12:07:52 +02:00
committed by GitHub
co-authored by GitHub maliakal_d
parent 4c02ce65cc
commit f31234bbc3
25 changed files with 188 additions and 69 deletions
+51 -39
View File
@@ -8,7 +8,6 @@
#include "DataStreamer.h"
#include "Fifo.h"
#include "GeneralData.h"
#include "sls/ZmqSocket.h"
#include "sls/sls_detector_exceptions.h"
#include <cerrno>
@@ -30,6 +29,10 @@ void DataStreamer::SetGeneralData(GeneralData *g) { generalData = g; }
void DataStreamer::SetFileIndex(uint64_t value) { fileIndex = value; }
void DataStreamer::SetFileName(const std::string &fname) {
fileNametoStream = fname;
}
void DataStreamer::SetNumberofPorts(xy np) { numPorts = np; }
void DataStreamer::SetFlipRows(bool fd) {
@@ -62,11 +65,10 @@ void DataStreamer::SetPortROI(ROI roi) {
}
}
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
void DataStreamer::ResetParametersforNewAcquisition() {
StopRunning();
startedFlag = false;
firstIndex = 0;
fileNametoStream = fname;
}
void DataStreamer::RecordFirstIndex(uint64_t fnum, size_t firstImageIndex) {
@@ -152,8 +154,7 @@ void DataStreamer::ProcessAnImage(sls_detector_header header, size_t size,
uint64_t fnum = header.frameNumber;
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum;
if (!SendDataHeader(header, size, generalData->nPixelsX,
generalData->nPixelsY)) {
if (!SendDataHeader(header, size)) {
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
<< " and streamer " << index;
}
@@ -164,34 +165,47 @@ void DataStreamer::ProcessAnImage(sls_detector_header header, size_t size,
}
}
int DataStreamer::SendDummyHeader() {
zmqHeader DataStreamer::prepareRxZmqHeader() {
zmqHeader zHeader;
zHeader.data = false;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
// parameters coming from the receiver
zHeader.dynamicRange = generalData->dynamicRange;
zHeader.fileIndex = fileIndex;
zHeader.flipRows = static_cast<int>(flipRows);
zHeader.fname = fileNametoStream;
zHeader.imageSize = generalData->imageSize;
if (generalData->detType == GOTTHARD2 && index != 0) {
zHeader.imageSize = generalData->vetoImageSize;
}
zHeader.ndetx = numPorts.x;
zHeader.ndety = numPorts.y;
zHeader.npixelsx = generalData->nPixelsX;
zHeader.npixelsy = generalData->nPixelsY;
zHeader.quad = quadEnable;
// update local copy only if it was updated (to prevent locking each time)
if (isAdditionalJsonUpdated) {
std::lock_guard<std::mutex> lock(additionalJsonMutex);
localAdditionalJsonHeader = additionalJsonHeader;
isAdditionalJsonUpdated = false;
}
zHeader.addJsonHeader = localAdditionalJsonHeader;
zHeader.rx_roi = portRoi.getIntArray();
return zHeader;
}
int DataStreamer::SendDummyHeader() {
zmqHeader zHeader = prepareRxZmqHeader();
zHeader.data = false;
return zmqSocket->SendHeader(index, zHeader);
}
int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
uint32_t nx, uint32_t ny) {
zmqHeader zHeader;
int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size) {
zmqHeader zHeader = prepareRxZmqHeader();
zHeader.data = true;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
uint64_t frameIndex = header.frameNumber - firstIndex;
uint64_t acquisitionIndex = header.frameNumber;
zHeader.dynamicRange = generalData->dynamicRange;
zHeader.fileIndex = fileIndex;
zHeader.ndetx = numPorts.x;
zHeader.ndety = numPorts.y;
zHeader.npixelsx = nx;
zHeader.npixelsy = ny;
zHeader.imageSize = size;
zHeader.acqIndex = acquisitionIndex;
zHeader.frameIndex = frameIndex;
zHeader.progress =
100 * ((double)(frameIndex + 1) / (double)(nTotalFrames));
zHeader.fname = fileNametoStream;
// parameter from detector header
zHeader.frameNumber = header.frameNumber;
zHeader.expLength = header.expLength;
zHeader.packetNumber = header.packetNumber;
@@ -205,26 +219,24 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
zHeader.detSpec4 = header.detSpec4;
zHeader.detType = header.detType;
zHeader.version = header.version;
zHeader.flipRows = static_cast<int>(flipRows);
zHeader.quad = quadEnable;
// parameter derived from header and receiver
uint64_t acquisitionIndex = header.frameNumber;
uint64_t frameIndex = header.frameNumber - firstIndex;
zHeader.acqIndex = acquisitionIndex;
zHeader.completeImage =
(header.packetNumber < generalData->packetsPerFrame ? false : true);
// update local copy only if it was updated (to prevent locking each time)
if (isAdditionalJsonUpdated) {
std::lock_guard<std::mutex> lock(additionalJsonMutex);
localAdditionalJsonHeader = additionalJsonHeader;
isAdditionalJsonUpdated = false;
}
zHeader.addJsonHeader = localAdditionalJsonHeader;
zHeader.rx_roi = portRoi.getIntArray();
zHeader.frameIndex = frameIndex;
zHeader.imageSize = size;
zHeader.progress =
100 * ((double)(frameIndex + 1) / (double)(nTotalFrames));
return zmqSocket->SendHeader(index, zHeader);
}
void DataStreamer::RestreamStop() {
void DataStreamer::StreamRxDummyHeader() {
if (!SendDummyHeader()) {
throw RuntimeError("Could not restream Dummy Header via ZMQ for port " +
throw RuntimeError("Could not stream Dummy Header via ZMQ for port " +
std::to_string(zmqSocket->GetPortNumber()));
}
}