diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index ba5ab9047..042e6e0bf 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -695,6 +695,15 @@ class Detector { */ void setRxZmqTimer(int time_in_ms, Positions pos = {}); + Result getRxZmqStartingFrame(Positions pos = {}) const; + + /** + * The starting frame index to stream out. 0 by default, which streams + * the first frame in an acquisition, and then depending on the rx zmq + * frequency/ timer. + */ + void setRxZmqStartingFrame(int fnum, Positions pos = {}); + Result getRxZmqPort(Positions pos = {}) const; /** diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 4feb91a06..ce4012f0d 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -807,6 +807,7 @@ class CmdProxy { /* ZMQ Streaming Parameters (Receiver<->Client) */ {"rx_datastream", &CmdProxy::rx_datastream}, {"rx_readfreq", &CmdProxy::rx_readfreq}, + {"rx_zmqstartfnum", &CmdProxy::rx_zmqstartfnum}, {"rx_zmqport", &CmdProxy::rx_zmqport}, {"zmqport", &CmdProxy::zmqport}, {"rx_zmqip", &CmdProxy::rx_zmqip}, @@ -1784,6 +1785,10 @@ class CmdProxy { "[nth frame]\n\tStream out every nth frame. Default is 1. 0 means " "streaming every 200 ms and discarding frames in this interval."); + INTEGER_COMMAND( + rx_zmqstartfnum, getRxZmqStartingFrame, setRxZmqStartingFrame, StringTo, + "[fnum]\n\tThe starting frame index to stream out. 0 by default, which streams the first frame in an acquisition, and then depending on the rx zmq frequency/ timer"); + INTEGER_COMMAND( rx_zmqport, getRxZmqPort, setRxZmqPort, StringTo, "[port]\n\tZmq port for data to be streamed out of the receiver. Also " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 97a180426..5c7a71123 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -954,6 +954,14 @@ void Detector::setRxZmqTimer(int time_in_ms, Positions pos) { pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, time_in_ms); } +Result Detector::getRxZmqStartingFrame(Positions pos) const { + return pimpl->Parallel(&Module::getReceiverStreamingStartingFrame, pos); +} + +void Detector::setRxZmqStartingFrame(int fnum, Positions pos) { + pimpl->Parallel(&Module::setReceiverStreamingStartingFrame, pos, fnum); +} + Result Detector::getRxZmqPort(Positions pos) const { return pimpl->Parallel(&Module::getReceiverStreamingPort, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 9e18104bd..9ffa20173 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -967,6 +967,18 @@ void Module::setReceiverStreamingTimer(int time_in_ms) { sendToReceiver(F_RECEIVER_STREAMING_TIMER, time_in_ms); } +int Module::getReceiverStreamingStartingFrame() { + return sendToReceiver(F_GET_RECEIVER_STREAMING_START_FNUM); +} + +void Module::setReceiverStreamingStartingFrame(int fnum) { + if (fnum < 0) { + throw RuntimeError("Invalid streaming starting frame number " + + std::to_string(fnum)); + } + sendToReceiver(F_SET_RECEIVER_STREAMING_START_FNUM, fnum, nullptr); +} + int Module::getReceiverStreamingPort() { return sendToReceiver(F_GET_RECEIVER_STREAMING_PORT); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 63f922a0e..bcef6975f 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -274,6 +274,8 @@ class Module : public virtual slsDetectorDefs { void setReceiverStreamingFrequency(int freq); int getReceiverStreamingTimer(); void setReceiverStreamingTimer(int time_in_ms = 200); + int getReceiverStreamingStartingFrame(); + void setReceiverStreamingStartingFrame(int fnum); int getReceiverStreamingPort(); void setReceiverStreamingPort(int port); sls::IpAddr getReceiverStreamingIP(); diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index aff796209..483c6134f 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -199,6 +199,8 @@ int ClientInterface::functionTable(){ flist[F_SET_RECEIVER_NUM_GATES] = &ClientInterface::set_num_gates; flist[F_SET_RECEIVER_GATE_DELAY] = &ClientInterface::set_gate_delay; flist[F_GET_RECEIVER_THREAD_IDS] = &ClientInterface::get_thread_ids; + flist[F_GET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::get_streaming_start_fnum; + flist[F_SET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::set_streaming_start_fnum; for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << @@ -1707,4 +1709,25 @@ int ClientInterface::get_thread_ids(Interface &socket) { auto retval = impl()->getThreadIds(); LOG(logDEBUG1) << "thread ids retval: " << sls::ToString(retval); return socket.sendResult(retval); -} \ No newline at end of file +} + +int ClientInterface::get_streaming_start_fnum(Interface &socket) { + int retval = impl()->getStreamingStartingFrameNumber(); + LOG(logDEBUG1) << "streaming start fnum:" << retval; + return socket.sendResult(retval); +} + +int ClientInterface::set_streaming_start_fnum(Interface &socket) { + auto index = socket.Receive(); + if (index < 0) { + throw RuntimeError("Invalid streaming start frame number: " + + std::to_string(index)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting streaming start fnum: " << index; + impl()->setStreamingStartingFrameNumber(index); + + int retval = impl()->getStreamingStartingFrameNumber(); + validate(index, retval, "set streaming start fnum", DEC); + return socket.Send(OK); +} diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index 3b0212d37..dc54a86dd 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -155,6 +155,8 @@ class ClientInterface : private virtual slsDetectorDefs { int set_num_gates(sls::ServerInterface &socket); int set_gate_delay(sls::ServerInterface &socket); int get_thread_ids(sls::ServerInterface &socket); + int get_streaming_start_fnum(sls::ServerInterface &socket); + int set_streaming_start_fnum(sls::ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 9725032a1..be6df647a 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -24,13 +24,14 @@ const std::string DataProcessor::TypeName = "DataProcessor"; DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype, bool fwenable, bool *mfwenable, bool *dsEnable, uint32_t *dr, uint32_t *freq, - uint32_t *timer, bool *fp, bool *act, + uint32_t *timer, uint32_t *sfnum, bool *fp, bool *act, bool *depaden, bool *sm, bool *qe, std::vector *cdl, int *cdo, int *cad) : ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype), dataStreamEnable(dsEnable), fileFormatType(ftype), fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable), dynamicRange(dr), streamingFrequency(freq), streamingTimerInMs(timer), + streamingStartFnum(sfnum), activated(act), deactivatedPaddingEnable(depaden), silentMode(sm), quadEnable(qe), framePadding(fp), ctbDbitList(cdl), ctbDbitOffset(cdo), ctbAnalogDataBytes(cad) { @@ -229,7 +230,7 @@ void DataProcessor::ProcessAnImage(char *buf) { timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000; // to send first image - currentFreqCount = *streamingFrequency; + currentFreqCount = *streamingFrequency - *streamingStartFnum; } } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 5e99a053a..28a65a970 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -37,6 +37,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { * @param dr pointer to dynamic range * @param freq pointer to streaming frequency * @param timer pointer to timer if streaming frequency is random + * @param sfnum pointer to streaming starting fnum * @param fp pointer to frame padding enable * @param act pointer to activated * @param depaden pointer to deactivated padding enable @@ -48,7 +49,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { */ DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype, bool fwenable, bool *mfwenable, bool *dsEnable, uint32_t *dr, - uint32_t *freq, uint32_t *timer, bool *fp, bool *act, + uint32_t *freq, uint32_t *timer, + uint32_t *sfnum, bool *fp, bool *act, bool *depaden, bool *sm, bool *qe, std::vector *cdl, int *cdo, int *cad); @@ -275,6 +277,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** Pointer to the timer if Streaming frequency is random */ uint32_t *streamingTimerInMs; + /** Pointer to streaming starting fnum */ + uint32_t *streamingStartFnum; + /** Current frequency count */ uint32_t currentFreqCount{0}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 621bdbcc4..c461de731 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -91,6 +91,7 @@ void Implementation::InitializeMembers() { dataStreamEnable = false; streamingFrequency = 1; streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS; + streamingStartFnum = 0; streamingPort = 0; streamingSrcIP = sls::IpAddr{}; @@ -292,7 +293,7 @@ void Implementation::setDetectorType(const detectorType d) { dataProcessor.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, &dynamicRange, - &streamingFrequency, &streamingTimerInMs, &framePadding, + &streamingFrequency, &streamingTimerInMs, &streamingStartFnum, &framePadding, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); } catch (...) { @@ -1017,7 +1018,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) { dataProcessor.push_back(sls::make_unique( i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, - &dynamicRange, &streamingFrequency, &streamingTimerInMs, + &dynamicRange, &streamingFrequency, &streamingTimerInMs, &streamingStartFnum, &framePadding, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); @@ -1232,6 +1233,18 @@ void Implementation::setStreamingTimer(const uint32_t time_in_ms) { LOG(logINFO) << "Streamer Timer: " << streamingTimerInMs; } +uint32_t Implementation::getStreamingStartingFrameNumber() const { + LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return streamingStartFnum; +} + +void Implementation::setStreamingStartingFrameNumber(const uint32_t fnum) { + if (streamingStartFnum != fnum) { + streamingStartFnum = fnum; + } + LOG(logINFO) << "Streaming Start Frame num: " << streamingStartFnum; +} + uint32_t Implementation::getStreamingPort() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; return streamingPort; diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 403ceb412..f2001ac14 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -121,6 +121,8 @@ class Implementation : private virtual slsDetectorDefs { void setStreamingFrequency(const uint32_t freq); uint32_t getStreamingTimer() const; void setStreamingTimer(const uint32_t time_in_ms); + uint32_t getStreamingStartingFrameNumber() const; + void setStreamingStartingFrameNumber(const uint32_t fnum); uint32_t getStreamingPort() const; void setStreamingPort(const uint32_t i); sls::IpAddr getStreamingSourceIP() const; @@ -299,6 +301,7 @@ class Implementation : private virtual slsDetectorDefs { bool dataStreamEnable; uint32_t streamingFrequency; uint32_t streamingTimerInMs; + uint32_t streamingStartFnum; uint32_t streamingPort; sls::IpAddr streamingSrcIP; std::map additionalJsonHeader; diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index b73049b05..8bd4ff538 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -308,6 +308,8 @@ enum detFuncs { F_SET_RECEIVER_NUM_GATES, F_SET_RECEIVER_GATE_DELAY, F_GET_RECEIVER_THREAD_IDS, + F_GET_RECEIVER_STREAMING_START_FNUM, + F_SET_RECEIVER_STREAMING_START_FNUM, NUM_REC_FUNCTIONS }; @@ -618,6 +620,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY"; case F_GET_RECEIVER_THREAD_IDS: return "F_GET_RECEIVER_THREAD_IDS"; + case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM"; + case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM"; + case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function"; }