Dev/rx disable datastream port (#1448)
Build and Deploy on local RHEL9 / build (push) Successful in 2m13s
Build on RHEL9 docker image / build (push) Successful in 3m53s
Build and Deploy on local RHEL8 / build (push) Successful in 4m58s
Build on RHEL8 docker image / build (push) Successful in 5m47s
Run Simulator Tests on local RHEL9 / build (push) Successful in 18m55s
Run Simulator Tests on local RHEL8 / build (push) Successful in 22m26s

- changed 
   - command from `datastream` to `udp_datastream` to be more specific
   - Detector API:
      - setNumberofUDPInterfaces(pos) =>setNumberofUDPInterfaces() # no position anymore
      - getDataStream(portPosition, pos) =>getUDPDataStream(portPosition, pos)
      - setDataStream(portPosition, pos) => setUDPDataStream(portPosition) # no position anymore
      
   - modified the dataprocessing thread: 
      - if gui or call back, start zmq processing (connecting sockets) before starting receiver (disabled ports sends dummy that the client zmq sockets are not ready for)
      - if only progress, starting progress processing thread after startReceiver
      -


- added
   - Detector API:
      - getRxDisabledUDPPortIndices()
      - getPortPositionList()  
   - allow disabling/enabling udp interface in receiver for Jungfrua/Moench when both udp interfaces is enabled  (This is to go fast, where only one half of the module matters)
   - write ports type and disabled ports to master file (tests for it as well)
   - tests for python commands as well
   - datastream command to deprecated commands
   - refactored tests to make the new parameters fit

* first draft of disabling data port at the receiver side. Todo: master file and stream for gui to use

* updated help in command

* formatting

* md5 unchanged

* fix test, check port position for detector type

* wip, udp port enable metadata in client, to:receiver, zmq streaming

* wip, master attributes

* wip, imple=> save only disabled ports with port index, 1 interface, is empty

* works in file. still needs refactoring

* updated writer versions

* udp ports type pass, disabled with api yet

* fixed disabled ports meta data as well

* fixed in developer via other PR

* renamed.more intuitive

* fix in gui that wont wait for disabled ports

* added tests for master file

* extra tests

* move the master fiel tests into its own tests with the disable marker for github tests

* refactoring

* python test

* more intuitive and doc

* release notes

* example for python

* back to before

* minor documentation fix and sending nports unnecessarily for getRxUDPPortDisableMetadata

* doc

* review fixes, 1. using std::array instead of vector, 2. moving udp_datastream command testing with different values into master attributes testing file because we test the master file

* minor

* review: update help

* progress printed before assigned

* try catch inside hdf5

* auto generated code for CLI and formatting

* missing packets should not be checked at github workflow level

* formatting

* improved python doc for udp_datastream help

* indent doc python done
This commit is contained in:
2026-07-13 14:58:25 +02:00
committed by GitHub
parent 9cbf588217
commit c3ad3d2e73
48 changed files with 1269 additions and 142431 deletions
+6
View File
@@ -62,8 +62,14 @@ support for building rpms
removed unused function readDataFile/writeDataFile from file_utils.h
changed api: datastream=>udp_datastream, set/getDatastream=>set/getUDPDatastream
also implemetned for jungfrau, moench at receiver side (top/bottom)
added rx_streamdummyheader to send the zmq dummy header any time. Allows pre-configuring zmq processing before acq begins.
allow disabling one UDP interface in the receiver.
setting number of UDP interfaces can only be set at detector level and not at module level. (individual modules)
2 On-board Detector Server Compatibility
==========================================
+61 -17
View File
@@ -622,7 +622,7 @@ class Detector(CppDetectorApi):
>>> d.exptime = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.exptime = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -674,7 +674,7 @@ class Detector(CppDetectorApi):
>>> d.period = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.period = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -740,7 +740,7 @@ class Detector(CppDetectorApi):
>>> d.delay = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.delay = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -2429,19 +2429,63 @@ class Detector(CppDetectorApi):
"""
@property
def datastream(self):
def udp_datastream(self):
"""
datastream [left|right] [0, 1]
[Eiger] Enables or disables data streaming from left or/and right side of detector for 10GbE mode. 1 (enabled) by default.
Get or set UDP data streaming for detector/receiver ports.
[Eiger]: LEFT, RIGHT - 10GbE UDP ports of the detector.
[Jungfrau][Moench]: TOP, BOTTOM - UDP ports of the receiver
(only when numinterfaces is set to 2).
:getter: Returns a dictionary containing the UDP data stream enable state
for all available ports. When multiple detector modules are present,
identical values are returned as a single boolean. If different
values are found, a list of booleans is returned.
:setter: Takes a tuple of ``(portPosition, bool)`` to set the UDP data
stream state for a single port.
Enum: portPosition
Example
-------
Get UDP streaming state for all ports:
>>> d.udp_datastream
{<portPosition.TOP: 2>: False, <portPosition.BOTTOM: 3>: True}
Multiple detectors with identical states:
>>> d.udp_datastream
{<portPosition.TOP: 2>: False, <portPosition.BOTTOM: 3>: True}
Multiple detectors with different states:
>>> d.udp_datastream
{<portPosition.TOP: 2>: [False, True], <portPosition.BOTTOM: 3>: [True, True]}
Enable UDP streaming for a specific port:
>>> from slsdet import portPosition
>>> d.udp_datastream = (portPosition.TOP, True)
Disable UDP streaming for a specific port:
>>> d.udp_datastream = (portPosition.BOTTOM, False)
"""
result = {}
for port in [defs.LEFT, defs.RIGHT]:
result[port] = element_if_equal(self.getDataStream(port))
if self.type in [detectorType.JUNGFRAU, detectorType.MOENCH]:
ports = [defs.TOP, defs.BOTTOM]
else:
ports = [defs.LEFT, defs.RIGHT]
for port in ports:
result[port] = element_if_equal(self.getUDPDataStream(port))
return result
@datastream.setter
def datastream(self, value):
ut.set_using_dict(self.setDataStream, *value)
@udp_datastream.setter
def udp_datastream(self, value):
self.setUDPDataStream(*value)
@property
@element
@@ -2473,7 +2517,7 @@ class Detector(CppDetectorApi):
>>> d.subexptime = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.subexptime = timedelta(seconds = 1.23, microseconds = 203)
>>>
>>> # using DurationWrapper to set in seconds
@@ -2539,7 +2583,7 @@ class Detector(CppDetectorApi):
>>> d.subdeadtime = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.subdeadtime = timedelta(seconds = 1.23, microseconds = 203)
>>>
>>> # using DurationWrapper to set in seconds
@@ -2736,7 +2780,7 @@ class Detector(CppDetectorApi):
>>> d.compdisabletime = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.compdisabletime = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -2829,7 +2873,7 @@ class Detector(CppDetectorApi):
>>> d.storagecell_delay = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.storagecell_delay = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -3175,7 +3219,7 @@ class Detector(CppDetectorApi):
>>> d.burstperiod = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.burstperiod = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
@@ -3335,7 +3379,7 @@ class Detector(CppDetectorApi):
>>> d.gatedelay = 5e-07
>>>
>>> # using timedelta (up to microseconds precision)
>>> from datatime import timedelta
>>> from datetime import timedelta
>>> d.gatedelay = timedelta(seconds = 1, microseconds = 3)
>>>
>>> # using DurationWrapper to set in seconds
+18 -12
View File
@@ -653,9 +653,9 @@ void init_det(py::module &m) {
Detector::getNumberofUDPInterfaces,
py::arg() = Positions{});
CppDetectorApi.def("setNumberofUDPInterfaces",
(void (Detector::*)(int, sls::Positions)) &
(void (Detector::*)(int)) &
Detector::setNumberofUDPInterfaces,
py::arg(), py::arg() = Positions{});
py::arg());
CppDetectorApi.def("getSelectedUDPInterface",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getSelectedUDPInterface,
@@ -841,6 +841,22 @@ void init_det(py::module &m) {
CppDetectorApi.def(
"setTransmissionDelay",
(void (Detector::*)(int)) & Detector::setTransmissionDelay, py::arg());
CppDetectorApi.def("getUDPDataStream",
(Result<bool>(Detector::*)(const defs::portPosition,
sls::Positions) const) &
Detector::getUDPDataStream,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def("setUDPDataStream",
(void (Detector::*)(const defs::portPosition, const bool,
sls::Positions)) &
Detector::setUDPDataStream,
py::arg(), py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getRxDisabledUDPPortIndices",
(std::vector<int>(Detector::*)() const) &
Detector::getRxDisabledUDPPortIndices);
CppDetectorApi.def("getPortPositionList",
(std::vector<defs::portPosition>(Detector::*)() const) &
Detector::getPortPositionList);
CppDetectorApi.def("getUseReceiverFlag",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getUseReceiverFlag,
@@ -1174,16 +1190,6 @@ void init_det(py::module &m) {
CppDetectorApi.def("setQuad",
(void (Detector::*)(const bool)) & Detector::setQuad,
py::arg());
CppDetectorApi.def("getDataStream",
(Result<bool>(Detector::*)(const defs::portPosition,
sls::Positions) const) &
Detector::getDataStream,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def("setDataStream",
(void (Detector::*)(const defs::portPosition, const bool,
sls::Positions)) &
Detector::setDataStream,
py::arg(), py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getTop",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getTop,
+87 -3
View File
@@ -11,9 +11,8 @@ from utils_for_test import (
LogLevel,
)
from slsdet import Detector
from slsdet._slsdet import slsDetectorDefs
from slsdet.utils import all_equal, element_if_equal
detectorType = slsDetectorDefs.detectorType
@@ -919,4 +918,89 @@ def test_type(session_simulator):
def test_numinterfaces(session_simulator):
d = Detector()
assert d.numinterfaces == 1
assert d.numinterfaces == 1
@pytest.mark.detectorintegration
def test_udp_datastream(session_simulator, request):
""" Test using udp_datastream for eiger, jungfrau and moench."""
det_type, num_interfaces, num_mods, d = session_simulator
assert d is not None
from slsdet import portPosition
if det_type in ['eiger']:
ports = [portPosition.LEFT, portPosition.RIGHT]
prev = [d.getUDPDataStream(i) for i in ports]
# ensure all equal for each value in prev
assert all_equal(prev)
prev_val = [element_if_equal(v) for v in prev]
#list
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (ports[0], [True, False])
# invalid port position
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (portPosition.TOP, True)
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (portPosition.BOTTOM, True)
# without port position
with pytest.raises(Exception) as exc_info:
d.udp_datastream = True
d.udp_datastream = (ports[0], False)
assert d.udp_datastream[ports[0]] is False
d.udp_datastream = (ports[1], False)
assert d.udp_datastream[ports[1]] is False
d.udp_datastream = (ports[0], True)
assert d.udp_datastream[ports[0]] is True
d.udp_datastream = (ports[1], True)
assert d.udp_datastream[ports[1]] is True
d.setUDPDataStream(ports[0], element_if_equal(prev[0]))
d.setUDPDataStream(ports[1], element_if_equal(prev[1]))
elif det_type in ['jungfrau', 'moench'] and num_interfaces == 2:
ports = [portPosition.TOP, portPosition.BOTTOM]
prev = [d.getUDPDataStream(i) for i in ports]
# ensure all equal for each value in prev
assert all_equal(prev)
prev_val = [element_if_equal(v) for v in prev]
#list
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (ports[0], [True, False])
# invalid port position
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (portPosition.LEFT, True)
with pytest.raises(Exception) as exc_info:
d.udp_datastream = (portPosition.RIGHT, True)
# without port position
with pytest.raises(Exception) as exc_info:
d.udp_datastream = True
d.udp_datastream = (ports[0], False)
assert d.udp_datastream[ports[0]] is False
d.udp_datastream = (ports[1], False)
assert d.udp_datastream[ports[1]] is False
d.udp_datastream = (ports[0], True)
assert d.udp_datastream[ports[0]] is True
d.udp_datastream = (ports[1], True)
assert d.udp_datastream[ports[1]] is True
d.setUDPDataStream(ports[0], element_if_equal(prev[0]))
d.setUDPDataStream(ports[1], element_if_equal(prev[1]))
else:
with pytest.raises(Exception) as exc_info:
d.udp_datastream
Log(LogLevel.INFOGREEN, f"{request.node.name} passed")
@@ -80,7 +80,7 @@ _sd() {
local IS_PATH=0
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_streamdummyheader rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_streamdummyheader rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_datastream udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -600,23 +600,6 @@ fi
fi
return 0
}
__datastream() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="0 1"
fi
fi
return 0
}
__dbitclk() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
@@ -2993,6 +2976,23 @@ __udp_cleardst() {
FCN_RETURN=""
return 0
}
__udp_datastream() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="0 1"
fi
fi
return 0
}
__udp_dstip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@
_sd() {
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_streamdummyheader rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port power powerchip powerdac powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_streamdummyheader rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_datastream udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -524,23 +524,6 @@ fi
fi
return 0
}
__datastream() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="0 1"
fi
fi
return 0
}
__dbitclk() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
@@ -2917,6 +2900,23 @@ __udp_cleardst() {
FCN_RETURN=""
return 0
}
__udp_datastream() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="bottom left right top"
fi
if [[ "${cword}" == "3" ]]; then
FCN_RETURN="0 1"
fi
fi
return 0
}
__udp_dstip() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then
+13 -13
View File
@@ -826,15 +826,6 @@ nextframenumber:
function: setNextFrameNumber
input_types: [ uint64_t ]
numinterfaces:
help: "[1, 2]\n\t[Jungfrau][Moench] Number of udp interfaces to stream data from detector. Default: 1.\n\tAlso enables second interface in receiver for listening (Writes a file per interface if writing enabled).\n\tAlso restarts client and receiver zmq sockets if zmq streaming enabled.\n\t[Eiger] Only gets with result 2."
inherit_actions: INTEGER_COMMAND_VEC_ID
actions:
GET:
function: getNumberofUDPInterfaces
PUT:
function: setNumberofUDPInterfaces
selinterface:
help: "[0, 1]\n\t[Jungfrau][Moench] The udp interface to stream data from detector. Effective only when number of interfaces is 1. Default: 0 (outer)"
inherit_actions: INTEGER_COMMAND_VEC_ID
@@ -1521,6 +1512,15 @@ zmqport:
function: setClientZmqPort
################# INTEGER_COMMAND_SET_NOID_GET_ID ############
numinterfaces:
help: "[1, 2]\n\t[Jungfrau][Moench] Number of udp interfaces to stream data from detector. Default: 1.\n\tAlso enables second interface in receiver for listening (Writes a file per interface if writing enabled).\n\tAlso restarts client and receiver zmq sockets if zmq streaming enabled.\n\t[Eiger] Only gets with result 2."
inherit_actions: INTEGER_COMMAND_SET_NOID_GET_ID
actions:
GET:
function: getNumberofUDPInterfaces
PUT:
function: setNumberofUDPInterfaces
sync:
inherit_actions: INTEGER_COMMAND_SET_NOID_GET_ID
help: "[0, 1]\n\t[Jungfrau][Moench] Enables or disables synchronization between modules. Sync mode requires at least one master configured. Also requires flatband cabling between master and slave with termination board."
@@ -3617,13 +3617,13 @@ quad:
cast_input: [ true ]
output: [ args.front() ]
datastream:
help: "[left|right] [0, 1]\n\t[Eiger] Enables or disables data streaming from left or/and right side of detector for 10 GbE mode. 1 (enabled) by default."
udp_datastream:
help: "[left|right|top|bottom] [0, 1]\n\tEnables or disables UDP data streaming from left or right of 10GbE UDP port of the detector. Options: left, right. Both ports are enabled (1) by default.\n\tEnables or disables UDP data streaming from the top or bottom of receiver. This option is available only when numinterfaces is set to 2. Options: top, bottom. Both interfaces are enabled (1) by default."
actions:
GET:
argc: 1
require_det_id: true
function: getDataStream
function: getUDPDataStream
input: [ 'args[0]' ]
input_types: [ defs::portPosition ]
cast_input: [ true ]
@@ -3631,7 +3631,7 @@ datastream:
PUT:
argc: 2
require_det_id: true
function: setDataStream
function: setUDPDataStream
input: [ 'args[0]', 'args[1]' ]
input_types: [ defs::portPosition, bool ]
cast_input: [ true, true ]
@@ -1,4 +1,3 @@
#configuration
detectorversion: firmwareversion
softwareversion: detectorserverversion
receiverversion: rx_version
@@ -8,8 +7,6 @@ detsizechan: detsize
trimdir: settingspath
settingsdir: settingspath
flippeddatax: fliprows
#acquisition parameters
cycles: triggers
cyclesl: triggersl
clkdivider: readoutspeed
@@ -18,10 +15,6 @@ vhighvoltage: highvoltage
digitest: imagetest
filter: filterresistor
readnlines: readnrows
# temperature
# super old dacs
vtr: vtrim
vrf: vrpreamp
vrs: vrshaper
@@ -33,8 +26,6 @@ vshaperneg: vrshaper_n
viinsh: vishaper
vpl: vcal_n
vph: vcal_p
# dacs
vthreshold: dac
vsvp: dac
vsvn: dac
@@ -93,17 +84,11 @@ vb_sda: dac
vcasc_sfp: dac
vipre_cds: dac
ibias_sfp: dac
defaultdacs: resetdacs
#acquisition
busy: clearbusy
receiver: rx_status
framescaught: rx_framescaught
startingfnum: nextframenumber
#Network Configuration (Detector<->Receiver)
detectorip: udp_srcip
detectorip2: udp_srcip2
detectormac: udp_srcmac
@@ -118,15 +103,11 @@ flowcontrol_10g: flowcontrol10g
txndelay_frame: txdelay_frame
txndelay_left: txdelay_left
txndelay_right: txdelay_right
#Receiver Config
r_silent: rx_silent
r_discardpolicy: rx_discardpolicy
r_padding: rx_padding
r_lock: rx_lock
r_lastclient: rx_lastclient
#File
fileformat: fformat
outdir: fpath
index: findex
@@ -134,23 +115,13 @@ enablefwrite: fwrite
masterfile: fmaster
overwrite: foverwrite
r_framesperfile: rx_framesperfile
#ZMQ Streaming Parameters (Receiver<->Client)
r_readfreq: rx_zmqfreq
rx_readfreq: rx_zmqfreq
rx_datastream: rx_zmqstream
#Eiger Specific
resmat: partialreset
#Jungfrau Specific
storagecells: extrastoragecells
auto_comp_disable: autocompdisable
comp_disable_time: compdisabletime
#Gotthard2 Specific
#Mythen3 Specific
#CTB Specific
adc: slowadc
flags: romode
i_a: im_a
@@ -158,16 +129,10 @@ i_b: im_b
i_c: im_c
i_d: im_d
i_io: im_io
#Pattern
patternX: pattern
#Moench
#Advanced
copydetectorserver: updatedetectorserver
#Insignificant
nframes: framecounter
now: runtime
timestamp: frametime
frameindex: rx_frameindex
frameindex: rx_frameindex
datastream: udp_datastream
@@ -2038,53 +2038,6 @@ dacvalues:
help: ''
infer_action: true
is_description: true
datastream:
actions:
GET:
args:
- arg_types:
- defs::portPosition
argc: 1
cast_input:
- true
check_det_id: false
convert_det_id: true
function: getDataStream
input:
- args[0]
input_types:
- defs::portPosition
output:
- OutString(t)
require_det_id: true
store_result_in_t: true
PUT:
args:
- arg_types:
- defs::portPosition
- bool
argc: 2
cast_input:
- true
- true
check_det_id: false
convert_det_id: true
function: setDataStream
input:
- args[0]
- args[1]
input_types:
- defs::portPosition
- bool
output:
- ToString(args)
require_det_id: true
store_result_in_t: false
command_name: datastream
function_alias: datastream
help: "[left|right] [0, 1]\n\t[Eiger] Enables or disables data streaming from left\
\ or/and right side of detector for 10 GbE mode. 1 (enabled) by default."
infer_action: true
dbitclk:
actions:
GET:
@@ -5671,7 +5624,7 @@ numinterfaces:
argc: 1
cast_input:
- true
check_det_id: false
check_det_id: true
convert_det_id: true
function: setNumberofUDPInterfaces
input:
@@ -5680,7 +5633,7 @@ numinterfaces:
- int
output:
- args.front()
require_det_id: true
require_det_id: false
store_result_in_t: false
command_name: numinterfaces
function_alias: numinterfaces
@@ -12035,6 +11988,56 @@ udp_cleardst:
help: "\n\tClears udp destination details on the detector."
infer_action: true
template: true
udp_datastream:
actions:
GET:
args:
- arg_types:
- defs::portPosition
argc: 1
cast_input:
- true
check_det_id: false
convert_det_id: true
function: getUDPDataStream
input:
- args[0]
input_types:
- defs::portPosition
output:
- OutString(t)
require_det_id: true
store_result_in_t: true
PUT:
args:
- arg_types:
- defs::portPosition
- bool
argc: 2
cast_input:
- true
- true
check_det_id: false
convert_det_id: true
function: setUDPDataStream
input:
- args[0]
- args[1]
input_types:
- defs::portPosition
- bool
output:
- ToString(args)
require_det_id: true
store_result_in_t: false
command_name: udp_datastream
function_alias: udp_datastream
help: "[left|right|top|bottom] [0, 1]\n\tEnables or disables UDP data streaming\
\ from left or right of 10GbE UDP port of the detector. Options: left, right.\
\ Both ports are enabled (1) by default.\n\tEnables or disables UDP data streaming\
\ from the top or bottom of receiver. This option is available only when numinterfaces\
\ is set to 2. Options: top, bottom. Both interfaces are enabled (1) by default."
infer_action: true
udp_dstip:
actions:
GET:
+35 -13
View File
@@ -719,8 +719,9 @@ class Detector {
* restarts client and receiver zmq sockets if zmq streaming enabled. \n
* [Gotthard2] second interface enabled to send veto information via 10Gbps
* for debugging. By default, if veto enabled, it is sent via 2.5 gbps
* interface. \nSetting this resets the receiver roi */
void setNumberofUDPInterfaces(int n, Positions pos = {});
* interface. \nSetting this resets the receiver roi and any udp datastream
* disables */
void setNumberofUDPInterfaces(int n);
/** [Jungfrau][Moench] */
Result<int> getSelectedUDPInterface(Positions pos = {}) const;
@@ -897,6 +898,37 @@ class Detector {
*/
void setTransmissionDelay(int step);
/** [Eiger] Returns whether the 10GbE UDP data stream from detector is
* enabled. Options: LEFT, RIGHT [Jungfrau][Moench] Returns whether the UDP
* data stream from receiver is enabled. Options: TOP, BOTTOM
*
*/
Result<bool> getUDPDataStream(const defs::portPosition port,
Positions pos = {}) const;
/** [Eiger] Enables or disables UDP data streaming from left or right of
* 10GbE UDP port of the detector. Default: enabled. Options: LEFT, RIGHT \n
* [Jungfrau][Moench] Enables or disables UDP data streaming from the top or
* bottom of receiver. Default: enabled. Options: TOP, BOTTOM. This option
* is available only when numinterfaces is set to 2.
*/
void setUDPDataStream(const defs::portPosition port, const bool enable,
Positions pos = {});
/** List of disabled UDP ports with index (moduleIndex * 2 + portIndex),
* where portIndex is 0 for BOTTOM/LEFT port, and 1 for TOP/RIGHT port.
* It is the index with 'd' in the file name when writing data. \n
* [Eiger] LEFT, RIGHT
* [Jungfrau][Moench] TOP, BOTTOM
* This feature is available only when numinterfaces is set to 2.
*/
std::vector<int> getRxDisabledUDPPortIndices() const;
/** list of possible port positions.
* [Eiger] LEFT, RIGHT
* [Jungfrau][Moench] TOP, BOTTOM
*/
std::vector<defs::portPosition> getPortPositionList() const;
///@}
/** @name Receiver Configuration */
@@ -1252,16 +1284,6 @@ class Detector {
* hardware required). */
void setQuad(const bool enable);
/** [Eiger] */
Result<bool> getDataStream(const defs::portPosition port,
Positions pos = {}) const;
/** [Eiger] enable or disable data streaming from left or right of detector
* for 10GbE. Default: enabled
*/
void setDataStream(const defs::portPosition port, const bool enable,
Positions pos = {});
/** [Eiger] Advanced */
Result<bool> getTop(Positions pos = {}) const;
@@ -2272,7 +2294,7 @@ class Detector {
private:
std::vector<uint16_t> getValidPortNumbers(uint16_t start_port);
void updateRxRateCorrections();
void setNumberofUDPInterfaces_(int n, Positions pos);
void setNumberofUDPInterfaces_(int n);
};
} // namespace sls
+82 -77
View File
@@ -2426,82 +2426,6 @@ std::string Caller::dacname(int action) {
return os.str();
}
std::string Caller::datastream(int action) {
std::ostringstream os;
// print help
if (action == slsDetectorDefs::HELP_ACTION) {
os << R"V0G0N([left|right] [0, 1]
[Eiger] Enables or disables data streaming from left or/and right side of detector for 10 GbE mode. 1 (enabled) by default. )V0G0N"
<< std::endl;
return os.str();
}
// check if action and arguments are valid
if (action == slsDetectorDefs::GET_ACTION) {
if (1 && args.size() != 1) {
throw RuntimeError("Wrong number of arguments for action GET");
}
if (args.size() == 1) {
try {
StringTo<defs::portPosition>(args[0]);
} catch (...) {
throw RuntimeError(
"Could not convert argument 0 to defs::portPosition");
}
}
}
else if (action == slsDetectorDefs::PUT_ACTION) {
if (1 && args.size() != 2) {
throw RuntimeError("Wrong number of arguments for action PUT");
}
if (args.size() == 2) {
try {
StringTo<defs::portPosition>(args[0]);
} catch (...) {
throw RuntimeError(
"Could not convert argument 0 to defs::portPosition");
}
try {
StringTo<bool>(args[1]);
} catch (...) {
throw RuntimeError("Could not convert argument 1 to bool");
}
}
}
else {
throw RuntimeError("INTERNAL ERROR: Invalid action: supported actions "
"are ['GET', 'PUT']");
}
// generate code for each action
if (action == slsDetectorDefs::GET_ACTION) {
if (args.size() == 1) {
auto arg0 = StringTo<defs::portPosition>(args[0]);
auto t = det->getDataStream(arg0, std::vector<int>{det_id});
os << OutString(t) << '\n';
}
}
if (action == slsDetectorDefs::PUT_ACTION) {
if (args.size() == 2) {
auto arg0 = StringTo<defs::portPosition>(args[0]);
auto arg1 = StringTo<bool>(args[1]);
det->setDataStream(arg0, arg1, std::vector<int>{det_id});
os << ToString(args) << '\n';
}
}
return os.str();
}
std::string Caller::dbitclk(int action) {
std::ostringstream os;
@@ -7052,8 +6976,12 @@ std::string Caller::numinterfaces(int action) {
if (action == slsDetectorDefs::PUT_ACTION) {
if (args.size() == 1) {
if (det_id != -1) {
throw RuntimeError(
"Cannot execute numinterfaces at module level");
}
auto arg0 = StringTo<int>(args[0]);
det->setNumberofUDPInterfaces(arg0, std::vector<int>{det_id});
det->setNumberofUDPInterfaces(arg0);
os << args.front() << '\n';
}
}
@@ -14985,6 +14913,83 @@ std::string Caller::udp_cleardst(int action) {
return os.str();
}
std::string Caller::udp_datastream(int action) {
std::ostringstream os;
// print help
if (action == slsDetectorDefs::HELP_ACTION) {
os << R"V0G0N([left|right|top|bottom] [0, 1]
Enables or disables UDP data streaming from left or right of 10GbE UDP port of the detector. Options: left, right. Both ports are enabled (1) by default.
Enables or disables UDP data streaming from the top or bottom of receiver. This option is available only when numinterfaces is set to 2. Options: top, bottom. Both interfaces are enabled (1) by default. )V0G0N"
<< std::endl;
return os.str();
}
// check if action and arguments are valid
if (action == slsDetectorDefs::GET_ACTION) {
if (1 && args.size() != 1) {
throw RuntimeError("Wrong number of arguments for action GET");
}
if (args.size() == 1) {
try {
StringTo<defs::portPosition>(args[0]);
} catch (...) {
throw RuntimeError(
"Could not convert argument 0 to defs::portPosition");
}
}
}
else if (action == slsDetectorDefs::PUT_ACTION) {
if (1 && args.size() != 2) {
throw RuntimeError("Wrong number of arguments for action PUT");
}
if (args.size() == 2) {
try {
StringTo<defs::portPosition>(args[0]);
} catch (...) {
throw RuntimeError(
"Could not convert argument 0 to defs::portPosition");
}
try {
StringTo<bool>(args[1]);
} catch (...) {
throw RuntimeError("Could not convert argument 1 to bool");
}
}
}
else {
throw RuntimeError("INTERNAL ERROR: Invalid action: supported actions "
"are ['GET', 'PUT']");
}
// generate code for each action
if (action == slsDetectorDefs::GET_ACTION) {
if (args.size() == 1) {
auto arg0 = StringTo<defs::portPosition>(args[0]);
auto t = det->getUDPDataStream(arg0, std::vector<int>{det_id});
os << OutString(t) << '\n';
}
}
if (action == slsDetectorDefs::PUT_ACTION) {
if (args.size() == 2) {
auto arg0 = StringTo<defs::portPosition>(args[0]);
auto arg1 = StringTo<bool>(args[1]);
det->setUDPDataStream(arg0, arg1, std::vector<int>{det_id});
os << ToString(args) << '\n';
}
}
return os.str();
}
std::string Caller::udp_dstlist(int action) {
std::ostringstream os;
+3 -2
View File
@@ -105,7 +105,6 @@ class Caller {
std::string daclist(int action);
std::string dacname(int action);
std::string dacvalues(int action);
std::string datastream(int action);
std::string dbitclk(int action);
std::string dbitphase(int action);
std::string dbitpipeline(int action);
@@ -345,6 +344,7 @@ class Caller {
std::string txdelay_right(int action);
std::string type(int action);
std::string udp_cleardst(int action);
std::string udp_datastream(int action);
std::string udp_dstip(int action);
std::string udp_dstip2(int action);
std::string udp_dstlist(int action);
@@ -474,7 +474,6 @@ class Caller {
{"daclist", &Caller::daclist},
{"dacname", &Caller::dacname},
{"dacvalues", &Caller::dacvalues},
{"datastream", &Caller::datastream},
{"dbitclk", &Caller::dbitclk},
{"dbitphase", &Caller::dbitphase},
{"dbitpipeline", &Caller::dbitpipeline},
@@ -718,6 +717,7 @@ class Caller {
{"txdelay_right", &Caller::txdelay_right},
{"type", &Caller::type},
{"udp_cleardst", &Caller::udp_cleardst},
{"udp_datastream", &Caller::udp_datastream},
{"udp_dstip", &Caller::udp_dstip},
{"udp_dstip2", &Caller::udp_dstip2},
{"udp_dstlist", &Caller::udp_dstlist},
@@ -903,6 +903,7 @@ class Caller {
{"now", "runtime"},
{"timestamp", "frametime"},
{"frameindex", "rx_frameindex"},
{"datastream", "udp_datastream"},
};
+26 -18
View File
@@ -1082,17 +1082,17 @@ Result<int> Detector::getNumberofUDPInterfaces(Positions pos) const {
return pimpl->Parallel(&Module::getNumberofUDPInterfacesFromShm, pos);
}
void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
void Detector::setNumberofUDPInterfaces(int n) {
auto detType = getDetectorType().squash();
if (detType != defs::JUNGFRAU && detType != defs::MOENCH) {
throw RuntimeError(
"Cannot set number of udp interfaces for this detector.");
}
// also called by vetostream (for gotthard2)
setNumberofUDPInterfaces_(n, pos);
setNumberofUDPInterfaces_(n);
}
void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
void Detector::setNumberofUDPInterfaces_(int n) {
if (!size()) {
throw RuntimeError("No modules added.");
}
@@ -1102,10 +1102,10 @@ void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
bool previouslyReceiverStreaming = false;
uint16_t rxStartingPort = 0;
if (useReceiver) {
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
previouslyReceiverStreaming = getRxZmqDataStream().squash(true);
rxStartingPort = getRxZmqPort({0}).squash(0);
}
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
pimpl->Parallel(&Module::setNumberofUDPInterfaces, {}, n);
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
setClientZmqPort(clientStartingPort, -1);
if (getUseReceiverFlag().squash(false)) {
@@ -1117,8 +1117,8 @@ void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
pimpl->setDataStreamingToClient(true);
}
if (previouslyReceiverStreaming) {
setRxZmqDataStream(false, pos);
setRxZmqDataStream(true, pos);
setRxZmqDataStream(false);
setRxZmqDataStream(true);
}
}
@@ -1317,6 +1317,24 @@ void Detector::setTransmissionDelay(int step) {
pimpl->setTransmissionDelay(step);
}
Result<bool> Detector::getUDPDataStream(const defs::portPosition port,
Positions pos) const {
return pimpl->getUDPDataStream(port, pos);
}
void Detector::setUDPDataStream(const defs::portPosition port,
const bool enable, Positions pos) {
pimpl->setUDPDataStream(port, enable, pos);
}
std::vector<int> Detector::getRxDisabledUDPPortIndices() const {
return pimpl->getRxDisabledUDPPortIndices();
}
std::vector<defs::portPosition> Detector::getPortPositionList() const {
return pimpl->getPortPositionList();
}
// Receiver
Result<bool> Detector::getUseReceiverFlag(Positions pos) const {
@@ -1750,16 +1768,6 @@ void Detector::setQuad(const bool enable) {
pimpl->Parallel(&Module::setQuad, {}, enable);
}
Result<bool> Detector::getDataStream(const defs::portPosition port,
Positions pos) const {
return pimpl->Parallel(&Module::getDataStream, pos, port);
}
void Detector::setDataStream(const defs::portPosition port, const bool enable,
Positions pos) {
pimpl->Parallel(&Module::setDataStream, pos, port, enable);
}
Result<bool> Detector::getTop(Positions pos) const {
return pimpl->Parallel(&Module::getTop, pos);
}
@@ -2012,7 +2020,7 @@ void Detector::setVetoStream(defs::streamingInterface interface,
? 2
: 1);
if (numinterfaces != old_numinterfaces) {
setNumberofUDPInterfaces_(numinterfaces, pos);
setNumberofUDPInterfaces_(numinterfaces);
}
}
+114 -43
View File
@@ -1126,10 +1126,17 @@ int DetectorImpl::acquire() {
// start receiver
if (receiver) {
Parallel(&Module::startReceiver, {});
}
startProcessingThread(receiver);
// to catch dummy zmq packets for disabled ports,
// start processing thread before startReceiver
if (dataReady != nullptr)
startRxZmqProcessingThread();
Parallel(&Module::startReceiver, {});
if (dataReady == nullptr)
startRxProgressThread();
}
// start and read all
try {
@@ -1314,53 +1321,46 @@ void DetectorImpl::printProgress(double progress) {
std::cout << '\r' << std::flush;
}
void DetectorImpl::startProcessingThread(bool receiver) {
void DetectorImpl::startRxZmqProcessingThread() {
dataProcessingThread =
std::thread(&DetectorImpl::processData, this, receiver);
std::thread(&DetectorImpl::readFrameFromReceiver, this);
}
void DetectorImpl::processData(bool receiver) {
if (receiver) {
if (dataReady != nullptr) {
readFrameFromReceiver();
}
// only update progress
else {
LOG(logINFO) << "Type 'q' and hit enter to stop acquisition";
double progress = 0;
printProgress(progress);
void DetectorImpl::startRxProgressThread() {
dataProcessingThread = std::thread(&DetectorImpl::printRxProgress, this);
}
while (true) {
// to exit acquire by typing q
if (kbhit() != 0) {
if (fgetc(stdin) == 'q') {
LOG(logINFO)
<< "Caught the command to stop acquisition";
stopDetector({});
}
}
// get and print progress
double temp =
(double)Parallel(&Module::getReceiverProgress, {0})
.squash();
if (temp != progress) {
printProgress(progress);
progress = temp;
}
void DetectorImpl::printRxProgress() {
LOG(logINFO) << "Type 'q' and hit enter to stop acquisition";
double progress = 0;
printProgress(progress);
// exiting loop
if (getJoinThreadFlag()) {
// print progress one final time before exiting
progress =
(double)Parallel(&Module::getReceiverProgress, {0})
.squash();
printProgress(progress);
break;
}
// otherwise error when connecting to the receiver too fast
std::this_thread::sleep_for(std::chrono::milliseconds(100));
while (true) {
// to exit acquire by typing q
if (kbhit() != 0) {
if (fgetc(stdin) == 'q') {
LOG(logINFO) << "Caught the command to stop acquisition";
stopDetector({});
}
}
// get and print progress
double temp =
(double)Parallel(&Module::getReceiverProgress, {0}).squash();
if (temp != progress) {
progress = temp;
printProgress(progress);
}
// exiting loop
if (getJoinThreadFlag()) {
// print progress one final time before exiting
progress =
(double)Parallel(&Module::getReceiverProgress, {0}).squash();
printProgress(progress);
break;
}
// otherwise error when connecting to the receiver too fast
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
@@ -1644,6 +1644,77 @@ void DetectorImpl::verifyUniqueHost(
}
}
void DetectorImpl::assertTwoUDPDataInterfaces(const std::string &cmd) const {
// assert globally
auto numInterfaces =
Parallel(&Module::getNumberofUDPInterfacesFromShm, {})
.tsquash("Inconsistent number of UDP interfaces among modules");
if (numInterfaces != 2) {
throw RuntimeError(
"Cannot " + cmd +
". Change number of udp interfaces to 2 (cmd = numinterfaces).");
}
}
Result<bool> DetectorImpl::getUDPDataStream(const defs::portPosition port,
Positions pos) const {
assertTwoUDPDataInterfaces("get enable/disable UDP ports");
return Parallel(&Module::getUDPDataStream, pos, port);
}
void DetectorImpl::setUDPDataStream(const defs::portPosition port,
const bool enable, Positions pos) {
assertTwoUDPDataInterfaces("set enable/disable UDP ports");
Parallel(&Module::setUDPDataStream, pos, port, enable);
updateRxUDPDatastreamMetadata();
}
void DetectorImpl::updateRxUDPDatastreamMetadata() {
assertTwoUDPDataInterfaces(
"update Disbaled UDP ports metadata in receiver");
std::vector<int> disable;
auto portList = getPortPositionList();
if (portList.size() != 2) {
throw RuntimeError("Invalid port size. Expected 2.");
}
// bottom and left is port 0
auto port0 = Parallel(&Module::getUDPDataStream, {}, portList[0]);
auto port1 = Parallel(&Module::getUDPDataStream, {}, portList[1]);
// if any of them are disabled
if (port0.any(false) || port1.any(false)) {
// for each module: if disabled, push port index
for (size_t i = 0; i != port0.size(); ++i) {
if (!port0[i]) {
disable.push_back(i * 2);
}
if (!port1[i]) {
disable.push_back(i * 2 + 1);
}
}
}
modules[0]->updateRxUDPPortDisableMetadata(disable);
}
std::vector<int> DetectorImpl::getRxDisabledUDPPortIndices() const {
assertTwoUDPDataInterfaces("get Disbaled UDP ports metadata from receiver");
return modules[0]->getRxUDPPortDisableMetadata();
}
std::vector<defs::portPosition> DetectorImpl::getPortPositionList() const {
switch (shm()->detType) {
case defs::JUNGFRAU:
case defs::MOENCH:
return std::vector<defs::portPosition>{defs::BOTTOM, defs::TOP};
case defs::EIGER:
return std::vector<defs::portPosition>{defs::LEFT, defs::RIGHT};
default:
throw RuntimeError("port Position does not exist for this detector");
}
}
std::vector<defs::ROI> DetectorImpl::getRxROI(int module_id) const {
if (shm()->detType == CHIPTESTBOARD ||
shm()->detType == defs::XILINX_CHIPTESTBOARD) {
+13 -4
View File
@@ -278,10 +278,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
void stopDetector(Positions pos);
/**
* Combines data from all readouts and gives it to the gui
* or just gives progress of acquisition by polling receivers
* gives progress of acquisition by polling receivers
*/
void processData(bool receiver);
void printRxProgress();
/**
* Convert raw file
@@ -310,6 +309,15 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<std::pair<std::string, uint16_t>>
verifyUniqueRxHost(const std::vector<std::string> &names) const;
void assertTwoUDPDataInterfaces(const std::string &cmd) const;
Result<bool> getUDPDataStream(const defs::portPosition port,
Positions pos) const;
void setUDPDataStream(const defs::portPosition port, const bool enable,
Positions pos);
void updateRxUDPDatastreamMetadata();
std::vector<int> getRxDisabledUDPPortIndices() const;
std::vector<defs::portPosition> getPortPositionList() const;
defs::xy getPortGeometry() const;
std::vector<defs::ROI> getRxROI(int module_id = -1) const;
void setRxROI(const std::vector<defs::ROI> &args);
@@ -441,7 +449,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
void printProgress(double progress);
void startProcessingThread(bool receiver);
void startRxZmqProcessingThread();
void startRxProgressThread();
/**
* Check if processing thread is ready to join main thread
+70 -12
View File
@@ -1407,6 +1407,76 @@ void Module::setTransmissionDelayRight(int value) {
sendToDetector(F_SET_TRANSMISSION_DELAY_RIGHT, value, nullptr);
}
bool Module::getUDPDataStream(const portPosition port) const {
// receiver only
if (shm()->detType == JUNGFRAU || shm()->detType == MOENCH) {
if (!shm()->useReceiverFlag) {
throw RuntimeError("No receiver to get udp datastream.");
}
return sendToReceiver<int>(F_RECEIVER_GET_UDP_DATASTREAM,
static_cast<int>(port));
} else
return sendToDetector<int>(F_GET_DATASTREAM, static_cast<int>(port));
}
void Module::setUDPDataStream(const portPosition port, const bool enable) {
int args[]{static_cast<int>(port), static_cast<int>(enable)};
if (shm()->detType == JUNGFRAU || shm()->detType == MOENCH) {
if (!shm()->useReceiverFlag) {
throw RuntimeError("No receiver to set udp datastream.");
}
sendToReceiver(F_RECEIVER_SET_UDP_DATASTREAM, args, nullptr);
} else {
sendToDetector(F_SET_DATASTREAM, args, nullptr);
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_UDP_DATASTREAM, args, nullptr);
}
}
}
void Module::updateRxUDPPortDisableMetadata(const std::vector<int> &disable) {
if (!shm()->useReceiverFlag) {
return;
}
LOG(logDEBUG) << "Updating UDP port disable metadata in Receiver 0";
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(F_RECEIVER_SET_UDP_PORT_DISABLE_META);
client.setFnum(F_RECEIVER_SET_UDP_PORT_DISABLE_META);
auto nports = static_cast<int>(disable.size());
client.Send(nports);
if (nports > 0) {
client.Send(disable);
}
if (client.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
std::vector<int> Module::getRxUDPPortDisableMetadata() const {
if (!shm()->useReceiverFlag) {
throw RuntimeError("No receiver to get disabled udp port indices.");
}
LOG(logDEBUG) << "Getting UDP port disable metadata in Receiver 0";
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(F_RECEIVER_GET_UDP_PORT_DISABLE_META);
client.setFnum(F_RECEIVER_GET_UDP_PORT_DISABLE_META);
if (client.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
auto nports = client.Receive<int>();
std::vector<int> retval(nports);
if (nports > 0) {
client.Receive(retval);
}
return retval;
}
// Receiver Config
bool Module::getUseReceiverFlag() const { return shm()->useReceiverFlag; }
@@ -1948,18 +2018,6 @@ void Module::setQuad(const bool enable) {
}
}
bool Module::getDataStream(const portPosition port) const {
return sendToDetector<int>(F_GET_DATASTREAM, static_cast<int>(port));
}
void Module::setDataStream(const portPosition port, const bool enable) {
int args[]{static_cast<int>(port), static_cast<int>(enable)};
sendToDetector(F_SET_DATASTREAM, args, nullptr);
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_DATASTREAM, args, nullptr);
}
}
bool Module::getTop() const {
return (static_cast<bool>(sendToDetector<int>(F_GET_TOP)));
}
+4 -2
View File
@@ -279,6 +279,10 @@ class Module : public virtual slsDetectorDefs {
void setTransmissionDelayLeft(int value);
int getTransmissionDelayRight() const;
void setTransmissionDelayRight(int value);
bool getUDPDataStream(const portPosition port) const;
void setUDPDataStream(const portPosition port, const bool enable);
void updateRxUDPPortDisableMetadata(const std::vector<int> &disable);
std::vector<int> getRxUDPPortDisableMetadata() const;
/**************************************************
* *
@@ -388,8 +392,6 @@ class Module : public virtual slsDetectorDefs {
void pulseChip(int n_pulses = 0);
bool getQuad() const;
void setQuad(const bool enable);
bool getDataStream(const portPosition port) const;
void setDataStream(const portPosition port, const bool enable);
bool getTop() const;
void setTop(bool value);
+16 -16
View File
@@ -694,22 +694,6 @@ int InferAction::dacvalues() {
}
}
int InferAction::datastream() {
if (args.size() == 1) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 2) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::dbitclk() {
if (args.size() == 0) {
@@ -4025,6 +4009,22 @@ int InferAction::udp_cleardst() {
}
}
int InferAction::udp_datastream() {
if (args.size() == 1) {
return slsDetectorDefs::GET_ACTION;
}
if (args.size() == 2) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::udp_dstip() {
if (args.size() == 0) {
+2 -2
View File
@@ -56,7 +56,6 @@ class InferAction {
int daclist();
int dacname();
int dacvalues();
int datastream();
int dbitclk();
int dbitphase();
int dbitpipeline();
@@ -296,6 +295,7 @@ class InferAction {
int txdelay_right();
int type();
int udp_cleardst();
int udp_datastream();
int udp_dstip();
int udp_dstip2();
int udp_dstlist();
@@ -390,7 +390,6 @@ class InferAction {
{"daclist", &InferAction::daclist},
{"dacname", &InferAction::dacname},
{"dacvalues", &InferAction::dacvalues},
{"datastream", &InferAction::datastream},
{"dbitclk", &InferAction::dbitclk},
{"dbitphase", &InferAction::dbitphase},
{"dbitpipeline", &InferAction::dbitpipeline},
@@ -634,6 +633,7 @@ class InferAction {
{"txdelay_right", &InferAction::txdelay_right},
{"type", &InferAction::type},
{"udp_cleardst", &InferAction::udp_cleardst},
{"udp_datastream", &InferAction::udp_datastream},
{"udp_dstip", &InferAction::udp_dstip},
{"udp_dstip2", &InferAction::udp_dstip2},
{"udp_dstlist", &InferAction::udp_dstlist},
+1
View File
@@ -6,6 +6,7 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/acquire/Acquire.cpp
${CMAKE_CURRENT_SOURCE_DIR}/acquire/CTBState.cpp
${CMAKE_CURRENT_SOURCE_DIR}/acquire/ExpectedState.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Caller/test-Caller.cpp
@@ -589,46 +589,6 @@ TEST_CASE("quad", "[.detectorintegration]") {
}
}
TEST_CASE("datastream", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_val_left = det.getDataStream(defs::LEFT);
auto prev_val_right = det.getDataStream(defs::RIGHT);
// no "left" or "right"
REQUIRE_THROWS(caller.call("datastream", {"1"}, -1, PUT));
{
std::ostringstream oss;
caller.call("datastream", {"left", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "datastream [left, 0]\n");
}
{
std::ostringstream oss;
caller.call("datastream", {"right", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "datastream [right, 0]\n");
}
{
std::ostringstream oss;
caller.call("datastream", {"left", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "datastream [left, 1]\n");
}
{
std::ostringstream oss;
caller.call("datastream", {"right", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "datastream [right, 1]\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setDataStream(defs::LEFT, prev_val_left[i], {i});
det.setDataStream(defs::RIGHT, prev_val_right[i], {i});
}
} else {
REQUIRE_THROWS(caller.call("datastream", {}, -1, GET));
REQUIRE_THROWS(caller.call("datastream", {"1"}, -1, PUT));
REQUIRE_THROWS(caller.call("datastream", {"left", "1"}, -1, PUT));
}
}
TEST_CASE("top", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
@@ -99,31 +99,4 @@ void test_onchip_dac_caller(defs::dacIndex index, const std::string &dacname,
}
}
std::pair<uint64_t, int>
calculate_ctb_image_size(const acq::CTBState &test_info, bool isXilinxCtb) {
LOG(logDEBUG1) << test_info;
sls::CtbImageInputs inputs{};
inputs.mode = test_info.readout_mode;
inputs.nAnalogSamples = test_info.num_adc_samples;
inputs.adcMask = test_info.adc_enable_10g;
if (!isXilinxCtb && !test_info.ten_giga) {
inputs.adcMask = test_info.adc_enable_1g;
}
inputs.nTransceiverSamples = test_info.num_trans_samples;
inputs.transceiverMask = test_info.transceiver_mask;
inputs.nDigitalSamples = test_info.num_dbit_samples;
inputs.dbitOffset = test_info.dbit_offset;
inputs.dbitReorder = test_info.dbit_reorder;
inputs.dbitList = test_info.dbit_list;
auto out = computeCtbImageSize(inputs);
uint64_t image_size =
out.nAnalogBytes + out.nDigitalBytes + out.nTransceiverBytes;
LOG(logDEBUG1) << "Expected image size: " << image_size;
int npixelx = out.nPixelsX;
LOG(logDEBUG1) << "Expected number of pixels in x: " << npixelx;
return std::make_pair(image_size, npixelx);
}
} // namespace sls
@@ -2,7 +2,7 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include "acquire/CTBState.h"
#include "checks/MasterFileChecks.h"
#include "sls/sls_detector_defs.h"
#include <chrono>
@@ -13,6 +13,8 @@
namespace sls {
namespace acq = sls::test::acquire;
namespace mf = sls::test::master_file;
namespace checks = sls::test::checks;
void test_valid_port_caller(const std::string &command,
const std::vector<std::string> &arguments,
@@ -23,7 +25,42 @@ void test_dac_caller(slsDetectorDefs::dacIndex index,
void test_onchip_dac_caller(slsDetectorDefs::dacIndex index,
const std::string &dacname, int dacvalue);
std::pair<uint64_t, int>
calculate_ctb_image_size(const acq::CTBState &test_info, bool isXilinxCtb);
/**
* Helper function to run an acquisition and check the master file (both binary
* and hdf5) for expected values. The function takes in a lambda that is called
* with the master filechecker object to perform checks on the master file. The
* acquisition is run with default acquisition and file states, but these can be
* modified within the lambda if needed. This version has the master file
* checker object created within the function instead of using a helper
* function, to allow for more flexibility in handling exceptions (especially
* HDF5 exceptions) and logging.
*/
template <typename F>
void test_run_with_master_file_checker(Detector &det, F f) {
auto acq_state = acq::default_acquisition_state();
auto file_state = acq::default_file_state();
std::array<defs::fileFormat, 2> formats = {defs::BINARY, defs::HDF5};
for (const auto &format : formats) {
file_state.file_format = format;
acq::run(det, acq_state, file_state);
std::string fname = acq::get_master_file_name(file_state);
if (format == defs::HDF5) {
#ifdef HDF5C
try {
mf::Checker<mf::H5Context> checker(fname);
f(det, acq_state, file_state, checker);
} catch (H5::Exception &e) {
LOG(logERROR) << "HDF5 error: " << e.getDetailMsg();
throw;
}
#endif
} else {
mf::Checker<mf::JsonContext> checker(fname);
f(det, acq_state, file_state, checker);
}
}
}
} // namespace sls
@@ -1,29 +1,15 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "acquire/ExpectedState.h"
#include "checks/MasterFileChecks.h"
#include "sls/Detector.h"
#include "sls/ToString.h"
#include "sls/logger.h"
#include "test-Caller-global.h"
#include "catch.hpp"
#include <filesystem>
#include <fstream>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <sstream>
#include <string>
#ifdef HDF5C
#include "H5Cpp.h"
#endif
namespace sls {
namespace mf = sls::test::master_file;
namespace acq = sls::test::acquire;
namespace checks = sls::test::checks;
TEST_CASE("check_master_file_attributes",
"[.detectorintegration][.disable_check_data_file]") {
@@ -32,10 +18,6 @@ TEST_CASE("check_master_file_attributes",
auto detType = det.getDetectorType().squash(defs::GENERIC);
INFO("Testing master file attributes with " << ToString(detType));
// currently num frame = 1 (default)
auto acq_state = acq::default_acquisition_state();
auto file_state = acq::default_file_state();
// if ctb, set to default and restore after test
std::optional<acq::CTBState> ctb_state = std::nullopt;
if (detType == defs::CHIPTESTBOARD ||
@@ -44,36 +26,75 @@ TEST_CASE("check_master_file_attributes",
}
acq::CTBStateGuard ctb_guard(det, ctb_state);
// binary => /tmp/sls_test_master_0.json
file_state.file_format = defs::BINARY;
acq::run(det, acq_state, file_state);
test_run_with_master_file_checker(
det, [&](auto &det, auto &acq_state, auto &file_state, auto &checker) {
// get expected state of parameters and check against master file
auto expected_state = acq::build_expected_state(
det, acq_state, file_state, ctb_state);
checks::check_metadata(checker, expected_state);
});
}
std::string fname = acq::get_master_file_name(file_state);
mf::Checker<mf::JsonContext> checker(fname);
TEST_CASE("udp_datastream with master file",
"[.detectorintegration][.disable_check_data_file]") {
Detector det;
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_val_left = det.getUDPDataStream(defs::LEFT);
auto prev_val_right = det.getUDPDataStream(defs::RIGHT);
// get expected state of parameters and check against master file
acq::ExpectedState expected_state =
acq::build_expected_state(det, acq_state, file_state, ctb_state);
checks::check_metadata(checker, expected_state);
det.setUDPDataStream(defs::LEFT, false);
// check master file
{
// expected
std::vector<defs::portPosition> expected_ports =
det.getPortPositionList();
std::vector<int> expected_disabled_ports =
det.getRxDisabledUDPPortIndices();
REQUIRE(expected_disabled_ports.size() > 0);
#ifdef HDF5C
try {
// hdf5 => /tmp/sls_test_master_0.h5
file_state.file_format = defs::HDF5;
acq::run(det, acq_state, file_state);
test_run_with_master_file_checker(
det, [&](auto &det, auto &acq_state, auto &file_state,
auto &checker) {
checks::check_udp_ports_type(checker, expected_ports);
checks::check_udp_ports_disabled(checker,
expected_disabled_ports);
});
}
std::string fname = acq::get_master_file_name(file_state);
mf::Checker<mf::H5Context> checker(fname);
for (int i = 0; i != det.size(); ++i) {
det.setUDPDataStream(defs::LEFT, prev_val_left[i], {i});
det.setUDPDataStream(defs::RIGHT, prev_val_right[i], {i});
}
} else if ((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) &&
(det.getNumberofUDPInterfaces().squash(0) == 2)) {
auto prev_val_top = det.getUDPDataStream(defs::TOP);
auto prev_val_bottom = det.getUDPDataStream(defs::BOTTOM);
// get expected state of parameters and check against master file
acq::ExpectedState expected_state =
acq::build_expected_state(det, acq_state, file_state, ctb_state);
checks::check_metadata(checker, expected_state);
} catch (H5::Exception &e) {
LOG(logERROR) << "HDF5 error: " << e.getDetailMsg();
throw;
det.setUDPDataStream(defs::TOP, false);
// check master file
{
// expected
std::vector<defs::portPosition> expected_ports =
det.getPortPositionList();
std::vector<int> expected_disabled_ports =
det.getRxDisabledUDPPortIndices();
REQUIRE(expected_disabled_ports.size() > 0);
test_run_with_master_file_checker(
det, [&](auto &det, auto &acq_state, auto &file_state,
auto &checker) {
checks::check_udp_ports_type(checker, expected_ports);
checks::check_udp_ports_disabled(checker,
expected_disabled_ports);
});
}
for (int i = 0; i != det.size(); ++i) {
det.setUDPDataStream(defs::TOP, prev_val_top[i], {i});
det.setUDPDataStream(defs::BOTTOM, prev_val_bottom[i], {i});
}
}
#endif
}
} // namespace sls
@@ -127,7 +127,8 @@ TEST_CASE("rx_framescaught", "[.detectorintegration]") {
}
}
TEST_CASE("rx_missingpackets", "[.detectorintegration]") {
TEST_CASE("rx_missingpackets",
"[.detectorintegration][.disable_check_data_file]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileWrite();
@@ -3068,6 +3068,95 @@ TEST_CASE("txdelay", "[.detectorintegration]") {
}
}
TEST_CASE("udp_datastream", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_val_left = det.getUDPDataStream(defs::LEFT);
auto prev_val_right = det.getUDPDataStream(defs::RIGHT);
// invalid args
REQUIRE_THROWS(caller.call("udp_datastream", {"top", "1"}, -1, PUT));
REQUIRE_THROWS(caller.call("udp_datastream", {"bottom", "1"}, -1, PUT));
// no "left" or "right" argument
REQUIRE_THROWS(caller.call("udp_datastream", {"1"}, -1, PUT));
{
std::ostringstream oss;
caller.call("udp_datastream", {"left", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [left, 0]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"right", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [right, 0]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"left", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [left, 1]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"right", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [right, 1]\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setUDPDataStream(defs::LEFT, prev_val_left[i], {i});
det.setUDPDataStream(defs::RIGHT, prev_val_right[i], {i});
}
} else if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH) {
// throw with 1 interface
if (det.getNumberofUDPInterfaces().squash() == 1) {
REQUIRE_THROWS(
caller.call("udp_datastream", {"top", "0"}, -1, PUT));
}
// 2 interfaces
else {
auto prev_val_top = det.getUDPDataStream(defs::TOP);
auto prev_val_bottom = det.getUDPDataStream(defs::BOTTOM);
// invalid args
REQUIRE_THROWS(
caller.call("udp_datastream", {"left", "1"}, -1, PUT));
REQUIRE_THROWS(
caller.call("udp_datastream", {"right", "1"}, -1, PUT));
// no "top" or "bottom" argument
REQUIRE_THROWS(caller.call("udp_datastream", {"1"}, -1, PUT));
{
std::ostringstream oss;
caller.call("udp_datastream", {"top", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [top, 0]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"bottom", "0"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [bottom, 0]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"top", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [top, 1]\n");
}
{
std::ostringstream oss;
caller.call("udp_datastream", {"bottom", "1"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_datastream [bottom, 1]\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setUDPDataStream(defs::TOP, prev_val_top[i], {i});
det.setUDPDataStream(defs::BOTTOM, prev_val_bottom[i], {i});
}
}
} else {
REQUIRE_THROWS(caller.call("udp_datastream", {}, -1, GET));
REQUIRE_THROWS(caller.call("udp_datastream", {"1"}, -1, PUT));
REQUIRE_THROWS(caller.call("udp_datastream", {"left", "1"}, -1, PUT));
REQUIRE_THROWS(caller.call("udp_datastream", {"top", "1"}, -1, PUT));
}
}
/* ZMQ Streaming Parameters (Receiver<->Client) */
TEST_CASE("zmqport", "[.detectorintegration]") {
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "CTBState.h"
#include "GeneralData.h"
namespace sls::test::acquire {
std::pair<uint64_t, int> calculate_ctb_image_size(const CTBState &test_info,
bool isXilinxCtb) {
LOG(logDEBUG1) << test_info;
CtbImageInputs inputs{};
inputs.mode = test_info.readout_mode;
inputs.nAnalogSamples = test_info.num_adc_samples;
inputs.adcMask = test_info.adc_enable_10g;
if (!isXilinxCtb && !test_info.ten_giga) {
inputs.adcMask = test_info.adc_enable_1g;
}
inputs.nTransceiverSamples = test_info.num_trans_samples;
inputs.transceiverMask = test_info.transceiver_mask;
inputs.nDigitalSamples = test_info.num_dbit_samples;
inputs.dbitOffset = test_info.dbit_offset;
inputs.dbitReorder = test_info.dbit_reorder;
inputs.dbitList = test_info.dbit_list;
auto out = computeCtbImageSize(inputs);
uint64_t image_size =
out.nAnalogBytes + out.nDigitalBytes + out.nTransceiverBytes;
LOG(logDEBUG1) << "Expected image size: " << image_size;
int npixelx = out.nPixelsX;
LOG(logDEBUG1) << "Expected number of pixels in x: " << npixelx;
return std::make_pair(image_size, npixelx);
}
} // namespace sls::test::acquire
@@ -135,4 +135,14 @@ class CTBStateGuard {
CTBState saved_;
};
/**
* @brief
* @param test_info current CTB state
* @param isXilinxCtb if the detector type is Xilinx CTB
* @return std::pair<uint64_t, int> pair of image size in bytes and number of
* channels in dimension X (Currently only analog channels)
*/
std::pair<uint64_t, int> calculate_ctb_image_size(const CTBState &test_info,
bool isXilinxCtb);
} // namespace sls::test::acquire
@@ -2,7 +2,6 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "ExpectedState.h"
#include "Caller/test-Caller-global.h"
#include "receiver_defs.h"
// unnamed namespace for internal linkage
@@ -47,7 +46,7 @@ defs::xy get_port_shape(const Detector &det,
"CTB state must be provided to calculate expected port shape");
}
portSize.x =
sls::calculate_ctb_image_size(
acq::calculate_ctb_image_size(
ctb_state.value(), det_type == defs::XILINX_CHIPTESTBOARD)
.second;
portSize.y = 1;
@@ -136,6 +135,14 @@ int get_num_udp_interfaces(const Detector &det) {
"Inconsistent number of UDP interfaces");
}
std::vector<defs::portPosition> get_udp_port_types(const Detector &det) {
return det.getPortPositionList();
}
std::vector<int> get_udp_ports_disabled(const Detector &det) {
return det.getRxDisabledUDPPortIndices();
}
int get_read_n_rows(const Detector &det) {
return det.getReadNRows().tsquash("Inconsistent number of read rows");
}
@@ -184,6 +191,10 @@ acq::JungfrauExpectedState build_jungfrau_specific_state(const Detector &det) {
e.exptime = get_exptime(det);
e.period = get_period(det);
e.num_udp_interfaces = get_num_udp_interfaces(det);
if (e.num_udp_interfaces == 2) {
e.udp_port_types = get_udp_port_types(det);
e.udp_ports_disabled = get_udp_ports_disabled(det);
}
e.read_n_rows = get_read_n_rows(det);
e.readout_speed = get_readout_speed(det);
return e;
@@ -195,6 +206,10 @@ acq::MoenchExpectedState build_moench_specific_state(const Detector &det) {
e.exptime = get_exptime(det);
e.period = get_period(det);
e.num_udp_interfaces = get_num_udp_interfaces(det);
if (e.num_udp_interfaces == 2) {
e.udp_port_types = get_udp_port_types(det);
e.udp_ports_disabled = get_udp_ports_disabled(det);
}
e.read_n_rows = get_read_n_rows(det);
e.readout_speed = get_readout_speed(det);
return e;
@@ -213,6 +228,8 @@ acq::EigerExpectedState build_eiger_specific_state(const Detector &det) {
e.sub_exptime = sub_exptime;
e.sub_period = sub_period;
e.quad = det.getQuad().tsquash("Inconsistent quad setting");
e.udp_port_types = get_udp_port_types(det);
e.udp_ports_disabled = get_udp_ports_disabled(det);
e.read_n_rows = get_read_n_rows(det);
{
for (auto item : det.getRateCorrection())
@@ -342,7 +359,7 @@ int get_expected_image_size(const Detector &det,
}
LOG(logINFORED) << ctb_state.value();
image_size =
sls::calculate_ctb_image_size(
acq::calculate_ctb_image_size(
ctb_state.value(), (det_type == defs::XILINX_CHIPTESTBOARD))
.first;
break;
@@ -31,6 +31,8 @@ struct JungfrauExpectedState {
ns exptime{};
ns period{};
int num_udp_interfaces{};
std::vector<defs::portPosition> udp_port_types;
std::vector<int> udp_ports_disabled;
int read_n_rows{};
defs::speedLevel readout_speed{};
};
@@ -40,6 +42,8 @@ struct MoenchExpectedState {
ns exptime{};
ns period{};
int num_udp_interfaces{};
std::vector<defs::portPosition> udp_port_types;
std::vector<int> udp_ports_disabled;
int read_n_rows{};
defs::speedLevel readout_speed{};
};
@@ -54,6 +58,8 @@ struct EigerExpectedState {
ns sub_exptime{};
ns sub_period{};
bool quad{};
std::vector<defs::portPosition> udp_port_types;
std::vector<int> udp_ports_disabled;
int read_n_rows{};
std::vector<int64_t> rate_corrections{};
defs::speedLevel readout_speed{};
@@ -128,6 +128,22 @@ void check_num_udp_interfaces(CheckerT &checker, const int &value) {
value);
}
template <typename CheckerT>
void check_udp_ports_type(CheckerT &checker,
const std::vector<defs::portPosition> &value) {
REQUIRE(value.size() == 2);
std::vector<std::string> ports = {ToString(value[0]), ToString(value[1])};
checker.template check<std::vector<std::string>>(
MasterAttributes::N_UDP_PORTS_TYPE.data(), ports);
}
template <typename CheckerT>
void check_udp_ports_disabled(CheckerT &checker,
const std::vector<int> &value) {
checker.template check<std::vector<int>>(
MasterAttributes::N_UDP_PORTS_DISABLED.data(), value);
}
template <typename CheckerT>
void check_read_n_rows(CheckerT &checker, const int &value) {
checker.template check<int>(MasterAttributes::N_NUMBER_OF_ROWS.data(),
@@ -318,6 +334,10 @@ void check_jungfrau_metadata(CheckerT &checker,
check_exptime(checker, st.exptime);
check_period(checker, st.period);
check_num_udp_interfaces(checker, st.num_udp_interfaces);
if (st.num_udp_interfaces == 2) {
check_udp_ports_type(checker, st.udp_port_types);
check_udp_ports_disabled(checker, st.udp_ports_disabled);
}
check_read_n_rows(checker, st.read_n_rows);
check_readout_speed(checker, st.readout_speed);
}
@@ -331,6 +351,10 @@ void check_moench_metadata(CheckerT &checker,
check_exptime(checker, st.exptime);
check_period(checker, st.period);
check_num_udp_interfaces(checker, st.num_udp_interfaces);
if (st.num_udp_interfaces == 2) {
check_udp_ports_type(checker, st.udp_port_types);
check_udp_ports_disabled(checker, st.udp_ports_disabled);
}
check_read_n_rows(checker, st.read_n_rows);
check_readout_speed(checker, st.readout_speed);
}
@@ -349,6 +373,8 @@ void check_eiger_metadata(CheckerT &checker,
check_sub_exptime(checker, st.sub_exptime);
check_sub_period(checker, st.sub_period);
check_quad(checker, st.quad);
check_udp_ports_type(checker, st.udp_port_types);
check_udp_ports_disabled(checker, st.udp_ports_disabled);
check_read_n_rows(checker, st.read_n_rows);
check_rate_corrections(checker, st.rate_corrections);
check_readout_speed(checker, st.readout_speed);
@@ -238,6 +238,23 @@ template <> struct Reader<H5Context, std::array<ns, 3UL>> {
}
};
template <> struct Reader<H5Context, std::vector<int>> {
static std::vector<int> read(const H5Context &ctx, const std::string &name,
AccessType access) {
if (access == AccessType::Attribute) {
throw RuntimeError("'std::vector<int>' attribute access not "
"supported for HDF5");
}
require_dataset(ctx, name);
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
auto len = get_1d_size(ds);
std::vector<int> out{};
out.resize(len);
ds.read(out.data(), H5::PredType::NATIVE_INT);
return out;
}
};
template <> struct Reader<H5Context, std::vector<int64_t>> {
static std::vector<int64_t>
read(const H5Context &ctx, const std::string &name, AccessType access) {
@@ -255,6 +272,29 @@ template <> struct Reader<H5Context, std::vector<int64_t>> {
}
};
template <> struct Reader<H5Context, std::vector<std::string>> {
static std::vector<std::string>
read(const H5Context &ctx, const std::string &name, AccessType access) {
if (access == AccessType::Attribute) {
throw RuntimeError(
"'std::vector<std::string>' attribute access not "
"supported for HDF5");
}
require_dataset(ctx, name);
auto ds = ctx.file.openDataSet(HDF5_GROUP + name);
H5::StrType strType(H5::PredType::C_S1, H5T_VARIABLE);
std::vector<const char *> raw;
raw.resize(get_1d_size(ds));
ds.read(raw.data(), strType);
std::vector<std::string> out;
out.reserve(raw.size());
for (auto c : raw) {
out.emplace_back(c);
}
return out;
}
};
template <> struct Reader<H5Context, std::map<std::string, std::string>> {
static std::map<std::string, std::string>
read(const H5Context &ctx, const std::string &name, AccessType access) {
@@ -120,6 +120,17 @@ template <> struct Reader<JsonContext, std::array<ns, 3UL>> {
}
};
template <> struct Reader<JsonContext, std::vector<int>> {
static std::vector<int> read(const JsonContext &ctx,
const std::string &name, AccessType access) {
std::vector<int> out{};
for (const auto &item : ctx.doc[name.c_str()].GetArray()) {
out.push_back(item.GetInt());
}
return out;
}
};
template <> struct Reader<JsonContext, std::vector<int64_t>> {
static std::vector<int64_t>
read(const JsonContext &ctx, const std::string &name, AccessType access) {
@@ -131,6 +142,17 @@ template <> struct Reader<JsonContext, std::vector<int64_t>> {
}
};
template <> struct Reader<JsonContext, std::vector<std::string>> {
static std::vector<std::string>
read(const JsonContext &ctx, const std::string &name, AccessType access) {
std::vector<std::string> out{};
for (const auto &item : ctx.doc[name.c_str()].GetArray()) {
out.push_back(item.GetString());
}
return out;
}
};
template <> struct Reader<JsonContext, std::map<std::string, std::string>> {
static std::map<std::string, std::string>
read(const JsonContext &ctx, const std::string &name, AccessType access) {
+78 -12
View File
@@ -207,7 +207,7 @@ int ClientInterface::functionTable(){
flist[F_GET_RECEIVER_STREAMING_HWM] = &ClientInterface::get_streaming_hwm;
flist[F_SET_RECEIVER_STREAMING_HWM] = &ClientInterface::set_streaming_hwm;
flist[F_RECEIVER_SET_ALL_THRESHOLD] = &ClientInterface::set_all_threshold;
flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream;
flist[F_RECEIVER_SET_UDP_DATASTREAM] = &ClientInterface::set_port_udp_datastream;
flist[F_GET_RECEIVER_ARPING] = &ClientInterface::get_arping;
flist[F_SET_RECEIVER_ARPING] = &ClientInterface::set_arping;
flist[F_RECEIVER_GET_RECEIVER_ROI] = &ClientInterface::get_receiver_roi;
@@ -221,6 +221,10 @@ int ClientInterface::functionTable(){
flist[F_SET_RECEIVER_DBIT_REORDER] = &ClientInterface::set_dbit_reorder;
flist[F_RECEIVER_GET_ROI_METADATA] = &ClientInterface::get_roi_metadata;
flist[F_SET_RECEIVER_READOUT_SPEED] = &ClientInterface::set_readout_speed;
flist[F_RECEIVER_GET_UDP_DATASTREAM] = &ClientInterface::get_port_udp_datastream;
flist[F_RECEIVER_SET_UDP_PORT_DISABLE_META] = &ClientInterface::set_udp_port_disable_meta;
flist[F_RECEIVER_GET_UDP_PORT_DISABLE_META] = &ClientInterface::get_udp_port_disable_meta;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@@ -383,8 +387,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) +
std::chrono::nanoseconds(arg.subDeadTimeNs));
impl()->setActivate(static_cast<bool>(arg.activate));
impl()->setDetectorDataStream(LEFT, arg.dataStreamLeft);
impl()->setDetectorDataStream(RIGHT, arg.dataStreamRight);
impl()->setUDPDataStream(LEFT, arg.dataStreamLeft);
impl()->setUDPDataStream(RIGHT, arg.dataStreamRight);
impl()->setQuad(arg.quad == 0 ? false : true);
impl()->setThresholdEnergy(arg.thresholdEnergyeV[0]);
}
@@ -1653,27 +1657,58 @@ int ClientInterface::set_all_threshold(Interface &socket) {
return socket.Send(OK);
}
int ClientInterface::set_detector_datastream(Interface &socket) {
int args[2]{-1, -1};
socket.Receive(args);
portPosition port = static_cast<portPosition>(args[0]);
void ClientInterface::validate_port_position(const portPosition port) {
bool exists = false;
switch (port) {
case LEFT:
case RIGHT:
if (detType == EIGER) {
exists = true;
}
break;
case TOP:
case BOTTOM:
if (detType == JUNGFRAU || detType == MOENCH) {
exists = true;
}
break;
default:
throw RuntimeError("Invalid port type");
}
bool enable = static_cast<int>(args[1]);
LOG(logDEBUG1) << "Setting datastream (" << ToString(port) << ") to "
<< ToString(enable);
if (detType != EIGER)
if (!exists) {
modeNotImplemented("Port type", port);
}
}
int ClientInterface::set_port_udp_datastream(Interface &socket) {
if (detType != EIGER && detType != JUNGFRAU && detType != MOENCH)
functionNotImplemented();
int args[2]{-1, -1};
socket.Receive(args);
portPosition port = static_cast<portPosition>(args[0]);
validate_port_position(port);
bool enable = static_cast<bool>(args[1]);
if (impl()->getNumberofUDPInterfaces() == 1)
throw RuntimeError("Cannot change UDP port datastream with only 1 "
"interface enabled. Hint: set 'numinterfaces' to 2");
LOG(logDEBUG1) << "Setting udp datastream (" << ToString(port) << ") to "
<< ToString(enable);
verifyIdle(socket);
impl()->setDetectorDataStream(port, enable);
impl()->setUDPDataStream(port, enable);
return socket.Send(OK);
}
int ClientInterface::get_port_udp_datastream(Interface &socket) {
auto arg = socket.Receive<int>();
portPosition port = static_cast<portPosition>(arg);
validate_port_position(port);
LOG(logDEBUG1) << "Getting udp datastream (" << ToString(port) << ")";
if (detType != EIGER && detType != JUNGFRAU && detType != MOENCH)
functionNotImplemented();
auto retval = static_cast<int>(impl()->getUDPDataStream(port));
return socket.sendResult(retval);
}
int ClientInterface::get_arping(Interface &socket) {
auto retval = static_cast<int>(impl()->getArping());
LOG(logDEBUG1) << "arping thread status:" << retval;
@@ -1884,4 +1919,35 @@ int ClientInterface::set_readout_speed(Interface &socket) {
return socket.Send(OK);
}
int ClientInterface::set_udp_port_disable_meta(Interface &socket) {
auto nports = socket.Receive<int>();
std::vector<int> portsDisabled;
if (nports > 0) {
portsDisabled.resize(nports);
socket.Receive(portsDisabled);
LOG(logDEBUG1) << "Disabled Ports Metadata:" << ToString(portsDisabled);
}
verifyIdle(socket);
try {
impl()->setUDPPortsDisabledMetadata(portsDisabled);
} catch (const std::exception &e) {
throw RuntimeError("Could not update UDP ports disabled metadata [" +
std::string(e.what()) + ']');
}
return socket.Send(OK);
}
int ClientInterface::get_udp_port_disable_meta(Interface &socket) {
auto retvals = impl()->getUDPPortsDisabledMetadata();
LOG(logDEBUG1) << "Receiver disabled udp ports retval:"
<< ToString(retvals);
socket.Send(OK);
auto size = static_cast<int>(retvals.size());
socket.Send(size);
if (size > 0)
socket.Send(retvals);
return OK;
}
} // namespace sls
+5 -1
View File
@@ -154,7 +154,9 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_streaming_hwm(ServerInterface &socket);
int set_streaming_hwm(ServerInterface &socket);
int set_all_threshold(ServerInterface &socket);
int set_detector_datastream(ServerInterface &socket);
void validate_port_position(const portPosition port);
int set_port_udp_datastream(ServerInterface &socket);
int get_port_udp_datastream(ServerInterface &socket);
int get_arping(ServerInterface &socket);
int set_arping(ServerInterface &socket);
int get_receiver_roi(ServerInterface &socket);
@@ -168,6 +170,8 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_dbit_reorder(ServerInterface &socket);
int get_roi_metadata(ServerInterface &socket);
int set_readout_speed(ServerInterface &socket);
int set_udp_port_disable_meta(ServerInterface &socket);
int get_udp_port_disable_meta(ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {
+2 -2
View File
@@ -153,14 +153,14 @@ void DataProcessor::CreateFirstFiles(const std::filesystem::path &filePath,
const uint64_t fileIndex,
const bool overWriteEnable,
const bool silentMode,
const bool detectorDataStream) {
const bool udpDataStream) {
if (dataFile == nullptr) {
throw RuntimeError("file object not contstructed");
}
CloseFiles();
// deactivated (half module/ single port or no roi), dont write file
if (!activated || !detectorDataStream || isOutsideRoi) {
if (!activated || !udpDataStream || isOutsideRoi) {
return;
}
+1 -1
View File
@@ -63,7 +63,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
void CreateFirstFiles(const std::filesystem::path &filePath,
const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const bool detectorDataStream);
const bool silentMode, const bool udpDataStream);
#ifdef HDF5C
uint32_t GetFilesInAcquisition() const;
std::string CreateVirtualFile(const std::filesystem::path &filePath,
+4
View File
@@ -193,6 +193,8 @@ class GeneralData {
slsDetectorDefs::NO_DISCARD};
/* actual image size after ctboffset and ctbreorder */
uint32_t actualImageSize{0};
/* bottom & top or left & right for 2 interfaces */
std::array<defs::portPosition, 2> udpPortTypes{defs::LEFT, defs::RIGHT};
GeneralData(){};
virtual ~GeneralData(){};
@@ -344,6 +346,7 @@ class JungfrauData : public GeneralData {
fifoDepth = 2500;
standardheader = true;
maxRowsPerReadout = 512;
udpPortTypes = {defs::BOTTOM, defs::TOP};
UpdateImageSize();
};
@@ -376,6 +379,7 @@ class MoenchData : public GeneralData {
standardheader = true;
maxRowsPerReadout = 400;
frameDiscardMode = slsDetectorDefs::DISCARD_PARTIAL_FRAMES;
udpPortTypes = {defs::BOTTOM, defs::TOP};
UpdateImageSize();
};
+63 -29
View File
@@ -188,7 +188,7 @@ void Implementation::SetupListener(int i) {
listener[i]->SetEthernetInterface(eth[i]);
listener[i]->SetActivate(activated);
listener[i]->SetIsOutsideRoi(portRois[i].noRoi());
listener[i]->SetDetectorDatastream(detectorDataStream[i]);
listener[i]->SetUDPDatastream(udpDataStream[i]);
listener[i]->SetSilentMode(silentMode);
}
@@ -606,7 +606,7 @@ double Implementation::getProgress() const {
double progress = 0;
int index = 0;
for (const auto &it : listener) {
if (detectorDataStream[index] && it->GetStartedFlag()) {
if (udpDataStream[index] && it->GetStartedFlag()) {
progress += (it->GetListenedIndex() + 1) / totalFrames;
}
++index;
@@ -746,9 +746,9 @@ void Implementation::stopReceiver() {
std::string summary;
if (!activated) {
summary = "\n\tDeactivated Receiver";
} else if (!detectorDataStream[i]) {
summary = (i == 0 ? "\n\tDeactivated Left Port"
: "\n\tDeactivated Right Port");
} else if (!udpDataStream[i]) {
summary = "\n\tDeactivated " +
ToString(generalData->udpPortTypes[i]) + " Port";
} else if (portRois[i].noRoi()) {
summary = "\n\tNo Roi on Port[" + std::to_string(i) + ']';
} else {
@@ -900,9 +900,9 @@ void Implementation::SetupWriter() {
std::string fileNamePrefix =
fileName + "_d" +
std::to_string(modulePos * generalData->numUDPInterfaces + i);
dataProcessor[i]->CreateFirstFiles(
filePath, fileNamePrefix, fileIndex, overwriteEnable,
silentMode, detectorDataStream[i]);
dataProcessor[i]->CreateFirstFiles(filePath, fileNamePrefix,
fileIndex, overwriteEnable,
silentMode, udpDataStream[i]);
}
} catch (const RuntimeError &e) {
shutDownUDPSockets();
@@ -999,6 +999,10 @@ void Implementation::StartMasterWriter() {
masterAttributes.gates = numberOfGates;
masterAttributes.additionalJsonHeader = additionalJsonHeader;
masterAttributes.readoutSpeed = readoutSpeed;
masterAttributes.udpPortTypes = {
ToString(generalData->udpPortTypes[0]),
ToString(generalData->udpPortTypes[1])};
masterAttributes.udpPortsDisabled = udpPortsDisabledMetadata;
// create master file
masterFileName = dataProcessor[0]->CreateMasterFile(
@@ -1100,6 +1104,11 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
// number of portrois should be equal to number of interfaces
ResetRois();
// reset udp data stream
udpDataStream[0] = true;
udpDataStream[1] = true;
udpPortsDisabledMetadata.clear();
// create threads
for (int i = 0; i < generalData->numUDPInterfaces; ++i) {
// listener and dataprocessor threads
@@ -1617,15 +1626,15 @@ void Implementation::setTenGigaEnable(const bool b) {
// datastream can be disabled/enabled only for Eiger 10GbE
if (generalData->detType == EIGER) {
if (!b) {
detectorDataStream[LEFT] = 1;
detectorDataStream[RIGHT] = 1;
udpDataStream[LEFT] = true;
udpDataStream[RIGHT] = true;
} else {
detectorDataStream[LEFT] = detectorDataStream10GbE[LEFT];
detectorDataStream[RIGHT] = detectorDataStream10GbE[RIGHT];
udpDataStream[LEFT] = udpDataStream10GbE[LEFT];
udpDataStream[RIGHT] = udpDataStream10GbE[RIGHT];
}
LOG(logDEBUG) << "Detector datastream updated [Left: "
<< ToString(detectorDataStream[LEFT])
<< ", Right: " << ToString(detectorDataStream[RIGHT])
<< ToString(udpDataStream[LEFT])
<< ", Right: " << ToString(udpDataStream[RIGHT])
<< "]";
}
}
@@ -1675,24 +1684,49 @@ void Implementation::setActivate(bool enable) {
LOG(logINFO) << "Activation: " << (activated ? "enabled" : "disabled");
}
bool Implementation::getDetectorDataStream(const portPosition port) const {
int index = (port == LEFT ? 0 : 1);
return detectorDataStream[index];
bool Implementation::getUDPDataStream(const portPosition port) const {
int index = 0;
// top goes to udp port 2 (jungfrau & moench)
if (port == TOP || port == RIGHT)
index = 1;
return udpDataStream[index];
}
void Implementation::setDetectorDataStream(const portPosition port,
const bool enable) {
int index = (port == LEFT ? 0 : 1);
detectorDataStream10GbE[index] = enable;
LOG(logINFO) << "Detector 10GbE datastream (" << ToString(port)
<< " Port): " << ToString(detectorDataStream10GbE[index]);
// update datastream for 10g
if (generalData->tengigaEnable) {
detectorDataStream[index] = detectorDataStream10GbE[index];
LOG(logDEBUG) << "Detector datastream updated ["
<< (index == 0 ? "Left" : "Right")
<< "] : " << ToString(detectorDataStream[index]);
void Implementation::setUDPDataStream(const portPosition port,
const bool enable) {
int index = 0;
// top goes to udp port 2 (jungfrau & moench)
if (port == TOP || port == RIGHT)
index = 1;
// jungfrau and moench: straightforward
if (generalData->detType != EIGER) {
udpDataStream[index] = enable;
LOG(logINFO) << "Detector datastream (" << ToString(port)
<< " Port): " << ToString(udpDataStream[index]);
}
// eiger: data stream can be disabled/enabled only for 10GbE
else {
udpDataStream10GbE[index] = enable;
LOG(logINFO) << "Detector 10GbE datastream (" << ToString(port)
<< " Port): " << ToString(udpDataStream10GbE[index]);
// update datastream for 10g
if (generalData->tengigaEnable) {
udpDataStream[index] = udpDataStream10GbE[index];
LOG(logDEBUG) << "Detector datastream updated (" << ToString(port)
<< " Port): " << ToString(udpDataStream[index]);
}
}
for (size_t i = 0; i != listener.size(); ++i)
listener[i]->SetUDPDatastream(udpDataStream[i]);
}
void Implementation::setUDPPortsDisabledMetadata(
const std::vector<int> &portsDisabled) {
udpPortsDisabledMetadata = portsDisabled;
}
std::vector<int> Implementation::getUDPPortsDisabledMetadata() const {
return udpPortsDisabledMetadata;
}
int Implementation::getReadNRows() const { return readNRows; }
+11 -8
View File
@@ -225,12 +225,13 @@ class Implementation : private virtual slsDetectorDefs {
/** [Eiger] If deactivated, receiver will create dummy data if deactivated
* padding is enabled (as it will receive nothing from detector) */
void setActivate(const bool enable);
bool getDetectorDataStream(const portPosition port) const;
/** [Eiger] If datastream is disabled, receiver will create dummy data if
* deactivated
* padding for that port is enabled (as it will receive nothing from
* detector) */
void setDetectorDataStream(const portPosition port, const bool enable);
bool getUDPDataStream(const portPosition port) const;
/** [Jungfrau][Moench] deactivated at receiver level only
* [Eiger] deactivated at module level
*/
void setUDPDataStream(const portPosition port, const bool enable);
void setUDPPortsDisabledMetadata(const std::vector<int> &portsDisabled);
std::vector<int> getUDPPortsDisabledMetadata() const;
int getReadNRows() const;
/* [Eiger][Jungfrau][Moench] */
void setReadNRows(const int value);
@@ -366,8 +367,10 @@ class Implementation : private virtual slsDetectorDefs {
bool flipRows{false};
bool quadEnable{false};
bool activated{true};
std::array<bool, 2> detectorDataStream = {{true, true}};
std::array<bool, 2> detectorDataStream10GbE = {{true, true}};
std::array<bool, 2> udpDataStream = {{true, true}};
std::vector<int> udpPortsDisabledMetadata;
// only for Eiger to remember (10Gbe selectable)
std::array<bool, 2> udpDataStream10GbE = {{true, true}};
int readNRows{0};
int thresholdEnergyeV{-1};
std::array<int, 3> thresholdAllEnergyeV = {{-1, -1, -1}};
+5 -5
View File
@@ -85,17 +85,17 @@ void Listener::SetEthernetInterface(const std::string e) {
void Listener::SetActivate(bool enable) {
activated = enable;
disabledPort = (!activated || !detectorDataStream || isOutsideRoi);
disabledPort = (!activated || !udpDataStream || isOutsideRoi);
}
void Listener::SetDetectorDatastream(bool enable) {
detectorDataStream = enable;
disabledPort = (!activated || !detectorDataStream || isOutsideRoi);
void Listener::SetUDPDatastream(bool enable) {
udpDataStream = enable;
disabledPort = (!activated || !udpDataStream || isOutsideRoi);
}
void Listener::SetIsOutsideRoi(bool enable) {
isOutsideRoi = enable;
disabledPort = (!activated || !detectorDataStream || isOutsideRoi);
disabledPort = (!activated || !udpDataStream || isOutsideRoi);
}
void Listener::SetSilentMode(bool enable) { silentMode = enable; }
+2 -2
View File
@@ -42,7 +42,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void SetUdpPortNumber(const uint16_t portNumber);
void SetEthernetInterface(const std::string e);
void SetActivate(bool enable);
void SetDetectorDatastream(bool enable);
void SetUDPDatastream(bool enable);
void SetIsOutsideRoi(bool enable);
void SetSilentMode(bool enable);
@@ -115,7 +115,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
uint16_t udpPortNumber{0};
std::string eth;
bool activated{false};
bool detectorDataStream{true};
bool udpDataStream{true};
bool isOutsideRoi{false};
bool silentMode;
bool disabledPort{false};
+58 -8
View File
@@ -53,6 +53,10 @@ void MasterAttributes::GetJungfrauBinaryAttributes(writer *w) {
WriteBinaryExposureTme(w);
WriteBinaryAcquisitionPeriod(w);
WriteBinaryNumberOfUDPInterfaces(w);
if (numUDPInterfaces == 2) {
WriteBinaryUDPPortsType(w);
WriteBinaryUDPPortsDisabled(w);
}
WriteBinaryNumberOfRows(w);
WriteBinaryReadoutSpeed(w);
}
@@ -63,6 +67,10 @@ void MasterAttributes::WriteJungfrauHDF5Attributes(H5::Group *group) {
WriteHDF5ExposureTime(group);
WriteHDF5AcquisitionPeriod(group);
WriteHDF5NumberOfUDPInterfaces(group);
if (numUDPInterfaces == 2) {
WriteHDF5UDPPortsType(group);
WriteHDF5UDPPortsDisabled(group);
}
WriteHDF5NumberOfRows(group);
WriteHDF5ReadoutSpeed(group);
}
@@ -73,6 +81,10 @@ void MasterAttributes::GetMoenchBinaryAttributes(writer *w) {
WriteBinaryExposureTme(w);
WriteBinaryAcquisitionPeriod(w);
WriteBinaryNumberOfUDPInterfaces(w);
if (numUDPInterfaces == 2) {
WriteBinaryUDPPortsType(w);
WriteBinaryUDPPortsDisabled(w);
}
WriteBinaryNumberOfRows(w);
WriteBinaryReadoutSpeed(w);
}
@@ -83,6 +95,10 @@ void MasterAttributes::WriteMoenchHDF5Attributes(H5::Group *group) {
WriteHDF5ExposureTime(group);
WriteHDF5AcquisitionPeriod(group);
WriteHDF5NumberOfUDPInterfaces(group);
if (numUDPInterfaces == 2) {
WriteHDF5UDPPortsType(group);
WriteHDF5UDPPortsDisabled(group);
}
WriteHDF5NumberOfRows(group);
WriteHDF5ReadoutSpeed(group);
}
@@ -98,6 +114,8 @@ void MasterAttributes::GetEigerBinaryAttributes(writer *w) {
WriteBinarySubExposureTime(w);
WriteBinarySubAcquisitionPeriod(w);
WriteBinaryQuad(w);
WriteBinaryUDPPortsType(w);
WriteBinaryUDPPortsDisabled(w);
WriteBinaryNumberOfRows(w);
WriteBinaryRateCorrections(w);
WriteBinaryReadoutSpeed(w);
@@ -114,6 +132,8 @@ void MasterAttributes::WriteEigerHDF5Attributes(H5::Group *group) {
WriteHDF5SubExposureTime(group);
WriteHDF5SubAcquisitionPeriod(group);
WriteHDF5Quad(group);
WriteHDF5UDPPortsType(group);
WriteHDF5UDPPortsDisabled(group);
WriteHDF5NumberOfRows(group);
WriteHDF5RateCorrections(group);
WriteHDF5ReadoutSpeed(group);
@@ -690,6 +710,26 @@ void MasterAttributes::WriteHDF5TransceiverSamples(H5::Group *group) {
}
#endif
void MasterAttributes::WriteBinaryUDPPortsType(writer *w) {
WriteBinary(w, N_UDP_PORTS_TYPE.data(), udpPortTypes);
}
#ifdef HDF5C
void MasterAttributes::WriteHDF5UDPPortsType(H5::Group *group) {
WriteHDF5StringArray(group, N_UDP_PORTS_TYPE.data(), udpPortTypes);
}
#endif
void MasterAttributes::WriteBinaryUDPPortsDisabled(writer *w) {
WriteBinary(w, N_UDP_PORTS_DISABLED.data(), udpPortsDisabled);
}
#ifdef HDF5C
void MasterAttributes::WriteHDF5UDPPortsDisabled(H5::Group *group) {
WriteHDF5Int(group, N_UDP_PORTS_DISABLED.data(), udpPortsDisabled);
}
#endif
#ifdef HDF5C
void MasterAttributes::WriteHDF5String(H5::Group *group,
const std::string &name,
@@ -704,15 +744,25 @@ void MasterAttributes::WriteHDF5String(H5::Group *group,
void MasterAttributes::WriteHDF5StringArray(
H5::Group *group, const std::string &name,
const std::vector<std::string> &value) {
std::vector<const char *> c;
for (auto &s : value) {
c.push_back(s.c_str());
try {
std::vector<const char *> c;
for (auto &s : value) {
c.push_back(s.c_str());
}
hsize_t dims[1] = {c.size()};
H5::DataSpace dataspace(1, dims);
H5::StrType strdatatype(H5::PredType::C_S1, H5T_VARIABLE);
H5::DataSet dataset =
group->createDataSet(name, strdatatype, dataspace);
dataset.write(c.data(), strdatatype);
} catch (H5::Exception &e) {
e.printErrorStack();
throw RuntimeError("Could not write attribute " + name +
" in HDf5 file");
} catch (std::exception &e) {
throw RuntimeError("Other excetion: Could not write attribute " + name +
" in HDf5 file. " + std::string(e.what()));
}
hsize_t dims[1] = {c.size()};
H5::DataSpace dataspace(1, dims);
H5::StrType strdatatype(H5::PredType::C_S1, H5T_VARIABLE);
H5::DataSet dataset = group->createDataSet(name, strdatatype, dataspace);
dataset.write(c.data(), strdatatype);
}
#endif
+34 -10
View File
@@ -68,6 +68,8 @@ class MasterAttributes {
std::map<std::string, std::string> additionalJsonHeader;
uint64_t framesInFile{0};
slsDetectorDefs::speedLevel readoutSpeed{slsDetectorDefs::FULL_SPEED};
std::vector<std::string> udpPortTypes;
std::vector<int> udpPortsDisabled;
inline static const std::string_view N_DETECTOR_TYPE = "Detector Type";
inline static const std::string_view N_TIMING_MODE = "Timing Mode";
@@ -125,6 +127,9 @@ class MasterAttributes {
inline static const std::string_view N_SCAN_PARAMETERS = "Scan Parameters";
inline static const std::string_view N_ADDITIONAL_JSON_HEADER =
"Additional JSON Header";
inline static const std::string_view N_UDP_PORTS_DISABLED =
"UDP Ports Disabled";
inline static const std::string_view N_UDP_PORTS_TYPE = "UDP Ports Type";
MasterAttributes() = default;
~MasterAttributes() = default;
@@ -334,7 +339,14 @@ class MasterAttributes {
#ifdef HDF5C
void WriteHDF5TransceiverSamples(H5::Group *group);
#endif
void WriteBinaryUDPPortsType(writer *w);
#ifdef HDF5C
void WriteHDF5UDPPortsType(H5::Group *group);
#endif
void WriteBinaryUDPPortsDisabled(writer *w);
#ifdef HDF5C
void WriteHDF5UDPPortsDisabled(H5::Group *group);
#endif
/** writes according to type */
template <typename T> void WriteBinaryValue(writer *w, const T &value) {
if constexpr (std::is_same_v<T, int>) {
@@ -402,10 +414,16 @@ class MasterAttributes {
template <typename T>
typename std::enable_if<!std::is_class<T>::value, void>::type
WriteHDF5Int(H5::Group *group, const std::string &name, const T &value) {
H5::DataSpace dataspace(H5S_SCALAR);
auto h5type = GetHDF5Type<T>();
H5::DataSet dataset = group->createDataSet(name, *h5type, dataspace);
dataset.write(&value, *h5type);
try {
H5::DataSpace dataspace(H5S_SCALAR);
auto h5type = GetHDF5Type<T>();
H5::DataSet dataset =
group->createDataSet(name, *h5type, dataspace);
dataset.write(&value, *h5type);
} catch (std::exception &e) {
throw RuntimeError("Could not write attribute " + name +
" in HDf5 file");
}
}
/** For arrays */
@@ -413,11 +431,17 @@ class MasterAttributes {
typename std::enable_if<std::is_class<T>::value, void>::type
WriteHDF5Int(H5::Group *group, const std::string &name, const T &value) {
using ElemT = typename T::value_type;
auto h5type = GetHDF5Type<ElemT>();
hsize_t dims[1] = {value.size()};
H5::DataSpace dataspace(1, dims);
H5::DataSet dataset = group->createDataSet(name, *h5type, dataspace);
dataset.write(value.data(), *h5type);
try {
auto h5type = GetHDF5Type<ElemT>();
hsize_t dims[1] = {value.size()};
H5::DataSpace dataspace(1, dims);
H5::DataSet dataset =
group->createDataSet(name, *h5type, dataspace);
dataset.write(value.data(), *h5type);
} catch (std::exception &e) {
throw RuntimeError("Could not write attribute " + name +
" in HDf5 file");
}
}
#endif
+2 -2
View File
@@ -19,8 +19,8 @@ namespace sls {
// files
// versions
#define HDF5_WRITER_VERSION (7.0) // 1 decimal places
#define BINARY_WRITER_VERSION (8.0) // 1 decimal places
#define HDF5_WRITER_VERSION (7.1) // 1 decimal places
#define BINARY_WRITER_VERSION (8.1) // 1 decimal places
#define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000
@@ -409,7 +409,7 @@ enum detFuncs {
F_GET_RECEIVER_STREAMING_HWM,
F_SET_RECEIVER_STREAMING_HWM,
F_RECEIVER_SET_ALL_THRESHOLD,
F_RECEIVER_SET_DATASTREAM,
F_RECEIVER_SET_UDP_DATASTREAM,
F_GET_RECEIVER_ARPING,
F_SET_RECEIVER_ARPING,
F_RECEIVER_GET_RECEIVER_ROI,
@@ -423,6 +423,9 @@ enum detFuncs {
F_SET_RECEIVER_DBIT_REORDER,
F_RECEIVER_GET_ROI_METADATA,
F_SET_RECEIVER_READOUT_SPEED,
F_RECEIVER_GET_UDP_DATASTREAM,
F_RECEIVER_SET_UDP_PORT_DISABLE_META,
F_RECEIVER_GET_UDP_PORT_DISABLE_META,
NUM_REC_FUNCTIONS
};
@@ -828,7 +831,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_RECEIVER_STREAMING_HWM: return "F_GET_RECEIVER_STREAMING_HWM";
case F_SET_RECEIVER_STREAMING_HWM: return "F_SET_RECEIVER_STREAMING_HWM";
case F_RECEIVER_SET_ALL_THRESHOLD: return "F_RECEIVER_SET_ALL_THRESHOLD";
case F_RECEIVER_SET_DATASTREAM: return "F_RECEIVER_SET_DATASTREAM";
case F_RECEIVER_SET_UDP_DATASTREAM: return "F_RECEIVER_SET_UDP_DATASTREAM";
case F_GET_RECEIVER_ARPING: return "F_GET_RECEIVER_ARPING";
case F_SET_RECEIVER_ARPING: return "F_SET_RECEIVER_ARPING";
case F_RECEIVER_GET_RECEIVER_ROI: return "F_RECEIVER_GET_RECEIVER_ROI";
@@ -842,6 +845,10 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_DBIT_REORDER: return "F_SET_RECEIVER_DBIT_REORDER";
case F_RECEIVER_GET_ROI_METADATA: return "F_RECEIVER_GET_ROI_METADATA";
case F_SET_RECEIVER_READOUT_SPEED: return "F_SET_RECEIVER_READOUT_SPEED";
case F_RECEIVER_GET_UDP_DATASTREAM: return "F_RECEIVER_GET_UDP_DATASTREAM";
case F_RECEIVER_SET_UDP_PORT_DISABLE_META: return "F_RECEIVER_SET_UDP_PORT_DISABLE_META";
case F_RECEIVER_GET_UDP_PORT_DISABLE_META: return "F_RECEIVER_GET_UDP_PORT_DISABLE_META";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";