MCDAQcontrolsignals.py 4.27 KB
Newer Older
1 2
 # -*- coding: utf-8 -*-
"""
3
Here the class of control signals are created. There are two types: analog and digital.
4
"""
5
from drivers.ADoutputs import daq_AO, daq_DO
6
from PyQt5 import QtCore
7 8
from subclasses.controllayouts import LaserControlLayout
from subclasses.controllayouts import LaserScanLayout
9
import numpy as np
10 11 12 13

AO_TYPES = ['cavity_piezo', 'electrode', 'laser_piezo']

class anal_control_signal(QtCore.QObject):
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    _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)
88 89 90 91 92 93 94 95 96 97 98 99 100 101
        
    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:
            self.AO.set_out(i)
        
102

103

104
class digital_control_signal(QtCore.QObject):
105
    _registry = []
106

107 108 109
    def __init__(self, name, channel, inverse=False):
        super().__init__()
        self._registry.append(self)
110

111 112 113 114
        self.name = name
        self.ch = channel
        self.initial_value = 0    
        self.DO = daq_DO(self.ch)
115

116
    def make_connections(self, frontend):
117

118 119 120
        for layout in LaserControlLayout._registry:
            if self.name in layout.checkboxes:
                layout.checkboxes[self.name].stateChanged.connect(self.when_change_digital)
121

122 123 124 125 126 127
    @QtCore.pyqtSlot(int)
    def when_change_digital(self, state):
        if state == QtCore.Qt.Checked:
            self.DO.set_out(True)
        else:
            self.DO.set_out(False)