From f3476f4024e3fe4a8529df8f4c23fca8bce58566 Mon Sep 17 00:00:00 2001 From: fedem-p Date: Wed, 16 Mar 2022 14:56:46 +0100 Subject: [PATCH 1/7] Enforcing abstract class, methods and properties --- sashimi/hardware/cameras/interface.py | 27 ++++++++++++++----- .../hardware/external_trigger/interface.py | 4 ++- sashimi/hardware/light_source/interface.py | 13 ++++++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/sashimi/hardware/cameras/interface.py b/sashimi/hardware/cameras/interface.py index 716adb5e..d63b6900 100644 --- a/sashimi/hardware/cameras/interface.py +++ b/sashimi/hardware/cameras/interface.py @@ -1,5 +1,5 @@ from enum import Enum - +from abc import ABC, abstractmethod class CameraException(Exception): pass @@ -14,11 +14,12 @@ class TriggerMode(Enum): EXTERNAL_TRIGGER = 2 -class AbstractCamera: +class AbstractCamera(ABC): def __init__(self, camera_id, max_sensor_resolution=None): self.camera_id = camera_id self.max_sensor_resolution = max_sensor_resolution - + + @abstractmethod def get_frames(self): """ Returns a list of arrays, each of which corresponds to an available frame. If no frames where found returns an @@ -26,18 +27,21 @@ def get_frames(self): """ pass + @abstractmethod def start_acquisition(self): """ Allocate as many frames as will fit in 2GB of memory and start data acquisition. """ pass + @abstractmethod def stop_acquisition(self): """ Stop data acquisition and release the memory allocated for frames. """ pass + @abstractmethod def shutdown(self): """ Close down the connection to the camera. @@ -45,38 +49,47 @@ def shutdown(self): self.stop_acquisition() @property + @abstractmethod def exposure_time(self): return None - + @exposure_time.setter + @abstractmethod def exposure_time(self, exp_val): pass - + @property + @abstractmethod def binning(self): return None @binning.setter + @abstractmethod def binning(self, exp_val): pass - + @property + @abstractmethod def roi(self): return None @roi.setter + @abstractmethod def roi(self, exp_val: tuple): pass - + @property + @abstractmethod def trigger_mode(self): return None @trigger_mode.setter + @abstractmethod def trigger_mode(self, exp_val): pass @property + @abstractmethod def frame_rate(self): return None diff --git a/sashimi/hardware/external_trigger/interface.py b/sashimi/hardware/external_trigger/interface.py index 503f62bd..b8f8dbd0 100644 --- a/sashimi/hardware/external_trigger/interface.py +++ b/sashimi/hardware/external_trigger/interface.py @@ -1,9 +1,11 @@ from typing import Optional +from abc import ABC, abstractmethod -class AbstractComm: +class AbstractComm(ABC): def __init__(self, address): self.address = address + @abstractmethod def trigger_and_receive_duration(self, config) -> Optional[float]: return None diff --git a/sashimi/hardware/light_source/interface.py b/sashimi/hardware/light_source/interface.py index 3c9d3b18..507dd838 100644 --- a/sashimi/hardware/light_source/interface.py +++ b/sashimi/hardware/light_source/interface.py @@ -1,4 +1,5 @@ from enum import Enum +from abc import ABC, abstractmethod class LaserState(Enum): @@ -14,34 +15,40 @@ class LaserWarning(Warning): pass -class AbstractLightSource: +class AbstractLightSource(ABC): def __init__(self, port): self.port = port self._status = LaserState.OFF self.intensity_units = None - def start(self): + def start(self): #TODO: remove? pass - + + @abstractmethod def set_power(self, current): """Sets power of laser based on self.intensity and self.intensity_units""" pass + @abstractmethod def close(self): pass @property + @abstractmethod def intensity(self): return None @intensity.setter + @abstractmethod def intensity(self, exp_val): pass @property + @abstractmethod def status(self): return self._status @status.setter + @abstractmethod def status(self, exp_val): pass From cc910a7f720b0b76e5642ed805685b95eb0f6c64 Mon Sep 17 00:00:00 2001 From: fedem-p Date: Wed, 16 Mar 2022 14:58:14 +0100 Subject: [PATCH 2/7] added implementation of abstract met + property --- sashimi/hardware/cameras/mock.py | 26 +++++++++++++++++++++++++ sashimi/hardware/light_source/cobolt.py | 4 ++++ sashimi/hardware/light_source/mock.py | 9 +++++++++ 3 files changed, 39 insertions(+) diff --git a/sashimi/hardware/cameras/mock.py b/sashimi/hardware/cameras/mock.py index af4bd05b..cb2f1a24 100644 --- a/sashimi/hardware/cameras/mock.py +++ b/sashimi/hardware/cameras/mock.py @@ -52,6 +52,14 @@ def roi(self): def roi(self, exp_val: tuple): self._roi = exp_val self.prepare_mock_image() + + @property + def trigger_mode(self): + return None + + @trigger_mode.setter + def trigger_mode(self, exp_val): + pass def prepare_mock_image(self): self.current_mock_image = block_reduce( @@ -76,3 +84,21 @@ def get_frames(self): else: self.previous_frame_time = self.current_time return frames + + def start_acquisition(self): + """ + Allocate as many frames as will fit in 2GB of memory and start data acquisition. + """ + pass + + def stop_acquisition(self): + """ + Stop data acquisition and release the memory allocated for frames. + """ + pass + + def shutdown(self): + """ + Close down the connection to the camera. + """ + self.stop_acquisition() \ No newline at end of file diff --git a/sashimi/hardware/light_source/cobolt.py b/sashimi/hardware/light_source/cobolt.py index aa3b997b..0e3baf6f 100644 --- a/sashimi/hardware/light_source/cobolt.py +++ b/sashimi/hardware/light_source/cobolt.py @@ -54,6 +54,10 @@ def get_info(self): def close(self): self.socket.close() + + def set_power(self, current): + """Sets power of laser based on self.intensity and self.intensity_units""" + pass @property def intensity(self): diff --git a/sashimi/hardware/light_source/mock.py b/sashimi/hardware/light_source/mock.py index b12c7bdb..a73b565e 100644 --- a/sashimi/hardware/light_source/mock.py +++ b/sashimi/hardware/light_source/mock.py @@ -7,6 +7,13 @@ def __init__(self, port=None): self._current = 0 self.intensity_units = "mocks" + def set_power(self, current): + """Sets power of laser based on self.intensity and self.intensity_units""" + pass + + def close(self): + pass + @property def intensity(self): return self._current @@ -22,3 +29,5 @@ def status(self): @status.setter def status(self, exp_val): self._status = exp_val + + From a2ec5cccaa1adc05fb286381e8bba624adaa1db0 Mon Sep 17 00:00:00 2001 From: fedem-p Date: Fri, 18 Mar 2022 14:40:18 +0100 Subject: [PATCH 3/7] abstract scanning --- sashimi/hardware/scanning/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sashimi/hardware/scanning/__init__.py b/sashimi/hardware/scanning/__init__.py index 76e32824..1b4cb57d 100644 --- a/sashimi/hardware/scanning/__init__.py +++ b/sashimi/hardware/scanning/__init__.py @@ -1,11 +1,13 @@ +import abc from contextlib import contextmanager +from abc import ABC, abstractmethod class ScanningError(Exception): pass -class AbstractScanInterface: +class AbstractScanInterface(ABC): def __init__(self, sample_rate, n_samples, conf, *args, **kwargs): self.sample_rate = sample_rate self.n_samples = n_samples From 456456e339c93a25d0fb07c363525b9956af9407 Mon Sep 17 00:00:00 2001 From: fedem-p Date: Fri, 1 Apr 2022 15:01:03 +0200 Subject: [PATCH 4/7] removed redundant import --- sashimi/hardware/scanning/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sashimi/hardware/scanning/__init__.py b/sashimi/hardware/scanning/__init__.py index 1b4cb57d..62713bb9 100644 --- a/sashimi/hardware/scanning/__init__.py +++ b/sashimi/hardware/scanning/__init__.py @@ -1,4 +1,3 @@ -import abc from contextlib import contextmanager from abc import ABC, abstractmethod From dec701f5c4b9dbbff11c658a81e153d18aaf3f1b Mon Sep 17 00:00:00 2001 From: fedem-p Date: Fri, 1 Apr 2022 15:38:55 +0200 Subject: [PATCH 5/7] enforce abstract in scanning --- sashimi/hardware/scanning/__init__.py | 27 +++++++++++--- sashimi/hardware/scanning/mock.py | 52 ++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/sashimi/hardware/scanning/__init__.py b/sashimi/hardware/scanning/__init__.py index 62713bb9..1997b28a 100644 --- a/sashimi/hardware/scanning/__init__.py +++ b/sashimi/hardware/scanning/__init__.py @@ -12,62 +12,79 @@ def __init__(self, sample_rate, n_samples, conf, *args, **kwargs): self.n_samples = n_samples self.conf = conf + @abstractmethod def start(self): pass + + @abstractmethod + def write(self): + pass + + @abstractmethod + def read(self): + pass @property + @abstractmethod def z_piezo(self): return None @z_piezo.setter + @abstractmethod def z_piezo(self, waveform): pass @property + @abstractmethod def z_frontal(self): return None @z_frontal.setter + @abstractmethod def z_frontal(self, waveform): pass @property + @abstractmethod def z_lateral(self): return None @z_lateral.setter + @abstractmethod def z_lateral(self, waveform): pass @property + @abstractmethod def camera_trigger(self): return None @camera_trigger.setter + @abstractmethod def camera_trigger(self, waveform): pass @property + @abstractmethod def xy_frontal(self): return None @xy_frontal.setter + @abstractmethod def xy_frontal(self, waveform): pass @property + @abstractmethod def xy_lateral(self): return None @xy_lateral.setter + @abstractmethod def xy_lateral(self, waveform): pass - def write(self): - pass - - def read(self): - pass + @contextmanager diff --git a/sashimi/hardware/scanning/mock.py b/sashimi/hardware/scanning/mock.py index 18721a38..2a4d4fec 100644 --- a/sashimi/hardware/scanning/mock.py +++ b/sashimi/hardware/scanning/mock.py @@ -9,6 +9,16 @@ def __init__(self, sample_rate, n_samples, conf): super().__init__(sample_rate, n_samples, conf) self.piezo_array = np.zeros(n_samples) + def start(self): + pass + + def read(self): + sleep(0.05) + + def write(self): + sleep(0.05) + + @property def z_piezo(self): len_sampling = len(self.piezo_array) @@ -18,11 +28,45 @@ def z_piezo(self): def z_piezo(self, waveform): self.piezo_array[:] = waveform - def read(self): - sleep(0.05) + @property + def z_frontal(self): + return None - def write(self): - sleep(0.05) + @z_frontal.setter + def z_frontal(self, waveform): + pass + + @property + def z_lateral(self): + return None + + @z_lateral.setter + def z_lateral(self, waveform): + pass + + @property + def camera_trigger(self): + return None + + @camera_trigger.setter + def camera_trigger(self, waveform): + pass + + @property + def xy_frontal(self): + return None + + @xy_frontal.setter + def xy_frontal(self, waveform): + pass + + @property + def xy_lateral(self): + return None + + @xy_lateral.setter + def xy_lateral(self, waveform): + pass @contextmanager From dc6bb5f5de4ae0124e0448884c3a6dd70b088899 Mon Sep 17 00:00:00 2001 From: fedem-p Date: Fri, 1 Apr 2022 15:39:24 +0200 Subject: [PATCH 6/7] linting --- sashimi/hardware/cameras/interface.py | 11 ++++++----- sashimi/hardware/cameras/mock.py | 4 ++-- sashimi/hardware/light_source/cobolt.py | 2 +- sashimi/hardware/light_source/interface.py | 4 ++-- sashimi/hardware/light_source/mock.py | 6 ++---- sashimi/hardware/scanning/__init__.py | 4 +--- sashimi/hardware/scanning/mock.py | 3 +-- 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/sashimi/hardware/cameras/interface.py b/sashimi/hardware/cameras/interface.py index d63b6900..271bbe28 100644 --- a/sashimi/hardware/cameras/interface.py +++ b/sashimi/hardware/cameras/interface.py @@ -1,6 +1,7 @@ from enum import Enum from abc import ABC, abstractmethod + class CameraException(Exception): pass @@ -18,7 +19,7 @@ class AbstractCamera(ABC): def __init__(self, camera_id, max_sensor_resolution=None): self.camera_id = camera_id self.max_sensor_resolution = max_sensor_resolution - + @abstractmethod def get_frames(self): """ @@ -52,12 +53,12 @@ def shutdown(self): @abstractmethod def exposure_time(self): return None - + @exposure_time.setter @abstractmethod def exposure_time(self, exp_val): pass - + @property @abstractmethod def binning(self): @@ -67,7 +68,7 @@ def binning(self): @abstractmethod def binning(self, exp_val): pass - + @property @abstractmethod def roi(self): @@ -77,7 +78,7 @@ def roi(self): @abstractmethod def roi(self, exp_val: tuple): pass - + @property @abstractmethod def trigger_mode(self): diff --git a/sashimi/hardware/cameras/mock.py b/sashimi/hardware/cameras/mock.py index cb2f1a24..638996ae 100644 --- a/sashimi/hardware/cameras/mock.py +++ b/sashimi/hardware/cameras/mock.py @@ -52,7 +52,7 @@ def roi(self): def roi(self, exp_val: tuple): self._roi = exp_val self.prepare_mock_image() - + @property def trigger_mode(self): return None @@ -101,4 +101,4 @@ def shutdown(self): """ Close down the connection to the camera. """ - self.stop_acquisition() \ No newline at end of file + self.stop_acquisition() diff --git a/sashimi/hardware/light_source/cobolt.py b/sashimi/hardware/light_source/cobolt.py index 0e3baf6f..38b01584 100644 --- a/sashimi/hardware/light_source/cobolt.py +++ b/sashimi/hardware/light_source/cobolt.py @@ -54,7 +54,7 @@ def get_info(self): def close(self): self.socket.close() - + def set_power(self, current): """Sets power of laser based on self.intensity and self.intensity_units""" pass diff --git a/sashimi/hardware/light_source/interface.py b/sashimi/hardware/light_source/interface.py index 507dd838..433d2f4a 100644 --- a/sashimi/hardware/light_source/interface.py +++ b/sashimi/hardware/light_source/interface.py @@ -21,9 +21,9 @@ def __init__(self, port): self._status = LaserState.OFF self.intensity_units = None - def start(self): #TODO: remove? + def start(self): pass - + @abstractmethod def set_power(self, current): """Sets power of laser based on self.intensity and self.intensity_units""" diff --git a/sashimi/hardware/light_source/mock.py b/sashimi/hardware/light_source/mock.py index a73b565e..9444bb91 100644 --- a/sashimi/hardware/light_source/mock.py +++ b/sashimi/hardware/light_source/mock.py @@ -10,10 +10,10 @@ def __init__(self, port=None): def set_power(self, current): """Sets power of laser based on self.intensity and self.intensity_units""" pass - + def close(self): pass - + @property def intensity(self): return self._current @@ -29,5 +29,3 @@ def status(self): @status.setter def status(self, exp_val): self._status = exp_val - - diff --git a/sashimi/hardware/scanning/__init__.py b/sashimi/hardware/scanning/__init__.py index 1997b28a..946eb5f0 100644 --- a/sashimi/hardware/scanning/__init__.py +++ b/sashimi/hardware/scanning/__init__.py @@ -15,7 +15,7 @@ def __init__(self, sample_rate, n_samples, conf, *args, **kwargs): @abstractmethod def start(self): pass - + @abstractmethod def write(self): pass @@ -84,8 +84,6 @@ def xy_lateral(self): def xy_lateral(self, waveform): pass - - @contextmanager def open_abstract_interface(sample_rate, n_samples, conf) -> AbstractScanInterface: diff --git a/sashimi/hardware/scanning/mock.py b/sashimi/hardware/scanning/mock.py index 2a4d4fec..a12bd3b3 100644 --- a/sashimi/hardware/scanning/mock.py +++ b/sashimi/hardware/scanning/mock.py @@ -17,8 +17,7 @@ def read(self): def write(self): sleep(0.05) - - + @property def z_piezo(self): len_sampling = len(self.piezo_array) From b12209adbf98a76f730258225ee3c32ebf83edbe Mon Sep 17 00:00:00 2001 From: fedem-p Date: Wed, 6 Apr 2022 11:16:42 +0200 Subject: [PATCH 7/7] enforced abstract shutdown method non abstract --- sashimi/hardware/cameras/interface.py | 1 - sashimi/hardware/cameras/mock.py | 6 ------ 2 files changed, 7 deletions(-) diff --git a/sashimi/hardware/cameras/interface.py b/sashimi/hardware/cameras/interface.py index 271bbe28..1f4a3418 100644 --- a/sashimi/hardware/cameras/interface.py +++ b/sashimi/hardware/cameras/interface.py @@ -42,7 +42,6 @@ def stop_acquisition(self): """ pass - @abstractmethod def shutdown(self): """ Close down the connection to the camera. diff --git a/sashimi/hardware/cameras/mock.py b/sashimi/hardware/cameras/mock.py index 638996ae..d324d7ad 100644 --- a/sashimi/hardware/cameras/mock.py +++ b/sashimi/hardware/cameras/mock.py @@ -96,9 +96,3 @@ def stop_acquisition(self): Stop data acquisition and release the memory allocated for frames. """ pass - - def shutdown(self): - """ - Close down the connection to the camera. - """ - self.stop_acquisition()