# -*- coding: utf-8 -*- """ Here the class of control signals are created. There are two types: analog and digital. """ import sys if sys.platform == 'linux': try: from drivers.ADoutputs_linux import daq_AO, daq_DO except Exception: print('No MCCDAQ found') from drivers.ADoutputs import daq_AO, daq_DO else: from drivers.ADoutputs import daq_AO, daq_DO from PyQt5 import QtCore from subclasses.controllayouts import LaserControlLayout from subclasses.controllayouts import LaserScanLayout import numpy as np AO_TYPES = ['cavity_piezo', 'electrode', 'laser_piezo'] class anal_control_signal(QtCore.QObject): _registry = [] scanStepSignal = QtCore.pyqtSignal(float) scanEndSignal = QtCore.pyqtSignal(float) def __init__(self, name, channel, ao_type, out_minimum = -10, out_maximum = 10, out_step = 0.1, feedfoward = False): super().__init__() if name in [ao.name for ao in self._registry]: raise ValueError('Two analog control signals cannot share the name: %s used already' % (name)) if channel in [ao.ch for ao in self._registry]: raise ValueError('Two analog control signals cannot share the channel: channel %s used already' % (channel)) if ao_type not in AO_TYPES: raise ValueError("Invalid ao type. Expected one of: %s" % AO_TYPES) self._registry.append(self) self.name = name self.ch = channel self.ao_type = ao_type self.AO = daq_AO(self.ch) self.is_feedwoward_enabled = feedfoward self.initial_value = 0 self.max = out_maximum self.min = out_minimum self.step = out_step self.siPrefix = True self.suffix = 'V' self.scanTimer = QtCore.QTimer() self.current_scan_step = 0 self.scan_array_gen = None def make_connections(self, frontend): for layout in LaserControlLayout._registry: if self.name in layout.spinboxes: layout.spinboxes[self.name].setMinimum(self.min) layout.spinboxes[self.name].setMaximum(self.max) layout.spinboxes[self.name].sigValueChanging.connect(self.sb_change) scan_layouts = [l for l in LaserScanLayout._registry if l.name == self.name] for scan_layout in scan_layouts: scan_layout.spinboxes['start'].setMinimum(self.min) scan_layout.spinboxes['start'].setMaximum(self.max) scan_layout.spinboxes['stop'].setMinimum(self.min) scan_layout.spinboxes['stop'].setMaximum(self.max) def name(self): return self.name def scan_event(self): self.current_scan_step = next(self.scan_array_gen) self.AO.set_out(self.current_scan_step) self.scanStepSignal.emit(self.current_scan_step) @QtCore.pyqtSlot(object) def scan_action(self, scan_array_gen): print('action') if self.scanTimer.isActive(): print('stop timer') self.scanTimer.stop() self.scanEndSignal.emit(self.current_scan_step) else: print('start timer') self.scan_array_gen = scan_array_gen self.scanTimer.start(5.0) @QtCore.pyqtSlot(object, object) def sb_change(self, sb, value): self.AO.set_out(value) def go_softly_to_value(self, target_value): start = self.AO.current_value if start==None: start = self.initial_value end = target_value steps_size = 0.002 array_of_steps= np.arange(min(start, end), max(start, end) + steps_size , steps_size) if endself.min: self.AO.set_out(i) class digital_control_signal(QtCore.QObject): _registry = [] def __init__(self, name, channel, inverse=True): super().__init__() self._registry.append(self) self.name = name self.ch = channel self.initial_value = 0 self.DO = daq_DO(self.ch) self.inverse = inverse def make_connections(self, frontend): for layout in LaserControlLayout._registry: if self.name in layout.checkboxes: layout.checkboxes[self.name].stateChanged.connect(self.when_change_digital) @QtCore.pyqtSlot(int) def when_change_digital(self, state): if state == QtCore.Qt.Checked: if self.inverse: self.DO.set_out(True) else: self.DO.set_out(False) else: if self.inverse: self.DO.set_out(False) else: self.DO.set_out(True)