Skip to content
MCDAQcontrolsignals.py 4.74 KiB
Newer Older
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 subclasses.controllayouts import LaserControlLayout
from subclasses.controllayouts import LaserScanLayout

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 end<start:
            array_of_steps = array_of_steps[::-1]
        for i in array_of_steps:
            if i<self.max and i>self.min:
                self.AO.set_out(i)
class digital_control_signal(QtCore.QObject):
    def __init__(self, name, channel, inverse=True):
        self.name = name
        self.ch = channel
        self.initial_value = 0    
        self.DO = daq_DO(self.ch)
        self.inverse = inverse
        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)
            if self.inverse:
                self.DO.set_out(False)
            else:
                self.DO.set_out(True)