diff --git a/cfg/terascan.cfg b/cfg/terascan.cfg index 528f79b..ed61d18 100644 --- a/cfg/terascan.cfg +++ b/cfg/terascan.cfg @@ -53,7 +53,7 @@ logic: daq_reader_logic: module.Class: 'common.daq_reader_logic.DAQReaderLogic' connect: - daq: daq_dummy + daq: nidaq #daq_reader_dummy options: update_interval: 0 # Period in ms to check for data updates. Integers only. 0 is as fast as possible @@ -65,27 +65,72 @@ logic: channel_buffer_size: 1048576 # optional (default: 1MSample) max_raw_data_bytes: 1073741824 # optional (default: 1GB) connect: - streamer: instream_dummy + streamer: wavemeter # instream_dummy fast_counter_logic: module.Class: 'common.fast_counter_logic.FastCounterLogic' connect: - fast_counter: fast_counter_dummy + fast_counter: swabian_timetagger # fast_counter_dummy scanning_laser_logic: module.Class: 'common.scanning_laser_logic.ScanningLaserLogic' connect: - laser: scanning_laser_dummy + laser: solstis_laser # scanning_laser_dummy options: - min_wavelength: 0.775 # in um - max_wavelength: 0.790 # in um + min_wavelength: 0.700 # in um + max_wavelength: 0.800 # in um hardware: - daq_dummy: + # Real Hardware: + nidaq: + module.Class: 'daq.nidaq.NIDAQ' + options: + device_str: 'Dev2' + channels: + signal: + description: 'Laser Lock TTL' + type: 0 # 0 for Digital, 1 for Analog + name: 'line0' # The name as idintified by the card + port: 1 # port number identified by the card + + wavemeter_proxy: + module.Class: 'wavemeter.high_finesse_proxy.HighFinesseProxy' + options: + watchdog_interval: 1.0 # how often the watchdog checks for errors/changes in s + dllPath: 'C:\Program Files (x86)\HighFinesse\Wavelength Meter WS6 3167\Projects\64\wlmData.dll' + + wavemeter: + module.Class: 'wavemeter.high_finesse_wavemeter.HighFinesseWavemeter' + connect: + proxy: wavemeter_proxy + options: + channels: + laser: + switch_ch: 1 # channel on the wavemeter switch + unit: 'm' # wavelength (m) or frequency (Hz) + exposure: 10 # exposure time in ms, optional + + swabian_timetagger: + module.Class: 'timetagger.swabian_tagger.SwabianTimeTagger' + options: + channels: + counts: 1 # label and channel number on the time tagger (1,2,3,4) + + solstis_laser: + module.Class: 'laser.solstis_laser.SolstisLaser' + options: + host_ip_addr: '192.168.1.225' # IP address of control computer + laser_ip_addr: '192.168.1.222' # IP address of laser + laser_port: 39933 # Port number to connect on + scan_rate: 13 # See "solstis_constants.py" TeraScanRate Enum for values + scan_type: 2 # see "solstis_constants.py" TeraScanType Enum for values + + # Dummy Hardware: + daq_reader_dummy: module.Class: 'dummy.daq_reader_dummy.DAQReaderDummy' instream_dummy: @@ -110,7 +155,7 @@ hardware: module.Class: 'dummy.fast_counter_dummy.FastCounterDummy' - laser_dummy: + scanning_laser_dummy: module.Class: 'dummy.scanning_laser_dummy.ScanningLaserDummy' \ No newline at end of file diff --git a/src/qudi/gui/terascan/terascan_gui.py b/src/qudi/gui/terascan/terascan_gui.py index 9ae2b2b..f72a5ac 100644 --- a/src/qudi/gui/terascan/terascan_gui.py +++ b/src/qudi/gui/terascan/terascan_gui.py @@ -121,6 +121,7 @@ def _start_stop_pressed(self) -> None: if self._mw.start_stop_button.text() == 'Start Measurement': self._mw.start_stop_button.setText('Stop Measurement') self._mw.plot_widget.setXRange(self._start_wavelength, self._stop_wavelength) + print('start measurement in terascan_gui') self.sigStartMeasurement.emit() else: self._mw.start_stop_button.setText('Start Measurement') @@ -130,14 +131,17 @@ def _start_stop_pressed(self) -> None: def _scan_finished(self) -> None: self._mw.start_stop_button.setText('Start Measurement') - @QtCore.Slot(List[TerascanData]) + @QtCore.Slot(object) def _receive_data(self, data: List[TerascanData]) -> None: img = np.zeros((len(data),2)) for i in range(len(data)): - img[i][0] = data[i].wavelength - img[i][1] = data[i].counts + # print(np.average(data[i].counts)) + #img[i][0] = data[i].wavelength + #img[i][1] = data[i].counts + img[i][0] = 775 + 15 * np.random.rand() + img[i][1] = 100 * np.random.rand() - self._mw.data_item.setData(x = img[:,0], y = img[:, 1]) + self._mw.data_item.setData(x = img[:, 0], y = img[:, 1]) @QtCore.Slot(float) diff --git a/src/qudi/gui/terascan/terascan_main_window.py b/src/qudi/gui/terascan/terascan_main_window.py index d42c9f6..6bd9453 100644 --- a/src/qudi/gui/terascan/terascan_main_window.py +++ b/src/qudi/gui/terascan/terascan_main_window.py @@ -54,12 +54,14 @@ def __init__(self, *args, **kwargs): self.start_wavelength.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) self.start_wavelength.setAlignment(QtCore.Qt.AlignHCenter) self.start_wavelength.setRange(0.3, 2) + self.start_wavelength.setDecimals(4) self.stop_wavelength_label = QtWidgets.QLabel('Stop Wavelength (um)') self.stop_wavelength = QtWidgets.QDoubleSpinBox() self.stop_wavelength.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) self.stop_wavelength.setAlignment(QtCore.Qt.AlignHCenter) self.stop_wavelength.setRange(0.3, 2) + self.stop_wavelength.setDecimals(4) self.plot_widget = pg.PlotWidget() self.plot_widget.getPlotItem().setContentsMargins(1, 1, 1, 1) diff --git a/src/qudi/hardware/camera/andor_camera.py b/src/qudi/hardware/camera/andor_camera.py index 39d19f3..58864a9 100644 --- a/src/qudi/hardware/camera/andor_camera.py +++ b/src/qudi/hardware/camera/andor_camera.py @@ -2,6 +2,7 @@ from ctypes import * import numpy as np import time +from collections.abc import Callable import pyAndorSDK2 as sdk from pyAndorSDK2 import atmcd_errors @@ -10,7 +11,7 @@ from qudi.interface.camera_interface import CameraInterface class AndorCamera(CameraInterface): - """ Hardware class for Andor Camera. Currently assumes there is only one + r""" Hardware class for Andor Camera. Currently assumes there is only one Andor camera attached Example config for copy-paste: @@ -28,7 +29,7 @@ class AndorCamera(CameraInterface): default_exposure: 1 # in seconds """ - + _dll_location: str = ConfigOption( name='dll_location', default=r'C:\Users\hoodl\Downloads\pyAndorSDK2_NEW\pyAndorSDK2', @@ -85,11 +86,11 @@ def on_activate(self): initialization_funcs = [ ('Setting Read Mode', lambda: self.andor.SetReadMode(4)), #4 = imaging mode, reads each pixel - + ('Setting VS Speed', lambda: self.andor.SetVSSpeed(4)), #4 index = 3.3 us ('Setting VS Amplitude', lambda: self.andor.SetVSAmplitude(0)), #keep 0 ('Setting HS Speed', lambda: self.andor.SetHSSpeed(0, 1)), #1 index = 5.0 (middle speed) - + ('Setting Pre-amp Gain', lambda: self.andor.SetPreAmpGain(2)), #index 2 = 5.1, highest ('Setting Baseline Clamp', lambda: self.andor.SetBaselineClamp(1)), #1 = on, keep baseline clamp on ('Setting Output Amplifyer', lambda: self.andor.SetOutputAmplifier(0)), #0 = EMCCD camera @@ -98,7 +99,7 @@ def on_activate(self): ('Setting Count Mode', lambda: self.andor.SetCountConvertMode(1)), #0 = bit counts, 1 = electrons, 2 = photons ('Setting Trigger Mode', lambda: self.andor.SetTriggerMode(0)), #0 = internal trigger (auto) ('Setting Image Binning Parameters', lambda: self.andor.SetImage(1, 1, 1, self.xpixels, 1, self.ypixels)), #sets horizontal and vertical binning - + ('Turning on Cooler', lambda: self.andor.CoolerON()), #turn on cooler ('Setting Cooler Mode', lambda: self.andor.SetCoolerMode(1)), #set cooler to maintain temp after shutoff (1) ('Setting Temperature', lambda: self.andor.SetTemperature(self.set_temp)) #sets temperature (kind of self explanatory) @@ -113,17 +114,16 @@ def on_activate(self): attempts = 0 while attempts < 3: current_temp = self._andor.GetTemperature()[1] - if np.abs(current_temp - self.set_temp) > self._temp_tolerance: - self._andor.SetTemperature(self.set_temp) + if np.abs(current_temp - self.set_temp) <= self._temp_tolerance: + break - self.log.warning( - f'Andor temperature ({current_temp}) not within tolerance of set point ({self.set_temp}).\nPausing to allow it to stabilize attempt {attempts}/3' - ) - time.sleep(5) - attempts += 1 + self._andor.SetTemperature(self.set_temp) - else: - break + self.log.warning( + f'Andor temperature ({current_temp}) not within tolerance of set point ({self.set_temp}).\nPausing to allow it to stabilize attempt {attempts}/3' + ) + time.sleep(5) + attempts += 1 current_temp = self._andor.GetTemperature()[1] if np.abs(current_temp - self.set_temp) > self._temp_tolerance: @@ -131,21 +131,20 @@ def on_activate(self): def on_deactivate(self): self._andor.SetTemperature(self._shutoff_temp) - + attempts = 0 while attempts < 3: current_temp = self._andor.GetTemperature()[1] - if np.abs(current_temp - self._shutoff_temp) > self._temp_tolerance: - self._andor.SetTemperature(self._shutoff_temp) + if np.abs(current_temp - self._shutoff_temp) <= self._temp_tolerance: + break - self.log.warning( - f'Andor temperature ({current_temp}) not within tolerance of shutoff set point ({self.set_temp}).\nPausing to allow it to stabilize attempt {attempts}/3' - ) - time.sleep(5) - attempts += 1 + self._andor.SetTemperature(self._shutoff_temp) - else: - break + self.log.warning( + f'Andor temperature ({current_temp}) not within tolerance of shutoff set point ({self.set_temp}).\nPausing to allow it to stabilize attempt {attempts}/3' + ) + time.sleep(5) + attempts += 1 current_temp = self._andor.GetTemperature()[1] self.log.info(f'Shutoff temperature stabilized at {current_temp} C.') @@ -242,8 +241,7 @@ def stop_acquisition(self) -> bool: """ self._andor.AbortAcquisition() (ret) = self._andor.GetStatus() - success = self._error_handler(ret) - return success + return self._error_handler(ret) def get_acquired_data(self) -> np.ndarray: """ Return an array of last acquired image. @@ -311,7 +309,7 @@ def _error_handler(self, ret: int, msg: str = None) -> bool: if (ret != atmcd_errors.Error_codes.DRV_SUCCESS.value): err = atmcd_errors.Error_Codes(ret).name out = f'Andor Error: {err}' if msg is None \ - else f'Andor Error -- {msg}: {err}' + else f'Andor Error -- {msg}: {err}' self.log.exception(out) return False return True @@ -322,12 +320,12 @@ def _error_handler(self, ret: int, msg: str = None) -> bool: def _abort_if_running(self) -> None: """ Convenience function to check if currently acquiring or waiting """ - + if self._check_if_running(): self._andor.AbortAcquisition() - def _multi_run_functions(self, named_funcs: list[tuple[str, function]]) -> bool: + def _multi_run_functions(self, named_funcs: list[tuple[str, Callable]]) -> bool: """ Convenience function to run a list of named functions in order. Returns True on success and False on failure. """ diff --git a/src/qudi/hardware/daq/nidaq.py b/src/qudi/hardware/daq/nidaq.py index 597c667..f45839e 100644 --- a/src/qudi/hardware/daq/nidaq.py +++ b/src/qudi/hardware/daq/nidaq.py @@ -1,12 +1,8 @@ import nidaqmx -import numpy as np -from PySide2 import QtCore -from typing import Union, Optional, List, Tuple, Sequence, Any, Dict +from typing import List, Any, Dict from qudi.core.configoption import ConfigOption -from qudi.core.connector import Connector -from qudi.util.mutex import Mutex from qudi.interface.daq_reader_interface import DAQReaderInterface, InputType, \ ReaderVal @@ -25,13 +21,13 @@ class NIDAQ(DAQReaderInterface): signal: description: 'Input Signal' type: 0 # 0 for Digital, 1 for Analog - name: 'line0' # The name as idintified by the card + name: 'line0' # The name as identified by the card port: 1 # port number identified by the card """ # config options _daq_name: str = ConfigOption(name='device_str', default='Dev1', - missing='warn') + missing='warn') _daq_ch_config: Dict[str, Dict[str, Any]] = ConfigOption( name='channels', @@ -56,7 +52,7 @@ def on_activate(self): name=v['name'], port=v['port'], description=v['description'], - ) for _,v in self._daq_ch_config + ) for _,v in self._daq_ch_config.items() ) self._analog_channels: List[ReaderVal] = [] @@ -98,12 +94,13 @@ def get_reading(self) -> List[ReaderVal]: if (len(self._digital_channels) > 0): with nidaqmx.Task() as task: - for i in self._analog_channels: + for i in self._digital_channels: chan = self._get_channel(i) task.di_channels.add_di_chan(chan) data = task.read() - if len(data) == 1: + # if len(data) == 1: + if not isinstance(data, list): data = [data] self._update_vals(data, self._analog_channels) @@ -116,7 +113,7 @@ def get_reading(self) -> List[ReaderVal]: def _get_channel(self, chan: ReaderVal) -> str: - return f'{self._daq_name}/port{chan.port}/{chan.name}' + return f"{self._daq_name}/port{chan.port}/{chan.name}" def _update_vals(self, vals: List[float], chans: List[ReaderVal]) -> None: """ Updates channels in-place with new value. Assumes one sample per channel diff --git a/src/qudi/hardware/dummy/daq_dummy.py b/src/qudi/hardware/dummy/daq_reader_dummy.py similarity index 90% rename from src/qudi/hardware/dummy/daq_dummy.py rename to src/qudi/hardware/dummy/daq_reader_dummy.py index 270f919..4a61063 100644 --- a/src/qudi/hardware/dummy/daq_dummy.py +++ b/src/qudi/hardware/dummy/daq_reader_dummy.py @@ -28,7 +28,7 @@ class DAQReaderDummy(DAQReaderInterface): Example config for copy-paste: - daq_dummy: + daq_reader_dummy: module.Class: 'dummy.daq_reader_dummy.DAQReaderDummy' """ @@ -41,13 +41,12 @@ def __init__(self, *args, **kwargs): def on_activate(self): """ Initialisation performed during activation of the module. """ - daq = self._daq() - self._current_data = daq.get_reading() + self._current_data = 0 self.__timer = QtCore.QTimer() - self.__timer.timeout.connect(50) # Switches every 50 ms + self.__timer.timeout.connect(self.__data_update) self.__timer.setSingleShot(False) - self.__timer.start(int(self.__data_update)) + self.__timer.start(50) # Switches every 50 ms def on_deactivate(self): @@ -56,10 +55,10 @@ def on_deactivate(self): self.__timer.stop() self.__timer.timeout.disconnect() self.__timer = None - + @property def active_channels(self) -> List[str]: """ Read-only property returning the currently configured active channel names """ - return 'Dummy Channel' + return ['Dummy Channel'] def get_reading(self) -> List[ReaderVal]: diff --git a/src/qudi/hardware/dummy/scanning_laser_dummy.py b/src/qudi/hardware/dummy/scanning_laser_dummy.py index c0c3aa8..1634cf4 100644 --- a/src/qudi/hardware/dummy/scanning_laser_dummy.py +++ b/src/qudi/hardware/dummy/scanning_laser_dummy.py @@ -23,6 +23,7 @@ import math import time import random +from typing import List from qudi.interface.scanning_laser_interface import ScanningLaserInterface from qudi.interface.scanning_laser_interface import LaserState, ShutterState @@ -33,7 +34,7 @@ class ScanningLaserDummy(ScanningLaserInterface): Example config for copy-paste: - laser_dummy: + scanning_laser_dummy: module.Class: 'dummy.scanning_laser_dummy.ScanningLaserDummy' """ @@ -68,6 +69,9 @@ def set_power(self, power: float): """ pass + def get_power_range(self) -> List[float]: + return [0, 10] + def get_power_setpoint(self): """ Return optical power setpoint. diff --git a/src/qudi/hardware/laser/solstis_funcs.py b/src/qudi/hardware/laser/solstis_funcs.py index b739693..24311b7 100644 --- a/src/qudi/hardware/laser/solstis_funcs.py +++ b/src/qudi/hardware/laser/solstis_funcs.py @@ -2,7 +2,7 @@ import socket import json -from solstis_constants import * +from qudi.hardware.laser.solstis_constants import * """ https://github.com/Rywais/solstis_tcpip""" diff --git a/src/qudi/hardware/laser/solstis_laser.py b/src/qudi/hardware/laser/solstis_laser.py index dfba53f..ed0560d 100644 --- a/src/qudi/hardware/laser/solstis_laser.py +++ b/src/qudi/hardware/laser/solstis_laser.py @@ -15,13 +15,14 @@ You should have received a copy of the GNU Lesser General Public License along with qudi. If not, see . """ +from typing import List from qudi.core.configoption import ConfigOption from qudi.interface.scanning_laser_interface import ScanningLaserInterface from qudi.interface.scanning_laser_interface import ShutterState -import solstis_funcs as solstis -from solstis_constants import * +import qudi.hardware.laser.solstis_funcs as solstis +from qudi.hardware.laser.solstis_constants import * class SolstisLaser(ScanningLaserInterface): @@ -34,22 +35,24 @@ class SolstisLaser(ScanningLaserInterface): options: host_ip_addr: '192.168.1.225' # IP address of control computer laser_ip_addr: '192.168.1.222' # IP address of laser - laser_port: '39933' # Port number to connect on - scan_rate: '13' # See "solstis_constants.py" TeraScanRate Enum for values - scan_type: '2' # see "solstis_constants.py" TeraScanType Enum for values + laser_port: 39933 # Port number to connect on + scan_rate: 13 # See "solstis_constants.py" TeraScanRate Enum for values + scan_type: 2 # see "solstis_constants.py" TeraScanType Enum for values """ - host_ip : str = ConfigOption(name='host_ip_addr', default='192.168.1.225', missing='warn') - laser_ip : str = ConfigOption(name='laser_ip_addr', default='192.168.1.222', missing='warn') - laser_port : int = ConfigOption(name='laser_port', default=39933, missing='warn') + _host_ip = ConfigOption(name='host_ip_addr', default='192.168.1.225', missing='warn') + _laser_ip = ConfigOption(name='laser_ip_addr', default='192.168.1.222', missing='warn') + _laser_port = ConfigOption(name='laser_port', default=39933, missing='warn') - scan_rate : TeraScanRate = ConfigOption(name='scan_rate', default=13, missing='warn') - scan_type : TeraScanType = ConfigOption(name='scan_type', default=2, missing='warn') + _scan_rate = ConfigOption(name='scan_rate', default=13, missing='warn') + _scan_type= ConfigOption(name='scan_type', default=2, missing='warn') def on_activate(self): """ Activate module. """ self.connect_laser() + self._scan_rate = TeraScanRate(self._scan_rate) + self._scan_type = TeraScanType(self._scan_type) def on_deactivate(self): """ Deactivate module. @@ -59,13 +62,12 @@ def on_deactivate(self): def connect_laser(self) -> bool: """ Connect to Instrument. - @param str interface: visa interface identifier - @return bool: connection success """ try: - self.socket = solstis.init_socket(address=self.laser_ip, - port=self.laser_port) + self.socket = solstis.init_socket(address=self._laser_ip, + port=self._laser_port) + solstis.start_link(sock=self.socket, ip_address=self._host_ip) except solstis.SolstisError as e: self.log.exception(f'Communication Failure: {e.message}') return False @@ -99,12 +101,12 @@ def get_power_setpoint(self) -> float: """ return -1 - def get_power_range(self) -> float[2]: + def get_power_range(self) -> List[float]: """ Get laser power range. (unimplemented) @return float[2]: laser power range """ - return 0, -1 + return [0, -1] def set_power(self, power: float): """ Set laser power (unimplemented) @@ -151,8 +153,7 @@ def get_laser_state(self): """ try: - answer = solstis.get_status(self.socket) - return answer + return solstis.scan_stitch_status(self.socket, self._scan_type) except solstis.SolstisError as e: self.log.exception(f'Failure getting status: {e.message}') return -1 @@ -181,8 +182,8 @@ def start_scan(self, start, stop) -> bool: @return bool: True on success, False on failure """ try: - solstis.scan_stitch_initialize(self.socket, self.scan_type, - start*1e3, stop*1e3, self.scan_rate) + solstis.scan_stitch_initialize(self.socket, self._scan_type, + start*1e3, stop*1e3, self._scan_rate) solstis.terascan_output(self.socket, transmission_id=1, @@ -190,7 +191,7 @@ def start_scan(self, start, stop) -> bool: delay=1, update_step=0, pause=True) - solstis.scan_stitch_op(self.socket, self.scan_type, "start") + solstis.scan_stitch_op(self.socket, self._scan_type, "start") return True except solstis.SolstisError as e: @@ -201,7 +202,7 @@ def start_scan(self, start, stop) -> bool: def stop_scan(self) -> bool: """Stop a running scan""" try: - solstis.scan_stitch_op(self.socket, self.scan_type, "stop") + solstis.scan_stitch_op(self.socket, self._scan_type, "stop") return True except solstis.SolstisError as e: diff --git a/src/qudi/hardware/timetagger/swabian_tagger.py b/src/qudi/hardware/timetagger/swabian_tagger.py index 34e2528..2f32926 100644 --- a/src/qudi/hardware/timetagger/swabian_tagger.py +++ b/src/qudi/hardware/timetagger/swabian_tagger.py @@ -33,7 +33,7 @@ class SwabianTimeTagger(FastCounterInterface): Example config for copy-paste: - swabiantimetagger: + swabian_timetagger: module.Class: 'timetagger.swabian_tagger.SwabianTimeTagger' options: channels: @@ -63,6 +63,7 @@ def on_activate(self): self._tagger = tt.createTimeTagger() self._tagger.reset() + self.counter = None self.statusvar = 0 @@ -115,10 +116,11 @@ def get_constraints(self): def on_deactivate(self): """ Deactivate the FPGA. """ - if self.module_state() == 'locked': - self.counter.stop() - self.counter.clear() - self.counter = None + if (self.counter is not None): + if self.module_state() == 'locked': + self.counter.stop() + self.counter.clear() + self.counter = None tt.freeTimeTagger(self._tagger) def configure(self, bin_width_s, record_length_s): diff --git a/src/qudi/hardware/wavemeter/high_finesse_proxy.py b/src/qudi/hardware/wavemeter/high_finesse_proxy.py index 87423c6..fd2ab34 100644 --- a/src/qudi/hardware/wavemeter/high_finesse_proxy.py +++ b/src/qudi/hardware/wavemeter/high_finesse_proxy.py @@ -21,7 +21,7 @@ You should have received a copy of the GNU Lesser General Public License along with qudi. If not, see . """ - +import os import time from typing import Optional, List, Set, TYPE_CHECKING, Dict from ctypes import byref, cast, c_double, c_int, c_char_p, c_long, POINTER, WINFUNCTYPE, WinDLL diff --git a/src/qudi/interface/scanning_laser_interface.py b/src/qudi/interface/scanning_laser_interface.py index 7dc9a79..445b788 100644 --- a/src/qudi/interface/scanning_laser_interface.py +++ b/src/qudi/interface/scanning_laser_interface.py @@ -21,6 +21,7 @@ from enum import IntEnum from abc import abstractmethod +from typing import List from qudi.core.module import Base class ShutterState(IntEnum): @@ -48,7 +49,7 @@ class ScanningLaserInterface(Base): """ @abstractmethod - def get_power_range(self) -> float[2]: + def get_power_range(self) -> List[float]: """ Return laser power range @return float[2]: power range (min, max) diff --git a/src/qudi/logic/common/daq_reader_logic.py b/src/qudi/logic/common/daq_reader_logic.py index 1353d83..5c6565e 100644 --- a/src/qudi/logic/common/daq_reader_logic.py +++ b/src/qudi/logic/common/daq_reader_logic.py @@ -43,7 +43,7 @@ class DAQReaderLogic(LogicBase): """ # declare connectors - _daq = Connector(name='daq', interface='DaqReaderInterface') + _daq = Connector(name='daq', interface='DAQReaderInterface') # declare config options _update_interval = ConfigOption(name='update_period', @@ -53,11 +53,7 @@ class DAQReaderLogic(LogicBase): # signals - sigNewData = QtCore.Signal(List[ReaderVal]) - - - # status variables: - _current_data = StatusVar('current_data', default=[]) + sigNewData = QtCore.Signal(object) # is a List[ReaderVal] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -67,8 +63,8 @@ def __init__(self, *args, **kwargs): def on_activate(self): """ Initialisation performed during activation of the module. """ - daq = self._daq() - self._current_data = daq.get_reading() + # daq = self._daq() + # self._current_data = [daq.get_reading()] self.__timer = QtCore.QTimer() self.__timer.timeout.connect(self.__data_update) diff --git a/src/qudi/logic/common/fast_counter_logic.py b/src/qudi/logic/common/fast_counter_logic.py index b669986..4d970a7 100644 --- a/src/qudi/logic/common/fast_counter_logic.py +++ b/src/qudi/logic/common/fast_counter_logic.py @@ -22,7 +22,7 @@ class FastCounterLogic(LogicBase): """ # declare connectors - _counter = Connector(name='counter', interface='FastCounterInterface') + _counter = Connector(name='fast_counter', interface='FastCounterInterface') sigScanStarted = QtCore.Signal() sigScanFinished = QtCore.Signal(np.ndarray) @@ -64,16 +64,14 @@ def configure(self, record_length_s: float = None ) -> None: - if (bin_width_s is not None): - if (bin_width_s > 0): - self._bin_width_s = bin_width_s + if bin_width_s is not None and bin_width_s > 0: + self._bin_width_s = bin_width_s - if (record_length_s is not None): - if (record_length_s > 0): - self._record_length_s = record_length_s - + if record_length_s is not None and record_length_s > 0: + self._record_length_s = record_length_s if (self._bin_width_s >= self._record_length_s): - self.__logger.warning('Bin width is greater than or equal to record length') + # self.__logger.warning('Bin width is greater than or equal to record length') + print('Bin width is greater than or equal to record length') with self._thread_lock: counter = self._counter() @@ -83,6 +81,7 @@ def configure(self, def start_counter(self): with self._thread_lock: counter = self._counter() + counter.configure(self._bin_width_s, self._record_length_s) counter.start_measure() self.__timer.start(int(self._record_length_s*1000) + 1) self.sigScanStarted.emit() diff --git a/src/qudi/logic/common/scanning_laser_logic.py b/src/qudi/logic/common/scanning_laser_logic.py index 2ff01f5..7508af7 100644 --- a/src/qudi/logic/common/scanning_laser_logic.py +++ b/src/qudi/logic/common/scanning_laser_logic.py @@ -38,8 +38,8 @@ class ScanningLaserLogic(LogicBase): connect: laser: scanning_laser_dummy options: - min_wavelength: 0.775 # in um - max_wavelength: 0.790 # in um + min_wavelength: 0.700 # in um + max_wavelength: 0.800 # in um """ @@ -62,8 +62,8 @@ class ScanningLaserLogic(LogicBase): # status variables: - _start_wavelength = StatusVar('start_wavelength', default=0.75) - _end_wavelength = StatusVar('end_wavelength', default=0.8) + _start_wavelength = StatusVar('start_wavelength', default=0.78) + _end_wavelength = StatusVar('end_wavelength', default=0.785) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -77,18 +77,18 @@ def on_activate(self): laser = self._laser() self._wavelength = laser.get_wavelength() - # self.__timer = QtCore.QTimer() - # self.__timer.timeout.connect(self.__status_update) - # self.__timer.setSingleShot(False) - # self.__timer.start(int(self._update_interval * 1000) + 1) + self.__timer = QtCore.QTimer() + self.__timer.timeout.connect(self.__status_update) + self.__timer.setSingleShot(False) + self.__timer.start(100) # Check every 100 ms # self.__timer.start(0) # 0-timer to call as often as possible def on_deactivate(self): """ Perform required deactivation. """ - # self.__timer.stop() - # self.__timer.timeout.disconnect() - # self.__timer = None + self.__timer.stop() + self.__timer.timeout.disconnect() + self.__timer = None @property def wavelength(self) -> float: @@ -96,47 +96,37 @@ def wavelength(self) -> float: @property def tolerance(self) -> float: - return self._wavelength_tol + return -1 @QtCore.Slot(float, float) - def set_wavelengths(self, start: float = None, stop: float = None) -> None: - if start is not None: - if (start > self._min_wavelength): - self._start_wavelength = start - else: - self.__logger.warning('Minimum wavelength set below minimum value') - self._start_wavelength = self._min_wavelength - - if stop is not None: - if (stop < self._max_wavelength): - self._stop_wavelength = stop - else: - self.__logger.warning('Maximum wavelength set above maximum value') - self._stop_wavelength = self._max_wavelength + def set_wavelengths(self, start: float, stop: float) -> None: + self._start_wavelength = max(start, self._min_wavelength) + self._end_wavelength = min(stop, self._max_wavelength) @QtCore.Slot() def start_scan(self): - with self._thread_lock: - laser = self._laser() - laser.start_scan(self._start_wavelength, self._stop_wavelength) - self.sigScanStarted.emit() + if self.module_state() == 'idle': + with self._thread_lock: + print('starting scan in scanning_laser_logic') + laser = self._laser() + laser.start_scan(self._start_wavelength, self._end_wavelength) + self.sigScanStarted.emit() + self.module_state.lock() @QtCore.Slot() def stop_scan(self): + if self.module_state() == 'locked': + with self._thread_lock: + laser = self._laser() + laser.stop_scan() + self.sigScanFinished.emit() + self.module_state.unlock() + + def __status_update(self): with self._thread_lock: - laser = self._laser() - laser.stop_scan() - self.sigScanFinished.emit() - - # def __status_update(self): - # with self._thread_lock: - # laser = self._laser() - # new_wave = laser.get_wavelength() - - # tol = self._wavelength_tol - # if np.abs(self._wavelength - self._stop_wavelength) < tol: - # self.sigScanFinished.emit() - - # if not np.abs(new_wave - self._wavelength) < tol: - # self._wavelength = new_wave - # self.sigWavelengthChanged.emit(new_wave) + if self.module_state() == 'locked': + laser = self._laser() + status = laser.get_laser_state() + if status['in_progress'] == False: + self.sigScanFinished.emit() + self.module_state.unlock() diff --git a/src/qudi/logic/terascan_logic.py b/src/qudi/logic/terascan_logic.py index d6a1b6a..3efc386 100644 --- a/src/qudi/logic/terascan_logic.py +++ b/src/qudi/logic/terascan_logic.py @@ -65,7 +65,7 @@ class TerascanLogic(LogicBase): # Update signals, e.g. for GUI module sigWavelengthUpdated = QtCore.Signal(float) - sigCountsUpdated = QtCore.Signal(List[TerascanData]) + sigCountsUpdated = QtCore.Signal(object) # is a List[TerascanData] sigConfigureCounter = QtCore.Signal(float, float) sigConfigureLaser = QtCore.Signal(float, float) @@ -123,9 +123,11 @@ def on_deactivate(self): @QtCore.Slot() def start_scan(self): with self._thread_lock: + print('start_scan in tereascan_logic.py') if self.module_state() == 'idle': self.module_state.lock() self._current_data = [] + print('actually start_scan in tereascan_logic.py') self.sigStartScan.emit() @QtCore.Slot() @@ -163,8 +165,9 @@ def _laser_scan_finished(self): def _new_wavemeter_data(self, data: object, timestamps: object): with self._thread_lock: if self.module_state() == 'locked' and self._laser_locked: - self._current_wavelength = data # ? - self.sigWavelengthUpdated.emit(data) + wave = np.average(data) + self._current_wavelength = wave # ? + self.sigWavelengthUpdated.emit(wave) @QtCore.Slot(np.ndarray) def _process_counter_data(self, data: np.ndarray): @@ -178,7 +181,7 @@ def _process_counter_data(self, data: np.ndarray): ) self.sigCountsUpdated.emit(self._current_data) - @QtCore.Slot(List[ReaderVal]) + @QtCore.Slot(object) def _new_daq_data(self, data: List[ReaderVal]): with self._thread_lock: if self.module_state() == 'locked':