From 7b865f0ee19fc21464d574b7f273c1c08b8b2d7a Mon Sep 17 00:00:00 2001 From: Mohacsi Istvan Date: Fri, 28 Jun 2024 13:34:25 +0200 Subject: [PATCH] Lot of code quality improvements --- tomcat_bec/devices/gigafrost/gfutils.py | 16 ++++++------- .../devices/gigafrost/gigafrostclient.py | 13 +++++++---- tomcat_bec/devices/gigafrost/readme.md | 5 +++- tomcat_bec/devices/gigafrost/stddaq_ws.py | 23 +++++++++++-------- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/tomcat_bec/devices/gigafrost/gfutils.py b/tomcat_bec/devices/gigafrost/gfutils.py index 1ecb4e8..b905aa9 100644 --- a/tomcat_bec/devices/gigafrost/gfutils.py +++ b/tomcat_bec/devices/gigafrost/gfutils.py @@ -87,18 +87,18 @@ def print_max_framerate(exposure_ms=_min_exposure_ms, shape="square"): if shape not in valid_shapes: raise ValueError("shape must be one of %s" % valid_shapes) if shape == "square": - for r in valid_roix: - _print_max_framerate(exposure_ms, r, r) + for px_r in valid_roix: + _print_max_framerate(exposure_ms, px_r, px_r) if shape == "portrait": - for x in valid_roix: - _print_max_framerate(exposure_ms, roix=x, roiy=_max_roiy) + for px_x in valid_roix: + _print_max_framerate(exposure_ms, roix=px_x, roiy=_max_roiy) if shape == "landscape": # valid_roix is a subset of valid_roiy. # Use the smaller set to get a more manageable amount of output lines - for y in valid_roix: - _print_max_framerate(exposure_ms, roix=_max_roix, roiy=y) + for px_y in valid_roix: + _print_max_framerate(exposure_ms, roix=_max_roix, roiy=px_y) def max_framerate_hz(exposure_ms=_min_exposure_ms, roix=_max_roix, roiy=_max_roiy, clk_mhz=62.5): @@ -224,10 +224,10 @@ layoutSchema = { } -def validateJson(jsonData): +def validate_json(json_data): """Silently validate a JSON data according to the predefined schema""" try: - jsonschema.validate(instance=jsonData, schema=layoutSchema) + jsonschema.validate(instance=json_data, schema=layoutSchema) except jsonschema.exceptions.ValidationError: return False return True diff --git a/tomcat_bec/devices/gigafrost/gigafrostclient.py b/tomcat_bec/devices/gigafrost/gigafrostclient.py index d33a5dc..122d715 100644 --- a/tomcat_bec/devices/gigafrost/gigafrostclient.py +++ b/tomcat_bec/devices/gigafrost/gigafrostclient.py @@ -31,6 +31,10 @@ class GigaFrostClient(Device): backend_url : str Backend url address necessary to set up the camera's udp header. (default: http://xbl-daq-23:8080) + + Bugs: + ---------- + FRAMERATE : Ignored in soft trigger mode, period becomes 2xexposure time """ # pylint: disable=too-many-instance-attributes @@ -281,7 +285,7 @@ class GigaFrostClient(Device): exposure : float, optional Exposure time [ms]. (default = 0.2) period : float, optional - Exposure period [ms]. (default = 1.0) + Exposure period [ms], ignored in soft trigger mode. (default = 1.0) roix : int, optional ROI size in the x-direction [pixels] (default = 2016) roiy : int, optional @@ -394,7 +398,7 @@ class GigaFrostClient(Device): """ if exp_mode not in self._valid_exposure_modes: raise ValueError( - "Invalid exposure mode! Valid modes are:\n" "{}".format(self._valid_exposure_modes) + f"Invalid exposure mode! Valid modes are:\n" "{self._valid_exposure_modes}" ) if exp_mode == "external": @@ -502,7 +506,7 @@ class GigaFrostClient(Device): """ if mode not in self._valid_trigger_modes: raise ValueError( - "Invalid trigger mode! Valid modes are:\n" "{}".format(self._valid_trigger_modes) + "Invalid trigger mode! Valid modes are:\n" "{self._valid_trigger_modes}" ) if mode == "auto": @@ -563,7 +567,7 @@ class GigaFrostClient(Device): """ if mode not in self._valid_enable_modes: raise ValueError( - "Invalid enable mode! Valid modes are:\n" "{}".format(self._valid_enable_modes) + "Invalid enable mode! Valid modes are:\n" "{self._valid_enable_modes}" ) if mode == "soft": @@ -601,6 +605,7 @@ class GigaFrostClient(Device): return self._south_ip def get_backend_url(self): + """Method to read the configured backend URL""" return self._backend_url def set_backend_ip(self, north, south): diff --git a/tomcat_bec/devices/gigafrost/readme.md b/tomcat_bec/devices/gigafrost/readme.md index 0a5e996..6dc4982 100644 --- a/tomcat_bec/devices/gigafrost/readme.md +++ b/tomcat_bec/devices/gigafrost/readme.md @@ -1,9 +1,12 @@ +# Gifgafrost camera at Tomcat +The GigaFrost camera IOC is a form from an ancient version of Helge's cameras. +As we're commissioning, the current folder also contains the standard DAQ client. # Opening GigaFrost panel - +The CaQtDM panel can be opened by: ''' caqtdm -macro "CAM=X02DA-CAM-GF2" X_X02DA_GIGAFROST_camControl_user.ui & ''' diff --git a/tomcat_bec/devices/gigafrost/stddaq_ws.py b/tomcat_bec/devices/gigafrost/stddaq_ws.py index 19474d2..a2f12a0 100644 --- a/tomcat_bec/devices/gigafrost/stddaq_ws.py +++ b/tomcat_bec/devices/gigafrost/stddaq_ws.py @@ -40,12 +40,17 @@ class StdDaqWsClient(Device): super().__init__(*args, parent=parent, **kwargs) self.status._metadata["write_access"] = False self._ws_url = url + self._mon = None # Connect ro the DAQ self.connect() def connect(self): - # StdDAQ may reject connection for a few seconds + """Connect to te StDAQs websockets interface + + StdDAQ may reject connection for a few seconds, so if it fails, wait + a bit and try to connect again. + """ try: self._client = connect(self._ws_url) except ConnectionRefusedError: @@ -104,8 +109,8 @@ class StdDaqWsClient(Device): f"Start command rejected (might be already running): {reply['reason']}" ) - self.t = Thread(target=self.poll) - self.t.start() + self._mon = Thread(target=self.poll) + self._mon.start() return super().stage() def unstage(self): @@ -114,10 +119,10 @@ class StdDaqWsClient(Device): WARN: This will also close the connection!!! """ message = {"command": "stop"} - self.message(message, wait_reply=False) + _ = self.message(message, wait_reply=False) return super().unstage() - def stop(self, *, success=False): + def stop(self): """ Stop a running acquisition WARN: This will also close the connection!!! @@ -126,16 +131,16 @@ class StdDaqWsClient(Device): # The poller thread locks recv raising a RuntimeError self.message(message, wait_reply=False) - def message(self, d: dict, timeout=1, wait_reply=True): + def message(self, message: dict, timeout=1, wait_reply=True): """Send a message to the StdDAQ and receive a reply Note: finishing acquisition meang StdDAQ will close connections so there's no idle state polling. """ - if isinstance(d, dict): - msg = json.dumps(d) + if isinstance(message, dict): + msg = json.dumps(message) else: - msg = str(d) + msg = str(message) # Send message (reopen connection if needed) try: