From 82f4c043208e4097cfd228732e5827797c81171a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Fri, 22 May 2026 17:51:32 +0200 Subject: [PATCH 1/5] creating scmos from pylablib driver --- pyproject.toml | 1 + .../plugins_2D/daq_2Dviewer_AndorSCMOS_2.py | 293 ++++++++++++++++++ .../hardware/sdk3_utils.py | 42 +++ .../resources/config_template.toml | 2 + src/pymodaq_plugins_andor/utils.py | 2 +- 5 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py create mode 100644 src/pymodaq_plugins_andor/hardware/sdk3_utils.py diff --git a/pyproject.toml b/pyproject.toml index 9edb929..93007d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ name = "pymodaq_plugins_andor" description = 'Set of PyMoDAQ plugins for Andor Camera (CCD camera using SDK2, SCMOS cameras using SDK3...)' dependencies = [ "pymodaq>=5.0.0", + "pylablib", #todo: list here all dependencies your package may have ] diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py new file mode 100644 index 0000000..1f58263 --- /dev/null +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py @@ -0,0 +1,293 @@ +import platform +import sys +import os + +from easydict import EasyDict as edict +import numpy as np + +from time import perf_counter + +from qtpy import QtWidgets, QtCore + +from pymodaq_utils.utils import ThreadCommand, find_dict_in_list_from_key_val, zeros_aligned +from pymodaq_utils.logger import set_logger, get_module_name +from pymodaq_utils.config import GlobalConfig + +from pymodaq_gui.parameter.utils import iter_children +from pymodaq_gui.parameter import Parameter + +from pymodaq.control_modules.viewer_utility_classes import comon_parameters, main + + +from pymodaq_plugins_utils.hardware.camera_base_pylablib import CameraBasePyLabLib, cam_params + +from pylablib.devices.Andor import AndorSDK3Camera + +from pymodaq_plugins_andor.hardware.sdk3_utils import get_camera_names + +logger = set_logger(get_module_name(__file__)) +config = GlobalConfig() + +CAM_NAMES = get_camera_names() + + +cam_params.extend( + [ + {'title': 'Encoding:', 'name': 'encoding', 'type': 'list', 'limits': []}, + {'title': 'Readout time (ms):', 'name': 'readout_time', 'type': 'float', 'value': 0., 'readonly': True}, + {'title': 'Trigger Settings:', 'name': 'trigger', 'type': 'group', 'children': [ + {'title': 'Mode:', 'name': 'trigger_mode', 'type': 'list', 'limits': []}, + {'title': 'Software Trigger:', 'name': 'soft_trigger', 'type': 'bool_push', 'value': False, + 'label': 'Fire'}, + {'title': 'External Trigger delay (ms):', 'name': 'ext_trigger_delay', 'type': 'float', 'value': 0.}, + ]}, + + {'title': 'Shutter Settings:', 'name': 'shutter', 'type': 'group', 'children': [ + {'title': 'Mode:', 'name': 'shutter_mode', 'type': 'list', 'limits': []}, + {'title': 'External Trigger is:', 'name': 'shutter_on_ext_trigger', 'type': 'list', 'limits': []}, + ]}, + + {'title': 'Temperature Settings:', 'name': 'temperature_settings', 'type': 'group', 'children': [ + {'title': 'Enable Cooling:', 'name': 'enable_cooling', 'type': 'bool', 'value': True}, + {'title': 'Set Point:', 'name': 'set_point', 'type': 'float', 'value': 0.}, + {'title': 'Current value:', 'name': 'current_value', 'type': 'float', 'value': 20, 'readonly': True}, + {'title': 'Status:', 'name': 'status', 'type': 'list', 'limits': [], 'readonly': True}, + ]}, + ] +) + + +class DAQ_2DViewer_AndorSCMOS_2(CameraBasePyLabLib): + """ + Base class for Andor SCMOS camera + + + =============== ================== + **Attributes** **Type** + + =============== ================== + + See Also + -------- + utility_classes.DAQ_Viewer_base + """ + + hardware_averaging = True # will use the accumulate acquisition mode if averaging is neccessary + live_mode_available = True + + serial_params = [{'title': 'Camera:', 'name': 'serial_number', 'type': 'list', 'value': CAM_NAMES[0], + 'limits': CAM_NAMES}] + params = comon_parameters + serial_params + cam_params + + def ini_attributes(self): + super().ini_attributes() + self.controller: AndorSDK3Camera = None + + self.temperature_timer = QtCore.QTimer() + self.temperature_timer.timeout.connect(self.update_temperature) + + def commit_settings(self, param: Parameter): + """ + """ + super().commit_settings(param) + + if param.name() == 'set_point': + self.stop() + self.controller.set_temperature(param.value(), + self.settings['temperature_settings', 'enable_cooling']) + + elif param.name() == 'encoding': + self.controller.set_attribute_value('SimplePreAmpGainControl', param.value()) + + elif param.name() in iter_children(self.settings.child('shutter'), []): + self.set_shutter() + + elif param.name() in iter_children(self.settings.child('temperature_settings'), []): + self.setup_temperature() + + elif param.name() == 'soft_trigger': + if param.value(): + self.controller.set_trigger_mode('software') + param.setValue(False) + + elif param.name() in iter_children(self.settings.child('trigger'), []): + self.set_trigger() + + + def ini_detector_custom(self, controller=None): + """ + Initialisation procedure of the detector in four steps : + * Register callback to get data from camera + * Get image size and current binning + * Set and Get temperature from camera + * Init axes from image + + Returns + ------- + string list ??? + The initialized status. + + See Also + -------- + daq_utils.ThreadCommand, hardware1D.DAQ_1DViewer_Picoscope.update_pico_settings + """ + + ind_camera = self.settings.child('serial_number').opts['limits'].index(self.settings['serial_number']) + if self.is_master: + self.controller = AndorSDK3Camera(idx=ind_camera) + + self.setup_temperature() + + self.setup_trigger() + + self.setup_shutter() + + def update_fps(self): + self.settings.child('timing_opts', 'fps').setValue(self.controller.get_attribute_value('FrameRate')) + + def setup_temperature(self): + temp = self.controller.get_attribute('SensorTemperature') + temp_status = self.controller.get_attribute('TemperatureStatus') + self.settings.child('temperature_settings', 'status').setLimits(temp_status.values) + self.settings.child('temperature_settings', 'set_point').setLimits((temp.min, temp.max)) + enable = self.settings['temperature_settings', 'enable_cooling'] + self.controller.set_temperature(self.settings['temperature_settings', 'set_point'], enable) + + if not self.temperature_timer.isActive(): + self.temperature_timer.start(2000) # Timer event fired every 2s + + self.update_temperature() + + def update_temperature(self): + """ + update temperature status and value. Fired using the temperature_timer every 2s when not grabbing + """ + temp = self.controller.get_attribute_value('SensorTemperature') + status = self.controller.get_attribute_value('TemperatureStatus') + self.settings.child('temperature_settings', 'current_value').setValue(temp) + self.settings.child('temperature_settings', 'status').setValue(status) + + + def setup_trigger(self): + trigger_mode = self.controller.get_attribute('TriggerMode') + self.settings.child('trigger', + 'trigger_mode').setLimits(trigger_mode.values) + + ext_trigger_delay = self.controller.get_attribute('ExternalTriggerDelay') + self.settings.child('trigger', + 'ext_trigger_delay').setLimits((ext_trigger_delay.min, + ext_trigger_delay.max)) + self.set_trigger() + + def set_trigger(self): + self.controller.set_attribute_value('TriggerMode', + self.settings['trigger', 'trigger_mode']) + if 'External' in self.controller.get_attribute_value('TriggerMode'): + ext_trigger_delay = self.controller.get_attribute('ExternalTriggerDelay') + self.settings.child('trigger', + 'ext_trigger_delay').setLimits((ext_trigger_delay.min, + ext_trigger_delay.max)) + self.controller.set_attribute_value('ExternalTriggerDelay', + self.settings['trigger', 'ext_trigger_delay'] / 1000) + self.settings.child('camera_settings', + 'trigger', + 'ext_trigger_delay').setValue( + self.controller.get_attribute_value('ExternalTriggerDelay') * 1000) + + def setup_shutter(self): + modes = self.controller.get_attribute('ShutterMode').values + output_modes = self.controller.get_attribute('ShutterOutputMode').values + self.settings.child('shutter', 'shutter_mode').setOpts(limits=modes) + self.settings.child('shutter', 'shutter_on_ext_trigger').setOpts(limits=output_modes) + self.set_shutter() + + def set_shutter(self): + self.controller.set_attribute_value('ShutterMode', self.settings['shutter', 'shutter_mode']) + self.controller.set_attribute_value('ShutterOutputMode', + self.settings['shutter', 'shutter_on_ext_trigger']) + + def close(self): + """ + + """ + self.temperature_timer.stop() + QtWidgets.QApplication.processEvents() + if self.controller is not None: + self.stop() + self.controller.close() + + + def grab_data(self, Naverage=1, **kwargs): + """ + Start new acquisition in two steps : + * Initialize data: self.data for the memory to store new data and self.data_average to store the average data + * Start acquisition with the given exposure in ms, in "1d" or "2d" mode + + =============== =========== ============================= + **Parameters** **Type** **Description** + Naverage int Number of images to average + =============== =========== ============================= + + See Also + -------- + daq_utils.ThreadCommand + """ + + self.temperature_timer.stop() + super().grab_data(Naverage, **kwargs) + + def stop(self): + """ + stop the camera's actions. + """ + try: + if self.controller is not None: + if self.controller.acquisition_in_progress(): + self.controller.stop_acquisition() + QtWidgets.QApplication.processEvents() + self.temperature_timer.start(2000) + + except: + pass + return "" + + +class AndorCallback(QtCore.QObject): + """ + + """ + data_sig = QtCore.Signal(list) + + def __init__(self, wait_fn): + super().__init__() + self.wait_fn = wait_fn + self.running = False + + def start(self, naverage, wait_time=0): + self.running = True + + self.wait_for_acquisition(naverage, wait_time) + + def stop(self): + self.running = False + + def wait_for_acquisition(self, naverage, wait_time): + ind_grab = 0 + while True: + if naverage == -1: # continuous grab + if not self.running: + break + else: + if ind_grab >= naverage or not self.running: + break + pData = self.wait_fn() + if not not pData: + ind_grab += 1 + #print(f'ind_grab_thread:{ind_grab}') + self.data_sig.emit([pData]) + QtCore.QThread.msleep(wait_time) + + + +if __name__ == '__main__': + main(__file__, init=False) \ No newline at end of file diff --git a/src/pymodaq_plugins_andor/hardware/sdk3_utils.py b/src/pymodaq_plugins_andor/hardware/sdk3_utils.py new file mode 100644 index 0000000..e2e89ff --- /dev/null +++ b/src/pymodaq_plugins_andor/hardware/sdk3_utils.py @@ -0,0 +1,42 @@ + +from pymodaq_utils.config import GlobalConfig +from pymodaq_utils.logger import get_module_name, set_logger + + +from pylablib.devices.Andor import AndorSDK3Camera +from pylablib.devices import Andor + +import pylablib as pll + + +logger = set_logger(get_module_name(__file__)) +config = GlobalConfig() + + +if config('andor', 'sdk3', 'dll_path') is not "": + pll.par["devices/dlls/andor_sdk3"] = config('andor', 'sdk3', 'dll_path') + + +def get_camera_names(): + camera_list = [] + try: + n_camera = Andor.get_cameras_number_SDK3() + for ind_cam in range(n_camera): + try: + cam = AndorSDK3Camera(idx=ind_cam) + model = cam.get_attribute_value('CameraModel') + name = cam.get_attribute_value('CameraName') + serial_number = cam.get_attribute_value('SerialNumber') + camera_list.append(f'{model} {serial_number}') + except Exception as e: + pass + finally: + try: + cam.close() + except: + pass + except Exception as e: + logger.exception(f'Impossible to communicate with camera, try to set another library path in the preferences') + + return camera_list + diff --git a/src/pymodaq_plugins_andor/resources/config_template.toml b/src/pymodaq_plugins_andor/resources/config_template.toml index 63486c6..a05e6e9 100644 --- a/src/pymodaq_plugins_andor/resources/config_template.toml +++ b/src/pymodaq_plugins_andor/resources/config_template.toml @@ -1,2 +1,4 @@ title = 'this is the configuration file of the Andor plugin' +[sdk3] +dll_path = "" # in case the library cannot load properly try to add here the path to the sdk3 libraries \ No newline at end of file diff --git a/src/pymodaq_plugins_andor/utils.py b/src/pymodaq_plugins_andor/utils.py index 4981b95..3449bc3 100644 --- a/src/pymodaq_plugins_andor/utils.py +++ b/src/pymodaq_plugins_andor/utils.py @@ -6,7 +6,7 @@ """ from pathlib import Path -from pymodaq_utils.config import BaseConfig, USER +from pymodaq_utils.config import BaseConfig, USER, GlobalConfig class Config(BaseConfig): From c6002fbb22235460699903e8eea37f890eed8637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Tue, 26 May 2026 15:20:00 +0200 Subject: [PATCH 2/5] Update daq_2Dviewer_AndorSCMOS_2.py --- .../plugins_2D/daq_2Dviewer_AndorSCMOS_2.py | 40 ++----------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py index 1f58263..cd91373 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py @@ -19,9 +19,10 @@ from pymodaq.control_modules.viewer_utility_classes import comon_parameters, main -from pymodaq_plugins_utils.hardware.camera_base_pylablib import CameraBasePyLabLib, cam_params +from pymodaq_plugins_utils.hardware.camera_base_pylablib import ( + CameraBasePyLabLib, cam_params, CameraCallback) -from pylablib.devices.Andor import AndorSDK3Camera +from pylablib.devices.Andor import AndorSDK3Camera, AndorTimeoutError from pymodaq_plugins_andor.hardware.sdk3_utils import get_camera_names @@ -252,41 +253,6 @@ def stop(self): return "" -class AndorCallback(QtCore.QObject): - """ - - """ - data_sig = QtCore.Signal(list) - - def __init__(self, wait_fn): - super().__init__() - self.wait_fn = wait_fn - self.running = False - - def start(self, naverage, wait_time=0): - self.running = True - - self.wait_for_acquisition(naverage, wait_time) - - def stop(self): - self.running = False - - def wait_for_acquisition(self, naverage, wait_time): - ind_grab = 0 - while True: - if naverage == -1: # continuous grab - if not self.running: - break - else: - if ind_grab >= naverage or not self.running: - break - pData = self.wait_fn() - if not not pData: - ind_grab += 1 - #print(f'ind_grab_thread:{ind_grab}') - self.data_sig.emit([pData]) - QtCore.QThread.msleep(wait_time) - if __name__ == '__main__': From 06a42425477ac059f64e3489b1608b2fe200c60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Tue, 30 Jun 2026 10:27:40 +0200 Subject: [PATCH 3/5] renaming plugin to be explicit with pylablib --- ...2Dviewer_AndorSCMOS_2.py => daq_2Dviewer_AndorSCMOSPll.py} | 4 +--- src/pymodaq_plugins_andor/hardware/sdk3_utils.py | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) rename src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/{daq_2Dviewer_AndorSCMOS_2.py => daq_2Dviewer_AndorSCMOSPll.py} (99%) diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOSPll.py similarity index 99% rename from src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py rename to src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOSPll.py index cd91373..7e85417 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOS_2.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_2D/daq_2Dviewer_AndorSCMOSPll.py @@ -58,7 +58,7 @@ ) -class DAQ_2DViewer_AndorSCMOS_2(CameraBasePyLabLib): +class DAQ_2DViewer_AndorSCMOSPll(CameraBasePyLabLib): """ Base class for Andor SCMOS camera @@ -253,7 +253,5 @@ def stop(self): return "" - - if __name__ == '__main__': main(__file__, init=False) \ No newline at end of file diff --git a/src/pymodaq_plugins_andor/hardware/sdk3_utils.py b/src/pymodaq_plugins_andor/hardware/sdk3_utils.py index e2e89ff..dc25786 100644 --- a/src/pymodaq_plugins_andor/hardware/sdk3_utils.py +++ b/src/pymodaq_plugins_andor/hardware/sdk3_utils.py @@ -2,7 +2,6 @@ from pymodaq_utils.config import GlobalConfig from pymodaq_utils.logger import get_module_name, set_logger - from pylablib.devices.Andor import AndorSDK3Camera from pylablib.devices import Andor From c166f50b3a58d78d5eeb9411f3c68f3b08d2a3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Tue, 30 Jun 2026 10:57:35 +0200 Subject: [PATCH 4/5] Update README.rst --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index dbc0747..7eabbda 100644 --- a/README.rst +++ b/README.rst @@ -41,5 +41,6 @@ Viewer2D ++++++++ * **AndorCCD**: Andor CCD camera using the SDK2 -* **AndorSCMOS**: Andor CCD camera using the SDK3 +* **AndorSCMOS**: Andor CCD camera using the SDK3 (legacy) +* **AndorSCMOSPll**: Andor CCD camera using the SDK3 through the pylablib driver (recommended) From bd117a4a371e6dd41b21bccb8895d53cd5c87871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Weber?= Date: Tue, 30 Jun 2026 11:03:27 +0200 Subject: [PATCH 5/5] renaming classes with legacy --- README.rst | 17 ++-- .../plugins_1D/daq_1Dviewer_ShamrockCCD.py | 91 ++++++++++-------- ...n.py => daq_1Dviewer_ShamrockCCDLegacy.py} | 91 ++++++++---------- .../plugins_1D/daq_1Dviewer_ShamrockSCMOS.py | 95 +++++++++++-------- ...py => daq_1Dviewer_ShamrockSCMOSLegacy.py} | 95 ++++++++----------- 5 files changed, 197 insertions(+), 192 deletions(-) rename src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/{daq_1Dviewer_ShamrockCCDComposition.py => daq_1Dviewer_ShamrockCCDLegacy.py} (61%) rename src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/{daq_1Dviewer_ShamrockSCMOSComposition.py => daq_1Dviewer_ShamrockSCMOSLegacy.py} (73%) diff --git a/README.rst b/README.rst index 7eabbda..0750a92 100644 --- a/README.rst +++ b/README.rst @@ -32,15 +32,20 @@ Actuators Viewer1D ++++++++ -* **ShamrockCCD**: Shamrock series of spectrometer using the Andor CCD cameras (built using double inheritance) -* **ShamrockSCMOS**: Shamrock series of spectrometer using the Andor SCMOS cameras (Not tested) (built using double inheritance) -* **ShamrockCCDComposition**: Shamrock series of spectrometer using the Andor CCD cameras (built using CCD camera inheritance and Shamrock composition) -* **ShamrockSCMOSComposition**: Shamrock series of spectrometer using the Andor SCMOS cameras (Not tested) (built using SCMOS camera inheritance and Shamrock composition) +* **ShamrockCCDLegacy**: Shamrock series of spectrometer using the Andor CCD cameras (built using double inheritance), this + is a legacy plugin don't use it anymore +* **ShamrockSCMOSLegacy**: Shamrock series of spectrometer using the Andor SCMOS cameras (Not tested) + (built using double inheritance), this is a legacy plugin don't use it anymore +* **ShamrockCCD**: Shamrock series of spectrometer using the Andor CCD cameras + (built using CCD camera inheritance and Shamrock composition) +* **ShamrockSCMOS**: Shamrock series of spectrometer using the Andor SCMOS cameras (Not tested) + (built using SCMOS camera inheritance and Shamrock composition) Viewer2D ++++++++ * **AndorCCD**: Andor CCD camera using the SDK2 -* **AndorSCMOS**: Andor CCD camera using the SDK3 (legacy) -* **AndorSCMOSPll**: Andor CCD camera using the SDK3 through the pylablib driver (recommended) +* **AndorSCMOS**: Andor CCD camera using the SDK3 +* **AndorSCMOSPll**: Andor CCD camera using the SDK3 through the pylablib driver (experimental but already in use, + subject to changes) diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCD.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCD.py index 0f30f78..2b464d0 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCD.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCD.py @@ -6,17 +6,16 @@ from pymodaq_gui.parameter import utils as putils -from pymodaq.utils.data import Axis, DataFromPlugins -from pymodaq.control_modules.viewer_utility_classes import main +from pymodaq.utils.data import Axis, DataFromPlugins, DataToExport +from pymodaq.control_modules.viewer_utility_classes import main, DAQ_Viewer_base, comon_parameters from pymodaq_plugins_andor.daq_viewer_plugins.plugins_2D.daq_2Dviewer_AndorCCD import DAQ_2DViewer_AndorCCD from pymodaq_plugins_andor.daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock - logger = set_logger(get_module_name(__file__)) -class DAQ_1DViewer_ShamrockCCD(DAQ_2DViewer_AndorCCD, DAQ_Move_Shamrock): +class DAQ_1DViewer_ShamrockCCD(DAQ_2DViewer_AndorCCD): """ =============== ================== @@ -38,27 +37,28 @@ class DAQ_1DViewer_ShamrockCCD(DAQ_2DViewer_AndorCCD, DAQ_Move_Shamrock): d['visible'] = True params = [{'title': 'Get Calibration:', 'name': 'get_calib', 'type': 'bool_push', 'value': False, - 'label': 'Update!'}] + param_camera + params_shamrock + 'label': 'Update!'},] + param_camera + [ + {'title': 'Shamrock Settings:', 'name': 'sham_settings', 'type': 'group', 'children': params_shamrock}, + ] - def __init__(self, parent=None, params_state=None): - DAQ_Move_Shamrock.__init__(self, parent, params_state) - DAQ_2DViewer_AndorCCD.__init__(self, parent, params_state) - self.camera_controller = None # this will be the controller attribute of the DAQ_2DViewer_AndorCCD instance - self.shamrock_controller = None # this will be the controller attribute of the DAQ_Move_Shamrock instance - # both plugins don't have the generic controller name 'controller' but specific one for this reason + def ini_attributes(self): + self.controller: DAQ_2DViewer_AndorCCD = None + self.shamrock_controller: DAQ_Move_Shamrock = None self.x_axis: Axis = None self.is_calibrated = False + super().ini_attributes() + def commit_settings(self, param): if param.name() == 'flip_wavelength': self.get_xaxis() elif 'camera_settings' in putils.get_param_path(param): - DAQ_2DViewer_AndorCCD.commit_settings(self, param) + super().commit_settings(param) elif 'spectro_settings' in putils.get_param_path(param): - DAQ_Move_Shamrock.commit_settings(self, param) + self.shamrock_controller.commit_settings(param) QtWidgets.QApplication.processEvents() if param.name() == 'spectro_wl': self.is_calibrated = False @@ -76,34 +76,36 @@ def commit_settings(self, param): param.setValue(False) def ini_detector(self, controller=None): - _, shamrock_initialized = DAQ_Move_Shamrock.ini_stage(self, controller) + cam_status, cam_init = super().ini_detector(controller) QtWidgets.QApplication.processEvents() - # if status_shamrock.initialized: - # self.move_Home() - _, camera_initialized = DAQ_2DViewer_AndorCCD.ini_detector(self, controller) + self.shamrock_controller = DAQ_Move_Shamrock(None, self.settings.child('sham_settings').saveState()) + self.shamrock_controller.settings = self.settings.child('sham_settings') + self.shamrock_controller.emit_status = self.emit_status + sham_status, sham_init = self.shamrock_controller.ini_stage(controller) + QtWidgets.QApplication.processEvents() - initialized = shamrock_initialized and camera_initialized + + initialized = sham_init and cam_init self.setCalibration() - #self.emit_status(ThreadCommand('close_splash')) - return '', initialized + return sham_status + cam_status, initialized def setCalibration(self): #setNpixels width, height = self.get_pixel_size() - err = self.shamrock_controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) - err = self.shamrock_controller.SetPixelWidthSR(0, width) + err = self.shamrock_controller.controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) + err = self.shamrock_controller.controller.SetPixelWidthSR(0, width) - self.get_wavelength() + self.shamrock_controller.get_wavelength() self.x_axis = self.get_xaxis() def getCalibration(self): - if self.shamrock_controller is not None: - (err, calib) = self.shamrock_controller.GetCalibrationSR(0, self.get_ROI_size_x()) + if self.shamrock_controller is not None and self.shamrock_controller.controller is not None: + (err, calib) = self.shamrock_controller.controller.GetCalibrationSR(0, self.get_ROI_size_x()) if err != "SHAMROCK_SUCCESS": raise Exception(err) @@ -123,17 +125,19 @@ def get_xaxis(self): Contains a vector of integer corresponding to the horizontal camera pixels. """ - if np.abs(self.settings.child('spectro_settings', 'spectro_wl').value()) < 1e-3: - DAQ_2DViewer_AndorCCD.get_xaxis(self) + if self.shamrock_controller is None or np.abs(self.settings.child('sham_settings', 'spectro_settings', 'spectro_wl').value()) < 1e-3: + nx = self.get_ROI_size_x() + calib = np.linspace(0, nx, nx-1) + self.x_axis = Axis(data=calib, label='Wavelength (nm)') else: calib = self.getCalibration() if (calib.astype('int') != 0).all(): # check if calib values are equal to zero - if self.settings.child('spectro_settings', 'flip_wavelength').value(): + if self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').value(): calib = calib[::-1] else: - self.settings.child('spectro_settings', 'flip_wavelength').setValue(False) + self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').setValue(False) #self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) self.x_axis = Axis(data=calib, label='Wavelength (nm)') @@ -149,18 +153,21 @@ def set_exposure_ms(self, exposure): self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) def stop(self): - DAQ_2DViewer_AndorCCD.stop(self) + if self.controller is not None: + super().stop() + if self.shamrock_controller is not None: + self.shamrock_controller.stop() def close(self): - if self.camera_controller is not None: - DAQ_2DViewer_AndorCCD.stop(self) + self.stop() if self.shamrock_controller is not None: - DAQ_Move_Shamrock.stop(self) + self.shamrock_controller.close() + super().close() def grab_data(self, Naverage=1, **kwargs): if not self.is_calibrated: self.get_xaxis() - DAQ_2DViewer_AndorCCD.grab_data(self, Naverage, **kwargs) + super().grab_data( Naverage, **kwargs) def emit_data(self): """ @@ -170,12 +177,16 @@ def emit_data(self): self.ind_grabbed += 1 sizey = self.settings.child('camera_settings', 'image_size', 'Ny').value() sizex = self.settings.child('camera_settings', 'image_size', 'Nx').value() - self.camera_controller.GetAcquiredDataNumpy(self.data_pointer, sizex * sizey) - self.data_grabed_signal.emit([DataFromPlugins(name='Camera', - data=[np.squeeze( - self.data.reshape((sizey, sizex)).astype(float))], - dim=self.data_shape, - axes=[self.x_axis]),]) + self.controller.GetAcquiredDataNumpy(self.data_pointer, sizex * sizey) + self.dte_signal.emit( + DataToExport('Spectro', + data=[ + DataFromPlugins(name='Camera', + data=[np.atleast_1d(np.squeeze(self.data.reshape( + (sizey, sizex)))).astype(float)], + dim=self.data_shape, + axes=[self.x_axis]), + ])) QtWidgets.QApplication.processEvents() # here to be sure the timeevents are executed even if in continuous grab mode except Exception as e: diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDComposition.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDLegacy.py similarity index 61% rename from src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDComposition.py rename to src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDLegacy.py index 421029d..76e1250 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDComposition.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockCCDLegacy.py @@ -6,16 +6,17 @@ from pymodaq_gui.parameter import utils as putils -from pymodaq.utils.data import Axis, DataFromPlugins, DataToExport -from pymodaq.control_modules.viewer_utility_classes import main, DAQ_Viewer_base, comon_parameters +from pymodaq.utils.data import Axis, DataFromPlugins +from pymodaq.control_modules.viewer_utility_classes import main from pymodaq_plugins_andor.daq_viewer_plugins.plugins_2D.daq_2Dviewer_AndorCCD import DAQ_2DViewer_AndorCCD from pymodaq_plugins_andor.daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock + logger = set_logger(get_module_name(__file__)) -class DAQ_1DViewer_ShamrockCCDComposition(DAQ_2DViewer_AndorCCD): +class DAQ_1DViewer_ShamrockCCDLegacy(DAQ_2DViewer_AndorCCD, DAQ_Move_Shamrock): """ =============== ================== @@ -37,28 +38,27 @@ class DAQ_1DViewer_ShamrockCCDComposition(DAQ_2DViewer_AndorCCD): d['visible'] = True params = [{'title': 'Get Calibration:', 'name': 'get_calib', 'type': 'bool_push', 'value': False, - 'label': 'Update!'},] + param_camera + [ - {'title': 'Shamrock Settings:', 'name': 'sham_settings', 'type': 'group', 'children': params_shamrock}, - ] + 'label': 'Update!'}] + param_camera + params_shamrock + def __init__(self, parent=None, params_state=None): + DAQ_Move_Shamrock.__init__(self, parent, params_state) + DAQ_2DViewer_AndorCCD.__init__(self, parent, params_state) - def ini_attributes(self): - self.controller: DAQ_2DViewer_AndorCCD = None - self.shamrock_controller: DAQ_Move_Shamrock = None + self.camera_controller = None # this will be the controller attribute of the DAQ_2DViewer_AndorCCD instance + self.shamrock_controller = None # this will be the controller attribute of the DAQ_Move_Shamrock instance + # both plugins don't have the generic controller name 'controller' but specific one for this reason self.x_axis: Axis = None self.is_calibrated = False - super().ini_attributes() - def commit_settings(self, param): if param.name() == 'flip_wavelength': self.get_xaxis() elif 'camera_settings' in putils.get_param_path(param): - super().commit_settings(param) + DAQ_2DViewer_AndorCCD.commit_settings(self, param) elif 'spectro_settings' in putils.get_param_path(param): - self.shamrock_controller.commit_settings(param) + DAQ_Move_Shamrock.commit_settings(self, param) QtWidgets.QApplication.processEvents() if param.name() == 'spectro_wl': self.is_calibrated = False @@ -76,36 +76,34 @@ def commit_settings(self, param): param.setValue(False) def ini_detector(self, controller=None): - cam_status, cam_init = super().ini_detector(controller) + _, shamrock_initialized = DAQ_Move_Shamrock.ini_stage(self, controller) QtWidgets.QApplication.processEvents() + # if status_shamrock.initialized: + # self.move_Home() - self.shamrock_controller = DAQ_Move_Shamrock(None, self.settings.child('sham_settings').saveState()) - self.shamrock_controller.settings = self.settings.child('sham_settings') - self.shamrock_controller.emit_status = self.emit_status - sham_status, sham_init = self.shamrock_controller.ini_stage(controller) - + _, camera_initialized = DAQ_2DViewer_AndorCCD.ini_detector(self, controller) QtWidgets.QApplication.processEvents() - - initialized = sham_init and cam_init + initialized = shamrock_initialized and camera_initialized self.setCalibration() - return sham_status + cam_status, initialized + #self.emit_status(ThreadCommand('close_splash')) + return '', initialized def setCalibration(self): #setNpixels width, height = self.get_pixel_size() - err = self.shamrock_controller.controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) - err = self.shamrock_controller.controller.SetPixelWidthSR(0, width) + err = self.shamrock_controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) + err = self.shamrock_controller.SetPixelWidthSR(0, width) - self.shamrock_controller.get_wavelength() + self.get_wavelength() self.x_axis = self.get_xaxis() def getCalibration(self): - if self.shamrock_controller is not None and self.shamrock_controller.controller is not None: - (err, calib) = self.shamrock_controller.controller.GetCalibrationSR(0, self.get_ROI_size_x()) + if self.shamrock_controller is not None: + (err, calib) = self.shamrock_controller.GetCalibrationSR(0, self.get_ROI_size_x()) if err != "SHAMROCK_SUCCESS": raise Exception(err) @@ -125,19 +123,17 @@ def get_xaxis(self): Contains a vector of integer corresponding to the horizontal camera pixels. """ - if self.shamrock_controller is None or np.abs(self.settings.child('sham_settings', 'spectro_settings', 'spectro_wl').value()) < 1e-3: - nx = self.get_ROI_size_x() - calib = np.linspace(0, nx, nx-1) - self.x_axis = Axis(data=calib, label='Wavelength (nm)') + if np.abs(self.settings.child('spectro_settings', 'spectro_wl').value()) < 1e-3: + DAQ_2DViewer_AndorCCD.get_xaxis(self) else: calib = self.getCalibration() if (calib.astype('int') != 0).all(): # check if calib values are equal to zero - if self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').value(): + if self.settings.child('spectro_settings', 'flip_wavelength').value(): calib = calib[::-1] else: - self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').setValue(False) + self.settings.child('spectro_settings', 'flip_wavelength').setValue(False) #self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) self.x_axis = Axis(data=calib, label='Wavelength (nm)') @@ -153,21 +149,18 @@ def set_exposure_ms(self, exposure): self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) def stop(self): - if self.controller is not None: - super().stop() - if self.shamrock_controller is not None: - self.shamrock_controller.stop() + DAQ_2DViewer_AndorCCD.stop(self) def close(self): - self.stop() + if self.camera_controller is not None: + DAQ_2DViewer_AndorCCD.stop(self) if self.shamrock_controller is not None: - self.shamrock_controller.close() - super().close() + DAQ_Move_Shamrock.stop(self) def grab_data(self, Naverage=1, **kwargs): if not self.is_calibrated: self.get_xaxis() - super().grab_data( Naverage, **kwargs) + DAQ_2DViewer_AndorCCD.grab_data(self, Naverage, **kwargs) def emit_data(self): """ @@ -177,16 +170,12 @@ def emit_data(self): self.ind_grabbed += 1 sizey = self.settings.child('camera_settings', 'image_size', 'Ny').value() sizex = self.settings.child('camera_settings', 'image_size', 'Nx').value() - self.controller.GetAcquiredDataNumpy(self.data_pointer, sizex * sizey) - self.dte_signal.emit( - DataToExport('Spectro', - data=[ - DataFromPlugins(name='Camera', - data=[np.atleast_1d(np.squeeze(self.data.reshape( - (sizey, sizex)))).astype(float)], - dim=self.data_shape, - axes=[self.x_axis]), - ])) + self.camera_controller.GetAcquiredDataNumpy(self.data_pointer, sizex * sizey) + self.data_grabed_signal.emit([DataFromPlugins(name='Camera', + data=[np.squeeze( + self.data.reshape((sizey, sizex)).astype(float))], + dim=self.data_shape, + axes=[self.x_axis]),]) QtWidgets.QApplication.processEvents() # here to be sure the timeevents are executed even if in continuous grab mode except Exception as e: diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOS.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOS.py index f351f8b..4d9ec74 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOS.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOS.py @@ -1,21 +1,23 @@ - import numpy as np from qtpy import QtWidgets +from time import perf_counter from pymodaq_utils.utils import ThreadCommand, find_dict_in_list_from_key_val -from pymodaq.utils.logger import set_logger, get_module_name +from pymodaq_utils.logger import set_logger, get_module_name from pymodaq_gui.parameter import utils as putils -from pymodaq.utils.data import Axis, DataFromPlugins +from pymodaq.utils.data import Axis, DataFromPlugins, DataToExport +from pymodaq.control_modules.viewer_utility_classes import main, DAQ_Viewer_base, comon_parameters + -from ..plugins_2D.daq_2Dviewer_AndorSCMOS import DAQ_2DViewer_AndorSCMOS -from ...daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock +from pymodaq_plugins_andor.daq_viewer_plugins.plugins_2D.daq_2Dviewer_AndorSCMOS import DAQ_2DViewer_AndorSCMOS +from pymodaq_plugins_andor.daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock logger = set_logger(get_module_name(__file__)) -class DAQ_1DViewer_ShamrockSCMOS(DAQ_2DViewer_AndorSCMOS, DAQ_Move_Shamrock): +class DAQ_1DViewer_ShamrockSCMOS(DAQ_2DViewer_AndorSCMOS): """ =============== ================== @@ -25,7 +27,6 @@ class DAQ_1DViewer_ShamrockSCMOS(DAQ_2DViewer_AndorSCMOS, DAQ_Move_Shamrock): -------- utility_classes.DAQ_Viewer_base """ - param_camera = DAQ_2DViewer_AndorSCMOS.params params_shamrock = DAQ_Move_Shamrock.params putils.get_param_dict_from_name(params_shamrock, 'andor_lib', pop=True) @@ -38,29 +39,28 @@ class DAQ_1DViewer_ShamrockSCMOS(DAQ_2DViewer_AndorSCMOS, DAQ_Move_Shamrock): d['visible'] = True params = [{'title': 'Get Calibration:', 'name': 'get_calib', 'type': 'bool_push', 'value': False, - 'label': 'Update!'}] + param_camera + params_shamrock - + 'label': 'Update!'},] + param_camera + [ + {'title': 'Shamrock Settings:', 'name': 'sham_settings', 'type': 'group', 'children': params_shamrock}, + ] - def __init__(self, parent=None, params_state=None): - DAQ_2DViewer_AndorSCMOS.__init__(self, parent, params_state) - DAQ_Move_Shamrock.__init__(self, parent, params_state) + def ini_attributes(self): + self.controller: DAQ_2DViewer_AndorSCMOS = None + self.shamrock_controller: DAQ_Move_Shamrock = None - self.camera_controller = None # this will be the controller attribute of the DAQ_2DViewer_AndorSCMOS instance - self.shamrock_controller = None # this will be the controller attribute of the DAQ_Move_Shamrock instance - # both plugins don't have the generic controller name 'controller' but specific one for this reason - - self.x_axis = None + self.x_axis: Axis = None self.is_calibrated = False + super().ini_attributes() + def commit_settings(self, param): if param.name() == 'flip_wavelength': self.get_xaxis() elif 'camera_settings' in putils.get_param_path(param): - DAQ_2DViewer_AndorSCMOS.commit_settings(self, param) + super().commit_settings(param) elif 'spectro_settings' in putils.get_param_path(param): - DAQ_Move_Shamrock.commit_settings(self, param) + self.shamrock_controller.commit_settings(param) QtWidgets.QApplication.processEvents() if param.name() == 'spectro_wl': self.is_calibrated = False @@ -78,33 +78,36 @@ def commit_settings(self, param): param.setValue(False) def ini_detector(self, controller=None): - _, shamrock_initialized = DAQ_Move_Shamrock.ini_stage(self, controller) + cam_status, cam_init = super().ini_detector(controller) QtWidgets.QApplication.processEvents() - # if status_shamrock.initialized: - # self.move_Home() - _, camera_initialized = DAQ_2DViewer_AndorSCMOS.ini_detector(self, controller) + self.shamrock_controller = DAQ_Move_Shamrock(None, self.settings.child('sham_settings').saveState()) + self.shamrock_controller.settings = self.settings.child('sham_settings') + self.shamrock_controller.emit_status = self.emit_status + sham_status, sham_init = self.shamrock_controller.ini_stage(controller) + QtWidgets.QApplication.processEvents() - initialized = shamrock_initialized and camera_initialized + + initialized = sham_init and cam_init self.setCalibration() - return '', initialized + return sham_status + cam_status, initialized def setCalibration(self): #setNpixels - width = self.get_pixel_size() - err = self.shamrock_controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) - err = self.shamrock_controller.SetPixelWidthSR(0, width) + width, height = self.get_pixel_size() + err = self.shamrock_controller.controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) + err = self.shamrock_controller.controller.SetPixelWidthSR(0, width) - self.get_wavelength() + self.shamrock_controller.get_wavelength() self.x_axis = self.get_xaxis() def getCalibration(self): - if self.shamrock_controller is not None: - (err, calib) = self.shamrock_controller.GetCalibrationSR(0, self.get_ROI_size_x()) + if self.shamrock_controller is not None and self.shamrock_controller.controller is not None: + (err, calib) = self.shamrock_controller.controller.GetCalibrationSR(0, self.get_ROI_size_x()) if err != "SHAMROCK_SUCCESS": raise Exception(err) @@ -124,24 +127,24 @@ def get_xaxis(self): Contains a vector of integer corresponding to the horizontal camera pixels. """ - if np.abs(self.settings.child('spectro_settings', 'spectro_wl').value()) < 1e-3: - DAQ_2DViewer_AndorSCMOS.get_xaxis(self) + if self.shamrock_controller is None or np.abs(self.settings.child('sham_settings', 'spectro_settings', 'spectro_wl').value()) < 1e-3: + nx = self.get_ROI_size_x() + calib = np.linspace(0, nx, nx-1) + self.x_axis = Axis(data=calib, label='Wavelength (nm)') else: calib = self.getCalibration() if (calib.astype('int') != 0).all(): # check if calib values are equal to zero - if self.settings.child('spectro_settings', 'flip_wavelength').value(): + if self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').value(): calib = calib[::-1] else: - self.settings.child('spectro_settings', 'flip_wavelength').setValue(False) - self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) + self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').setValue(False) + #self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) self.x_axis = Axis(data=calib, label='Wavelength (nm)') - self.emit_x_axis() return self.x_axis - def get_exposure_ms(self): #for compatibility with PyMoDAQ Spectro module self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) @@ -152,16 +155,21 @@ def set_exposure_ms(self, exposure): self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) def stop(self): - DAQ_2DViewer_AndorSCMOS.stop(self) + if self.controller is not None: + super().stop() + if self.shamrock_controller is not None: + self.shamrock_controller.stop() def close(self): - DAQ_2DViewer_AndorSCMOS.stop(self) - DAQ_Move_Shamrock.stop(self) + self.stop() + if self.shamrock_controller is not None: + self.shamrock_controller.close() + super().close() def grab_data(self, Naverage=1, **kwargs): if not self.is_calibrated: self.get_xaxis() - DAQ_2DViewer_AndorSCMOS.grab_data(self, Naverage, **kwargs) + super().grab_data( Naverage, **kwargs) def emit_data(self, buffer_pointer): """ @@ -246,3 +254,6 @@ def emit_data(self, buffer_pointer): logger.exception(str(e)) + +if __name__ == '__main__': + main(__file__, True) diff --git a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSComposition.py b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSLegacy.py similarity index 73% rename from src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSComposition.py rename to src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSLegacy.py index 2bad1ee..8e03a62 100644 --- a/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSComposition.py +++ b/src/pymodaq_plugins_andor/daq_viewer_plugins/plugins_1D/daq_1Dviewer_ShamrockSCMOSLegacy.py @@ -1,23 +1,21 @@ + import numpy as np from qtpy import QtWidgets -from time import perf_counter from pymodaq_utils.utils import ThreadCommand, find_dict_in_list_from_key_val -from pymodaq_utils.logger import set_logger, get_module_name +from pymodaq.utils.logger import set_logger, get_module_name from pymodaq_gui.parameter import utils as putils -from pymodaq.utils.data import Axis, DataFromPlugins, DataToExport -from pymodaq.control_modules.viewer_utility_classes import main, DAQ_Viewer_base, comon_parameters - +from pymodaq.utils.data import Axis, DataFromPlugins -from pymodaq_plugins_andor.daq_viewer_plugins.plugins_2D.daq_2Dviewer_AndorSCMOS import DAQ_2DViewer_AndorSCMOS -from pymodaq_plugins_andor.daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock +from ..plugins_2D.daq_2Dviewer_AndorSCMOS import DAQ_2DViewer_AndorSCMOS +from ...daq_move_plugins.daq_move_Shamrock import DAQ_Move_Shamrock logger = set_logger(get_module_name(__file__)) -class DAQ_1DViewer_ShamrockCCDComposition(DAQ_2DViewer_AndorSCMOS): +class DAQ_1DViewer_ShamrockSCMOSLegacy(DAQ_2DViewer_AndorSCMOS, DAQ_Move_Shamrock): """ =============== ================== @@ -27,6 +25,7 @@ class DAQ_1DViewer_ShamrockCCDComposition(DAQ_2DViewer_AndorSCMOS): -------- utility_classes.DAQ_Viewer_base """ + param_camera = DAQ_2DViewer_AndorSCMOS.params params_shamrock = DAQ_Move_Shamrock.params putils.get_param_dict_from_name(params_shamrock, 'andor_lib', pop=True) @@ -39,28 +38,29 @@ class DAQ_1DViewer_ShamrockCCDComposition(DAQ_2DViewer_AndorSCMOS): d['visible'] = True params = [{'title': 'Get Calibration:', 'name': 'get_calib', 'type': 'bool_push', 'value': False, - 'label': 'Update!'},] + param_camera + [ - {'title': 'Shamrock Settings:', 'name': 'sham_settings', 'type': 'group', 'children': params_shamrock}, - ] + 'label': 'Update!'}] + param_camera + params_shamrock - def ini_attributes(self): - self.controller: DAQ_2DViewer_AndorSCMOS = None - self.shamrock_controller: DAQ_Move_Shamrock = None + def __init__(self, parent=None, params_state=None): - self.x_axis: Axis = None - self.is_calibrated = False + DAQ_2DViewer_AndorSCMOS.__init__(self, parent, params_state) + DAQ_Move_Shamrock.__init__(self, parent, params_state) - super().ini_attributes() + self.camera_controller = None # this will be the controller attribute of the DAQ_2DViewer_AndorSCMOS instance + self.shamrock_controller = None # this will be the controller attribute of the DAQ_Move_Shamrock instance + # both plugins don't have the generic controller name 'controller' but specific one for this reason + + self.x_axis = None + self.is_calibrated = False def commit_settings(self, param): if param.name() == 'flip_wavelength': self.get_xaxis() elif 'camera_settings' in putils.get_param_path(param): - super().commit_settings(param) + DAQ_2DViewer_AndorSCMOS.commit_settings(self, param) elif 'spectro_settings' in putils.get_param_path(param): - self.shamrock_controller.commit_settings(param) + DAQ_Move_Shamrock.commit_settings(self, param) QtWidgets.QApplication.processEvents() if param.name() == 'spectro_wl': self.is_calibrated = False @@ -78,36 +78,33 @@ def commit_settings(self, param): param.setValue(False) def ini_detector(self, controller=None): - cam_status, cam_init = super().ini_detector(controller) + _, shamrock_initialized = DAQ_Move_Shamrock.ini_stage(self, controller) QtWidgets.QApplication.processEvents() + # if status_shamrock.initialized: + # self.move_Home() - self.shamrock_controller = DAQ_Move_Shamrock(None, self.settings.child('sham_settings').saveState()) - self.shamrock_controller.settings = self.settings.child('sham_settings') - self.shamrock_controller.emit_status = self.emit_status - sham_status, sham_init = self.shamrock_controller.ini_stage(controller) - + _, camera_initialized = DAQ_2DViewer_AndorSCMOS.ini_detector(self, controller) QtWidgets.QApplication.processEvents() - - initialized = sham_init and cam_init + initialized = shamrock_initialized and camera_initialized self.setCalibration() - return sham_status + cam_status, initialized + return '', initialized def setCalibration(self): #setNpixels - width, height = self.get_pixel_size() - err = self.shamrock_controller.controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) - err = self.shamrock_controller.controller.SetPixelWidthSR(0, width) + width = self.get_pixel_size() + err = self.shamrock_controller.SetNumberPixelsSR(0, self.get_ROI_size_x()) + err = self.shamrock_controller.SetPixelWidthSR(0, width) - self.shamrock_controller.get_wavelength() + self.get_wavelength() self.x_axis = self.get_xaxis() def getCalibration(self): - if self.shamrock_controller is not None and self.shamrock_controller.controller is not None: - (err, calib) = self.shamrock_controller.controller.GetCalibrationSR(0, self.get_ROI_size_x()) + if self.shamrock_controller is not None: + (err, calib) = self.shamrock_controller.GetCalibrationSR(0, self.get_ROI_size_x()) if err != "SHAMROCK_SUCCESS": raise Exception(err) @@ -127,24 +124,24 @@ def get_xaxis(self): Contains a vector of integer corresponding to the horizontal camera pixels. """ - if self.shamrock_controller is None or np.abs(self.settings.child('sham_settings', 'spectro_settings', 'spectro_wl').value()) < 1e-3: - nx = self.get_ROI_size_x() - calib = np.linspace(0, nx, nx-1) - self.x_axis = Axis(data=calib, label='Wavelength (nm)') + if np.abs(self.settings.child('spectro_settings', 'spectro_wl').value()) < 1e-3: + DAQ_2DViewer_AndorSCMOS.get_xaxis(self) else: calib = self.getCalibration() if (calib.astype('int') != 0).all(): # check if calib values are equal to zero - if self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').value(): + if self.settings.child('spectro_settings', 'flip_wavelength').value(): calib = calib[::-1] else: - self.settings.child('sham_settings', 'spectro_settings', 'flip_wavelength').setValue(False) - #self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) + self.settings.child('spectro_settings', 'flip_wavelength').setValue(False) + self.emit_status(ThreadCommand('Update_Status', ['Impossible to flip wavelength', "log"])) self.x_axis = Axis(data=calib, label='Wavelength (nm)') + self.emit_x_axis() return self.x_axis + def get_exposure_ms(self): #for compatibility with PyMoDAQ Spectro module self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) @@ -155,21 +152,16 @@ def set_exposure_ms(self, exposure): self.emit_status(ThreadCommand('exposure_ms', [self.settings.child('camera_settings', 'exposure').value()])) def stop(self): - if self.controller is not None: - super().stop() - if self.shamrock_controller is not None: - self.shamrock_controller.stop() + DAQ_2DViewer_AndorSCMOS.stop(self) def close(self): - self.stop() - if self.shamrock_controller is not None: - self.shamrock_controller.close() - super().close() + DAQ_2DViewer_AndorSCMOS.stop(self) + DAQ_Move_Shamrock.stop(self) def grab_data(self, Naverage=1, **kwargs): if not self.is_calibrated: self.get_xaxis() - super().grab_data( Naverage, **kwargs) + DAQ_2DViewer_AndorSCMOS.grab_data(self, Naverage, **kwargs) def emit_data(self, buffer_pointer): """ @@ -254,6 +246,3 @@ def emit_data(self, buffer_pointer): logger.exception(str(e)) - -if __name__ == '__main__': - main(__file__, True)