diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 9079c932e..a5ba4134d 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -11,6 +11,7 @@ pybind11_add_module(_slsdet src/current.cpp src/duration.cpp src/DurationWrapper.cpp + src/pedestal.cpp ) target_link_libraries(_slsdet PUBLIC @@ -27,8 +28,7 @@ set( PYTHON_FILES slsdet/__init__.py slsdet/adcs.py slsdet/dacs.py - slsdet/voltages.py - slsdet/slowadcs.py + slsdet/powers.py slsdet/decorators.py slsdet/detector_property.py slsdet/detector.py diff --git a/python/examples/use_pedestalmode.py b/python/examples/use_pedestalmode.py new file mode 100644 index 000000000..ad209bf2d --- /dev/null +++ b/python/examples/use_pedestalmode.py @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package +from slsdet import Detector, pedestalParameters + +p = pedestalParameters() +p.frames = 10 +p.loops= 20 + + + +d = Detector() +d.pedestalmode = p \ No newline at end of file diff --git a/python/setup.py b/python/setup.py index 47c732e82..aee81b640 100755 --- a/python/setup.py +++ b/python/setup.py @@ -35,6 +35,7 @@ ext_modules = [ 'src/scan.cpp', 'src/duration.cpp', 'src/DurationWrapper.cpp', + 'src/pedestal.cpp', ] diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index dd657ecf8..8915bc130 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -4,8 +4,7 @@ from .eiger import Eiger from .ctb import Ctb from .dacs import DetectorDacs, Dac -from .voltages import DetectorVoltages, Voltage -from .slowadcs import DetectorSlowAdcs, SlowAdc +from .powers import DetectorPowers, Power from .detector import Detector from .jungfrau import Jungfrau from .mythen3 import Mythen3 @@ -27,4 +26,5 @@ IpAddr = _slsdet.IpAddr MacAddr = _slsdet.MacAddr scanParameters = _slsdet.scanParameters currentSrcParameters = _slsdet.currentSrcParameters -DurationWrapper = _slsdet.DurationWrapper \ No newline at end of file +DurationWrapper = _slsdet.DurationWrapper +pedestalParameters = _slsdet.pedestalParameters \ No newline at end of file diff --git a/python/slsdet/ctb.py b/python/slsdet/ctb.py index 74e4a59ee..ad671a93e 100644 --- a/python/slsdet/ctb.py +++ b/python/slsdet/ctb.py @@ -3,8 +3,7 @@ from .detector import Detector, freeze from .utils import element_if_equal from .dacs import DetectorDacs, NamedDacs -from .voltages import DetectorVoltages, NamedVoltages -from .slowadcs import DetectorSlowAdcs, NamedSlowAdcs +from .powers import DetectorPowers, NamedPowers import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty @@ -17,17 +16,12 @@ class Ctb(Detector): super().__init__(id) self._frozen = False self._dacs = NamedDacs(self) - self._voltages = NamedVoltages(self) - self._slowadcs = NamedSlowAdcs(self) + self._powers = NamedPowers(self) @property def dacs(self): return self._dacs @property - def voltages(self): - return self._voltages - - @property - def slowadcs(self): - return self._slowadcs \ No newline at end of file + def powers(self): + return self._powers \ No newline at end of file diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 2cbd5266d..95e3593cc 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -182,6 +182,7 @@ class Detector(CppDetectorApi): @port.setter def port(self, value): + ut.validate_port(value) ut.set_using_dict(self.setControlPort, value) @property @@ -197,6 +198,7 @@ class Detector(CppDetectorApi): @stopport.setter def stopport(self, args): + ut.validate_port(args) ut.set_using_dict(self.setStopPort, args) @@ -866,6 +868,7 @@ class Detector(CppDetectorApi): @rx_tcpport.setter def rx_tcpport(self, port): + ut.validate_port(port) ut.set_using_dict(self.setRxPort, port) @property @@ -1145,11 +1148,14 @@ class Detector(CppDetectorApi): @rx_zmqport.setter def rx_zmqport(self, port): if isinstance(port, int): + ut.validate_port(port) self.setRxZmqPort(port, -1) elif isinstance(port, dict): + ut.validate_port(port) ut.set_using_dict(self.setRxZmqPort, port) elif is_iterable(port): for i, p in enumerate(port): + ut.validate_port(p) self.setRxZmqPort(p, i) else: raise ValueError("Unknown argument type") @@ -1179,11 +1185,14 @@ class Detector(CppDetectorApi): @zmqport.setter def zmqport(self, port): if isinstance(port, int): + ut.validate_port(port) self.setClientZmqPort(port, -1) elif isinstance(port, dict): + ut.validate_port(port) ut.set_using_dict(self.setClientZmqPort, port) elif is_iterable(port): for i, p in enumerate(port): + ut.validate_port(p) self.setClientZmqPort(p, i) else: raise ValueError("Unknown argument type") @@ -1493,6 +1502,7 @@ class Detector(CppDetectorApi): @udp_dstport.setter def udp_dstport(self, port): + ut.validate_port(port) ut.set_using_dict(self.setDestinationUDPPort, port) @property @@ -1514,6 +1524,7 @@ class Detector(CppDetectorApi): @udp_dstport2.setter def udp_dstport2(self, port): + ut.validate_port(port) ut.set_using_dict(self.setDestinationUDPPort2, port) @property @@ -1828,17 +1839,17 @@ class Detector(CppDetectorApi): self.setSignalNames(value) @property - def voltagelist(self): + def powerlist(self): """ - List of names for every voltage for this board. 5 voltage supply + List of names for every power for this board. 5 power supply :setter: Only implemented for Chiptestboard """ - return self.getVoltageNames() + return self.getPowerNames() - @voltagelist.setter - def voltagelist(self, value): - self.setVoltageNames(value) + @powerlist.setter + def powerlist(self, value): + self.setPowerNames(value) @property def slowadclist(self): @@ -1851,7 +1862,7 @@ class Detector(CppDetectorApi): @slowadclist.setter def slowadclist(self, value): - self.setSlowAdcNames(value) + self.setSlowADCNames(value) @property def dacvalues(self): @@ -1862,11 +1873,11 @@ class Detector(CppDetectorApi): } @property - def voltagevalues(self): - """Gets the voltage values for every voltage for this detector.""" + def powervalues(self): + """Gets the power values for every power for this detector.""" return { - voltage.name.lower(): element_if_equal(np.array(self.getVoltage(voltage))) - for voltage in self.getVoltageList() + power.name.lower(): element_if_equal(np.array(self.getPower(power))) + for power in self.getPowerList() } @property @@ -2026,6 +2037,7 @@ class Detector(CppDetectorApi): @virtual.setter def virtual(self, args): n_detectors, starting_port = args + ut.validate_port(starting_port) self.setVirtualDetectorServers(n_detectors, starting_port) @@ -2854,7 +2866,27 @@ class Detector(CppDetectorApi): @filtercells.setter def filtercells(self, value): ut.set_using_dict(self.setNumberOfFilterCells, value) + + @property + @element + def pedestalmode(self): + """ + [Jungfrau] Enables or disables pedestal mode. Pass in a pedestalParameters object + see python/examples/use_pedestalmode.py + Note + ---- + The number of frames or triggers is overwritten by #pedestal_frames x pedestal_loops x 2. \n + In auto timing mode or in trigger mode with #frames > 1, #frames is overwritten and #triggers = 1, else #triggers is overwritten and #frames = 1. \n + One cannot set #frames, #triggers or timing mode in pedestal mode (exception thrown).\n + Disabling pedestal mode will set back the normal mode values of #frames and #triggers." + """ + return self.getPedestalMode() + + @pedestalmode.setter + def pedestalmode(self, value): + ut.set_using_dict(self.setPedestalMode, value) + @property def maxclkphaseshift(self): """ @@ -3814,73 +3846,73 @@ class Detector(CppDetectorApi): @property @element def v_a(self): - """[Ctb] Voltage supply a in mV.""" - return self.getVoltage(dacIndex.V_POWER_A) + """[Ctb] Power supply a in mV.""" + return self.getPower(dacIndex.V_POWER_A) @v_a.setter def v_a(self, value): value = ut.merge_args(dacIndex.V_POWER_A, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property @element def v_b(self): - """[Ctb] Voltage supply b in mV.""" - return self.getVoltage(dacIndex.V_POWER_B) + """[Ctb] Power supply b in mV.""" + return self.getPower(dacIndex.V_POWER_B) @v_b.setter def v_b(self, value): value = ut.merge_args(dacIndex.V_POWER_B, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property @element def v_c(self): - """[Ctb] Voltage supply c in mV.""" - return self.getVoltage(dacIndex.V_POWER_C) + """[Ctb] Power supply c in mV.""" + return self.getPower(dacIndex.V_POWER_C) @v_c.setter def v_c(self, value): value = ut.merge_args(dacIndex.V_POWER_C, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property @element def v_d(self): - """[Ctb] Voltage supply d in mV.""" - return self.getVoltage(dacIndex.V_POWER_D) + """[Ctb] Power supply d in mV.""" + return self.getPower(dacIndex.V_POWER_D) @v_d.setter def v_d(self, value): value = ut.merge_args(dacIndex.V_POWER_D, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property @element def v_io(self): - """[Ctb] Voltage supply io in mV. Minimum 1200 mV. + """[Ctb] Power supply io in mV. Minimum 1200 mV. Note ---- Must be the first power regulator to be set after fpga reset (on-board detector server start up). """ - return self.getVoltage(dacIndex.V_POWER_IO) + return self.getPower(dacIndex.V_POWER_IO) @v_io.setter def v_io(self, value): value = ut.merge_args(dacIndex.V_POWER_IO, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property @element def v_limit(self): """[Ctb] Soft limit for power supplies (ctb only) and DACS in mV.""" - return self.getVoltage(dacIndex.V_LIMIT) + return self.getPower(dacIndex.V_LIMIT) @v_limit.setter def v_limit(self, value): value = ut.merge_args(dacIndex.V_LIMIT, value) - ut.set_using_dict(self.setVoltage, *value) + ut.set_using_dict(self.setPower, *value) @property diff --git a/python/slsdet/powers.py b/python/slsdet/powers.py new file mode 100755 index 000000000..8de1781c7 --- /dev/null +++ b/python/slsdet/powers.py @@ -0,0 +1,195 @@ +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package +from .detector_property import DetectorProperty +from functools import partial +import numpy as np +import _slsdet +from .detector import freeze +dacIndex = _slsdet.slsDetectorDefs.dacIndex +class Power(DetectorProperty): + """ + This class represents a power on the Chip Test Board. One instance handles all + powers with the same name for a multi detector instance. (TODO: Not needed for CTB) + + .. note :: + + This class is used to build up DetectorPowers and is in general + not directly accessible to the user. + + + """ + def __init__(self, name, enum, default, detector): + + super().__init__(partial(detector.getPower, enum), + lambda x, y : detector.setPower(enum, x, y), + detector.size, + name) + + self.default = default + + + def __repr__(self): + """String representation for a single power in all modules""" + powerstr = ''.join([f'{item:5d}' for item in self.get()]) + return f'{self.__name__:15s}:{powerstr}' + +class NamedPowers: + """ + New implementation of the detector powers. + """ + _frozen = False + _direct_access = ['_detector', '_current', '_powernames'] + def __init__(self, detector): + self._detector = detector + self._current = 0 + + #only get the powernames if we have modules attached + if detector.size() == 0: + self._powernames = ["VA", "VB", "VC", "VD", "VIO"] + else: + self._powernames = [n.replace(" ", "") for n in detector.getPowerNames()] + + # Populate the powers + for i,name in enumerate(self._powernames): + #name, enum, low, high, default, detector + k = dacIndex(i + int(dacIndex.V_POWER_A)) + setattr(self, name, Power(name, k, 0, detector)) + + self._frozen = True + + # def __getattr__(self, name): + # return self.__getattribute__('_' + name) + + def __setattr__(self, name, value): + if not self._frozen: + #durning init we need to be able to set up the class + super().__setattr__(name, value) + else: + #Later we restrict us to manipulate powers and a few fields + if name in self._direct_access: + super().__setattr__(name, value) + elif name in self._powernames: + return self.__getattribute__(name).__setitem__(slice(None, None), value) + else: + raise AttributeError(f'Power not found: {name}') + + def __next__(self): + if self._current >= len(self._powernames): + self._current = 0 + raise StopIteration + else: + self._current += 1 + return self.__getattribute__(self._powernames[self._current-1]) + # return self.__getattr__(self._powernames[self._current-1]) + + def __iter__(self): + return self + + def __repr__(self): + r_str = ['========== POWERS ========='] + r_str += [repr(power) for power in self] + return '\n'.join(r_str) + def get_asarray(self): + """ + Read the powers into a numpy array with dimensions [npowers, nmodules] + """ + power_array = np.zeros((len(self._powernames), len(self._detector))) + for i, _d in enumerate(self): + power_array[i,:] = _d[:] + return power_array + + def to_array(self): + return self.get_asarray() + + def set_from_array(self, power_array): + """ + Set the power from an numpy array with power values. [npowers, nmodules] + """ + power_array = power_array.astype(np.int) + for i, _d in enumerate(self): + _d[:] = power_array[i] + + def from_array(self, power_array): + self.set_from_array(power_array) + +class DetectorPowers: + _powers = [] + _powernames = [_d[0] for _d in _powers] + _allowed_attr = ['_detector', '_current'] + _frozen = False + + def __init__(self, detector): + # We need to at least initially know which detector we are connected to + self._detector = detector + + # Index to support iteration + self._current = 0 + + # Name the attributes? + for _d in self._powers: + setattr(self, '_'+_d[0], Power(*_d, detector)) + + self._frozen = True + + def __getattr__(self, name): + return self.__getattribute__('_' + name) + + @property + def powernames(self): + return [_d[0] for _d in _powers] + + def __setattr__(self, name, value): + if name in self._powernames: + return self.__getattribute__('_' + name).__setitem__(slice(None, None), value) + else: + if self._frozen == True and name not in self._allowed_attr: + raise AttributeError(f'Power not found: {name}') + super().__setattr__(name, value) + + + def __next__(self): + if self._current >= len(self._powers): + self._current = 0 + raise StopIteration + else: + self._current += 1 + return self.__getattr__(self._powernames[self._current-1]) + + def __iter__(self): + return self + + def __repr__(self): + r_str = ['========== POWERS ========='] + r_str += [repr(power) for power in self] + return '\n'.join(r_str) + + def get_asarray(self): + """ + Read the powers into a numpy array with dimensions [npowers, nmodules] + """ + power_array = np.zeros((len(self._powers), len(self._detector))) + for i, _d in enumerate(self): + power_array[i,:] = _d[:] + return power_array + + def to_array(self): + return self.get_asarray() + + def set_from_array(self, power_array): + """ + Set the powers from an numpy array with power values. [npowers, nmodules] + """ + power_array = power_array.astype(np.int) + for i, _d in enumerate(self): + _d[:] = power_array[i] + + def from_array(self, power_array): + self.set_from_array(power_array) + + def set_default(self): + """ + Set all powers to their default values + """ + for _d in self: + _d[:] = _d.default + diff --git a/python/slsdet/proxy.py b/python/slsdet/proxy.py index 90c9f4523..cd10cb38a 100644 --- a/python/slsdet/proxy.py +++ b/python/slsdet/proxy.py @@ -60,18 +60,27 @@ class SlowAdcProxy: def __getitem__(self, key): dac_index = dacIndex(int(dacIndex.SLOW_ADC0)+key) - return element_if_equal(self.det.getSlowADC(dac_index)) + return element_if_equal(self.det.getSlowADC(dac_index))/1000 #TODO! Multi module? def __repr__(self): rstr = '' - for i in range(8): + for i,name in enumerate(self.det.getSlowADCNames()): r = element_if_equal(self.__getitem__(i)) if isinstance(r, list): - rstr += ' '.join(f'{item} uV' for item in r) + rstr += ' '.join(f'{item/1000} mV' for item in r) else: - rstr += f'{i}: {r} uV\n' + rstr += f'[{i}] {name}: {r/1000} mV\n' return rstr.strip('\n') + + def __getattr__(self, name): + if name in self.det.getSlowADCNames(): + i = self.det.getSlowADCIndex(name) + return element_if_equal(self.det.getSlowADC(i)) + else: + raise ValueError(f"Could not find slow adc with name: {name}") + + class ClkDivProxy: """ diff --git a/python/slsdet/slowadcs.py b/python/slsdet/slowadcs.py deleted file mode 100755 index ae153a706..000000000 --- a/python/slsdet/slowadcs.py +++ /dev/null @@ -1,195 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package -from .detector_property import DetectorProperty -from functools import partial -import numpy as np -import _slsdet -from .detector import freeze -dacIndex = _slsdet.slsDetectorDefs.dacIndex -class SlowAdc(DetectorProperty): - """ - This class represents a slowadc on the Chip Test Board. One instance handles all - slowadcs with the same name for a multi detector instance. (TODO: Not needed for CTB) - - .. note :: - - This class is used to build up DetectorSlowAdcs and is in general - not directly accessible to the user. - - - """ - def __init__(self, name, enum, default, detector): - - super().__init__(partial(detector.getVoltage, enum), - lambda x, y : detector.setVoltage(enum, x, y), - detector.size, - name) - - self.default = default - - - def __repr__(self): - """String representation for a single slowadc in all modules""" - slowadcstr = ''.join([f'{item:5d}' for item in self.get()]) - return f'{self.__name__:15s}:{slowadcstr}' - -class NamedSlowAdcs: - """ - New implementation of the detector slowadcs. - """ - _frozen = False - _direct_access = ['_detector', '_current', '_voltagenames'] - def __init__(self, detector): - self._detector = detector - self._current = 0 - - #only get the voltagenames if we have modules attached - if detector.size() == 0: - self._voltagenames = ["VA", "VB", "VC", "VD", "VIO"] - else: - self._voltagenames = [n.replace(" ", "") for n in detector.getVoltageNames()] - - # Populate the slowadcs - for i,name in enumerate(self._voltagenames): - #name, enum, low, high, default, detector - k = dacIndex(i + int(dacIndex.V_POWER_A)) - setattr(self, name, SlowAdc(name, k, 0, detector)) - - self._frozen = True - - # def __getattr__(self, name): - # return self.__getattribute__('_' + name) - - def __setattr__(self, name, value): - if not self._frozen: - #durning init we need to be able to set up the class - super().__setattr__(name, value) - else: - #Later we restrict us to manipulate slowadcs and a few fields - if name in self._direct_access: - super().__setattr__(name, value) - elif name in self._voltagenames: - return self.__getattribute__(name).__setitem__(slice(None, None), value) - else: - raise AttributeError(f'SlowAdc not found: {name}') - - def __next__(self): - if self._current >= len(self._voltagenames): - self._current = 0 - raise StopIteration - else: - self._current += 1 - return self.__getattribute__(self._voltagenames[self._current-1]) - # return self.__getattr__(self._voltagenames[self._current-1]) - - def __iter__(self): - return self - - def __repr__(self): - r_str = ['========== SLOW ADCS ========='] - r_str += [repr(slowadc) for slowadc in self] - return '\n'.join(r_str) - def get_asarray(self): - """ - Read the slowadcs into a numpy array with dimensions [nslowadcs, nmodules] - """ - voltage_array = np.zeros((len(self._voltagenames), len(self._detector))) - for i, _d in enumerate(self): - voltage_array[i,:] = _d[:] - return voltage_array - - def to_array(self): - return self.get_asarray() - - def set_from_array(self, voltage_array): - """ - Set the slowadc from an numpy array with slowadc values. [nslowadcs, nmodules] - """ - voltage_array = voltage_array.astype(np.int) - for i, _d in enumerate(self): - _d[:] = voltage_array[i] - - def from_array(self, voltage_array): - self.set_from_array(voltage_array) - -class DetectorSlowAdcs: - _slowadcs = [] - _voltagenames = [_d[0] for _d in _slowadcs] - _allowed_attr = ['_detector', '_current'] - _frozen = False - - def __init__(self, detector): - # We need to at least initially know which detector we are connected to - self._detector = detector - - # Index to support iteration - self._current = 0 - - # Name the attributes? - for _d in self._slowadcs: - setattr(self, '_'+_d[0], SlowAdc(*_d, detector)) - - self._frozen = True - - def __getattr__(self, name): - return self.__getattribute__('_' + name) - - @property - def voltagenames(self): - return [_d[0] for _d in _slowadcs] - - def __setattr__(self, name, value): - if name in self._voltagenames: - return self.__getattribute__('_' + name).__setitem__(slice(None, None), value) - else: - if self._frozen == True and name not in self._allowed_attr: - raise AttributeError(f'SlowAdc not found: {name}') - super().__setattr__(name, value) - - - def __next__(self): - if self._current >= len(self._slowadcs): - self._current = 0 - raise StopIteration - else: - self._current += 1 - return self.__getattr__(self._voltagenames[self._current-1]) - - def __iter__(self): - return self - - def __repr__(self): - r_str = ['========== SLOW ADCS ========='] - r_str += [repr(slowadc) for slowadc in self] - return '\n'.join(r_str) - - def get_asarray(self): - """ - Read the slowadcs into a numpy array with dimensions [nslowadcs, nmodules] - """ - voltage_array = np.zeros((len(self._slowadcs), len(self._detector))) - for i, _d in enumerate(self): - voltage_array[i,:] = _d[:] - return voltage_array - - def to_array(self): - return self.get_asarray() - - def set_from_array(self, voltage_array): - """ - Set the slowadcs from an numpy array with slowadc values. [nslowadcs, nmodules] - """ - voltage_array = voltage_array.astype(np.int) - for i, _d in enumerate(self): - _d[:] = voltage_array[i] - - def from_array(self, voltage_array): - self.set_from_array(voltage_array) - - def set_default(self): - """ - Set all slowadcs to their default values - """ - for _d in self: - _d[:] = _d.default - diff --git a/python/slsdet/utils.py b/python/slsdet/utils.py index 60bbbb2a7..89a7651bc 100755 --- a/python/slsdet/utils.py +++ b/python/slsdet/utils.py @@ -278,3 +278,9 @@ def hostname_list(args): return hosts else: raise ValueError("hostname needs to be string or list of strings") + + +def validate_port(value): + if value <= 0 or value > 65535: + raise ValueError("port must be in range 1 - 65535") + diff --git a/python/slsdet/voltages.py b/python/slsdet/voltages.py deleted file mode 100755 index f545d5dd0..000000000 --- a/python/slsdet/voltages.py +++ /dev/null @@ -1,195 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package -from .detector_property import DetectorProperty -from functools import partial -import numpy as np -import _slsdet -from .detector import freeze -dacIndex = _slsdet.slsDetectorDefs.dacIndex -class Voltage(DetectorProperty): - """ - This class represents a voltage on the Chip Test Board. One instance handles all - voltages with the same name for a multi detector instance. (TODO: Not needed for CTB) - - .. note :: - - This class is used to build up DetectorVoltages and is in general - not directly accessible to the user. - - - """ - def __init__(self, name, enum, default, detector): - - super().__init__(partial(detector.getVoltage, enum), - lambda x, y : detector.setVoltage(enum, x, y), - detector.size, - name) - - self.default = default - - - def __repr__(self): - """String representation for a single voltage in all modules""" - voltagestr = ''.join([f'{item:5d}' for item in self.get()]) - return f'{self.__name__:15s}:{voltagestr}' - -class NamedVoltages: - """ - New implementation of the detector voltages. - """ - _frozen = False - _direct_access = ['_detector', '_current', '_voltagenames'] - def __init__(self, detector): - self._detector = detector - self._current = 0 - - #only get the voltagenames if we have modules attached - if detector.size() == 0: - self._voltagenames = ["VA", "VB", "VC", "VD", "VIO"] - else: - self._voltagenames = [n.replace(" ", "") for n in detector.getVoltageNames()] - - # Populate the voltages - for i,name in enumerate(self._voltagenames): - #name, enum, low, high, default, detector - k = dacIndex(i + int(dacIndex.V_POWER_A)) - setattr(self, name, Voltage(name, k, 0, detector)) - - self._frozen = True - - # def __getattr__(self, name): - # return self.__getattribute__('_' + name) - - def __setattr__(self, name, value): - if not self._frozen: - #durning init we need to be able to set up the class - super().__setattr__(name, value) - else: - #Later we restrict us to manipulate voltages and a few fields - if name in self._direct_access: - super().__setattr__(name, value) - elif name in self._voltagenames: - return self.__getattribute__(name).__setitem__(slice(None, None), value) - else: - raise AttributeError(f'Voltage not found: {name}') - - def __next__(self): - if self._current >= len(self._voltagenames): - self._current = 0 - raise StopIteration - else: - self._current += 1 - return self.__getattribute__(self._voltagenames[self._current-1]) - # return self.__getattr__(self._voltagenames[self._current-1]) - - def __iter__(self): - return self - - def __repr__(self): - r_str = ['========== VOLTAGES ========='] - r_str += [repr(voltage) for voltage in self] - return '\n'.join(r_str) - def get_asarray(self): - """ - Read the voltages into a numpy array with dimensions [nvoltages, nmodules] - """ - voltage_array = np.zeros((len(self._voltagenames), len(self._detector))) - for i, _d in enumerate(self): - voltage_array[i,:] = _d[:] - return voltage_array - - def to_array(self): - return self.get_asarray() - - def set_from_array(self, voltage_array): - """ - Set the voltage from an numpy array with voltage values. [nvoltages, nmodules] - """ - voltage_array = voltage_array.astype(np.int) - for i, _d in enumerate(self): - _d[:] = voltage_array[i] - - def from_array(self, voltage_array): - self.set_from_array(voltage_array) - -class DetectorVoltages: - _voltages = [] - _voltagenames = [_d[0] for _d in _voltages] - _allowed_attr = ['_detector', '_current'] - _frozen = False - - def __init__(self, detector): - # We need to at least initially know which detector we are connected to - self._detector = detector - - # Index to support iteration - self._current = 0 - - # Name the attributes? - for _d in self._voltages: - setattr(self, '_'+_d[0], Voltage(*_d, detector)) - - self._frozen = True - - def __getattr__(self, name): - return self.__getattribute__('_' + name) - - @property - def voltagenames(self): - return [_d[0] for _d in _voltages] - - def __setattr__(self, name, value): - if name in self._voltagenames: - return self.__getattribute__('_' + name).__setitem__(slice(None, None), value) - else: - if self._frozen == True and name not in self._allowed_attr: - raise AttributeError(f'Voltage not found: {name}') - super().__setattr__(name, value) - - - def __next__(self): - if self._current >= len(self._voltages): - self._current = 0 - raise StopIteration - else: - self._current += 1 - return self.__getattr__(self._voltagenames[self._current-1]) - - def __iter__(self): - return self - - def __repr__(self): - r_str = ['========== VOLTAGES ========='] - r_str += [repr(voltage) for voltage in self] - return '\n'.join(r_str) - - def get_asarray(self): - """ - Read the voltages into a numpy array with dimensions [nvoltages, nmodules] - """ - voltage_array = np.zeros((len(self._voltages), len(self._detector))) - for i, _d in enumerate(self): - voltage_array[i,:] = _d[:] - return voltage_array - - def to_array(self): - return self.get_asarray() - - def set_from_array(self, voltage_array): - """ - Set the voltages from an numpy array with voltage values. [nvoltages, nmodules] - """ - voltage_array = voltage_array.astype(np.int) - for i, _d in enumerate(self): - _d[:] = voltage_array[i] - - def from_array(self, voltage_array): - self.set_from_array(voltage_array) - - def set_default(self): - """ - Set all voltages to their default values - """ - for _d in self: - _d[:] = _d.default - diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 81206da20..a1e211ae4 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -48,7 +48,7 @@ void init_det(py::module &m) { Detector::setHostname, py::arg()); CppDetectorApi.def("setVirtualDetectorServers", - (void (Detector::*)(int, int)) & + (void (Detector::*)(int, uint16_t)) & Detector::setVirtualDetectorServers, py::arg(), py::arg()); CppDetectorApi.def("getShmId", @@ -751,19 +751,19 @@ void init_det(py::module &m) { Detector::setDestinationUDPMAC2, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getDestinationUDPPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getDestinationUDPPort, py::arg() = Positions{}); CppDetectorApi.def("setDestinationUDPPort", - (void (Detector::*)(int, int)) & + (void (Detector::*)(uint16_t, int)) & Detector::setDestinationUDPPort, py::arg(), py::arg() = -1); CppDetectorApi.def("getDestinationUDPPort2", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getDestinationUDPPort2, py::arg() = Positions{}); CppDetectorApi.def("setDestinationUDPPort2", - (void (Detector::*)(int, int)) & + (void (Detector::*)(uint16_t, int)) & Detector::setDestinationUDPPort2, py::arg(), py::arg() = -1); CppDetectorApi.def("reconfigureUDPDestination", @@ -844,12 +844,12 @@ void init_det(py::module &m) { Detector::setRxHostname, py::arg()); CppDetectorApi.def("getRxPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getRxPort, py::arg() = Positions{}); - CppDetectorApi.def("setRxPort", - (void (Detector::*)(int, int)) & Detector::setRxPort, - py::arg(), py::arg() = -1); + CppDetectorApi.def( + "setRxPort", (void (Detector::*)(uint16_t, int)) & Detector::setRxPort, + py::arg(), py::arg() = -1); CppDetectorApi.def("getRxFifoDepth", (Result(Detector::*)(sls::Positions) const) & Detector::getRxFifoDepth, @@ -1032,11 +1032,12 @@ void init_det(py::module &m) { Detector::setRxZmqStartingFrame, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getRxZmqPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getRxZmqPort, py::arg() = Positions{}); CppDetectorApi.def("setRxZmqPort", - (void (Detector::*)(int, int)) & Detector::setRxZmqPort, + (void (Detector::*)(uint16_t, int)) & + Detector::setRxZmqPort, py::arg(), py::arg() = -1); CppDetectorApi.def( "getRxZmqIP", @@ -1048,11 +1049,11 @@ void init_det(py::module &m) { Detector::setRxZmqIP, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getClientZmqPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getClientZmqPort, py::arg() = Positions{}); CppDetectorApi.def("setClientZmqPort", - (void (Detector::*)(int, int)) & + (void (Detector::*)(uint16_t, int)) & Detector::setClientZmqPort, py::arg(), py::arg() = -1); CppDetectorApi.def( @@ -1269,6 +1270,16 @@ void init_det(py::module &m) { (void (Detector::*)(int, sls::Positions)) & Detector::setNumberOfFilterCells, py::arg(), py::arg() = Positions{}); + CppDetectorApi.def( + "getPedestalMode", + (Result(Detector::*)(sls::Positions) const) & + Detector::getPedestalMode, + py::arg() = Positions{}); + CppDetectorApi.def( + "setPedestalMode", + (void (Detector::*)(const defs::pedestalParameters, sls::Positions)) & + Detector::setPedestalMode, + py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getROI", (Result(Detector::*)(sls::Positions) const) & Detector::getROI, @@ -1524,29 +1535,21 @@ void init_det(py::module &m) { (Result(Detector::*)(sls::Positions) const) & Detector::getSYNCClock, py::arg() = Positions{}); - CppDetectorApi.def("getADCPipeline", - (Result(Detector::*)(sls::Positions) const) & - Detector::getADCPipeline, - py::arg() = Positions{}); - CppDetectorApi.def("setADCPipeline", - (void (Detector::*)(int, sls::Positions)) & - Detector::setADCPipeline, - py::arg(), py::arg() = Positions{}); - CppDetectorApi.def("getVoltageList", + CppDetectorApi.def("getPowerList", (std::vector(Detector::*)() const) & - Detector::getVoltageList); + Detector::getPowerList); CppDetectorApi.def("getSlowADCList", (std::vector(Detector::*)() const) & Detector::getSlowADCList); CppDetectorApi.def( - "getVoltage", + "getPower", (Result(Detector::*)(defs::dacIndex, sls::Positions) const) & - Detector::getVoltage, + Detector::getPower, py::arg(), py::arg() = Positions{}); CppDetectorApi.def( - "setVoltage", + "setPower", (void (Detector::*)(defs::dacIndex, int, sls::Positions)) & - Detector::setVoltage, + Detector::setPower, py::arg(), py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getADCVpp", (Result(Detector::*)(bool, sls::Positions) const) & @@ -1614,9 +1617,9 @@ void init_det(py::module &m) { Detector::setDBITClock, py::arg(), py::arg() = Positions{}); CppDetectorApi.def( - "getMeasuredVoltage", + "getMeasuredPower", (Result(Detector::*)(defs::dacIndex, sls::Positions) const) & - Detector::getMeasuredVoltage, + Detector::getMeasuredPower, py::arg(), py::arg() = Positions{}); CppDetectorApi.def( "getMeasuredCurrent", @@ -1733,26 +1736,26 @@ void init_det(py::module &m) { (std::string(Detector::*)(const int) const) & Detector::getSignalName, py::arg()); - CppDetectorApi.def("setVoltageNames", + CppDetectorApi.def("setPowerNames", (void (Detector::*)(const std::vector)) & - Detector::setVoltageNames, + Detector::setPowerNames, py::arg()); - CppDetectorApi.def("getVoltageNames", + CppDetectorApi.def("getPowerNames", (std::vector(Detector::*)() const) & - Detector::getVoltageNames); + Detector::getPowerNames); CppDetectorApi.def( - "getVoltageIndex", + "getPowerIndex", (defs::dacIndex(Detector::*)(const std::string &) const) & - Detector::getVoltageIndex, + Detector::getPowerIndex, py::arg()); CppDetectorApi.def( - "setVoltageName", + "setPowerName", (void (Detector::*)(const defs::dacIndex, const std::string &)) & - Detector::setVoltageName, + Detector::setPowerName, py::arg(), py::arg()); - CppDetectorApi.def("getVoltageName", + CppDetectorApi.def("getPowerName", (std::string(Detector::*)(const defs::dacIndex) const) & - Detector::getVoltageName, + Detector::getPowerName, py::arg()); CppDetectorApi.def("setSlowADCNames", (void (Detector::*)(const std::vector)) & @@ -1891,6 +1894,14 @@ void init_det(py::module &m) { sls::Positions)) & Detector::setAdditionalJsonParameter, py::arg(), py::arg(), py::arg() = Positions{}); + CppDetectorApi.def("getADCPipeline", + (Result(Detector::*)(sls::Positions) const) & + Detector::getADCPipeline, + py::arg() = Positions{}); + CppDetectorApi.def("setADCPipeline", + (void (Detector::*)(int, sls::Positions)) & + Detector::setADCPipeline, + py::arg(), py::arg() = Positions{}); CppDetectorApi.def( "programFPGA", (void (Detector::*)(const std::string &, const bool, sls::Positions)) & @@ -1978,19 +1989,19 @@ void init_det(py::module &m) { Detector::setADCInvert, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getControlPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getControlPort, py::arg() = Positions{}); CppDetectorApi.def("setControlPort", - (void (Detector::*)(int, sls::Positions)) & + (void (Detector::*)(uint16_t, sls::Positions)) & Detector::setControlPort, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getStopPort", - (Result(Detector::*)(sls::Positions) const) & + (Result(Detector::*)(sls::Positions) const) & Detector::getStopPort, py::arg() = Positions{}); CppDetectorApi.def("setStopPort", - (void (Detector::*)(int, sls::Positions)) & + (void (Detector::*)(uint16_t, sls::Positions)) & Detector::setStopPort, py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getDetectorLock", diff --git a/python/src/main.cpp b/python/src/main.cpp index 9144b2315..901c4900e 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -19,6 +19,8 @@ void init_pattern(py::module &); void init_scan(py::module &); void init_source(py::module &); void init_duration(py::module &); +void init_pedestal(py::module &); + PYBIND11_MODULE(_slsdet, m) { m.doc() = R"pbdoc( C/C++ API @@ -37,6 +39,7 @@ PYBIND11_MODULE(_slsdet, m) { init_scan(m); init_source(m); init_duration(m); + init_pedestal(m); // init_experimental(m); py::module io = m.def_submodule("io", "Submodule for io"); diff --git a/python/src/pedestal.cpp b/python/src/pedestal.cpp new file mode 100644 index 000000000..b956f7252 --- /dev/null +++ b/python/src/pedestal.cpp @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package + +#include "py_headers.h" + +#include "sls/ToString.h" +#include "sls/sls_detector_defs.h" + +namespace py = pybind11; +void init_pedestal(py::module &m) { + + using src = slsDetectorDefs::pedestalParameters; + py::class_ pedestalParameters(m, "pedestalParameters"); + + pedestalParameters.def(py::init()); + pedestalParameters.def_readwrite("enable", &src::enable); + pedestalParameters.def_readwrite("frames", &src::frames); + pedestalParameters.def_readwrite("loops", &src::loops); + pedestalParameters.def(pybind11::self == pybind11::self); + + pedestalParameters.def("__repr__", + [](const src &a) { return sls::ToString(a); }); +} diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index d1a233731..8617c8206 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -193,6 +193,7 @@ void qDrawPlot::SetupPlots() { gainplot2d = new SlsQt2DPlot(boxPlot, true); gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5, nPixelsY - 0.5, gainData); + gainplot2d->Update(); gainplot2d->hide(); connect(plot2d, SIGNAL(PlotZoomedSignal(const QRectF &)), this, SLOT(Zoom2DGainPlot(const QRectF &))); @@ -1009,6 +1010,7 @@ void qDrawPlot::Update2dPlot() { if (isGainDataExtracted) { gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5, nPixelsY - 0.5, gainData); + gainplot2d->Update(); if (!gainplot2d->isVisible()) { gainplot2d->setFixedWidth(plot2d->width() / qDefs::DATA_GAIN_PLOT_RATIO); diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 2b21140d0..e8aff2c87 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 88147ed8a..ca094263d 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -1789,8 +1789,8 @@ int configureMAC() { uint32_t dstip = udpDetails[0].dstip; uint64_t srcmac = udpDetails[0].srcmac; uint64_t dstmac = udpDetails[0].dstmac; - int srcport = udpDetails[0].srcport; - int dstport = udpDetails[0].dstport; + uint16_t srcport = udpDetails[0].srcport; + uint16_t dstport = udpDetails[0].dstport; LOG(logINFOBLUE, ("Configuring MAC\n")); char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], @@ -1802,10 +1802,10 @@ int configureMAC() { LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n", + "\tDest Port : %hu\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); // 1 giga udp diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 58b1e032a..dc23c0984 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index aa73fc651..ad9b875f7 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -1808,9 +1808,9 @@ int configureMAC() { uint32_t dstip = udpDetails[iRxEntry].dstip; uint64_t srcmac = udpDetails[iRxEntry].srcmac; uint64_t dstmac = udpDetails[iRxEntry].dstmac; - int srcport = udpDetails[iRxEntry].srcport; - int dstport = udpDetails[iRxEntry].dstport; - int dstport2 = udpDetails[iRxEntry].dstport2; + uint16_t srcport = udpDetails[iRxEntry].srcport; + uint16_t dstport = udpDetails[iRxEntry].dstport; + uint16_t dstport2 = udpDetails[iRxEntry].dstport2; char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], dst_mac[MAC_ADDRESS_SIZE], dst_ip[INET_ADDRSTRLEN]; @@ -1824,11 +1824,11 @@ int configureMAC() { LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n" - "\tDest Port2 : %d\n", + "\tDest Port : %hu\n" + "\tDest Port2 : %hu\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport, dstport2)); } diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index fb05afdc4..9ae5e2cac 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 107b33b2c..e7401f474 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -1902,8 +1902,8 @@ void setFirstUDPDestination(int value) { } void setupHeader(int iRxEntry, int vetoInterface, uint32_t destip, - uint64_t destmac, uint32_t destport, uint64_t sourcemac, - uint32_t sourceip, uint32_t sourceport) { + uint64_t destmac, uint16_t destport, uint64_t sourcemac, + uint32_t sourceip, uint16_t sourceport) { // start addr uint32_t addr = BASE_UDP_RAM; @@ -1995,10 +1995,10 @@ int configureMAC() { uint64_t srcmac2 = udpDetails[iRxEntry].srcmac2; uint64_t dstmac = udpDetails[iRxEntry].dstmac; uint64_t dstmac2 = udpDetails[iRxEntry].dstmac2; - int srcport = udpDetails[iRxEntry].srcport; - int srcport2 = udpDetails[iRxEntry].srcport2; - int dstport = udpDetails[iRxEntry].dstport; - int dstport2 = udpDetails[iRxEntry].dstport2; + uint16_t srcport = udpDetails[iRxEntry].srcport; + uint16_t srcport2 = udpDetails[iRxEntry].srcport2; + uint16_t dstport = udpDetails[iRxEntry].dstport; + uint16_t dstport2 = udpDetails[iRxEntry].dstport2; char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], dst_mac[MAC_ADDRESS_SIZE], dst_ip[INET_ADDRSTRLEN]; @@ -2020,10 +2020,10 @@ int configureMAC() { LOG(logINFO, ("\tData Interface \n")); LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n\n", + "\tDest Port : %hu\n\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); if (getVetoStream()) { @@ -2039,10 +2039,10 @@ int configureMAC() { LOG(logINFO, ("\tSource IP2 : %s\n" "\tSource MAC2 : %s\n" - "\tSource Port2: %d\n" + "\tSource Port2: %hu\n" "\tDest IP2 : %s\n" "\tDest MAC2 : %s\n" - "\tDest Port2 : %d\n\n", + "\tDest Port2 : %hu\n\n", src_ip2, src_mac2, srcport2, dst_ip2, dst_mac2, dstport2)); } #ifdef VIRTUAL @@ -3323,6 +3323,27 @@ void *start_timer(void *arg) { break; } + // change gain and data for every frame + { + const int nchannels = NCHIP * NCHAN; + int gainVal = 0; + for (int i = 0; i < nchannels; ++i) { + if ((i % nchannels) < 400) { + gainVal = 1 + frameNr; + } else if ((i % nchannels) < 800) { + gainVal = 2 + frameNr; + } else { + gainVal = 3 + frameNr; + } + int dataVal = + *((uint16_t *)(imageData + i * sizeof(uint16_t))); + dataVal += frameNr; + int channelVal = + (dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST); + *((uint16_t *)(imageData + i * sizeof(uint16_t))) = + (uint16_t)channelVal; + } + } // sleep for exposure time struct timespec begin, end; clock_gettime(CLOCK_REALTIME, &begin); diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index cb5703d6c..9aaaff86b 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c index 4af3fd012..f95c613f1 100644 --- a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c @@ -1425,8 +1425,8 @@ int configureMAC() { uint32_t dstip = udpDetails[0].dstip; uint64_t srcmac = udpDetails[0].srcmac; uint64_t dstmac = udpDetails[0].dstmac; - int srcport = udpDetails[0].srcport; - int dstport = udpDetails[0].dstport; + uint16_t srcport = udpDetails[0].srcport; + uint16_t dstport = udpDetails[0].dstport; LOG(logINFOBLUE, ("Configuring MAC\n")); char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], @@ -1438,10 +1438,10 @@ int configureMAC() { LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n", + "\tDest Port : %hu\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); #ifdef VIRTUAL diff --git a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h index 488fbdc09..e00358c91 100644 --- a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h @@ -255,6 +255,17 @@ #define PLL_CNTRL_ADDR_OFST (16) #define PLL_CNTRL_ADDR_MSK (0x0000003F << PLL_CNTRL_ADDR_OFST) + +/* Pedestal Mode Regiser */ +#define PEDESTAL_MODE_REG (0x57 << MEM_MAP_SHIFT) + +#define PEDESTAL_MODE_ITRTNS_OFST (0) +#define PEDESTAL_MODE_ITRTNS_MSK (0x0000FFFF << PEDESTAL_MODE_ITRTNS_OFST) +#define PEDESTAL_MODE_LNGTH_OFST (16) +#define PEDESTAL_MODE_LNGTH_MSK (0x000000FF << PEDESTAL_MODE_LNGTH_OFST) +#define PEDESTAL_MODE_ENBLE_OFST (31) +#define PEDESTAL_MODE_ENBLE_MSK (0x00000001 << PEDESTAL_MODE_ENBLE_OFST) + /* Config Register for chip 1.1 */ #define CONFIG_V11_REG (0x58 << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 2419197f5..93d1e3bc8 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 6c93e0529..a3972d215 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -55,6 +55,9 @@ int32_t clkPhase[NUM_CLOCKS] = {}; int detPos[4] = {}; int chipConfigured = 0; +uint64_t normal_mode_frames = -1; +uint64_t normal_mode_triggers = -1; + int isInitCheckDone() { return initCheckDone; } int getInitResult(char **mess) { @@ -555,6 +558,13 @@ void setupDetector() { setFlipRows(DEFAULT_FLIP_ROWS); setReadNRows(MAX_ROWS_PER_READOUT); } +#ifdef VIRTUAL + // setting pedestalmode depends on previous values + bus_w(PEDESTAL_MODE_REG, + bus_r(PEDESTAL_MODE_REG) & ~PEDESTAL_MODE_ENBLE_MSK); +#endif + setPedestalMode(DEFAULT_PEDESTAL_MODE, DEFAULT_PEDESTAL_FRAMES, + DEFAULT_PEDESTAL_LOOPS); } int resetToDefaultDacs(int hardReset) { @@ -975,6 +985,9 @@ int getNextFrameNumber(uint64_t *retval) { } void setNumFrames(int64_t val) { + if (getPedestalMode()) { + return; + } if (val > 0) { LOG(logINFO, ("Setting number of frames %lld\n", (long long int)val)); set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); @@ -986,6 +999,9 @@ int64_t getNumFrames() { } void setNumTriggers(int64_t val) { + if (getPedestalMode()) { + return; + } if (val > 0) { LOG(logINFO, ("Setting number of triggers %lld\n", (long long int)val)); set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); @@ -1439,6 +1455,9 @@ void setSynchronization(int enable) { } void setTiming(enum timingMode arg) { + if (getPedestalMode()) { + return; + } switch (arg) { case AUTO_TIMING: LOG(logINFO, ("Set Timing: Auto\n")); @@ -1532,8 +1551,8 @@ int getPrimaryInterface() { } void setupHeader(int iRxEntry, enum interfaceType type, uint32_t destip, - uint64_t destmac, uint32_t destport, uint64_t sourcemac, - uint32_t sourceip, uint32_t sourceport) { + uint64_t destmac, uint16_t destport, uint64_t sourcemac, + uint32_t sourceip, uint16_t sourceport) { // start addr uint32_t addr = (type == INNER ? RXR_ENDPOINT_INNER_START_REG @@ -1628,10 +1647,10 @@ int configureMAC() { uint64_t srcmac2 = udpDetails[iRxEntry].srcmac2; uint64_t dstmac = udpDetails[iRxEntry].dstmac; uint64_t dstmac2 = udpDetails[iRxEntry].dstmac2; - int srcport = udpDetails[iRxEntry].srcport; - int srcport2 = udpDetails[iRxEntry].srcport2; - int dstport = udpDetails[iRxEntry].dstport; - int dstport2 = udpDetails[iRxEntry].dstport2; + uint16_t srcport = udpDetails[iRxEntry].srcport; + uint16_t srcport2 = udpDetails[iRxEntry].srcport2; + uint16_t dstport = udpDetails[iRxEntry].dstport; + uint16_t dstport2 = udpDetails[iRxEntry].dstport2; char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], dst_mac[MAC_ADDRESS_SIZE], dst_ip[INET_ADDRSTRLEN]; @@ -1655,10 +1674,10 @@ int configureMAC() { : (selInterface ? "Not Used" : "Used"))); LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n\n", + "\tDest Port : %hu\n\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); LOG(logINFO, @@ -1668,10 +1687,10 @@ int configureMAC() { LOG(logINFO, ("\tSource IP2 : %s\n" "\tSource MAC2 : %s\n" - "\tSource Port2: %d\n" + "\tSource Port2: %hu\n" "\tDest IP2 : %s\n" "\tDest MAC2 : %s\n" - "\tDest Port2 : %d\n\n", + "\tDest Port2 : %hu\n\n", src_ip2, src_mac2, srcport2, dst_ip2, dst_mac2, dstport2)); } #ifdef VIRTUAL @@ -2513,6 +2532,82 @@ uint64_t getSelectCurrentSource() { } } +int getPedestalMode() { + return ((bus_r(PEDESTAL_MODE_REG) & PEDESTAL_MODE_ENBLE_MSK) >> + PEDESTAL_MODE_ENBLE_OFST); +} + +void getPedestalParameters(uint8_t *frames, uint16_t *loops) { + uint32_t addr = PEDESTAL_MODE_REG; + *frames = + ((bus_r(addr) & PEDESTAL_MODE_LNGTH_MSK) >> PEDESTAL_MODE_LNGTH_OFST); + *loops = ((bus_r(PEDESTAL_MODE_REG) & PEDESTAL_MODE_ITRTNS_MSK) >> + PEDESTAL_MODE_ITRTNS_OFST); +} + +void setPedestalMode(int enable, uint8_t frames, uint16_t loops) { + int prevPedestalEnable = getPedestalMode(); + uint32_t addr = PEDESTAL_MODE_REG; + + if (enable) { + LOG(logINFOBLUE, ("Enabling pedestal mode [frames: %hhu, loops: %hu]\n", + frames, loops)); + + // frames + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_LNGTH_MSK); + bus_w(addr, bus_r(addr) | ((frames << PEDESTAL_MODE_LNGTH_OFST) & + PEDESTAL_MODE_LNGTH_MSK)); + // loops + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_ITRTNS_MSK); + bus_w(addr, bus_r(addr) | ((loops << PEDESTAL_MODE_ITRTNS_OFST) & + PEDESTAL_MODE_ITRTNS_MSK)); + // enable + bus_w(addr, bus_r(addr) | PEDESTAL_MODE_ENBLE_MSK); + + // if it was switched off before, remember the #frames and #triggers + if (prevPedestalEnable == 0) { + normal_mode_frames = getNumFrames(); + normal_mode_triggers = getNumTriggers(); + LOG(logINFO, ("\tRemembering Normal mode #frames and " + "#triggers[%lld, %lld]\n", + normal_mode_frames, normal_mode_triggers)); + } + + // overwrite #frames and #triggers to new values + int64_t expFrames = -1; + int64_t expTriggers = -1; + enum timingMode timing = getTiming(); + if (timing == AUTO_TIMING || + (timing == TRIGGER_EXPOSURE && normal_mode_frames > 1)) { + expFrames = frames * loops * 2; + expTriggers = 1; + } else { + expFrames = 1; + expTriggers = frames * loops * 2; + } + LOG(logINFO, ("\tOverwriting [#frames: %lld, #triggers: %lld]\n", + expFrames, expTriggers)); + set64BitReg(expFrames, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); + set64BitReg(expTriggers, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); + + } else { + LOG(logINFOBLUE, ("Disabling pedestal mode\n")); + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_ENBLE_MSK); + + // if it was switched on before, reset the normal mode #frames and + // #triggers + if (prevPedestalEnable == 1) { + LOG(logINFO, + ("\tResetting to Normal mode [#frames:%lld, #triggers:%lld\n", + normal_mode_frames, normal_mode_triggers)); + set64BitReg(normal_mode_frames, SET_FRAMES_LSB_REG, + SET_FRAMES_MSB_REG); + set64BitReg(normal_mode_triggers, SET_CYCLES_LSB_REG, + SET_CYCLES_MSB_REG); + } + } +} + int getTenGigaFlowControl() { return ((bus_r(CONFIG_REG) & CONFIG_ETHRNT_FLW_CNTRL_MSK) >> CONFIG_ETHRNT_FLW_CNTRL_OFST); @@ -2632,6 +2727,7 @@ void *start_timer(void *arg) { if (i % pixelsPerPacket == 0) { ++dataVal; } + if ((i % 1024) < 300) { gainVal = 1; } else if ((i % 1024) < 600) { @@ -2672,6 +2768,28 @@ void *start_timer(void *arg) { clock_gettime(CLOCK_REALTIME, &begin); usleep(expUs); + // change gain and data for every frame + { + const int npixels = (NCHAN * NCHIP); + for (int i = 0; i < npixels; ++i) { + int gainVal = 0; + if ((i % 1024) < 300) { + gainVal = 1 + iframes; + } else if ((i % 1024) < 600) { + gainVal = 2 + iframes; + } else { + gainVal = 3 + iframes; + } + int dataVal = + *((uint16_t *)(imageData + i * sizeof(uint16_t))); + dataVal += iframes; + int pixelVal = + (dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST); + *((uint16_t *)(imageData + i * sizeof(uint16_t))) = + (uint16_t)pixelVal; + } + } + int srcOffset = 0; int srcOffset2 = DATA_BYTES / 2; int row0 = (numInterfaces == 1 ? detPos[1] : detPos[3]); diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index e0e0afd16..2d0033822 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -5,8 +5,8 @@ #include "sls/sls_detector_defs.h" #define MIN_REQRD_VRSN_T_RD_API 0x171220 -#define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010) -#define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011) +#define REQRD_FRMWRE_VRSN_BOARD2 0x230920 // 1.0 pcb (version = 010) +#define REQRD_FRMWRE_VRSN 0x230921 // 2.0 pcb (version = 011) #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS \ @@ -52,6 +52,9 @@ #define DEFAULT_FLIP_ROWS (0) #define DEFAULT_FILTER_RESISTOR (1) // higher resistor #define DEFAULT_FILTER_CELL (0) +#define DEFAULT_PEDESTAL_MODE (0) +#define DEFAULT_PEDESTAL_FRAMES (1) +#define DEFAULT_PEDESTAL_LOOPS (1) #define HIGHVOLTAGE_MIN (60) #define HIGHVOLTAGE_MAX (200) diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 551eafc95..b253cbd16 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 88db419d9..e4ec00a8c 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -1120,8 +1120,8 @@ int getPrimaryInterface() { } void setupHeader(int iRxEntry, enum interfaceType type, uint32_t destip, - uint64_t destmac, uint32_t destport, uint64_t sourcemac, - uint32_t sourceip, uint32_t sourceport) { + uint64_t destmac, uint16_t destport, uint64_t sourcemac, + uint32_t sourceip, uint16_t sourceport) { // start addr uint32_t addr = (type == INNER ? RXR_ENDPOINT_INNER_START_REG @@ -1216,10 +1216,10 @@ int configureMAC() { uint64_t srcmac2 = udpDetails[iRxEntry].srcmac2; uint64_t dstmac = udpDetails[iRxEntry].dstmac; uint64_t dstmac2 = udpDetails[iRxEntry].dstmac2; - int srcport = udpDetails[iRxEntry].srcport; - int srcport2 = udpDetails[iRxEntry].srcport2; - int dstport = udpDetails[iRxEntry].dstport; - int dstport2 = udpDetails[iRxEntry].dstport2; + uint16_t srcport = udpDetails[iRxEntry].srcport; + uint16_t srcport2 = udpDetails[iRxEntry].srcport2; + uint16_t dstport = udpDetails[iRxEntry].dstport; + uint16_t dstport2 = udpDetails[iRxEntry].dstport2; char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], dst_mac[MAC_ADDRESS_SIZE], dst_ip[INET_ADDRSTRLEN]; @@ -1243,10 +1243,10 @@ int configureMAC() { : (selInterface ? "Not Used" : "Used"))); LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n\n", + "\tDest Port : %hu\n\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); LOG(logINFO, @@ -1256,10 +1256,10 @@ int configureMAC() { LOG(logINFO, ("\tSource IP2 : %s\n" "\tSource MAC2 : %s\n" - "\tSource Port2: %d\n" + "\tSource Port2: %hu\n" "\tDest IP2 : %s\n" "\tDest MAC2 : %s\n" - "\tDest Port2 : %d\n\n", + "\tDest Port2 : %hu\n\n", src_ip2, src_mac2, srcport2, dst_ip2, dst_mac2, dstport2)); } #ifdef VIRTUAL diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index bdc2183d9..ca8e99814 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index dda8c2b4c..3fcfda045 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -1963,8 +1963,8 @@ int configureMAC() { uint32_t dstip = udpDetails[iRxEntry].dstip; uint64_t srcmac = udpDetails[iRxEntry].srcmac; uint64_t dstmac = udpDetails[iRxEntry].dstmac; - int srcport = udpDetails[iRxEntry].srcport; - int dstport = udpDetails[iRxEntry].dstport; + uint16_t srcport = udpDetails[iRxEntry].srcport; + uint16_t dstport = udpDetails[iRxEntry].dstport; char src_mac[MAC_ADDRESS_SIZE], src_ip[INET_ADDRSTRLEN], dst_mac[MAC_ADDRESS_SIZE], dst_ip[INET_ADDRSTRLEN]; @@ -1976,10 +1976,10 @@ int configureMAC() { LOG(logINFOBLUE, ("\tEntry %d\n", iRxEntry)); LOG(logINFO, ("\tSource IP : %s\n" "\tSource MAC : %s\n" - "\tSource Port : %d\n" + "\tSource Port : %hu\n" "\tDest IP : %s\n" "\tDest MAC : %s\n" - "\tDest Port : %d\n", + "\tDest Port : %hu\n", src_ip, src_mac, srcport, dst_ip, dst_mac, dstport)); } #ifdef VIRTUAL diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index fbb399ff9..d7858498f 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -42,10 +42,10 @@ single detector. enum interfaceType { OUTER, INNER }; typedef struct udpStruct_s { - int srcport; - int srcport2; - int dstport; - int dstport2; + uint16_t srcport; + uint16_t srcport2; + uint16_t dstport; + uint16_t dstport2; uint64_t srcmac; uint64_t srcmac2; uint64_t dstmac; @@ -467,8 +467,8 @@ void setFirstUDPDestination(int value); void selectPrimaryInterface(int val); int getPrimaryInterface(); void setupHeader(int iRxEntry, enum interfaceType type, uint32_t destip, - uint64_t destmac, uint32_t destport, uint64_t sourcemac, - uint32_t sourceip, uint32_t sourceport); + uint64_t destmac, uint16_t destport, uint64_t sourcemac, + uint32_t sourceip, uint16_t sourceport); #endif #if defined(JUNGFRAUD) || defined(MOENCHD) || defined(GOTTHARD2D) || \ defined(MYTHEN3D) || defined(CHIPTESTBOARDD) @@ -516,7 +516,7 @@ void setDigitalIODelay(uint64_t pinMask, int delay); // jungfrau/moench specific - powerchip, autocompdisable, clockdiv, asictimer, // clock, pll, flashing firmware -#if defined(MOENCHED) +#if defined(MOENCHD) void setADCPipeline(int val); int getADCPipeline(); #endif @@ -556,6 +556,9 @@ int getCurrentSource(); int getFixCurrentSource(); int getNormalCurrentSource(); uint64_t getSelectCurrentSource(); +int getPedestalMode(); +void getPedestalParameters(uint8_t *frames, uint16_t *loops); +void setPedestalMode(int enable, uint8_t frames, uint16_t loops); #endif // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index fcb819060..4bf70907f 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -327,3 +327,5 @@ int getRow(); int setRow(int); int getColumn(); int setColumn(int); +int get_pedestal_mode(int); +int set_pedestal_mode(int); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c index 3542ba431..9f608bbd1 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c @@ -13,6 +13,7 @@ #include "slsDetectorServer_funcs.h" #include +#include #include #include #include @@ -276,6 +277,15 @@ int main(int argc, char *argv[]) { LOG(logERROR, ("Could not set handler function for SIGINT")); } + // validate control and stop port number + if (0 >= portno || portno > USHRT_MAX || 0 >= (portno + 1) || + (portno + 1) > USHRT_MAX) { + LOG(logERROR, ("Invalid control server or stop server port " + "numbers (%d, %d). It must be in range 1 - %d", + portno, portno + 1, USHRT_MAX)); + return -1; + } + if (sharedMemory_create(portno) == FAIL) { return -1; } diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 3a4015767..9cbc8b4da 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -486,6 +486,8 @@ void function_table() { flist[F_SET_ROW] = &set_row; flist[F_GET_COLUMN] = &get_column; flist[F_SET_COLUMN] = &set_column; + flist[F_GET_PEDESTAL_MODE] = &get_pedestal_mode; + flist[F_SET_PEDESTAL_MODE] = &set_pedestal_mode; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -724,7 +726,18 @@ int set_timing_mode(int file_des) { case GATED: case TRIGGER_GATED: #endif - setTiming(arg); +#if JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, + "Cannot set timing mode in pedestal mode. Switch off " + "pedestal mode to change timing mode.\n"); + LOG(logERROR, (mess)); + } +#endif + if (ret == OK) + setTiming(arg); break; default: modeNotImplemented("Timing mode", (int)arg); @@ -1935,57 +1948,59 @@ int acquire(int blocking, int file_des) { #ifdef EIGERD // check for hardware mac and hardware ip if (udpDetails[0].srcmac != getDetectorMAC()) { - ret = FAIL; - uint64_t sourcemac = getDetectorMAC(); - char src_mac[MAC_ADDRESS_SIZE]; - getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); - sprintf(mess, + ret = FAIL; + uint64_t sourcemac = getDetectorMAC(); + char src_mac[MAC_ADDRESS_SIZE]; + getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); + sprintf( + mess, "Invalid udp source mac address for this detector. Must be " "same as hardware detector mac address %s\n", src_mac); - LOG(logERROR, (mess)); - } else if (!enableTenGigabitEthernet(GET_FLAG) && - (udpDetails[0].srcip != getDetectorIP())) { - ret = FAIL; - uint32_t sourceip = getDetectorIP(); - char src_ip[INET_ADDRSTRLEN]; - getIpAddressinString(src_ip, sourceip); - sprintf(mess, + LOG(logERROR, (mess)); + } else if (!enableTenGigabitEthernet(GET_FLAG) && + (udpDetails[0].srcip != getDetectorIP())) { + ret = FAIL; + uint32_t sourceip = getDetectorIP(); + char src_ip[INET_ADDRSTRLEN]; + getIpAddressinString(src_ip, sourceip); + sprintf( + mess, "Invalid udp source ip address for this detector. Must be " "same as hardware detector ip address %s in 1G readout " "mode \n", src_ip); - LOG(logERROR, (mess)); - } else + LOG(logERROR, (mess)); + } else #endif - if (configured == FAIL) { - ret = FAIL; - strcpy(mess, "Could not start acquisition because "); - strcat(mess, configureMessage); - LOG(logERROR, (mess)); - } else if (sharedMemory_getScanStatus() == RUNNING) { - ret = FAIL; - strcpy(mess, "Could not start acquisition because a scan is " - "already running!\n"); - LOG(logERROR, (mess)); - } else { - memset(scanErrMessage, 0, MAX_STR_LENGTH); - sharedMemory_setScanStop(0); - sharedMemory_setScanStatus(IDLE); // if it was error - if (pthread_create(&pthread_tid, NULL, &start_state_machine, - &blocking)) { + if (configured == FAIL) { ret = FAIL; - strcpy(mess, "Could not start acquisition thread!\n"); + strcpy(mess, "Could not start acquisition because "); + strcat(mess, configureMessage); + LOG(logERROR, (mess)); + } else if (sharedMemory_getScanStatus() == RUNNING) { + ret = FAIL; + strcpy(mess, "Could not start acquisition because a scan is " + "already running!\n"); LOG(logERROR, (mess)); } else { - // wait for blocking always (scan or not) - // non blocking-no scan also wait (for error message) - // non blcoking-scan dont wait (there is scanErrorMessage) - if (blocking || !scan) { - pthread_join(pthread_tid, NULL); + memset(scanErrMessage, 0, MAX_STR_LENGTH); + sharedMemory_setScanStop(0); + sharedMemory_setScanStatus(IDLE); // if it was error + if (pthread_create(&pthread_tid, NULL, &start_state_machine, + &blocking)) { + ret = FAIL; + strcpy(mess, "Could not start acquisition thread!\n"); + LOG(logERROR, (mess)); + } else { + // wait for blocking always (scan or not) + // non blocking-no scan also wait (for error message) + // non blcoking-scan dont wait (there is scanErrorMessage) + if (blocking || !scan) { + pthread_join(pthread_tid, NULL); + } } } - } } return Server_SendResult(file_des, INT32, NULL, 0); } @@ -2211,6 +2226,14 @@ int set_num_frames(int file_des) { (long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE); LOG(logERROR, (mess)); } +#elif JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, "Cannot set frames in pedestal mode. It is " + "overwritten anyway.\n"); + LOG(logERROR, (mess)); + } #endif if (ret == OK) { setNumFrames(arg); @@ -2247,10 +2270,22 @@ int set_num_triggers(int file_des) { // only set if (Server_VerifyLock() == OK) { - setNumTriggers(arg); - int64_t retval = getNumTriggers(); - LOG(logDEBUG1, ("retval num triggers %lld\n", (long long int)retval)); - validate64(&ret, mess, arg, retval, "set number of triggers", DEC); +#if JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, "Cannot set triggers in pedestal mode. It is " + "overwritten anyway.\n"); + LOG(logERROR, (mess)); + } +#endif + if (ret == OK) { + setNumTriggers(arg); + int64_t retval = getNumTriggers(); + LOG(logDEBUG1, + ("retval num triggers %lld\n", (long long int)retval)); + validate64(&ret, mess, arg, retval, "set number of triggers", DEC); + } } return Server_SendResult(file_des, INT64, NULL, 0); } @@ -5366,11 +5401,11 @@ int get_dest_udp_mac2(int file_des) { int set_dest_udp_port(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int arg = 0; + uint16_t arg = 0; - if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + if (receiveData(file_des, &arg, sizeof(arg), INT16) < 0) return printSocketReadError(); - LOG(logINFO, ("Setting udp destination port: %u\n", arg)); + LOG(logINFO, ("Setting udp destination port: %hu\n", arg)); // only set if (Server_VerifyLock() == OK) { @@ -5381,30 +5416,30 @@ int set_dest_udp_port(int file_des) { } } } - return Server_SendResult(file_des, INT32, NULL, 0); + return Server_SendResult(file_des, INT16, NULL, 0); } int get_dest_udp_port(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int retval = -1; + uint16_t retval = -1; LOG(logDEBUG1, ("Getting destination port")); // get only retval = udpDetails[0].dstport; - LOG(logDEBUG, ("udp destination port retval: %u\n", retval)); + LOG(logDEBUG, ("udp destination port retval: %hu\n", retval)); - return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); + return Server_SendResult(file_des, INT16, &retval, sizeof(retval)); } int set_dest_udp_port2(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int arg = 0; + uint16_t arg = 0; - if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + if (receiveData(file_des, &arg, sizeof(arg), INT16) < 0) return printSocketReadError(); - LOG(logINFO, ("Setting udp destination port2: %u\n", arg)); + LOG(logINFO, ("Setting udp destination port2: %hu\n", arg)); #if !defined(JUNGFRAUD) && !defined(MOENCHD) && !defined(EIGERD) && \ !defined(GOTTHARD2D) @@ -5420,13 +5455,13 @@ int set_dest_udp_port2(int file_des) { } } #endif - return Server_SendResult(file_des, INT32, NULL, 0); + return Server_SendResult(file_des, INT16, NULL, 0); } int get_dest_udp_port2(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int retval = -1; + uint16_t retval = -1; LOG(logDEBUG1, ("Getting destination port2\n")); #if !defined(JUNGFRAUD) && !defined(MOENCHD) && !defined(EIGERD) && \ @@ -5435,9 +5470,9 @@ int get_dest_udp_port2(int file_des) { #else // get only retval = udpDetails[0].dstport2; - LOG(logDEBUG1, ("udp destination port2 retval: %u\n", retval)); + LOG(logDEBUG1, ("udp destination port2 retval: %hu\n", retval)); #endif - return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); + return Server_SendResult(file_des, INT16, &retval, sizeof(retval)); } int set_num_interfaces(int file_des) { @@ -6990,6 +7025,7 @@ int get_receiver_parameters(int file_des) { int n = 0; int i32 = 0; int64_t i64 = 0; + uint16_t u16 = 0; uint32_t u32 = 0; uint64_t u64 = 0; @@ -7032,8 +7068,8 @@ int get_receiver_parameters(int file_des) { return printSocketReadError(); // udp dst port - i32 = udpDetails[0].dstport; - n += sendData(file_des, &i32, sizeof(i32), INT32); + u16 = udpDetails[0].dstport; + n += sendData(file_des, &u16, sizeof(u16), INT16); if (n < 0) return printSocketReadError(); @@ -7051,8 +7087,8 @@ int get_receiver_parameters(int file_des) { return printSocketReadError(); // udp dst port2 - i32 = udpDetails[0].dstport2; - n += sendData(file_des, &i32, sizeof(i32), INT32); + u16 = udpDetails[0].dstport2; + n += sendData(file_des, &u16, sizeof(u16), INT16); if (n < 0) return printSocketReadError(); @@ -7790,62 +7826,20 @@ int set_scan(int file_des) { int stop = args[3]; int step = args[4]; - // disable scan - if (enable == 0) { - LOG(logINFOBLUE, ("Disabling scan")); - scan = 0; - numScanSteps = 0; - // setting number of frames to 1 - int64_t arg = 1; - setNumFrames(arg); - retval = getNumFrames(); - LOG(logDEBUG1, ("retval num frames %lld\n", (long long int)retval)); - validate64(&ret, mess, arg, retval, "set number of frames", DEC); +#ifdef JUNGFRAUD + if (getPedestalMode()) { + ret = FAIL; + strcpy(mess, "Cannot set scan when in pedestal mode.\n"); + LOG(logERROR, (mess)); } - // enable scan - else { - if ((start < stop && step <= 0) || (stop < start && step >= 0)) { - ret = FAIL; - sprintf(mess, "Invalid scan parameters\n"); - LOG(logERROR, (mess)); - } else { - // trimbit scan - if (index == TRIMBIT_SCAN) { - LOG(logINFOBLUE, ("Trimbit scan enabled\n")); - scanTrimbits = 1; - scanGlobalIndex = index; - scanSettleTime_ns = dacTime; - } - // dac scan - else { - // validate index - getDACIndex(index); - if (ret == OK) { - LOG(logINFOBLUE, ("Dac [%d] scan enabled\n", index)); - scanTrimbits = 0; - scanGlobalIndex = index; - scanSettleTime_ns = dacTime; - } - } - } - // valid scan - if (ret == OK) { - scan = 1; - numScanSteps = (abs(stop - start) / abs(step)) + 1; - if (scanSteps != NULL) { - free(scanSteps); - } - scanSteps = malloc(numScanSteps * sizeof(int)); - for (int i = 0; i != numScanSteps; ++i) { - scanSteps[i] = start + i * step; - LOG(logDEBUG1, ("scansteps[%d]:%d\n", i, scanSteps[i])); - } - LOG(logINFOBLUE, ("Enabling scan for %s, start[%d], stop[%d], " - "step[%d], nsteps[%d]\n", - scanTrimbits == 1 ? "trimbits" : "dac", start, - stop, step, numScanSteps)); - - // setting number of frames to scansteps +#endif + if (ret == OK) { + // disable scan + if (enable == 0) { + LOG(logINFOBLUE, ("Disabling scan")); + scan = 0; + numScanSteps = 0; + // setting number of frames to 1 int64_t arg = 1; setNumFrames(arg); retval = getNumFrames(); @@ -7853,7 +7847,63 @@ int set_scan(int file_des) { ("retval num frames %lld\n", (long long int)retval)); validate64(&ret, mess, arg, retval, "set number of frames", DEC); - retval = numScanSteps; + } + // enable scan + else { + if ((start < stop && step <= 0) || + (stop < start && step >= 0)) { + ret = FAIL; + sprintf(mess, "Invalid scan parameters\n"); + LOG(logERROR, (mess)); + } else { + // trimbit scan + if (index == TRIMBIT_SCAN) { + LOG(logINFOBLUE, ("Trimbit scan enabled\n")); + scanTrimbits = 1; + scanGlobalIndex = index; + scanSettleTime_ns = dacTime; + } + // dac scan + else { + // validate index + getDACIndex(index); + if (ret == OK) { + LOG(logINFOBLUE, + ("Dac [%d] scan enabled\n", index)); + scanTrimbits = 0; + scanGlobalIndex = index; + scanSettleTime_ns = dacTime; + } + } + } + // valid scan + if (ret == OK) { + scan = 1; + numScanSteps = (abs(stop - start) / abs(step)) + 1; + if (scanSteps != NULL) { + free(scanSteps); + } + scanSteps = malloc(numScanSteps * sizeof(int)); + for (int i = 0; i != numScanSteps; ++i) { + scanSteps[i] = start + i * step; + LOG(logDEBUG1, ("scansteps[%d]:%d\n", i, scanSteps[i])); + } + LOG(logINFOBLUE, + ("Enabling scan for %s, start[%d], stop[%d], " + "step[%d], nsteps[%d]\n", + scanTrimbits == 1 ? "trimbits" : "dac", start, stop, + step, numScanSteps)); + + // setting number of frames to scansteps + int64_t arg = 1; + setNumFrames(arg); + retval = getNumFrames(); + LOG(logDEBUG1, + ("retval num frames %lld\n", (long long int)retval)); + validate64(&ret, mess, arg, retval, "set number of frames", + DEC); + retval = numScanSteps; + } } } } @@ -9170,7 +9220,8 @@ int get_dest_udp_list(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); uint32_t arg = 0; - uint32_t retvals[5] = {}; + uint16_t retvals16[2] = {}; + uint32_t retvals32[3] = {}; uint64_t retvals64[2] = {}; if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) @@ -9189,34 +9240,36 @@ int get_dest_udp_list(int file_des) { MAX_UDP_DESTINATION - 1); LOG(logERROR, (mess)); } else { - retvals[0] = arg; - retvals[1] = udpDetails[arg].dstport; - retvals[2] = udpDetails[arg].dstport2; - retvals[3] = udpDetails[arg].dstip; - retvals[4] = udpDetails[arg].dstip2; + // arg; + retvals16[0] = udpDetails[arg].dstport; + retvals16[1] = udpDetails[arg].dstport2; + retvals32[0] = udpDetails[arg].dstip; + retvals32[1] = udpDetails[arg].dstip2; retvals64[0] = udpDetails[arg].dstmac; retvals64[1] = udpDetails[arg].dstmac2; // swap ip - retvals[3] = __builtin_bswap32(retvals[3]); - retvals[4] = __builtin_bswap32(retvals[4]); + retvals32[0] = __builtin_bswap32(retvals32[0]); + retvals32[1] = __builtin_bswap32(retvals32[1]); // convert to string char ip[INET_ADDRSTRLEN], ip2[INET_ADDRSTRLEN]; - getIpAddressinString(ip, retvals[3]); - getIpAddressinString(ip2, retvals[4]); + getIpAddressinString(ip, retvals32[0]); + getIpAddressinString(ip2, retvals32[1]); char mac[MAC_ADDRESS_SIZE], mac2[MAC_ADDRESS_SIZE]; getMacAddressinString(mac, MAC_ADDRESS_SIZE, retvals64[0]); getMacAddressinString(mac2, MAC_ADDRESS_SIZE, retvals64[1]); LOG(logDEBUG1, - ("Udp Dest. retval [%d]: [port %d, port2 %d, ip %s, ip2 %s, " + ("Udp Dest. retval [%d]: [port %hu, port2 %hu, ip %s, ip2 %s, " "mac %s, mac2 %s]\n", - retvals[0], retvals[1], retvals[2], ip, ip2, mac, mac2)); + arg, retvals16[0], retvals16[1], ip, ip2, mac, mac2)); } #endif Server_SendResult(file_des, INT32, NULL, 0); if (ret != FAIL) { - sendData(file_des, retvals, sizeof(retvals), INT32); + sendData(file_des, &arg, sizeof(arg), INT32); + sendData(file_des, retvals16, sizeof(retvals16), INT16); + sendData(file_des, retvals32, sizeof(retvals32), INT32); sendData(file_des, retvals64, sizeof(retvals64), INT64); } return ret; @@ -9225,22 +9278,28 @@ int get_dest_udp_list(int file_des) { int set_dest_udp_list(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - uint32_t args[5] = {}; + uint32_t arg = 0; + uint16_t args16[2] = {}; + uint32_t args32[2] = {}; uint64_t args64[2] = {}; - if (receiveData(file_des, args, sizeof(args), INT32) < 0) + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, args16, sizeof(args16), INT16) < 0) + return printSocketReadError(); + if (receiveData(file_des, args32, sizeof(args32), INT32) < 0) return printSocketReadError(); if (receiveData(file_des, args64, sizeof(args64), INT64) < 0) return printSocketReadError(); // swap ip - args[3] = __builtin_bswap32(args[3]); - args[4] = __builtin_bswap32(args[4]); + args32[0] = __builtin_bswap32(args32[0]); + args32[1] = __builtin_bswap32(args32[1]); // convert to string char ip[INET_ADDRSTRLEN], ip2[INET_ADDRSTRLEN]; - getIpAddressinString(ip, args[3]); - getIpAddressinString(ip2, args[4]); + getIpAddressinString(ip, args32[0]); + getIpAddressinString(ip2, args32[1]); char mac[MAC_ADDRESS_SIZE], mac2[MAC_ADDRESS_SIZE]; getMacAddressinString(mac, MAC_ADDRESS_SIZE, args64[0]); getMacAddressinString(mac2, MAC_ADDRESS_SIZE, args64[1]); @@ -9251,11 +9310,11 @@ int set_dest_udp_list(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - int entry = args[0]; + int entry = arg; LOG(logINFOBLUE, - ("Setting udp dest. [%d]: [port %d, port2 %d, ip %s, ip2 %s, " + ("Setting udp dest. [%d]: [port %hu, port2 %hu, ip %s, ip2 %s, " "mac %s, mac2 %s]\n", - entry, args[1], args[2], ip, ip2, mac, mac2)); + entry, args16[0], args16[1], ip, ip2, mac, mac2)); if (entry < 1 || entry >= MAX_UDP_DESTINATION) { ret = FAIL; @@ -9266,7 +9325,7 @@ int set_dest_udp_list(int file_des) { LOG(logERROR, (mess)); } #if defined(EIGERD) || defined(MYTHEN3D) - else if (args[4] != 0 || args64[1] != 0) { + else if (args32[1] != 0 || args64[1] != 0) { ret = FAIL; strcpy(mess, "Could not set udp destination. ip2 and mac2 not " "implemented for this detector.\n"); @@ -9275,17 +9334,17 @@ int set_dest_udp_list(int file_des) { #endif else { if (check_detector_idle("set udp destination list entries") == OK) { - if (args[1] != 0) { - udpDetails[entry].dstport = args[1]; + if (args16[0] != 0) { + udpDetails[entry].dstport = args16[0]; } - if (args[2] != 0) { - udpDetails[entry].dstport2 = args[2]; + if (args16[1] != 0) { + udpDetails[entry].dstport2 = args16[1]; } - if (args[3] != 0) { - udpDetails[entry].dstip = args[3]; + if (args32[0] != 0) { + udpDetails[entry].dstip = args32[0]; } - if (args[4] != 0) { - udpDetails[entry].dstip2 = args[4]; + if (args32[1] != 0) { + udpDetails[entry].dstip2 = args32[1]; } if (args64[0] != 0) { udpDetails[entry].dstmac = args64[0]; @@ -10730,4 +10789,108 @@ int setColumn(int value) { memcpy(pos, getDetectorPosition(), sizeof(pos)); pos[X] = value; return setDetectorPosition(pos); -} \ No newline at end of file +} + +int get_pedestal_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retvalEnable = -1; + uint8_t retvalFrames = -1; + uint16_t retvalLoops = -1; + LOG(logDEBUG1, ("Getting pedestal mode\n")); + +#if !defined(JUNGFRAUD) + functionNotImplemented(); +#else + retvalEnable = getPedestalMode(); + getPedestalParameters(&retvalFrames, &retvalLoops); + LOG(logDEBUG1, ("pedestal mode retval: [enable:%d frames:%hhu, " + "loops:%hu]\n", + retvalEnable, retvalFrames, retvalLoops)); +#endif + Server_SendResult(file_des, INT32, NULL, 0); + if (ret != FAIL) { + sendData(file_des, &retvalEnable, sizeof(retvalEnable), INT32); + sendData(file_des, &retvalFrames, sizeof(retvalFrames), OTHER); + sendData(file_des, &retvalLoops, sizeof(retvalLoops), INT16); + } + return ret; +} + +int set_pedestal_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int enable = -1; + uint8_t frames = -1; + uint16_t loops = -1; + + if (receiveData(file_des, &enable, sizeof(enable), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, &frames, sizeof(frames), OTHER) < 0) + return printSocketReadError(); + if (receiveData(file_des, &loops, sizeof(loops), INT16) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Setting pedestal mode: enable:%d frames:%hhu, " + "loops:%hu]\n", + enable, frames, loops)); + +#if !defined(JUNGFRAUD) + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if (check_detector_idle("set pedestal mode") == OK) { + if (enable != 0 && enable != 1) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Invalid enable argument %d. " + "Options: [0, 1]\n", + enable); + LOG(logERROR, (mess)); + } else if (enable == 1 && (frames == 0 || loops == 0)) { + ret = FAIL; + sprintf(mess, + "Could not set pedestal mode. Frames and loops cannot " + "be 0. [%hhu, %hu].\n", + frames, loops); + LOG(logERROR, (mess)); + } else { + setPedestalMode(enable, frames, loops); + int retvalEnable = getPedestalMode(); + LOG(logDEBUG1, ("pedestal mode retval: %d\n", retvalEnable)); + if (enable != retvalEnable) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Tried to %s, but is %s\n", + (enable ? "enable" : "disable"), + (retvalEnable ? "enabled" : "disabled")); + LOG(logERROR, (mess)); + } + if (enable) { + uint8_t retvalFrames = -1; + uint16_t retvalLoops = -1; + getPedestalParameters(&retvalFrames, &retvalLoops); + LOG(logDEBUG1, + ("pedestal mode retval: [enable:%d frames:%hhu, " + "loops:%hu]\n", + retvalEnable, retvalFrames, retvalLoops)); + if (frames != retvalFrames || loops != retvalLoops) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Tried to set " + "[enable: %d, frames: %hhu, loops: %hu], but got " + "[enable: %d, frames: %hhu, loops: %hu].\n", + enable, frames, loops, retvalEnable, retvalFrames, + retvalLoops); + LOG(logERROR, (mess)); + } + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index fc0f1e311..09c15f6cd 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -66,7 +66,7 @@ class Detector { /** connects to n servers at local host starting at specific control port. * Every virtual server will have a stop port (control port + 1) */ - void setVirtualDetectorServers(int numServers, int startingPort); + void setVirtualDetectorServers(int numServers, uint16_t startingPort); /** Gets shared memory ID */ int getShmId() const; @@ -791,20 +791,20 @@ class Detector { */ void setDestinationUDPMAC2(const MacAddr mac, Positions pos = {}); - Result getDestinationUDPPort(Positions pos = {}) const; + Result getDestinationUDPPort(Positions pos = {}) const; /** Default is 50001. \n If module_id is -1, ports for each module is * calculated (incremented by 1 if no 2nd interface) */ - void setDestinationUDPPort(int port, int module_id = -1); + void setDestinationUDPPort(uint16_t port, int module_id = -1); /** [Eiger] right port[Jungfrau][Moench] bottom half [Gotthard2] veto * debugging */ - Result getDestinationUDPPort2(Positions pos = {}) const; + Result getDestinationUDPPort2(Positions pos = {}) const; /** [Eiger] right port[Jungfrau][Moench] bottom half [Gotthard2] veto * debugging \n Default is 50002. \n If module_id is -1, ports for each * module is calculated (incremented by 1 if no 2nd interface)*/ - void setDestinationUDPPort2(int port, int module_id = -1); + void setDestinationUDPPort2(uint16_t port, int module_id = -1); /** Reconfigures Detector with UDP destination. More for debugging as the * configuration is done automatically when the detector has sufficient UDP @@ -904,14 +904,14 @@ class Detector { /** multiple rx hostnames. Single element will set it for all */ void setRxHostname(const std::vector &name); - Result getRxPort(Positions pos = {}) const; + Result getRxPort(Positions pos = {}) const; /** TCP port for client-receiver communication. \n * Default is 1954. \n Must be different if multiple receivers on same pc. * \n Must be first command to set a receiver parameter to be able to * communicate. \n Multi command will automatically increment port for * individual modules.*/ - void setRxPort(int port, int module_id = -1); + void setRxPort(uint16_t port, int module_id = -1); Result getRxFifoDepth(Positions pos = {}) const; @@ -1089,7 +1089,7 @@ class Detector { */ void setRxZmqStartingFrame(int fnum, Positions pos = {}); - Result getRxZmqPort(Positions pos = {}) const; + Result getRxZmqPort(Positions pos = {}) const; /** Zmq port for data to be streamed out of the receiver. \n * Also restarts receiver zmq streaming if enabled. \n Default is 30001. \n @@ -1098,7 +1098,7 @@ class Detector { * no 2nd interface). \n Restarts receiver zmq sockets only if it was * already enabled */ - void setRxZmqPort(int port, int module_id = -1); + void setRxZmqPort(uint16_t port, int module_id = -1); Result getRxZmqIP(Positions pos = {}) const; @@ -1108,7 +1108,7 @@ class Detector { * receiver. */ void setRxZmqIP(const IpAddr ip, Positions pos = {}); - Result getClientZmqPort(Positions pos = {}) const; + Result getClientZmqPort(Positions pos = {}) const; /** Port number to listen to zmq data streamed out from receiver or * intermediate process. \n Must be different for every detector (and udp @@ -1117,7 +1117,7 @@ class Detector { * sockets only if it was already enabled \n Default connects to receiver * zmq streaming out port (30001). */ - void setClientZmqPort(int port, int module_id = -1); + void setClientZmqPort(uint16_t port, int module_id = -1); Result getClientZmqIp(Positions pos = {}) const; @@ -1359,6 +1359,20 @@ class Detector { */ void setNumberOfFilterCells(int cell, Positions pos = {}); + /** [Jungfrau] */ + Result getPedestalMode(Positions pos = {}) const; + + /** [Jungfrau] In pedestal mode, the number of frames or triggers is + * overwritten by \n(#pedestal_frames x #pedestal_loops x 2). \nIn + * auto timing mode or in trigger mode with #frames > 1, #frames is + * overwritten and #triggers = 1, \nelse #triggers is overwritten and + * #frames = 1. One cannot set #frames, #triggers or timing mode in pedestal + * mode (it will throw an exception). Disabling pedestal mode will set back + * the original values of #frames and #triggers + */ + void setPedestalMode(const defs::pedestalParameters par, + Positions pos = {}); + ///@} /** @name Gotthard Specific */ @@ -1615,21 +1629,21 @@ class Detector { /** [CTB] in MHZ */ Result getSYNCClock(Positions pos = {}) const; - /** gets list of voltage enums */ - std::vector getVoltageList() const; + /** gets list of power enums */ + std::vector getPowerList() const; /** gets list of slow adc enums */ std::vector getSlowADCList() const; /** [CTB] */ - Result getVoltage(defs::dacIndex index, Positions pos = {}) const; + Result getPower(defs::dacIndex index, Positions pos = {}) const; /** * [CTB] mV * [Ctb] Options: V_LIMIT, V_POWER_A, V_POWER_B, V_POWER_C, * V_POWER_D, V_POWER_IO, V_POWER_CHIP */ - void setVoltage(defs::dacIndex index, int value, Positions pos = {}); + void setPower(defs::dacIndex index, int value, Positions pos = {}); /** * [CTB] Options: [0- 4] or [1V, 1.14V, 1.33V, 1.6V, 2V] @@ -1697,8 +1711,8 @@ class Detector { /** * [CTB] mV * Options: V_POWER_A, V_POWER_B, V_POWER_C, V_POWER_D, V_POWER_IO */ - Result getMeasuredVoltage(defs::dacIndex index, - Positions pos = {}) const; + Result getMeasuredPower(defs::dacIndex index, + Positions pos = {}) const; /** * [CTB] mA @@ -1792,19 +1806,19 @@ class Detector { std::string getSignalName(const int i) const; /** [CTB] */ - void setVoltageNames(const std::vector names); + void setPowerNames(const std::vector names); /** [CTB] */ - std::vector getVoltageNames() const; + std::vector getPowerNames() const; /** [CTB] */ - defs::dacIndex getVoltageIndex(const std::string &name) const; + defs::dacIndex getPowerIndex(const std::string &name) const; /** [CTB] */ - void setVoltageName(const defs::dacIndex i, const std::string &name); + void setPowerName(const defs::dacIndex i, const std::string &name); /** [CTB] */ - std::string getVoltageName(const defs::dacIndex i) const; + std::string getPowerName(const defs::dacIndex i) const; /** [CTB] */ void setSlowADCNames(const std::vector names); @@ -2068,18 +2082,18 @@ class Detector { * * * ************************************************/ - Result getControlPort(Positions pos = {}) const; + Result getControlPort(Positions pos = {}) const; /** Detector Control TCP port (for client communication with Detector * control server) Default is 1952. Normally unchanged. Set different ports * for virtual servers on same pc */ - void setControlPort(int value, Positions pos = {}); + void setControlPort(uint16_t value, Positions pos = {}); - Result getStopPort(Positions pos = {}) const; + Result getStopPort(Positions pos = {}) const; /** Port number of the stop server on detector for detector-client tcp * interface. Default is 1953. Normally unchanged. */ - void setStopPort(int value, Positions pos = {}); + void setStopPort(uint16_t value, Positions pos = {}); Result getDetectorLock(Positions pos = {}) const; @@ -2112,7 +2126,7 @@ class Detector { ///@} private: - std::vector getPortNumbers(int start_port); + std::vector getValidPortNumbers(uint16_t start_port); void updateRxRateCorrections(); void setNumberofUDPInterfaces_(int n, Positions pos); }; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index dff178822..d56bd0f96 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -197,7 +197,7 @@ std::string CmdProxy::VirtualServer(int action) { throw RuntimeError("Cannot execute this at module level"); } det->setVirtualDetectorServers(StringTo(args[0]), - StringTo(args[1])); + StringTo(args[1])); os << ToString(args); } else { throw RuntimeError("Unknown action"); @@ -2105,6 +2105,55 @@ std::string CmdProxy::TemperatureEvent(int action) { return os.str(); } +std::string CmdProxy::PedestalMode(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << " [frames] [loops]\n\t\t[Jungfrau] " + "Enable pedestal mode. \n\t\tThe number of frames or triggers is " + "overwritten by: \n\t\t(#pedestal_frames x #pedestal_loops x 2). " + "\n\t\tIn auto timing mode or in trigger mode with #frames > 1, " + "\n\t\t#frames is overwritten and #triggers = 1, \n\t\telse " + "#triggers is overwritten and #frames = 1. \n\t\tOne cannot set " + "#frames, #triggers or timing mode in pedestal mode (exception " + "thrown).\n\n"; + os << cmd + << " [0]\n\t\t[Jungfrau] Disable pedestal " + "mode.\n\t\tDisabling pedestal mode will set back the normal " + "mode values of #frames and #triggers." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 0) { + WrongNumberOfParameters(0); + } + auto t = det->getPedestalMode(std::vector{det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + // disable + if (args.size() == 1) { + if (args[0] != "0") { + throw RuntimeError( + "Unknown argument " + args[0] + + ". Did you mean '0' to disable pedestal mode?"); + } + det->setPedestalMode(defs::pedestalParameters()); + } + // enable + else if (args.size() == 2) { + uint8_t frames = StringTo(args[0]); + uint16_t loops = StringTo(args[1]); + det->setPedestalMode(defs::pedestalParameters(frames, loops)); + } else { + throw RuntimeError( + "Invalid number of parareters for this command."); + } + os << ToString(args) << '\n'; + } else { + throw RuntimeError("Unknown action"); + } + return os.str(); +} + /* Gotthard Specific */ std::string CmdProxy::ROI(int action) { @@ -2670,7 +2719,7 @@ std::string CmdProxy::SlowADC(int action) { os << cmd << ' '; if (action == defs::HELP_ACTION) { os << "[n_channel (0-7 for channel]\n\t[Ctb] Slow " - "ADC channel in uV" + "ADC channel in mV" << '\n'; } else if (action == defs::GET_ACTION) { if (args.size() != 1) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index f89360cc6..f53cd6407 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -187,7 +187,6 @@ namespace sls { return os.str(); \ } -/** int or enum */ #define INTEGER_COMMAND_VEC_ID_GET(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \ std::string CMDNAME(const int action) { \ std::ostringstream os; \ @@ -1054,10 +1053,10 @@ class CmdProxy { {"signallist", &CmdProxy::signallist}, {"signalname", &CmdProxy::signalname}, {"signalindex", &CmdProxy::signalindex}, - {"voltagelist", &CmdProxy::voltagelist}, - {"voltagename", &CmdProxy::voltagename}, - {"voltageindex", &CmdProxy::voltageindex}, - {"voltagevalues", &CmdProxy::voltagevalues}, + {"powerlist", &CmdProxy::powerlist}, + {"powername", &CmdProxy::powername}, + {"powerindex", &CmdProxy::powerindex}, + {"powervalues", &CmdProxy::powervalues}, {"slowadclist", &CmdProxy::slowadclist}, {"slowadcname", &CmdProxy::slowadcname}, {"slowadcindex", &CmdProxy::slowadcindex}, @@ -1188,6 +1187,7 @@ class CmdProxy { {"storagecell_delay", &CmdProxy::storagecell_delay}, {"gainmode", &CmdProxy::gainmode}, {"filtercells", &CmdProxy::filtercells}, + {"pedestalmode", &CmdProxy::PedestalMode}, /* Gotthard Specific */ {"roi", &CmdProxy::ROI}, @@ -1400,6 +1400,7 @@ class CmdProxy { std::string DataStream(int action); /* Jungfrau Specific */ std::string TemperatureEvent(int action); + std::string PedestalMode(int action); /* Gotthard Specific */ std::string ROI(int action); /* Gotthard2 Specific */ @@ -1778,22 +1779,21 @@ class CmdProxy { "[name] \n\t\t[ChipTestBoard] Get " "the signal index for the given name."); - CTB_NAMED_LIST(voltagelist, getVoltageNames, setVoltageNames, - "[voltagename1 voltagename2 .. voltagename4] " + CTB_NAMED_LIST(powerlist, getPowerNames, setPowerNames, + "[powername1 powername2 .. powername4] " "\n\t\t[ChipTestBoard] Set " - "the list of voltage names for this board."); + "the list of power names for this board."); - CTB_SINGLE_DACNAME(voltagename, getVoltageName, setVoltageName, - defs::V_POWER_A, + CTB_SINGLE_DACNAME(powername, getPowerName, setPowerName, defs::V_POWER_A, "[0-4][name] \n\t\t[ChipTestBoard] Set " - "the voltage at the given position to the given name."); + "the power at the given position to the given name."); - CTB_GET_DACINDEX(voltageindex, getVoltageIndex, defs::V_POWER_A, + CTB_GET_DACINDEX(powerindex, getPowerIndex, defs::V_POWER_A, "[name] \n\t\t[ChipTestBoard] Get " - "the voltage index for the given name."); + "the power index for the given name."); - CTB_VALUES(voltagevalues, getVoltage, getVoltageList, getVoltageNames, - "[name] \n\t\t[ChipTestBoard] Get values of all voltages."); + CTB_VALUES(powervalues, getPower, getPowerList, getPowerNames, + "[name] \n\t\t[ChipTestBoard] Get values of all powers."); CTB_VALUES(slowadcvalues, getSlowADC, getSlowADCList, getSlowADCNames, "[name] \n\t\t[ChipTestBoard] Get values of all slow adcs."); @@ -1976,14 +1976,14 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID_GET( udp_dstport, getDestinationUDPPort, setDestinationUDPPort, - StringTo, + StringTo, "[n]\n\tPort number of the receiver (destination) udp " "interface. Default is 50001. \n\tIf multi command, ports for each " "module is calculated (incremented by 1 if no 2nd interface)"); INTEGER_COMMAND_VEC_ID_GET( udp_dstport2, getDestinationUDPPort2, setDestinationUDPPort2, - StringTo, + StringTo, "[n]\n\t[Jungfrau][Moench][Eiger][Gotthard2] Port number of the " "receiver (destination) udp interface 2. Default is 50002. " "\n\tIf multi command, ports for each module is calculated " @@ -2041,7 +2041,7 @@ class CmdProxy { /* Receiver Config */ INTEGER_COMMAND_VEC_ID_GET( - rx_tcpport, getRxPort, setRxPort, StringTo, + rx_tcpport, getRxPort, setRxPort, StringTo, "[port]\n\tTCP port for client-receiver communication. Default is " "1954. Must be different if multiple receivers on same pc. Must be " "first command to set a receiver parameter. Multi command will " @@ -2172,7 +2172,7 @@ class CmdProxy { "and then depending on the rx zmq frequency/ timer"); INTEGER_COMMAND_VEC_ID_GET( - rx_zmqport, getRxZmqPort, setRxZmqPort, StringTo, + rx_zmqport, getRxZmqPort, setRxZmqPort, StringTo, "[port]\n\tZmq port for data to be streamed out of the receiver. " "Also restarts receiver zmq streaming if enabled. Default is 30001. " "Modified only when using an intermediate process between receiver and " @@ -2180,7 +2180,7 @@ class CmdProxy { "Multi command will automatically increment for individual modules."); INTEGER_COMMAND_VEC_ID_GET( - zmqport, getClientZmqPort, setClientZmqPort, StringTo, + zmqport, getClientZmqPort, setClientZmqPort, StringTo, "[port]\n\tZmq port in client(gui) or intermediate process for " "data to be streamed to from receiver. Default connects to receiver " "zmq streaming out port (30001). Modified only when using an " @@ -2425,7 +2425,7 @@ class CmdProxy { GET_COMMAND(syncclk, getSYNCClock, "[n_clk in MHz]\n\t[Ctb] Sync clock in MHz."); - INTEGER_IND_COMMAND(v_limit, getVoltage, setVoltage, StringTo, + INTEGER_IND_COMMAND(v_limit, getPower, setPower, StringTo, defs::V_LIMIT, "[n_value]\n\t[Ctb] Soft limit for power " "supplies (ctb only) and DACS in mV."); @@ -2467,47 +2467,43 @@ class CmdProxy { "[n_clk in MHz]\n\t[Ctb] Clock for latching the " "digital bits in MHz."); - INTEGER_IND_COMMAND(v_a, getVoltage, setVoltage, StringTo, - defs::V_POWER_A, - "[n_value]\n\t[Ctb] Voltage supply a in mV."); + INTEGER_IND_COMMAND(v_a, getPower, setPower, StringTo, defs::V_POWER_A, + "[n_value]\n\t[Ctb] Power supply a in mV."); - INTEGER_IND_COMMAND(v_b, getVoltage, setVoltage, StringTo, - defs::V_POWER_B, - "[n_value]\n\t[Ctb] Voltage supply b in mV."); + INTEGER_IND_COMMAND(v_b, getPower, setPower, StringTo, defs::V_POWER_B, + "[n_value]\n\t[Ctb] Power supply b in mV."); - INTEGER_IND_COMMAND(v_c, getVoltage, setVoltage, StringTo, - defs::V_POWER_C, - "[n_value]\n\t[Ctb] Voltage supply c in mV."); + INTEGER_IND_COMMAND(v_c, getPower, setPower, StringTo, defs::V_POWER_C, + "[n_value]\n\t[Ctb] Power supply c in mV."); - INTEGER_IND_COMMAND(v_d, getVoltage, setVoltage, StringTo, - defs::V_POWER_D, - "[n_value]\n\t[Ctb] Voltage supply d in mV."); + INTEGER_IND_COMMAND(v_d, getPower, setPower, StringTo, defs::V_POWER_D, + "[n_value]\n\t[Ctb] Power supply d in mV."); INTEGER_IND_COMMAND( - v_io, getVoltage, setVoltage, StringTo, defs::V_POWER_IO, - "[n_value]\n\t[Ctb] Voltage supply io in mV. Minimum 1200 mV. Must " + v_io, getPower, setPower, StringTo, defs::V_POWER_IO, + "[n_value]\n\t[Ctb] Power supply io in mV. Minimum 1200 mV. Must " "be the first power regulator to be set after fpga reset (on-board " "detector server start up)."); INTEGER_IND_COMMAND( - v_chip, getVoltage, setVoltage, StringTo, defs::V_POWER_CHIP, - "[n_value]\n\t[Ctb] Voltage supply chip in mV. Do not use it " + v_chip, getPower, setPower, StringTo, defs::V_POWER_CHIP, + "[n_value]\n\t[Ctb] Power supply chip in mV. Do not use it " "unless " "you are completely sure you will not fry the board."); - GET_IND_COMMAND(vm_a, getMeasuredVoltage, defs::V_POWER_A, "", + GET_IND_COMMAND(vm_a, getMeasuredPower, defs::V_POWER_A, "", "\n\t[Ctb] Measured voltage of power supply a in mV."); - GET_IND_COMMAND(vm_b, getMeasuredVoltage, defs::V_POWER_B, "", + GET_IND_COMMAND(vm_b, getMeasuredPower, defs::V_POWER_B, "", "\n\t[Ctb] Measured voltage of power supply b in mV."); - GET_IND_COMMAND(vm_c, getMeasuredVoltage, defs::V_POWER_C, "", + GET_IND_COMMAND(vm_c, getMeasuredPower, defs::V_POWER_C, "", "\n\t[Ctb] Measured voltage of power supply c in mV."); - GET_IND_COMMAND(vm_d, getMeasuredVoltage, defs::V_POWER_D, "", + GET_IND_COMMAND(vm_d, getMeasuredPower, defs::V_POWER_D, "", "\n\t[Ctb] Measured voltage of power supply d in mV."); - GET_IND_COMMAND(vm_io, getMeasuredVoltage, defs::V_POWER_IO, "", + GET_IND_COMMAND(vm_io, getMeasuredPower, defs::V_POWER_IO, "", "\n\t[Ctb] Measured voltage of power supply io in mV."); GET_IND_COMMAND(im_a, getMeasuredCurrent, defs::I_POWER_A, "", @@ -2619,13 +2615,13 @@ class CmdProxy { /* Insignificant */ INTEGER_COMMAND_VEC_ID( - port, getControlPort, setControlPort, StringTo, + port, getControlPort, setControlPort, StringTo, "[n]\n\tPort number of the control server on detector for " "detector-client tcp interface. Default is 1952. Normally unchanged. " "Set different ports for virtual servers on same pc."); INTEGER_COMMAND_VEC_ID( - stopport, getStopPort, setStopPort, StringTo, + stopport, getStopPort, setStopPort, StringTo, "[n]\n\tPort number of the stop server on detector for detector-client " "tcp interface. Default is 1953. Normally unchanged."); diff --git a/slsDetectorSoftware/src/CtbConfig.cpp b/slsDetectorSoftware/src/CtbConfig.cpp index a76a99b43..94f4c10fd 100644 --- a/slsDetectorSoftware/src/CtbConfig.cpp +++ b/slsDetectorSoftware/src/CtbConfig.cpp @@ -20,11 +20,11 @@ CtbConfig::CtbConfig() { for (size_t i = 0; i != num_signals; ++i) { setSignalName(i, "BIT" + ToString(i)); } - setVoltageName(0, "VA"); - setVoltageName(1, "VB"); - setVoltageName(2, "VC"); - setVoltageName(3, "VD"); - setVoltageName(4, "VIO"); + setPowerName(0, "VA"); + setPowerName(1, "VB"); + setPowerName(2, "VC"); + setPowerName(3, "VD"); + setPowerName(4, "VIO"); for (size_t i = 0; i != num_slowADCs; ++i) { setSlowADCName(i, "SLOWADC" + ToString(i)); } @@ -54,10 +54,10 @@ void CtbConfig::check_signal_index(size_t i) const { } } -void CtbConfig::check_voltage_index(size_t i) const { - if (i >= num_voltages) { +void CtbConfig::check_power_index(size_t i) const { + if (i >= num_powers) { std::ostringstream oss; - oss << "Invalid Voltage index. Options: 0 - " << num_voltages + oss << "Invalid Power index. Options: 0 - " << num_powers << " or V_POWER_A - V_POWER_IO"; throw RuntimeError(oss.str()); } @@ -176,33 +176,33 @@ std::vector CtbConfig::getSignalNames() const { return names; } -void CtbConfig::setVoltageName(size_t index, const std::string &name) { - check_voltage_index(index); +void CtbConfig::setPowerName(size_t index, const std::string &name) { + check_power_index(index); check_size(name); - char *dst = &voltagenames[index * name_length]; + char *dst = &powernames[index * name_length]; memset(dst, '\0', name_length); memcpy(dst, &name[0], name.size()); } -void CtbConfig::setVoltageNames(const std::vector &names) { - if (names.size() != num_voltages) { - throw RuntimeError("Voltage names need to be of size " + - std::to_string(num_voltages)); +void CtbConfig::setPowerNames(const std::vector &names) { + if (names.size() != num_powers) { + throw RuntimeError("Power names need to be of size " + + std::to_string(num_powers)); } - for (size_t i = 0; i != num_voltages; ++i) { - setVoltageName(i, names[i]); + for (size_t i = 0; i != num_powers; ++i) { + setPowerName(i, names[i]); } } -std::string CtbConfig::getVoltageName(size_t index) const { - check_voltage_index(index); - return voltagenames + index * name_length; +std::string CtbConfig::getPowerName(size_t index) const { + check_power_index(index); + return powernames + index * name_length; } -std::vector CtbConfig::getVoltageNames() const { +std::vector CtbConfig::getPowerNames() const { std::vector names; - for (size_t i = 0; i != num_voltages; ++i) - names.push_back(getVoltageName(i)); + for (size_t i = 0; i != num_powers; ++i) + names.push_back(getPowerName(i)); return names; } diff --git a/slsDetectorSoftware/src/CtbConfig.h b/slsDetectorSoftware/src/CtbConfig.h index 2232dc29d..2e03996d3 100644 --- a/slsDetectorSoftware/src/CtbConfig.h +++ b/slsDetectorSoftware/src/CtbConfig.h @@ -8,19 +8,19 @@ class CtbConfig { static constexpr size_t num_dacs = 18; static constexpr size_t num_adcs = 32; static constexpr size_t num_signals = 64; - static constexpr size_t num_voltages = 5; + static constexpr size_t num_powers = 5; static constexpr size_t num_slowADCs = 8; static constexpr const char *shm_tag_ = "ctbdacs"; char dacnames[name_length * num_dacs]{}; char adcnames[name_length * num_adcs]{}; char signalnames[name_length * num_signals]{}; - char voltagenames[name_length * num_voltages]{}; + char powernames[name_length * num_powers]{}; char slowADCnames[name_length * num_slowADCs]{}; void check_dac_index(size_t i) const; void check_adc_index(size_t i) const; void check_signal_index(size_t i) const; - void check_voltage_index(size_t i) const; + void check_power_index(size_t i) const; void check_slow_adc_index(size_t i) const; void check_size(const std::string &name) const; @@ -46,10 +46,10 @@ class CtbConfig { std::string getSignalName(size_t index) const; std::vector getSignalNames() const; - void setVoltageNames(const std::vector &names); - void setVoltageName(size_t index, const std::string &name); - std::string getVoltageName(size_t index) const; - std::vector getVoltageNames() const; + void setPowerNames(const std::vector &names); + void setPowerName(size_t index, const std::string &name); + std::string getPowerName(size_t index) const; + std::vector getPowerNames() const; void setSlowADCNames(const std::vector &names); void setSlowADCName(size_t index, const std::string &name); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 5e63c8b71..344bde73c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -107,7 +107,9 @@ void Detector::setHostname(const std::vector &hostname) { pimpl->setHostname(hostname); } -void Detector::setVirtualDetectorServers(int numServers, int startingPort) { +void Detector::setVirtualDetectorServers(int numServers, + uint16_t startingPort) { + validatePortRange(startingPort, numServers * 2); pimpl->setVirtualDetectorServers(numServers, startingPort); } @@ -982,10 +984,10 @@ void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { throw RuntimeError("No modules added."); } bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); - int clientStartingPort = getClientZmqPort({0}).squash(0); + uint16_t clientStartingPort = getClientZmqPort({0}).squash(0); bool useReceiver = getUseReceiverFlag().squash(false); bool previouslyReceiverStreaming = false; - int rxStartingPort = 0; + uint16_t rxStartingPort = 0; if (useReceiver) { previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true); rxStartingPort = getRxZmqPort({0}).squash(0); @@ -1108,34 +1110,36 @@ void Detector::setDestinationUDPMAC2(const MacAddr mac, Positions pos) { pimpl->Parallel(&Module::setDestinationUDPMAC2, pos, mac); } -Result Detector::getDestinationUDPPort(Positions pos) const { +Result Detector::getDestinationUDPPort(Positions pos) const { return pimpl->Parallel(&Module::getDestinationUDPPort, pos); } -void Detector::setDestinationUDPPort(int port, int module_id) { +void Detector::setDestinationUDPPort(uint16_t port, int module_id) { if (module_id == -1) { - std::vector port_list = getPortNumbers(port); + std::vector port_list = getValidPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { pimpl->Parallel(&Module::setDestinationUDPPort, {idet}, port_list[idet]); } } else { + validatePortNumber(port); pimpl->Parallel(&Module::setDestinationUDPPort, {module_id}, port); } } -Result Detector::getDestinationUDPPort2(Positions pos) const { +Result Detector::getDestinationUDPPort2(Positions pos) const { return pimpl->Parallel(&Module::getDestinationUDPPort2, pos); } -void Detector::setDestinationUDPPort2(int port, int module_id) { +void Detector::setDestinationUDPPort2(uint16_t port, int module_id) { if (module_id == -1) { - std::vector port_list = getPortNumbers(port); + std::vector port_list = getValidPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { pimpl->Parallel(&Module::setDestinationUDPPort2, {idet}, port_list[idet]); } } else { + validatePortNumber(port); pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id}, port); } } @@ -1235,21 +1239,23 @@ void Detector::setRxHostname(const std::vector &name) { updateRxRateCorrections(); } -Result Detector::getRxPort(Positions pos) const { +Result Detector::getRxPort(Positions pos) const { return pimpl->Parallel(&Module::getReceiverPort, pos); } -void Detector::setRxPort(int port, int module_id) { +void Detector::setRxPort(uint16_t port, int module_id) { if (module_id == -1) { - std::vector port_list(size()); - for (auto &it : port_list) { - it = port++; - } + validatePortRange(port, size() - 1); + + std::vector port_list(size()); + std::iota(std::begin(port_list), std::end(port_list), port); + // no need to verify hostname-port combo as unique port(incremented) for (int idet = 0; idet < size(); ++idet) { pimpl->Parallel(&Module::setReceiverPort, {idet}, port_list[idet]); } } else { + validatePortNumber(port); pimpl->verifyUniqueRxHost(port, module_id); pimpl->Parallel(&Module::setReceiverPort, {module_id}, port); } @@ -1440,20 +1446,21 @@ void Detector::setRxZmqStartingFrame(int fnum, Positions pos) { pimpl->Parallel(&Module::setReceiverStreamingStartingFrame, pos, fnum); } -Result Detector::getRxZmqPort(Positions pos) const { +Result Detector::getRxZmqPort(Positions pos) const { return pimpl->Parallel(&Module::getReceiverStreamingPort, pos); } -void Detector::setRxZmqPort(int port, int module_id) { +void Detector::setRxZmqPort(uint16_t port, int module_id) { bool previouslyReceiverStreaming = getRxZmqDataStream(std::vector{module_id}).squash(false); if (module_id == -1) { - std::vector port_list = getPortNumbers(port); + std::vector port_list = getValidPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { pimpl->Parallel(&Module::setReceiverStreamingPort, {idet}, port_list[idet]); } } else { + validatePortNumber(port); pimpl->Parallel(&Module::setReceiverStreamingPort, {module_id}, port); } if (previouslyReceiverStreaming) { @@ -1475,19 +1482,20 @@ void Detector::setRxZmqIP(const IpAddr ip, Positions pos) { } } -Result Detector::getClientZmqPort(Positions pos) const { +Result Detector::getClientZmqPort(Positions pos) const { return pimpl->Parallel(&Module::getClientStreamingPort, pos); } -void Detector::setClientZmqPort(int port, int module_id) { +void Detector::setClientZmqPort(uint16_t port, int module_id) { bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); if (module_id == -1) { - std::vector port_list = getPortNumbers(port); + std::vector port_list = getValidPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { pimpl->Parallel(&Module::setClientStreamingPort, {idet}, port_list[idet]); } } else { + validatePortNumber(port); pimpl->Parallel(&Module::setClientStreamingPort, {module_id}, port); } if (previouslyClientStreaming) { @@ -1752,6 +1760,16 @@ void Detector::setNumberOfFilterCells(int cell, Positions pos) { pimpl->Parallel(&Module::setNumberOfFilterCells, pos, cell); } +Result +Detector::getPedestalMode(Positions pos) const { + return pimpl->Parallel(&Module::getPedestalMode, pos); +} + +void Detector::setPedestalMode(const defs::pedestalParameters par, + Positions pos) { + pimpl->Parallel(&Module::setPedestalMode, pos, par); +} + // Gotthard Specific Result Detector::getROI(Positions pos) const { @@ -2051,9 +2069,9 @@ Result Detector::getSYNCClock(Positions pos) const { return pimpl->Parallel(&Module::getClockFrequency, pos, defs::SYNC_CLOCK); } -std::vector Detector::getVoltageList() const { +std::vector Detector::getPowerList() const { if (getDetectorType().squash() != defs::CHIPTESTBOARD) { - throw RuntimeError("Voltage list not implemented for this detector"); + throw RuntimeError("Power list not implemented for this detector"); } return std::vector{defs::V_POWER_A, defs::V_POWER_B, defs::V_POWER_C, defs::V_POWER_D, @@ -2069,7 +2087,7 @@ std::vector Detector::getSlowADCList() const { defs::SLOW_ADC4, defs::SLOW_ADC5, defs::SLOW_ADC6, defs::SLOW_ADC7}; } -Result Detector::getVoltage(defs::dacIndex index, Positions pos) const { +Result Detector::getPower(defs::dacIndex index, Positions pos) const { switch (index) { case defs::V_LIMIT: case defs::V_POWER_A: @@ -2080,12 +2098,12 @@ Result Detector::getVoltage(defs::dacIndex index, Positions pos) const { case defs::V_POWER_CHIP: break; default: - throw RuntimeError("Unknown Voltage Index"); + throw RuntimeError("Unknown Power Index"); } return pimpl->Parallel(&Module::getDAC, pos, index, true); } -void Detector::setVoltage(defs::dacIndex index, int value, Positions pos) { +void Detector::setPower(defs::dacIndex index, int value, Positions pos) { switch (index) { case defs::V_LIMIT: case defs::V_POWER_A: @@ -2096,7 +2114,7 @@ void Detector::setVoltage(defs::dacIndex index, int value, Positions pos) { case defs::V_POWER_CHIP: break; default: - throw RuntimeError("Unknown Voltage Index"); + throw RuntimeError("Unknown Power Index"); } pimpl->Parallel(&Module::setDAC, pos, value, index, true); } @@ -2167,8 +2185,8 @@ void Detector::setDBITClock(int value_in_MHz, Positions pos) { value_in_MHz); } -Result Detector::getMeasuredVoltage(defs::dacIndex index, - Positions pos) const { +Result Detector::getMeasuredPower(defs::dacIndex index, + Positions pos) const { switch (index) { case defs::V_POWER_A: case defs::V_POWER_B: @@ -2178,7 +2196,7 @@ Result Detector::getMeasuredVoltage(defs::dacIndex index, case defs::V_POWER_CHIP: break; default: - throw RuntimeError("Unknown Voltage Index"); + throw RuntimeError("Unknown Power Index"); } return pimpl->Parallel(&Module::getADC, pos, index); } @@ -2359,39 +2377,39 @@ std::string Detector::getSignalName(const int i) const { return pimpl->getCtbSignalName(i); } -void Detector::setVoltageNames(const std::vector names) { +void Detector::setPowerNames(const std::vector names) { if (getDetectorType().squash() != defs::CHIPTESTBOARD) throw RuntimeError("Named powers only for CTB"); - pimpl->setCtbVoltageNames(names); + pimpl->setCtbPowerNames(names); } -std::vector Detector::getVoltageNames() const { +std::vector Detector::getPowerNames() const { if (getDetectorType().squash() != defs::CHIPTESTBOARD) throw RuntimeError("Named powers only for CTB"); - return pimpl->getCtbVoltageNames(); + return pimpl->getCtbPowerNames(); } -defs::dacIndex Detector::getVoltageIndex(const std::string &name) const { +defs::dacIndex Detector::getPowerIndex(const std::string &name) const { if (getDetectorType().squash() != defs::CHIPTESTBOARD) throw RuntimeError("Named powers only for CTB"); - auto names = getVoltageNames(); + auto names = getPowerNames(); auto it = std::find(names.begin(), names.end(), name); if (it == names.end()) - throw RuntimeError("Voltage name not found"); + throw RuntimeError("Power name not found"); return static_cast(it - names.begin() + defs::V_POWER_A); } -void Detector::setVoltageName(const defs::dacIndex index, - const std::string &name) { +void Detector::setPowerName(const defs::dacIndex index, + const std::string &name) { if (getDetectorType().squash() != defs::CHIPTESTBOARD) throw RuntimeError("Named powers only for CTB"); - pimpl->setCtbVoltageName(index, name); + pimpl->setCtbPowerName(index, name); } -std::string Detector::getVoltageName(const defs::dacIndex i) const { +std::string Detector::getPowerName(const defs::dacIndex i) const { if (getDetectorType().squash() != defs::CHIPTESTBOARD) throw RuntimeError("Named powers only for CTB"); - return pimpl->getCtbVoltageName(i); + return pimpl->getCtbPowerName(i); } void Detector::setSlowADCNames(const std::vector names) { @@ -2665,21 +2683,23 @@ void Detector::setADCInvert(uint32_t value, Positions pos) { // Insignificant -Result Detector::getControlPort(Positions pos) const { +Result Detector::getControlPort(Positions pos) const { return pimpl->Parallel(&Module::getControlPort, pos); } -void Detector::setControlPort(int value, Positions pos) { +void Detector::setControlPort(uint16_t value, Positions pos) { + validatePortNumber(value); pimpl->verifyUniqueDetHost(value, pos); pimpl->Parallel(&Module::setControlPort, pos, value); } -Result Detector::getStopPort(Positions pos) const { +Result Detector::getStopPort(Positions pos) const { // not verifying unique stop port (control port is sufficient) return pimpl->Parallel(&Module::getStopPort, pos); } -void Detector::setStopPort(int value, Positions pos) { +void Detector::setStopPort(uint16_t value, Positions pos) { + validatePortNumber(value); pimpl->Parallel(&Module::setStopPort, pos, value); } @@ -2714,13 +2734,17 @@ Result Detector::getMeasurementTime(Positions pos) const { std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); } -std::vector Detector::getPortNumbers(int start_port) { +std::vector Detector::getValidPortNumbers(uint16_t start_port) { int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash( "Number of UDP Interfaces is not consistent among modules"); - std::vector res; + + validatePortRange(start_port, (size() - 1) * num_sockets_per_detector); + + std::vector res; res.reserve(size()); for (int idet = 0; idet < size(); ++idet) { - res.push_back(start_port + (idet * num_sockets_per_detector)); + uint16_t port = start_port + (idet * num_sockets_per_detector); + res.push_back(port); } return res; } diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 202d621fd..9bf392e5a 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -242,7 +242,8 @@ std::string DetectorImpl::exec(const char *cmd) { return result; } -void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) { +void DetectorImpl::setVirtualDetectorServers(const int numdet, + const uint16_t port) { std::vector hostnames; for (int i = 0; i < numdet; ++i) { // * 2 is for control and stop port @@ -283,7 +284,7 @@ void DetectorImpl::addModule(const std::string &name) { LOG(logINFO) << "Adding module " << name; auto host = verifyUniqueDetHost(name); std::string hostname = host.first; - int port = host.second; + uint16_t port = host.second; // get type by connecting detectorType type = Module::getTypeFromDetector(hostname, port); @@ -1583,41 +1584,41 @@ defs::xy DetectorImpl::calculatePosition(int moduleIndex, return pos; } -void DetectorImpl::verifyUniqueDetHost(const int port, +void DetectorImpl::verifyUniqueDetHost(const uint16_t port, std::vector positions) const { // port for given positions if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) { positions.resize(modules.size()); std::iota(begin(positions), end(positions), 0); } - std::vector> hosts(size()); + std::vector> hosts(size()); for (auto it : positions) { hosts[it].second = port; } verifyUniqueHost(true, hosts); } -void DetectorImpl::verifyUniqueRxHost(const int port, +void DetectorImpl::verifyUniqueRxHost(const uint16_t port, const int moduleId) const { - std::vector> hosts(size()); + std::vector> hosts(size()); hosts[moduleId].second = port; verifyUniqueHost(false, hosts); } -std::pair +std::pair DetectorImpl::verifyUniqueDetHost(const std::string &name) { // extract port // C++17 could be auto [hostname, port] = ParseHostPort(name); auto res = ParseHostPort(name); std::string hostname = res.first; - int port = res.second; + uint16_t port = res.second; if (port == 0) { port = DEFAULT_TCP_CNTRL_PORTNO; } int detSize = size(); // mod not yet added - std::vector> hosts(detSize + 1); + std::vector> hosts(detSize + 1); hosts[detSize].first = hostname; hosts[detSize].second = port; @@ -1625,7 +1626,7 @@ DetectorImpl::verifyUniqueDetHost(const std::string &name) { return std::make_pair(hostname, port); } -std::pair +std::pair DetectorImpl::verifyUniqueRxHost(const std::string &name, std::vector positions) const { // no checks if setting to none @@ -1636,7 +1637,7 @@ DetectorImpl::verifyUniqueRxHost(const std::string &name, // C++17 could be auto [hostname, port] = ParseHostPort(name); auto res = ParseHostPort(name); std::string hostname = res.first; - int port = res.second; + uint16_t port = res.second; // hostname and port for given positions if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) { @@ -1644,7 +1645,7 @@ DetectorImpl::verifyUniqueRxHost(const std::string &name, std::iota(begin(positions), end(positions), 0); } - std::vector> hosts(size()); + std::vector> hosts(size()); for (auto it : positions) { hosts[it].first = hostname; hosts[it].second = port; @@ -1654,7 +1655,7 @@ DetectorImpl::verifyUniqueRxHost(const std::string &name, return std::make_pair(hostname, port); } -std::vector> +std::vector> DetectorImpl::verifyUniqueRxHost(const std::vector &names) const { if ((int)names.size() != size()) { throw RuntimeError( @@ -1663,7 +1664,7 @@ DetectorImpl::verifyUniqueRxHost(const std::vector &names) const { } // extract ports - std::vector> hosts; + std::vector> hosts; for (const auto &name : names) { hosts.push_back(ParseHostPort(name)); } @@ -1673,7 +1674,7 @@ DetectorImpl::verifyUniqueRxHost(const std::vector &names) const { } void DetectorImpl::verifyUniqueHost( - bool isDet, std::vector> &hosts) const { + bool isDet, std::vector> &hosts) const { // fill from shm if not provided for (int i = 0; i != size(); ++i) { @@ -1689,7 +1690,7 @@ void DetectorImpl::verifyUniqueHost( // remove the ones without a hostname hosts.erase(std::remove_if(hosts.begin(), hosts.end(), - [](const std::pair &x) { + [](const std::pair &x) { return (x.first == "none" || x.first.empty()); }), @@ -2038,21 +2039,21 @@ void DetectorImpl::setCtbSignalName(const int index, const std::string &name) { ctb_shm()->setSignalName(index, name); } -std::vector DetectorImpl::getCtbVoltageNames() const { - return ctb_shm()->getVoltageNames(); +std::vector DetectorImpl::getCtbPowerNames() const { + return ctb_shm()->getPowerNames(); } -void DetectorImpl::setCtbVoltageNames(const std::vector &names) { - ctb_shm()->setVoltageNames(names); +void DetectorImpl::setCtbPowerNames(const std::vector &names) { + ctb_shm()->setPowerNames(names); } -std::string DetectorImpl::getCtbVoltageName(const defs::dacIndex i) const { - return ctb_shm()->getVoltageName(static_cast(i - defs::V_POWER_A)); +std::string DetectorImpl::getCtbPowerName(const defs::dacIndex i) const { + return ctb_shm()->getPowerName(static_cast(i - defs::V_POWER_A)); } -void DetectorImpl::setCtbVoltageName(const defs::dacIndex index, - const std::string &name) { - ctb_shm()->setVoltageName(static_cast(index - defs::V_POWER_A), name); +void DetectorImpl::setCtbPowerName(const defs::dacIndex index, + const std::string &name) { + ctb_shm()->setPowerName(static_cast(index - defs::V_POWER_A), name); } std::vector DetectorImpl::getCtbSlowADCNames() const { diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index da37f6c00..9baefe8b3 100644 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -84,7 +84,9 @@ class DetectorImpl : public virtual slsDetectorDefs { */ virtual ~DetectorImpl(); - template struct NonDeduced { using type = CT; }; + template struct NonDeduced { + using type = CT; + }; template Result Parallel(RT (Module::*somefunc)(CT...), std::vector positions, @@ -220,7 +222,7 @@ class DetectorImpl : public virtual slsDetectorDefs { * @param numdet number of modules * @param port starting port number */ - void setVirtualDetectorServers(const int numdet, const int port); + void setVirtualDetectorServers(const int numdet, const uint16_t port); /** Sets the hostname of all sls modules in shared memory and updates * local cache */ @@ -307,14 +309,16 @@ class DetectorImpl : public virtual slsDetectorDefs { void setDefaultDac(defs::dacIndex index, int defaultValue, defs::detectorSettings sett, Positions pos); - void verifyUniqueDetHost(const int port, std::vector positions) const; - void verifyUniqueRxHost(const int port, const int moduleId) const; + void verifyUniqueDetHost(const uint16_t port, + std::vector positions) const; + void verifyUniqueRxHost(const uint16_t port, const int moduleId) const; - std::pair verifyUniqueDetHost(const std::string &name); - std::pair + std::pair + verifyUniqueDetHost(const std::string &name); + std::pair verifyUniqueRxHost(const std::string &name, std::vector positions) const; - std::vector> + std::vector> verifyUniqueRxHost(const std::vector &names) const; defs::ROI getRxROI() const; @@ -340,10 +344,10 @@ class DetectorImpl : public virtual slsDetectorDefs { void setCtbSignalNames(const std::vector &names); void setCtbSignalName(const int index, const std::string &name); - std::vector getCtbVoltageNames() const; - std::string getCtbVoltageName(const defs::dacIndex i) const; - void setCtbVoltageNames(const std::vector &names); - void setCtbVoltageName(const defs::dacIndex index, const std::string &name); + std::vector getCtbPowerNames() const; + std::string getCtbPowerName(const defs::dacIndex i) const; + void setCtbPowerNames(const std::vector &names); + void setCtbPowerName(const defs::dacIndex index, const std::string &name); std::vector getCtbSlowADCNames() const; std::string getCtbSlowADCName(const defs::dacIndex i) const; @@ -439,9 +443,8 @@ class DetectorImpl : public virtual slsDetectorDefs { defs::xy getPortGeometry() const; defs::xy calculatePosition(int moduleIndex, defs::xy geometry) const; - void - verifyUniqueHost(bool isDet, - std::vector> &hosts) const; + void verifyUniqueHost( + bool isDet, std::vector> &hosts) const; const int detectorIndex{0}; SharedMemory shm{0, -1}; diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 9e47652a7..33603c6ea 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -165,11 +165,15 @@ std::string Module::getReceiverSoftwareVersion() const { // static function slsDetectorDefs::detectorType -Module::getTypeFromDetector(const std::string &hostname, int cport) { +Module::getTypeFromDetector(const std::string &hostname, uint16_t cport) { LOG(logDEBUG1) << "Getting Module type "; ClientSocket socket("Detector", hostname, cport); socket.Send(F_GET_DETECTOR_TYPE); - socket.Receive(); // TODO! Should we look at this OK/FAIL? + if (socket.Receive() == FAIL) { + throw RuntimeError("Detector (" + hostname + ", " + + std::to_string(cport) + + ") returned error at getting detector type"); + } auto retval = socket.Receive(); LOG(logDEBUG1) << "Module type is " << retval; return retval; @@ -1241,22 +1245,22 @@ void Module::setDestinationUDPMAC2(const MacAddr mac) { sendToDetector(F_SET_DEST_UDP_MAC2, mac, nullptr); } -int Module::getDestinationUDPPort() const { - return sendToDetector(F_GET_DEST_UDP_PORT); +uint16_t Module::getDestinationUDPPort() const { + return sendToDetector(F_GET_DEST_UDP_PORT); } -void Module::setDestinationUDPPort(const int port) { +void Module::setDestinationUDPPort(const uint16_t port) { sendToDetector(F_SET_DEST_UDP_PORT, port, nullptr); if (shm()->useReceiverFlag) { sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr); } } -int Module::getDestinationUDPPort2() const { - return sendToDetector(F_GET_DEST_UDP_PORT2); +uint16_t Module::getDestinationUDPPort2() const { + return sendToDetector(F_GET_DEST_UDP_PORT2); } -void Module::setDestinationUDPPort2(const int port) { +void Module::setDestinationUDPPort2(const uint16_t port) { sendToDetector(F_SET_DEST_UDP_PORT2, port, nullptr); if (shm()->useReceiverFlag) { sendToReceiver(F_SET_RECEIVER_UDP_PORT2, port, nullptr); @@ -1354,7 +1358,8 @@ std::string Module::getReceiverHostname() const { return std::string(shm()->rxHostname); } -void Module::setReceiverHostname(const std::string &hostname, const int port, +void Module::setReceiverHostname(const std::string &hostname, + const uint16_t port, const bool initialChecks) { { std::ostringstream oss; @@ -1427,13 +1432,10 @@ void Module::setReceiverHostname(const std::string &hostname, const int port, updateReceiverStreamingIP(); } -int Module::getReceiverPort() const { return shm()->rxTCPPort; } +uint16_t Module::getReceiverPort() const { return shm()->rxTCPPort; } -int Module::setReceiverPort(int port_number) { - if (port_number >= 0 && port_number != shm()->rxTCPPort) { - shm()->rxTCPPort = port_number; - } - return shm()->rxTCPPort; +void Module::setReceiverPort(uint16_t port_number) { + shm()->rxTCPPort = port_number; } int Module::getReceiverFifoDepth() const { @@ -1645,11 +1647,11 @@ void Module::setReceiverStreamingStartingFrame(int fnum) { sendToReceiver(F_SET_RECEIVER_STREAMING_START_FNUM, fnum, nullptr); } -int Module::getReceiverStreamingPort() const { - return sendToReceiver(F_GET_RECEIVER_STREAMING_PORT); +uint16_t Module::getReceiverStreamingPort() const { + return sendToReceiver(F_GET_RECEIVER_STREAMING_PORT); } -void Module::setReceiverStreamingPort(int port) { +void Module::setReceiverStreamingPort(uint16_t port) { sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr); } @@ -1668,9 +1670,9 @@ void Module::setReceiverStreamingIP(const IpAddr ip) { sendToReceiver(F_SET_RECEIVER_STREAMING_SRC_IP, ip, nullptr); } -int Module::getClientStreamingPort() const { return shm()->zmqport; } +uint16_t Module::getClientStreamingPort() const { return shm()->zmqport; } -void Module::setClientStreamingPort(int port) { shm()->zmqport = port; } +void Module::setClientStreamingPort(uint16_t port) { shm()->zmqport = port; } IpAddr Module::getClientStreamingIP() const { return shm()->zmqip; } @@ -1938,6 +1940,20 @@ void Module::setNumberOfFilterCells(int value) { sendToDetector(F_SET_NUM_FILTER_CELLS, value, nullptr); } +defs::pedestalParameters Module::getPedestalMode() const { + return sendToDetector(F_GET_PEDESTAL_MODE); +} + +void Module::setPedestalMode(const defs::pedestalParameters par) { + sendToDetector(F_SET_PEDESTAL_MODE, par, nullptr); + if (shm()->useReceiverFlag) { + auto value = getNumberOfFrames(); + sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr); + value = getNumberOfTriggers(); + sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr); + } +} + // Gotthard Specific slsDetectorDefs::ROI Module::getROI() const { @@ -2839,15 +2855,17 @@ void Module::setADCInvert(uint32_t value) { } // Insignificant -int Module::getControlPort() const { return shm()->controlPort; } +uint16_t Module::getControlPort() const { return shm()->controlPort; } -void Module::setControlPort(int port_number) { +void Module::setControlPort(uint16_t port_number) { shm()->controlPort = port_number; } -int Module::getStopPort() const { return shm()->stopPort; } +uint16_t Module::getStopPort() const { return shm()->stopPort; } -void Module::setStopPort(int port_number) { shm()->stopPort = port_number; } +void Module::setStopPort(uint16_t port_number) { + shm()->stopPort = port_number; +} bool Module::getLockDetector() const { return sendToDetector(F_LOCK_SERVER, GET_FLAG); @@ -3928,8 +3946,8 @@ void Module::sendProgram(bool blackfin, std::vector buffer, void Module::simulatingActivityinDetector(const std::string &functionType, const int timeRequired) { - LOG(logINFO) << "(Simulating) " << functionType << " for module " - << moduleIndex << " (" << shm()->hostname << ")"; + LOG(logINFO) << functionType << " for module " << moduleIndex << " (" + << shm()->hostname << ")"; printf("%d%%\r", 0); std::cout << std::flush; const int ERASE_TIME = timeRequired; diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index fd0b99eda..4c3d5a97f 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -19,7 +19,7 @@ namespace sls { class ServerInterface; #define MODULE_SHMAPIVERSION 0x190726 -#define MODULE_SHMVERSION 0x200402 +#define MODULE_SHMVERSION 0x230913 /** * @short structure allocated in shared memory to store Module settings for @@ -36,8 +36,8 @@ struct sharedModule { /** END OF FIXED PATTERN -----------------------------------------------*/ slsDetectorDefs::xy numberOfModule; - int controlPort; - int stopPort; + uint16_t controlPort; + uint16_t stopPort; char settingsDir[MAX_STR_LENGTH]; /** list of the energies at which the Module has been trimmed */ StaticVector trimEnergies; @@ -46,11 +46,11 @@ struct sharedModule { slsDetectorDefs::xy nChip; int nDacs; char rxHostname[MAX_STR_LENGTH]; - int rxTCPPort; + uint16_t rxTCPPort; /** if rxHostname and rxTCPPort can be connected to */ bool useReceiverFlag; /** Listening tcp port from gui (only data) */ - int zmqport; + uint16_t zmqport; /** Listening tcp ip address from gui (only data) **/ IpAddr zmqip; int numUDPInterfaces; @@ -102,7 +102,7 @@ class Module : public virtual slsDetectorDefs { std::string getReceiverSoftwareVersion() const; static detectorType getTypeFromDetector(const std::string &hostname, - int cport = DEFAULT_TCP_CNTRL_PORTNO); + uint16_t cport = DEFAULT_TCP_CNTRL_PORTNO); /** Get Detector type from shared memory */ detectorType getDetectorType() const; @@ -261,10 +261,10 @@ class Module : public virtual slsDetectorDefs { void setDestinationUDPMAC(const MacAddr mac); MacAddr getDestinationUDPMAC2() const; void setDestinationUDPMAC2(const MacAddr mac); - int getDestinationUDPPort() const; - void setDestinationUDPPort(int udpport); - int getDestinationUDPPort2() const; - void setDestinationUDPPort2(int udpport); + uint16_t getDestinationUDPPort() const; + void setDestinationUDPPort(uint16_t udpport); + uint16_t getDestinationUDPPort2() const; + void setDestinationUDPPort2(uint16_t udpport); void reconfigureUDPDestination(); void validateUDPConfiguration(); std::string printReceiverConfiguration(); @@ -286,10 +286,10 @@ class Module : public virtual slsDetectorDefs { * ************************************************/ bool getUseReceiverFlag() const; std::string getReceiverHostname() const; - void setReceiverHostname(const std::string &hostname, const int port, + void setReceiverHostname(const std::string &hostname, const uint16_t port, const bool initialChecks); - int getReceiverPort() const; - int setReceiverPort(int port_number); + uint16_t getReceiverPort() const; + void setReceiverPort(uint16_t port_number); int getReceiverFifoDepth() const; void setReceiverFifoDepth(int n_frames); bool getReceiverSilentMode() const; @@ -349,12 +349,12 @@ class Module : public virtual slsDetectorDefs { void setReceiverStreamingTimer(int time_in_ms = 200); int getReceiverStreamingStartingFrame() const; void setReceiverStreamingStartingFrame(int fnum); - int getReceiverStreamingPort() const; - void setReceiverStreamingPort(int port); + uint16_t getReceiverStreamingPort() const; + void setReceiverStreamingPort(uint16_t port); IpAddr getReceiverStreamingIP() const; void setReceiverStreamingIP(const IpAddr ip); - int getClientStreamingPort() const; - void setClientStreamingPort(int port); + uint16_t getClientStreamingPort() const; + void setClientStreamingPort(uint16_t port); IpAddr getClientStreamingIP() const; void setClientStreamingIP(const IpAddr ip); int getReceiverStreamingHwm() const; @@ -419,6 +419,8 @@ class Module : public virtual slsDetectorDefs { void setGainMode(const gainMode mode); int getNumberOfFilterCells() const; void setNumberOfFilterCells(int value); + defs::pedestalParameters getPedestalMode() const; + void setPedestalMode(defs::pedestalParameters par); /************************************************** * * @@ -597,10 +599,10 @@ class Module : public virtual slsDetectorDefs { * Insignificant * * * * ************************************************/ - int getControlPort() const; - void setControlPort(int port_number); - int getStopPort() const; - void setStopPort(int port_number); + uint16_t getControlPort() const; + void setControlPort(uint16_t port_number); + uint16_t getStopPort() const; + void setStopPort(uint16_t port_number); bool getLockDetector() const; void setLockDetector(bool lock); IpAddr getLastClientIP() const; diff --git a/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp b/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp index d23ec6a6b..ad3211888 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-chiptestboard.cpp @@ -261,15 +261,15 @@ TEST_CASE("signalindex", "[.cmd]") { } } -TEST_CASE("voltagelist", "[.cmd]") { +TEST_CASE("powerlist", "[.cmd]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev = det.getVoltageNames(); + auto prev = det.getPowerNames(); - REQUIRE_THROWS(proxy.Call("voltagelist", {"a", "s", "d"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powerlist", {"a", "s", "d"}, -1, PUT)); std::vector names; for (int iarg = 0; iarg != 5; ++iarg) { @@ -277,87 +277,87 @@ TEST_CASE("voltagelist", "[.cmd]") { } { std::ostringstream oss; - REQUIRE_NOTHROW(proxy.Call("voltagelist", names, -1, PUT, oss)); + REQUIRE_NOTHROW(proxy.Call("powerlist", names, -1, PUT, oss)); } { std::ostringstream oss; - REQUIRE_NOTHROW(proxy.Call("voltagelist", {}, -1, GET, oss)); + REQUIRE_NOTHROW(proxy.Call("powerlist", {}, -1, GET, oss)); REQUIRE(oss.str() == - std::string("voltagelist ") + ToString(names) + '\n'); + std::string("powerlist ") + ToString(names) + '\n'); } - det.setVoltageNames(prev); + det.setPowerNames(prev); } else { - REQUIRE_THROWS(proxy.Call("voltagelist", {"a", "b"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("voltagelist", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("powerlist", {"a", "b"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powerlist", {}, -1, GET)); } } -TEST_CASE("voltagename", "[.cmd]") { +TEST_CASE("powername", "[.cmd]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { defs::dacIndex ind = static_cast(2 + defs::V_POWER_A); - std::string str_voltage_index = "2"; - auto prev = det.getVoltageName(ind); + std::string str_power_index = "2"; + auto prev = det.getPowerName(ind); // 1 arg throw - REQUIRE_THROWS(proxy.Call("voltagename", {"2", "3", "bname"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powername", {"2", "3", "bname"}, -1, PUT)); // invalid index - REQUIRE_THROWS(proxy.Call("voltagename", {"5", "bname"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powername", {"5", "bname"}, -1, PUT)); { std::ostringstream oss; - REQUIRE_NOTHROW(proxy.Call( - "voltagename", {str_voltage_index, "bname"}, -1, PUT, oss)); + REQUIRE_NOTHROW(proxy.Call("powername", {str_power_index, "bname"}, + -1, PUT, oss)); } { std::ostringstream oss; REQUIRE_NOTHROW( - proxy.Call("voltagename", {str_voltage_index}, -1, GET, oss)); - REQUIRE(oss.str() == std::string("voltagename ") + - str_voltage_index + " bname\n"); + proxy.Call("powername", {str_power_index}, -1, GET, oss)); + REQUIRE(oss.str() == + std::string("powername ") + str_power_index + " bname\n"); } - det.setVoltageName(ind, prev); + det.setPowerName(ind, prev); } else { - REQUIRE_THROWS(proxy.Call("voltagename", {"2", "b"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("voltagename", {"2"}, -1, GET)); + REQUIRE_THROWS(proxy.Call("powername", {"2", "b"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powername", {"2"}, -1, GET)); } } -TEST_CASE("voltageindex", "[.cmd]") { +TEST_CASE("powerindex", "[.cmd]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { defs::dacIndex ind = static_cast(2 + defs::V_POWER_A); - std::string str_voltage_index = "2"; + std::string str_power_index = "2"; // 1 arg throw - REQUIRE_THROWS(proxy.Call("voltageindex", {"2", "2"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("powerindex", {"2", "2"}, -1, PUT)); // invalid index - REQUIRE_THROWS(proxy.Call("voltageindex", {"5"}, -1, PUT)); - auto voltagename = det.getVoltageName(ind); + REQUIRE_THROWS(proxy.Call("powerindex", {"5"}, -1, PUT)); + auto powername = det.getPowerName(ind); { std::ostringstream oss; REQUIRE_NOTHROW( - proxy.Call("voltageindex", {voltagename}, -1, GET, oss)); + proxy.Call("powerindex", {powername}, -1, GET, oss)); REQUIRE(oss.str() == - std::string("voltageindex ") + str_voltage_index + '\n'); + std::string("powerindex ") + str_power_index + '\n'); } } else { - REQUIRE_THROWS(proxy.Call("voltageindex", {"2"}, -1, GET)); + REQUIRE_THROWS(proxy.Call("powerindex", {"2"}, -1, GET)); } } -TEST_CASE("voltagevalues", "[.cmd]") { +TEST_CASE("powervalues", "[.cmd]") { Detector det; CmdProxy proxy(&det); - REQUIRE_NOTHROW(proxy.Call("voltagevalues", {}, -1, GET)); - REQUIRE_THROWS(proxy.Call("voltagevalues", {}, -1, PUT)); + REQUIRE_NOTHROW(proxy.Call("powervalues", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("powervalues", {}, -1, PUT)); } TEST_CASE("slowadcvalues", "[.cmd]") { @@ -733,7 +733,7 @@ TEST_CASE("v_limit", "[.cmd]") { auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev_val = det.getVoltage(defs::V_LIMIT); + auto prev_val = det.getPower(defs::V_LIMIT); { std::ostringstream oss; proxy.Call("v_limit", {"1500"}, -1, PUT, oss); @@ -758,7 +758,7 @@ TEST_CASE("v_limit", "[.cmd]") { if (prev_val[i] == -100) { prev_val[i] = 0; } - det.setVoltage(defs::V_LIMIT, prev_val[i], {i}); + det.setPower(defs::V_LIMIT, prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("v_limit", {}, -1, GET)); @@ -1006,7 +1006,7 @@ TEST_CASE("v_a", "[.cmd]") { CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev_val = det.getVoltage(defs::V_POWER_A); + auto prev_val = det.getPower(defs::V_POWER_A); { std::ostringstream oss1, oss2; proxy.Call("v_a", {"700"}, -1, PUT, oss1); @@ -1015,7 +1015,7 @@ TEST_CASE("v_a", "[.cmd]") { REQUIRE(oss2.str() == "v_a 700\n"); } for (int i = 0; i != det.size(); ++i) { - det.setVoltage(defs::V_POWER_A, prev_val[i], {i}); + det.setPower(defs::V_POWER_A, prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("v_a", {}, -1, GET)); @@ -1027,7 +1027,7 @@ TEST_CASE("v_b", "[.cmd]") { CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev_val = det.getVoltage(defs::V_POWER_B); + auto prev_val = det.getPower(defs::V_POWER_B); { std::ostringstream oss1, oss2; proxy.Call("v_b", {"700"}, -1, PUT, oss1); @@ -1036,7 +1036,7 @@ TEST_CASE("v_b", "[.cmd]") { REQUIRE(oss2.str() == "v_b 700\n"); } for (int i = 0; i != det.size(); ++i) { - det.setVoltage(defs::V_POWER_B, prev_val[i], {i}); + det.setPower(defs::V_POWER_B, prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("v_b", {}, -1, GET)); @@ -1048,7 +1048,7 @@ TEST_CASE("v_c", "[.cmd]") { CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev_val = det.getVoltage(defs::V_POWER_C); + auto prev_val = det.getPower(defs::V_POWER_C); { std::ostringstream oss1, oss2; proxy.Call("v_c", {"700"}, -1, PUT, oss1); @@ -1057,7 +1057,7 @@ TEST_CASE("v_c", "[.cmd]") { REQUIRE(oss2.str() == "v_c 700\n"); } for (int i = 0; i != det.size(); ++i) { - det.setVoltage(defs::V_POWER_C, prev_val[i], {i}); + det.setPower(defs::V_POWER_C, prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("v_c", {}, -1, GET)); @@ -1069,7 +1069,7 @@ TEST_CASE("v_d", "[.cmd]") { CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::CHIPTESTBOARD) { - auto prev_val = det.getVoltage(defs::V_POWER_D); + auto prev_val = det.getPower(defs::V_POWER_D); { std::ostringstream oss1, oss2; proxy.Call("v_d", {"700"}, -1, PUT, oss1); @@ -1078,7 +1078,7 @@ TEST_CASE("v_d", "[.cmd]") { REQUIRE(oss2.str() == "v_d 700\n"); } for (int i = 0; i != det.size(); ++i) { - det.setVoltage(defs::V_POWER_D, prev_val[i], {i}); + det.setPower(defs::V_POWER_D, prev_val[i], {i}); } } else { REQUIRE_THROWS(proxy.Call("v_d", {}, -1, GET)); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-global.cpp b/slsDetectorSoftware/tests/test-CmdProxy-global.cpp index e89c38aef..fd92bc162 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-global.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-global.cpp @@ -11,6 +11,26 @@ namespace sls { using test::GET; using test::PUT; +void test_valid_port(const std::string &command, + const std::vector &arguments, int detector_id, + int action) { + Detector det; + CmdProxy proxy(&det); + + std::vector arg(arguments); + if (arg.empty()) + arg.push_back("0"); + + int test_values[3] = {77797, -1, 0}; + for (int i = 0; i != 3; ++i) { + int port_number = test_values[i]; + arg[arg.size() - 1] = std::to_string(port_number); + REQUIRE_THROWS(proxy.Call(command, arg, detector_id, action)); + /*REQUIRE_THROWS_WITH(proxy.Call(command, arguments, detector_id, + action), "Invalid port range. Must be between 1 - 65535.");*/ + } +} + void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) { Detector det; CmdProxy proxy(&det); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-global.h b/slsDetectorSoftware/tests/test-CmdProxy-global.h index ab869529b..164fbbc8a 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-global.h +++ b/slsDetectorSoftware/tests/test-CmdProxy-global.h @@ -5,6 +5,10 @@ namespace sls { +void test_valid_port(const std::string &command, + const std::vector &arguments, int detector_id, + int action); + void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue); void test_onchip_dac(slsDetectorDefs::dacIndex index, diff --git a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp index af81fd7df..f069a6f5d 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp @@ -506,6 +506,161 @@ TEST_CASE("filtercells", "[.cmd]") { } } +TEST_CASE("pedestalmode", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU) { + auto prev_val = det.getPedestalMode(); + auto prev_frames = det.getNumberOfFrames().tsquash( + "Inconsistent number of frames to test"); + auto prev_triggers = det.getNumberOfTriggers().tsquash( + "Inconsistent number of triggers to test"); + auto prev_timingmode = + det.getTimingMode().tsquash("Inconsistent timing mode to test"); + + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {}, 0, GET)); + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"0"}, -1, GET)); + + REQUIRE_THROWS(proxy.Call("pedestalmode", {"256", "10"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"-1", "10"}, 0, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"20", "65536"}, 0, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"20", "-1"}, 0, PUT)); + + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"30", "1000"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [30, 1000]\n"); + } + // cannot change any of these in pedestal mode + REQUIRE_THROWS_WITH(proxy.Call("frames", {"200"}, -1, PUT), + "Detector returned: Cannot set frames in pedestal " + "mode. It is overwritten anyway.\n"); + REQUIRE_THROWS_WITH(proxy.Call("triggers", {"200"}, -1, PUT), + "Detector returned: Cannot set triggers in " + "pedestal mode. It is overwritten anyway.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("timing", {"auto"}, -1, PUT), + "Detector returned: Cannot set timing mode in pedestal mode. " + "Switch off pedestal mode to change timing mode.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("scan", {"vb_comp", "500", "1500", "10"}, -1, PUT), + "Detector returned: Cannot set scan when in pedestal mode.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("scan", {"0"}, -1, PUT), + "Detector returned: Cannot set scan when in pedestal mode.\n"); + // should not throw to get these values though + REQUIRE_NOTHROW(proxy.Call("frames", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("triggers", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("timing", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("scan", {}, -1, GET)); + + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"50", "500"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [50, 500]\n"); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "pedestalmode [enabled, 50, 500]\n"); + } + { + auto pedemode = det.getPedestalMode().tsquash( + "Inconsistent pedestal mode to test"); + REQUIRE(pedemode.enable == true); + REQUIRE(pedemode.frames == 50); + REQUIRE(pedemode.loops == 500); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [0]\n"); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "pedestalmode [disabled]\n"); + } + + uint8_t pedestalFrames = 50; + uint16_t pedestalLoops = 1000; + int64_t expNumFrames = pedestalFrames * pedestalLoops * 2; + auto origFrames = det.getNumberOfFrames().squash(-1); + auto origTriggers = det.getNumberOfTriggers().squash(-1); + + // auto mode + det.setTimingMode(defs::AUTO_TIMING); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + auto numTriggers = det.getNumberOfTriggers().squash(-1); + auto numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == expNumFrames); + REQUIRE(numTriggers == 1); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + // trigger mode (frames > 1) + REQUIRE_NOTHROW(det.setTimingMode(defs::TRIGGER_EXPOSURE)); + origFrames = 5; + REQUIRE_NOTHROW(det.setNumberOfFrames(origFrames)); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == expNumFrames); + REQUIRE(numTriggers == 1); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + // trigger mode (frames = 1) + origFrames = 1; + REQUIRE_NOTHROW(det.setNumberOfFrames(origFrames)); + origTriggers = 10; + REQUIRE_NOTHROW(det.setNumberOfTriggers(origTriggers)); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == 1); + REQUIRE(numTriggers == expNumFrames); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + det.setNumberOfFrames(prev_frames); + det.setNumberOfTriggers(prev_triggers); + det.setTimingMode(prev_timingmode); + for (int i = 0; i != det.size(); ++i) { + det.setPedestalMode(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("pedestalmode", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + } +} + TEST_CASE("sync", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp index 3e57da61d..364335450 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-rx.cpp @@ -5,6 +5,7 @@ #include "sls/Detector.h" #include "sls/Version.h" #include "sls/sls_detector_defs.h" +#include "test-CmdProxy-global.h" #include #include "sls/versionAPI.h" @@ -223,7 +224,7 @@ TEST_CASE("rx_tcpport", "[.cmd][.rx]") { CmdProxy proxy(&det); auto prev_val = det.getRxPort(); - int port = 3500; + uint16_t port = 3500; proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT); for (int i = 0; i != det.size(); ++i) { std::ostringstream oss; @@ -237,6 +238,22 @@ TEST_CASE("rx_tcpport", "[.cmd][.rx]") { proxy.Call("rx_tcpport", {}, i, GET, oss); REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); } + + test_valid_port("rx_tcpport", {}, -1, PUT); + test_valid_port("rx_tcpport", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("rx_tcpport", {"65535"}, -1, PUT)); + auto rxHostname = det.getRxHostname().squash("none"); + if (rxHostname != "none") { + std::ostringstream oss; + for (int i = 0; i != det.size(); ++i) { + oss << rxHostname << ":" << 65536 + i << "+"; + } + REQUIRE_THROWS(proxy.Call("rx_hostname", {oss.str()}, -1, PUT)); + } + } + for (int i = 0; i != det.size(); ++i) { det.setRxPort(prev_val[i], i); } @@ -810,7 +827,7 @@ TEST_CASE("rx_zmqport", "[.cmd][.rx]") { proxy.Call("numinterfaces", {"2"}, -1, PUT); socketsperdetector *= 2; } - int port = 3500; + uint16_t port = 3500; proxy.Call("rx_zmqport", {std::to_string(port)}, -1, PUT); for (int i = 0; i != det.size(); ++i) { std::ostringstream oss; @@ -828,6 +845,14 @@ TEST_CASE("rx_zmqport", "[.cmd][.rx]") { std::to_string(port + i * socketsperdetector) + '\n'); } + + test_valid_port("rx_zmqport", {}, -1, PUT); + test_valid_port("rx_zmqport", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("rx_zmqport", {"65535"}, -1, PUT)); + } + for (int i = 0; i != det.size(); ++i) { det.setRxZmqPort(prev_val_zmqport[i], i); } diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index c52353805..6e819ecd9 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -5,6 +5,7 @@ #include "sls/Detector.h" #include "sls/file_utils.h" #include "sls/sls_detector_defs.h" +#include "test-CmdProxy-global.h" #include #include @@ -76,7 +77,13 @@ TEST_CASE("hostname", "[.cmd]") { REQUIRE_NOTHROW(proxy.Call("hostname", {}, -1, GET)); } -// virtual: not testing +TEST_CASE("virtual", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_THROWS(proxy.Call("virtual", {}, -1, GET)); + test_valid_port("virtual", {"1"}, -1, PUT); + REQUIRE_THROWS(proxy.Call("virtual", {"3", "65534"}, -1, PUT)); +} TEST_CASE("versions", "[.cmd]") { Detector det; @@ -2693,6 +2700,12 @@ TEST_CASE("udp_dstport", "[.cmd]") { proxy.Call("udp_dstport", {"50084"}, -1, PUT, oss); REQUIRE(oss.str() == "udp_dstport 50084\n"); } + test_valid_port("udp_dstport", {}, -1, PUT); + test_valid_port("udp_dstport", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("udp_dstport", {"65535"}, -1, PUT)); + } for (int i = 0; i != det.size(); ++i) { det.setDestinationUDPPort(prev_val[i], {i}); } @@ -2781,8 +2794,18 @@ TEST_CASE("udp_dstport2", "[.cmd]") { proxy.Call("udp_dstport2", {"50084"}, -1, PUT, oss); REQUIRE(oss.str() == "udp_dstport2 50084\n"); } + + test_valid_port("udp_dstport2", {}, -1, PUT); + test_valid_port("udp_dstport2", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("udp_dstport2", {"65535"}, -1, PUT)); + } + for (int i = 0; i != det.size(); ++i) { - det.setDestinationUDPPort2(prev_val[i], {i}); + if (prev_val[i] != 0) { + det.setDestinationUDPPort2(prev_val[i], {i}); + } } } else { REQUIRE_THROWS(proxy.Call("udp_dstport2", {}, -1, GET)); @@ -2976,7 +2999,7 @@ TEST_CASE("zmqport", "[.cmd]") { det.setNumberofUDPInterfaces(2); socketsperdetector *= 2; } - int port = 3500; + uint16_t port = 3500; auto port_str = std::to_string(port); { std::ostringstream oss; @@ -3005,6 +3028,12 @@ TEST_CASE("zmqport", "[.cmd]") { std::to_string(port + i * socketsperdetector) + '\n'); } + test_valid_port("zmqport", {}, -1, PUT); + test_valid_port("zmqport", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("zmqport", {"65535"}, -1, PUT)); + } if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH) { det.setNumberofUDPInterfaces(prev); } @@ -3384,6 +3413,12 @@ TEST_CASE("port", "[.cmd]") { proxy.Call("port", {}, 0, GET, oss); REQUIRE(oss.str() == "port 1942\n"); } + test_valid_port("port", {}, -1, PUT); + test_valid_port("port", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("port", {"65536"}, -1, PUT)); + } det.setControlPort(prev_val, {0}); } @@ -3401,6 +3436,12 @@ TEST_CASE("stopport", "[.cmd]") { proxy.Call("stopport", {}, 0, GET, oss); REQUIRE(oss.str() == "stopport 1942\n"); } + test_valid_port("stopport", {}, -1, PUT); + test_valid_port("stopport", {}, 0, PUT); + // should fail for the second module + if (det.size() > 1) { + REQUIRE_THROWS(proxy.Call("stopport", {"65536"}, -1, PUT)); + } det.setStopPort(prev_val, {0}); } diff --git a/slsDetectorSoftware/tests/test-CtbConfig.cpp b/slsDetectorSoftware/tests/test-CtbConfig.cpp index 9b75f94c4..a6b83691c 100644 --- a/slsDetectorSoftware/tests/test-CtbConfig.cpp +++ b/slsDetectorSoftware/tests/test-CtbConfig.cpp @@ -26,7 +26,7 @@ TEST_CASE("Default construction") { REQUIRE(adcnames[1] == "ADC1"); REQUIRE(adcnames[2] == "ADC2"); REQUIRE(adcnames[3] == "ADC3"); - auto powernames = c.getVoltageNames(); + auto powernames = c.getPowerNames(); REQUIRE(powernames.size() == 5); REQUIRE(powernames[0] == "VA"); REQUIRE(powernames[1] == "VB"); diff --git a/slsReceiverSoftware/include/sls/Receiver.h b/slsReceiverSoftware/include/sls/Receiver.h index a7af073bd..cbeccd29a 100644 --- a/slsReceiverSoftware/include/sls/Receiver.h +++ b/slsReceiverSoftware/include/sls/Receiver.h @@ -28,7 +28,7 @@ class Receiver : private virtual slsDetectorDefs { * throws an exception in case of failure * @param tcpip_port_no TCP/IP port number */ - Receiver(int tcpip_port_no = 1954); + Receiver(uint16_t tcpip_port_no = 1954); ~Receiver(); diff --git a/slsReceiverSoftware/src/BinaryDataFile.cpp b/slsReceiverSoftware/src/BinaryDataFile.cpp index d170532ab..4f5b90f4d 100644 --- a/slsReceiverSoftware/src/BinaryDataFile.cpp +++ b/slsReceiverSoftware/src/BinaryDataFile.cpp @@ -23,7 +23,7 @@ void BinaryDataFile::CreateFirstBinaryDataFile(const std::string &fNamePrefix, const uint64_t fIndex, const bool ovEnable, const bool sMode, - const uint32_t uPortNumber, + const uint16_t uPortNumber, const uint32_t mFramesPerFile) { subFileIndex = 0; diff --git a/slsReceiverSoftware/src/BinaryDataFile.h b/slsReceiverSoftware/src/BinaryDataFile.h index a6e9bcbdb..79daffa61 100644 --- a/slsReceiverSoftware/src/BinaryDataFile.h +++ b/slsReceiverSoftware/src/BinaryDataFile.h @@ -16,7 +16,7 @@ class BinaryDataFile : private virtual slsDetectorDefs, public File { void CloseFile() override; void CreateFirstBinaryDataFile(const std::string &fNamePrefix, const uint64_t fIndex, const bool ovEnable, - const bool sMode, const uint32_t uPortNumber, + const bool sMode, const uint16_t uPortNumber, const uint32_t mFramesPerFile) override; void WriteToFile(char *imageData, sls_receiver_header &header, diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 9f328ff68..24942d6a5 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -41,10 +41,9 @@ ClientInterface::~ClientInterface() { tcpThread->join(); } -ClientInterface::ClientInterface(int portNumber) - : detType(GOTTHARD), - portNumber(portNumber > 0 ? portNumber : DEFAULT_TCP_RX_PORTNO), - server(portNumber) { +ClientInterface::ClientInterface(uint16_t portNumber) + : detType(GOTTHARD), portNumber(portNumber), server(portNumber) { + validatePortNumber(portNumber); functionTable(); parentThreadId = gettid(); tcpThread = @@ -1064,9 +1063,12 @@ int ClientInterface::get_file_format(Interface &socket) { } int ClientInterface::set_streaming_port(Interface &socket) { - auto port = socket.Receive(); - if (port < 0) { - throw RuntimeError("Invalid zmq port " + std::to_string(port)); + auto port = socket.Receive(); + try { + validatePortNumber(port); + } catch (...) { + throw RuntimeError( + "Could not set streaming (zmq) port number. Invalid value."); } verifyIdle(socket); impl()->setStreamingPort(port); @@ -1074,7 +1076,7 @@ int ClientInterface::set_streaming_port(Interface &socket) { } int ClientInterface::get_streaming_port(Interface &socket) { - int retval = impl()->getStreamingPort(); + uint16_t retval = impl()->getStreamingPort(); LOG(logDEBUG1) << "streaming port:" << retval; return socket.sendResult(retval); } @@ -1449,7 +1451,7 @@ int ClientInterface::set_udp_ip2(Interface &socket) { } int ClientInterface::set_udp_port(Interface &socket) { - auto arg = socket.Receive(); + auto arg = socket.Receive(); verifyIdle(socket); LOG(logDEBUG1) << "Setting UDP Port:" << arg; impl()->setUDPPortNumber(arg); @@ -1457,7 +1459,7 @@ int ClientInterface::set_udp_port(Interface &socket) { } int ClientInterface::set_udp_port2(Interface &socket) { - auto arg = socket.Receive(); + auto arg = socket.Receive(); verifyIdle(socket); if (detType != JUNGFRAU && detType != MOENCH && detType != EIGER && detType != GOTTHARD2) { diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index e9b496617..89b4ce7d6 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -17,7 +17,7 @@ class ServerInterface; class ClientInterface : private virtual slsDetectorDefs { enum numberMode { DEC, HEX }; detectorType detType; - int portNumber{0}; + uint16_t portNumber{0}; ServerSocket server; std::unique_ptr receiver; std::unique_ptr tcpThread; @@ -29,7 +29,7 @@ class ClientInterface : private virtual slsDetectorDefs { public: virtual ~ClientInterface(); - ClientInterface(int portNumber = -1); + ClientInterface(uint16_t portNumber = DEFAULT_TCP_RX_PORTNO); std::string getReceiverVersion(); //***callback functions*** diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 71acdb03f..000c2ad85 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -127,7 +127,7 @@ void DataProcessor::CreateFirstFiles(const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, - const uint32_t udpPortNumber, + const uint16_t udpPortNumber, const uint64_t numImages, const bool detectorDataStream) { if (dataFile == nullptr) { diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 198d557e6..af8af6d17 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -56,7 +56,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void CreateFirstFiles(const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, - const bool silentMode, const uint32_t udpPortNumber, + const bool silentMode, const uint16_t udpPortNumber, const uint64_t numImages, const bool detectorDataStream); #ifdef HDF5C diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 6eb833aea..a645246cd 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -84,8 +84,8 @@ void DataStreamer::RecordFirstIndex(uint64_t fnum, size_t firstImageIndex) { << ", First Streamer Index:" << fnum; } -void DataStreamer::CreateZmqSockets(uint32_t port, const IpAddr ip, int hwm) { - uint32_t portnum = port + index; +void DataStreamer::CreateZmqSockets(uint16_t port, const IpAddr ip, int hwm) { + uint16_t portnum = port + index; std::string sip = ip.str(); try { zmqSocket = new ZmqSocket(portnum, (ip != 0 ? sip.c_str() : nullptr)); diff --git a/slsReceiverSoftware/src/DataStreamer.h b/slsReceiverSoftware/src/DataStreamer.h index 6f3fbb7d3..2e6f931af 100644 --- a/slsReceiverSoftware/src/DataStreamer.h +++ b/slsReceiverSoftware/src/DataStreamer.h @@ -48,7 +48,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { * @param ip streaming source ip * @param hwm streaming high water mark */ - void CreateZmqSockets(uint32_t port, const IpAddr ip, int hwm); + void CreateZmqSockets(uint16_t port, const IpAddr ip, int hwm); void CloseZmqSocket(); void RestreamStop(); diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index b578c36db..c30a86238 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -58,7 +58,7 @@ class File : private virtual slsDetectorDefs { virtual void CreateFirstHDF5DataFile( const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, - const uint32_t udpPortNumber, const uint32_t maxFramesPerFile, + const uint16_t udpPortNumber, const uint32_t maxFramesPerFile, const uint64_t numImages, const uint32_t nPixelsX, const uint32_t nPixelsY, const uint32_t dynamicRange) { LOG(logERROR) @@ -70,7 +70,7 @@ class File : private virtual slsDetectorDefs { const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, - const uint32_t udpPortNumber, + const uint16_t udpPortNumber, const uint32_t maxFramesPerFile) { LOG(logERROR) << "This is a generic function CreateFirstBinaryDataFile that " diff --git a/slsReceiverSoftware/src/HDF5DataFile.cpp b/slsReceiverSoftware/src/HDF5DataFile.cpp index faae336b6..9e4d48e9e 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.cpp +++ b/slsReceiverSoftware/src/HDF5DataFile.cpp @@ -88,7 +88,7 @@ void HDF5DataFile::CloseFile() { void HDF5DataFile::CreateFirstHDF5DataFile( const std::string &fNamePrefix, const uint64_t fIndex, const bool owEnable, - const bool sMode, const uint32_t uPortNumber, const uint32_t mFramesPerFile, + const bool sMode, const uint16_t uPortNumber, const uint32_t mFramesPerFile, const uint64_t nImages, const uint32_t nX, const uint32_t nY, const uint32_t dr) { diff --git a/slsReceiverSoftware/src/HDF5DataFile.h b/slsReceiverSoftware/src/HDF5DataFile.h index c8eaef937..e3a7b19b3 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.h +++ b/slsReceiverSoftware/src/HDF5DataFile.h @@ -25,7 +25,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { void CreateFirstHDF5DataFile(const std::string &fNamePrefix, const uint64_t fIndex, const bool owEnable, - const bool sMode, const uint32_t uPortNumber, + const bool sMode, const uint16_t uPortNumber, const uint32_t mFramesPerFile, const uint64_t nImages, const uint32_t nX, const uint32_t nY, const uint32_t dr) override; @@ -69,7 +69,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { uint64_t fileIndex{0}; bool overWriteEnable{false}; bool silentMode{false}; - uint32_t udpPortNumber{0}; + uint16_t udpPortNumber{0}; static const int EIGER_NUM_PIXELS{256 * 2 * 256}; static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 5548fc685..ad3613798 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -1140,17 +1140,17 @@ void Implementation::setEthernetInterface2(const std::string &c) { LOG(logINFO) << "Ethernet Interface 2: " << eth[1]; } -uint32_t Implementation::getUDPPortNumber() const { return udpPortNum[0]; } +uint16_t Implementation::getUDPPortNumber() const { return udpPortNum[0]; } -void Implementation::setUDPPortNumber(const uint32_t i) { +void Implementation::setUDPPortNumber(const uint16_t i) { udpPortNum[0] = i; listener[0]->SetUdpPortNumber(i); LOG(logINFO) << "UDP Port Number[0]: " << udpPortNum[0]; } -uint32_t Implementation::getUDPPortNumber2() const { return udpPortNum[1]; } +uint16_t Implementation::getUDPPortNumber2() const { return udpPortNum[1]; } -void Implementation::setUDPPortNumber2(const uint32_t i) { +void Implementation::setUDPPortNumber2(const uint16_t i) { udpPortNum[1] = i; if (listener.size() > 1) { listener[1]->SetUdpPortNumber(i); @@ -1251,9 +1251,9 @@ void Implementation::setStreamingStartingFrameNumber(const uint32_t fnum) { LOG(logINFO) << "Streaming Start Frame num: " << streamingStartFnum; } -uint32_t Implementation::getStreamingPort() const { return streamingPort; } +uint16_t Implementation::getStreamingPort() const { return streamingPort; } -void Implementation::setStreamingPort(const uint32_t i) { +void Implementation::setStreamingPort(const uint16_t i) { streamingPort = i; LOG(logINFO) << "Streaming Port: " << streamingPort; } diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 0e00d131a..7c41a91e6 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -117,11 +117,11 @@ class Implementation : private virtual slsDetectorDefs { std::string getEthernetInterface2() const; /* [Jungfrau][Moench] */ void setEthernetInterface2(const std::string &c); - uint32_t getUDPPortNumber() const; - void setUDPPortNumber(const uint32_t i); - uint32_t getUDPPortNumber2() const; + uint16_t getUDPPortNumber() const; + void setUDPPortNumber(const uint16_t i); + uint16_t getUDPPortNumber2() const; /* [Eiger][Jungfrau][Moench] */ - void setUDPPortNumber2(const uint32_t i); + void setUDPPortNumber2(const uint16_t i); int getUDPSocketBufferSize() const; void setUDPSocketBufferSize(const int s); int getActualUDPSocketBufferSize() const; @@ -140,8 +140,8 @@ class Implementation : private virtual slsDetectorDefs { void setStreamingTimer(const uint32_t time_in_ms); uint32_t getStreamingStartingFrameNumber() const; void setStreamingStartingFrameNumber(const uint32_t fnum); - uint32_t getStreamingPort() const; - void setStreamingPort(const uint32_t i); + uint16_t getStreamingPort() const; + void setStreamingPort(const uint16_t i); IpAddr getStreamingSourceIP() const; void setStreamingSourceIP(const IpAddr ip); int getStreamingHwm() const; @@ -336,7 +336,7 @@ class Implementation : private virtual slsDetectorDefs { // network configuration (UDP) std::array eth; - std::array udpPortNum{ + std::array udpPortNum{ {DEFAULT_UDP_DST_PORTNO, DEFAULT_UDP_DST_PORTNO + 1}}; int actualUDPSocketBufferSize{0}; @@ -345,7 +345,7 @@ class Implementation : private virtual slsDetectorDefs { uint32_t streamingFrequency{1}; uint32_t streamingTimerInMs{DEFAULT_STREAMING_TIMER_IN_MS}; uint32_t streamingStartFnum{0}; - uint32_t streamingPort{0}; + uint16_t streamingPort{0}; IpAddr streamingSrcIP = IpAddr{}; int streamingHwm{-1}; std::map additionalJsonHeader; diff --git a/slsReceiverSoftware/src/Listener.cpp b/slsReceiverSoftware/src/Listener.cpp index bb5a9a0c6..f1cb897df 100644 --- a/slsReceiverSoftware/src/Listener.cpp +++ b/slsReceiverSoftware/src/Listener.cpp @@ -71,7 +71,7 @@ void Listener::SetFifo(Fifo *f) { fifo = f; } void Listener::SetGeneralData(GeneralData *g) { generalData = g; } -void Listener::SetUdpPortNumber(const uint32_t portNumber) { +void Listener::SetUdpPortNumber(const uint16_t portNumber) { udpPortNumber = portNumber; } diff --git a/slsReceiverSoftware/src/Listener.h b/slsReceiverSoftware/src/Listener.h index 9b78ec95a..91e3d9cd9 100644 --- a/slsReceiverSoftware/src/Listener.h +++ b/slsReceiverSoftware/src/Listener.h @@ -39,7 +39,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject { void SetFifo(Fifo *f); void SetGeneralData(GeneralData *g); - void SetUdpPortNumber(const uint32_t portNumber); + void SetUdpPortNumber(const uint16_t portNumber); void SetEthernetInterface(const std::string e); void SetActivate(bool enable); void SetDetectorDatastream(bool enable); @@ -112,7 +112,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject { std::atomic *status; std::unique_ptr udpSocket{nullptr}; - uint32_t udpPortNumber{0}; + uint16_t udpPortNumber{0}; std::string eth; bool activated{false}; bool detectorDataStream{true}; diff --git a/slsReceiverSoftware/src/MultiReceiverApp.cpp b/slsReceiverSoftware/src/MultiReceiverApp.cpp index e1cf19832..b9ac35eab 100644 --- a/slsReceiverSoftware/src/MultiReceiverApp.cpp +++ b/slsReceiverSoftware/src/MultiReceiverApp.cpp @@ -3,6 +3,7 @@ /* Creates the slsMultiReceiver for running multiple receivers form a single * binary */ #include "sls/Receiver.h" +#include "sls/ToString.h" #include "sls/container_utils.h" #include "sls/logger.h" #include "sls/sls_detector_defs.h" @@ -36,14 +37,12 @@ void sigInterruptHandler(int p) { sem_post(&semaphore); } /** * prints usage of this example program */ -void printHelp() { - cprintf( - RESET, - "Usage:\n" - "./slsMultiReceiver(detReceiver) [start_tcp_port] " - "[num_receivers] [optional: 1 for call back (print frame header for " - "debugging), 0 for none (default)]\n\n"); - exit(EXIT_FAILURE); +std::string getHelpMessage() { + return std::string( + "\n\nUsage:\n" + "./slsMultiReceiver(detReceiver) [start_tcp_port (non-zero and 16 " + "bit)] [num_receivers] [optional: 1 for call back (print frame header " + "for debugging), 0 for none (default)]\n\n"); } /** @@ -140,25 +139,31 @@ int main(int argc, char *argv[]) { /** - set default values */ int numReceivers = 1; - int startTCPPort = 1954; + uint16_t startTCPPort = 1954; int withCallback = 0; sem_init(&semaphore, 1, 0); /** - get number of receivers and start tcp port from command line * arguments */ - if (argc != 3 && argc != 4) - printHelp(); - if ((argc == 3) && ((!sscanf(argv[1], "%d", &startTCPPort)) || - (!sscanf(argv[2], "%d", &numReceivers)))) - printHelp(); - if ((argc == 4) && ((!sscanf(argv[1], "%d", &startTCPPort)) || - (!sscanf(argv[2], "%d", &numReceivers)) || - (!sscanf(argv[3], "%d", &withCallback)))) - printHelp(); + try { + if (argc == 3 || argc == 4) { + startTCPPort = sls::StringTo(argv[1]); + if (startTCPPort == 0) { + throw; + } + numReceivers = std::stoi(argv[2]); + if (argc == 4) { + withCallback = std::stoi(argv[3]); + } + } else + throw; + } catch (...) { + throw std::runtime_error(getHelpMessage()); + } cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n", (long)gettid()); cprintf(RESET, "Number of Receivers: %d\n", numReceivers); - cprintf(RESET, "Start TCP Port: %d\n", startTCPPort); + cprintf(RESET, "Start TCP Port: %hu\n", startTCPPort); cprintf(RESET, "Callback Enable: %d\n", withCallback); /** - Catch signal SIGINT to close files and call destructors properly */ diff --git a/slsReceiverSoftware/src/Receiver.cpp b/slsReceiverSoftware/src/Receiver.cpp index 892448983..bff6757e0 100644 --- a/slsReceiverSoftware/src/Receiver.cpp +++ b/slsReceiverSoftware/src/Receiver.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package #include "sls/Receiver.h" #include "ClientInterface.h" +#include "sls/ToString.h" #include "sls/container_utils.h" #include "sls/logger.h" #include "sls/sls_detector_exceptions.h" @@ -29,7 +30,7 @@ Receiver::~Receiver() = default; Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) { // options - int tcpip_port_no = 1954; + uint16_t tcpip_port_no = 1954; uid_t userid = -1; // parse command line for config @@ -51,6 +52,15 @@ Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) { int option_index = 0; int c = 0; + std::string help_message = + "\nUsage: " + std::string(argv[0]) + " [arguments]\n" + + "Possible arguments are:\n" + + "\t-t, --rx_tcpport : TCP Communication Port with " + "client. Non-zero and 16 bit.\n" + + "\t-u, --uid : Set effective user id if receiver " + "\n" + + "\t started with privileges. \n\n"; + while (c != -1) { c = getopt_long(argc, argv, "hvf:t:u:", long_options, &option_index); @@ -61,12 +71,18 @@ Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) { switch (c) { case 't': - sscanf(optarg, "%d", &tcpip_port_no); + try { + tcpip_port_no = sls::StringTo(optarg); + validatePortNumber(tcpip_port_no); + } catch (...) { + throw RuntimeError("Could not scan TCP port number." + + help_message); + } break; case 'u': if (sscanf(optarg, "%u", &userid) != 1) { - throw RuntimeError("Could not scan uid"); + throw RuntimeError("Could not scan uid" + help_message); } break; @@ -76,19 +92,9 @@ Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) { exit(EXIT_SUCCESS); case 'h': + std::cout << help_message << std::endl; + exit(EXIT_SUCCESS); default: - std::cout << std::endl; - - std::string help_message = - "Usage: " + std::string(argv[0]) + " [arguments]\n" + - "Possible arguments are:\n" + - "\t-t, --rx_tcpport : TCP Communication Port with " - "client. \n" + - "\t-u, --uid : Set effective user id if receiver " - "\n" + - "\t started with privileges. \n\n"; - - // std::cout << help_message << std::endl; throw RuntimeError(help_message); } } @@ -118,7 +124,7 @@ Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) { tcpipInterface = make_unique(tcpip_port_no); } -Receiver::Receiver(int tcpip_port_no) { +Receiver::Receiver(uint16_t tcpip_port_no) { // might throw an exception tcpipInterface = make_unique(tcpip_port_no); } diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index bfeb09fd9..efef1161c 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -58,6 +58,9 @@ std::ostream &operator<<(std::ostream &os, std::string ToString(const slsDetectorDefs::currentSrcParameters &r); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::currentSrcParameters &r); +std::string ToString(const slsDetectorDefs::pedestalParameters &r); +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::pedestalParameters &r); const std::string &ToString(const std::string &s); /** Convert std::chrono::duration with specified output unit */ @@ -316,6 +319,8 @@ template <> defs::vetoAlgorithm StringTo(const std::string &s); template <> defs::gainMode StringTo(const std::string &s); template <> defs::polarity StringTo(const std::string &s); +template <> uint8_t StringTo(const std::string &s); +template <> uint16_t StringTo(const std::string &s); template <> uint32_t StringTo(const std::string &s); template <> uint64_t StringTo(const std::string &s); template <> int StringTo(const std::string &s); diff --git a/slsSupportLib/include/sls/UdpRxSocket.h b/slsSupportLib/include/sls/UdpRxSocket.h index a982ed471..1ee1b3554 100644 --- a/slsSupportLib/include/sls/UdpRxSocket.h +++ b/slsSupportLib/include/sls/UdpRxSocket.h @@ -7,6 +7,7 @@ UDP socket class to receive data. The intended use is in the receiver listener loop. Should be used RAII style... */ +#include #include //ssize_t namespace sls { @@ -15,8 +16,8 @@ class UdpRxSocket { int sockfd_{-1}; public: - UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr, - int kernel_buffer_size = 0); + UdpRxSocket(uint16_t port, ssize_t packet_size, + const char *hostname = nullptr, int kernel_buffer_size = 0); ~UdpRxSocket(); bool ReceivePacket(char *dst) noexcept; int getBufferSize() const; diff --git a/slsSupportLib/include/sls/ZmqSocket.h b/slsSupportLib/include/sls/ZmqSocket.h index 7baa6defd..679cb7f20 100644 --- a/slsSupportLib/include/sls/ZmqSocket.h +++ b/slsSupportLib/include/sls/ZmqSocket.h @@ -103,7 +103,7 @@ class ZmqSocket { * @param hostname_or_ip hostname or ip of server * @param portnumber port number */ - ZmqSocket(const char *const hostname_or_ip, const uint32_t portnumber); + ZmqSocket(const char *const hostname_or_ip, const uint16_t portnumber); /** * Constructor for a server @@ -111,7 +111,7 @@ class ZmqSocket { * @param portnumber port number * @param ethip is the ip of the ethernet interface to stream zmq from */ - ZmqSocket(const uint32_t portnumber, const char *ethip); + ZmqSocket(const uint16_t portnumber, const char *ethip); /** Returns high water mark for outbound messages */ int GetSendHighWaterMark(); @@ -143,7 +143,7 @@ class ZmqSocket { * Returns Port Number * @returns Port Number */ - uint32_t GetPortNumber() { return portno; } + uint16_t GetPortNumber() { return portno; } /** * Returns Server Address @@ -251,7 +251,7 @@ class ZmqSocket { }; /** Port Number */ - uint32_t portno; + uint16_t portno; /** Socket descriptor */ mySocketDescriptors sockfd; diff --git a/slsSupportLib/include/sls/network_utils.h b/slsSupportLib/include/sls/network_utils.h index e0e48c416..cce2c429d 100644 --- a/slsSupportLib/include/sls/network_utils.h +++ b/slsSupportLib/include/sls/network_utils.h @@ -64,8 +64,8 @@ class MacAddr { struct UdpDestination { uint32_t entry{}; - uint32_t port{}; - uint32_t port2{}; + uint16_t port{}; + uint16_t port2{}; IpAddr ip; IpAddr ip2; MacAddr mac; @@ -88,5 +88,6 @@ IpAddr HostnameToIp(const char *hostname); std::string IpToInterfaceName(const std::string &ip); MacAddr InterfaceNameToMac(const std::string &inf); IpAddr InterfaceNameToIp(const std::string &ifn); - +void validatePortNumber(uint16_t port); +void validatePortRange(uint16_t startPort, int numPorts); } // namespace sls diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 506614497..a90890a90 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -30,8 +30,8 @@ // C includes #include #endif -//Need macros for C compatibility -//NOLINTBEGIN(cppcoreguidelines-macro-usage) +// Need macros for C compatibility +// NOLINTBEGIN(cppcoreguidelines-macro-usage) #define BIT32_MASK 0xFFFFFFFF #define MAX_RX_DBIT 64 @@ -80,7 +80,7 @@ #define DEFAULT_STREAMING_TIMER_IN_MS 500 #define NUM_RX_THREAD_IDS 9 -//NOLINTEND(cppcoreguidelines-macro-usage) +// NOLINTEND(cppcoreguidelines-macro-usage) #ifdef __cplusplus class slsDetectorDefs { public: @@ -547,6 +547,29 @@ enum streamingInterface { } } __attribute__((packed)); + struct pedestalParameters { + int enable; + uint8_t frames; + uint16_t loops; + + /** [Jungfrau] disable */ + pedestalParameters() : enable(0), frames(0), loops(0) {} + + /** [Jungfrau] enable */ + pedestalParameters(uint8_t pedestalFrames, uint16_t pedestalLoops) + : enable(1), frames(pedestalFrames), loops(pedestalLoops) { + if (frames == 0 || loops == 0) { + throw sls::RuntimeError( + "Pedestal frames or loops cannot be 0."); + } + } + + bool operator==(const pedestalParameters &other) const { + return ((enable == other.enable) && (frames == other.frames) && + (loops == other.loops)); + } + } __attribute__((packed)); + /** * structure to udpate receiver */ @@ -556,10 +579,10 @@ enum streamingInterface { int moduleIndex{0}; char hostname[MAX_STR_LENGTH]; int udpInterfaces{1}; - int udp_dstport{0}; + uint16_t udp_dstport{0}; uint32_t udp_dstip{0U}; uint64_t udp_dstmac{0LU}; - int udp_dstport2{0}; + uint16_t udp_dstport2{0}; uint32_t udp_dstip2{0U}; uint64_t udp_dstmac2{0LU}; int64_t frames{0}; diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index d9005d08e..b0b6de884 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -290,6 +290,8 @@ enum detFuncs { F_SET_ROW, F_GET_COLUMN, F_SET_COLUMN, + F_GET_PEDESTAL_MODE, + F_SET_PEDESTAL_MODE, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 512, /**< detector function should not exceed this @@ -687,6 +689,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_ROW: return "F_SET_ROW"; case F_GET_COLUMN: return "F_GET_COLUMN"; case F_SET_COLUMN: return "F_SET_COLUMN"; + case F_GET_PEDESTAL_MODE: return "F_GET_PEDESTAL_MODE"; + case F_SET_PEDESTAL_MODE: return "F_SET_PEDESTAL_MODE"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/sls/string_utils.h b/slsSupportLib/include/sls/string_utils.h index b27f298d3..eec1a0c08 100644 --- a/slsSupportLib/include/sls/string_utils.h +++ b/slsSupportLib/include/sls/string_utils.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include #include @@ -60,6 +61,6 @@ bool is_int(const std::string &s); bool replace_first(std::string *s, const std::string &substr, const std::string &repl); -std::pair ParseHostPort(const std::string &s); +std::pair ParseHostPort(const std::string &s); } // namespace sls diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index e7ce03cff..d830030bf 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -4,10 +4,10 @@ #define RELEASE "developer" #define APILIB "developer 0x230224" #define APIRECEIVER "developer 0x230224" -#define APIEIGER "developer 0x230525" -#define APIGOTTHARD "developer 0x230615" -#define APIGOTTHARD2 "developer 0x230615" -#define APIMYTHEN3 "developer 0x230621" -#define APIJUNGFRAU "developer 0x230720" -#define APIMOENCH "developer 0x230725" -#define APICTB "developer 0x230720" +#define APICTB "developer 0x230922" +#define APIGOTTHARD "developer 0x230922" +#define APIGOTTHARD2 "developer 0x230922" +#define APIMYTHEN3 "developer 0x230922" +#define APIMOENCH "developer 0x230922" +#define APIEIGER "developer 0x230922" +#define APIJUNGFRAU "developer 0x230928" diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 763cdccd7..66206fe16 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -155,6 +155,23 @@ std::ostream &operator<<(std::ostream &os, return os << ToString(r); } +std::string ToString(const slsDetectorDefs::pedestalParameters &r) { + std::ostringstream oss; + oss << '['; + if (r.enable) + oss << "enabled, " << std::to_string(r.frames) << ", " << r.loops; + else + oss << "disabled"; + + oss << ']'; + return oss.str(); +} + +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::pedestalParameters &r) { + return os << ToString(r); +} + std::string ToString(const defs::runStatus s) { switch (s) { case defs::ERROR: @@ -1083,6 +1100,28 @@ template <> defs::polarity StringTo(const std::string &s) { throw RuntimeError("Unknown polarity mode " + s); } +template <> uint8_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + int value = std::stoi(s, nullptr, base); + if (value < std::numeric_limits::min() || + value > std::numeric_limits::max()) { + throw RuntimeError("Cannot scan uint8_t from string '" + s + + "'. Value must be in range 0 - 255."); + } + return static_cast(value); +} + +template <> uint16_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + int value = std::stoi(s, nullptr, base); + if (value < std::numeric_limits::min() || + value > std::numeric_limits::max()) { + throw RuntimeError("Cannot scan uint16_t from string '" + s + + "'. Value must be in range 0 - 65535."); + } + return static_cast(value); +} + template <> uint32_t StringTo(const std::string &s) { int base = s.find("0x") != std::string::npos ? 16 : 10; return std::stoul(s, nullptr, base); diff --git a/slsSupportLib/src/UdpRxSocket.cpp b/slsSupportLib/src/UdpRxSocket.cpp index 1ef7b2d7c..2cb8c079c 100644 --- a/slsSupportLib/src/UdpRxSocket.cpp +++ b/slsSupportLib/src/UdpRxSocket.cpp @@ -15,8 +15,8 @@ namespace sls { -UdpRxSocket::UdpRxSocket(int port, ssize_t packet_size, const char *hostname, - int kernel_buffer_size) +UdpRxSocket::UdpRxSocket(uint16_t port, ssize_t packet_size, + const char *hostname, int kernel_buffer_size) : packet_size_(packet_size) { struct addrinfo hints {}; hints.ai_family = AF_UNSPEC; diff --git a/slsSupportLib/src/ZmqSocket.cpp b/slsSupportLib/src/ZmqSocket.cpp index f0ed37fba..2ab6e583f 100644 --- a/slsSupportLib/src/ZmqSocket.cpp +++ b/slsSupportLib/src/ZmqSocket.cpp @@ -15,7 +15,7 @@ namespace sls { using namespace rapidjson; ZmqSocket::ZmqSocket(const char *const hostname_or_ip, - const uint32_t portnumber) + const uint16_t portnumber) : portno(portnumber), sockfd(false) { // Extra check that throws if conversion fails, could be removed auto ipstr = HostnameToIp(hostname_or_ip).str(); @@ -55,7 +55,7 @@ ZmqSocket::ZmqSocket(const char *const hostname_or_ip, << GetReceiveHighWaterMark(); } -ZmqSocket::ZmqSocket(const uint32_t portnumber, const char *ethip) +ZmqSocket::ZmqSocket(const uint16_t portnumber, const char *ethip) : portno(portnumber), sockfd(true) { // create context sockfd.contextDescriptor = zmq_ctx_new(); @@ -289,24 +289,24 @@ int ZmqSocket::ReceiveHeader(const int index, zmqHeader &zHeader, header_buffer.get(), MAX_STR_LENGTH, 0); if (bytes_received > 0) { #ifdef ZMQ_DETAIL - cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno, + cprintf(BLUE, "Header %d [%hu] Length: %d Header:%s \n", index, portno, bytes_received, header_buffer.get()); #endif if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader, version)) { #ifdef ZMQ_DETAIL - cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index, - portno, bytes_received, header_buffer.get()); + cprintf(RED, "Parsed Header %d [%hu] Length: %d Header:%s \n", + index, portno, bytes_received, header_buffer.get()); #endif if (!zHeader.data) { #ifdef ZMQ_DETAIL - cprintf(RED, "%d [%d] Received end of acquisition\n", index, + cprintf(RED, "%d [%hu] Received end of acquisition\n", index, portno); #endif return 0; } #ifdef ZMQ_DETAIL - cprintf(GREEN, "%d [%d] data\n", index, portno); + cprintf(GREEN, "%d [%hu] data\n", index, portno); #endif return 1; } diff --git a/slsSupportLib/src/network_utils.cpp b/slsSupportLib/src/network_utils.cpp index 3a44b6fef..423e9825a 100644 --- a/slsSupportLib/src/network_utils.cpp +++ b/slsSupportLib/src/network_utils.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -203,4 +204,18 @@ MacAddr InterfaceNameToMac(const std::string &inf) { return MacAddr(mac); } +void validatePortNumber(uint16_t port) { + // random local port. might work if internal = bad practise + if (port == 0) { + throw RuntimeError("Invalid port number. Must be between 1 - 65535."); + } +} + +void validatePortRange(uint16_t startPort, int numPorts) { + validatePortNumber(startPort); + if ((startPort + numPorts) > std::numeric_limits::max()) { + throw RuntimeError("Invalid port range. Must be between 1 - 65535."); + } +} + } // namespace sls diff --git a/slsSupportLib/src/string_utils.cpp b/slsSupportLib/src/string_utils.cpp index 5f60ff7ab..0ed191685 100644 --- a/slsSupportLib/src/string_utils.cpp +++ b/slsSupportLib/src/string_utils.cpp @@ -4,9 +4,12 @@ #include "sls/string_utils.h" #include "sls/container_utils.h" #include "sls/network_utils.h" + #include #include +#include #include + namespace sls { std::vector split(const std::string &strToSplit, char delimeter) { @@ -50,15 +53,15 @@ bool replace_first(std::string *s, const std::string &substr, return false; } -std::pair ParseHostPort(const std::string &s) { +std::pair ParseHostPort(const std::string &s) { // TODO deal with to many :, port not there? // no port return hostname as is and port as 0 std::string host; - int port{0}; + uint16_t port{0}; auto res = split(s, ':'); host = res[0]; if (res.size() > 1) { - port = std::stoi(res[1]); + port = StringTo(res[1]); } return std::make_pair(host, port); } diff --git a/slsSupportLib/tests/test-ZmqSocket.cpp b/slsSupportLib/tests/test-ZmqSocket.cpp index 513bc1392..8dba7fc8b 100644 --- a/slsSupportLib/tests/test-ZmqSocket.cpp +++ b/slsSupportLib/tests/test-ZmqSocket.cpp @@ -6,7 +6,7 @@ namespace sls { TEST_CASE("Throws when cannot create socket") { - REQUIRE_THROWS(ZmqSocket("sdiasodjajpvv", 5076001)); + REQUIRE_THROWS(ZmqSocket("sdiasodjajpvv", 50001)); } TEST_CASE("Get port number for sub") { diff --git a/slsSupportLib/tests/test-network_utils.cpp b/slsSupportLib/tests/test-network_utils.cpp index b5beab9b3..0828cef56 100644 --- a/slsSupportLib/tests/test-network_utils.cpp +++ b/slsSupportLib/tests/test-network_utils.cpp @@ -115,7 +115,7 @@ TEST_CASE("Copy construct a MacAddr") { } TEST_CASE("udp dst struct basic properties") { - static_assert(sizeof(UdpDestination) == 36, + static_assert(sizeof(UdpDestination) == 32, "udpDestination struct size does not match"); UdpDestination dst{}; REQUIRE(dst.entry == 0);