Commit a1922349 authored by Martin Drechsler's avatar Martin Drechsler

starting to build new gui

parent f00ff9e8
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Here the class of control signals are created. There are two types: analog and digital.
This is a temporary script file.
""" """
import numpy as np
from ADoutputs import daq_AO, daq_DO from ADoutputs import daq_AO, daq_DO
from PyQt5 import QtCore from PyQt5 import QtCore
from subclasses.controllayouts import LaserControlLayout
from subclasses.controllayouts import LaserScanLayout
AO_TYPES = ['cavity_piezo', 'electrode', 'laser_piezo'] AO_TYPES = ['cavity_piezo', 'electrode', 'laser_piezo']
class anal_control_signal(QtCore.QObject): class anal_control_signal(QtCore.QObject):
_registry = [] _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): def __init__(self, name, channel, ao_type, out_minimum = -10, out_maximum = 10, out_step = 0.1, feedfoward = False):
super().__init__() super().__init__()
...@@ -21,13 +24,62 @@ class anal_control_signal(QtCore.QObject): ...@@ -21,13 +24,62 @@ class anal_control_signal(QtCore.QObject):
self.name = name self.name = name
self.ch = channel self.ch = channel
self.ao_type = ao_type self.ao_type = ao_type
try:
self.AO = daq_AO(self.ch)
except:
show_warning('Analog output %i not found. Daq might not be connected' % self.ch)
self.is_feedwoward_enabled = feedfoward self.is_feedwoward_enabled = feedfoward
self.initial_value = 0 self.initial_value = 0
self.max = out_maximum self.max = out_maximum
self.min = out_minimum self.min = out_minimum
self.step = out_step self.step = out_step
self.siPrefix = True self.siPrefix = True
self.suffix = 'V' self.suffix = 'V'
self.scanTimer = QtCore.QTimer()
self.current_scan_step = 0
self.scan_array_gen = None
def make_connections(self, frontend):
# internal connections
# external connections
for layout in LaserControlLayout._registry:
if self.name in layout.spinboxes:
print(self.name, ' connected', layout.name)
layout.spinboxes[self.name].setMinimum(self.min)
layout.spinboxes[self.name].setMaximum(self.max)
layout.spinboxes[self.name].setValue(self.initial_value)
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)
# -*- coding: utf-8 -*-
"""
This is the gui where the spinboxes and checkboxes for controlling the mc daq live. Nevertheless, measurements are not
controlled from this Gui. It is more for searching and exploring the paremeters.
@author: Usuario
"""
import sys
from PyQt5 import QtGui, QtCore
import qdarkstyle
import os
os.environ['PYQTGRAPH_QT_LIB'] = 'PyQt5'
from subclasses.controllayouts import LaserControlLayout
from subclasses.controllayouts import LaserScanLayout
from pyqtgraph import dockarea
from MCDAQcontrolsignals import anal_control_signal
class ControlGui(QtGui.QFrame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.area = dockarea.DockArea()
self.grid = QtGui.QGridLayout()
self.grid.addWidget(self.area, 0, 0)
self.setLayout(self.grid)
self.dock_397 = dockarea.Dock('397', (100, 100))
self.dock_866 = dockarea.Dock('866', (100, 100))
self.area.addDock(self.dock_397)
self.area.addDock(self.dock_866, 'left', self.dock_397)
self.laser397_control_layout = LaserControlLayout('397', checkboxes=[], spinboxes = ['piezoA397', 'piezoB397'])
self.laser397_scan_layout = LaserScanLayout(name='piezoA397', signal_to_scan_layout=self.laser397_control_layout)
self.dock_397.addWidget(self.laser397_control_layout)
self.dock_397.addWidget(self.laser397_scan_layout)
self.laser866_control_layout = LaserControlLayout('866', checkboxes=[], spinboxes = ['piezoA866', 'piezoB866'])
self.laser866_scan_layout = LaserScanLayout(name='piezoA866', signal_to_scan_layout=self.laser866_control_layout)
self.dock_866.addWidget(self.laser866_control_layout)
self.dock_866.addWidget(self.laser866_scan_layout)
self.show()
def make_connections(self, backend):
# external connections
scan_layout_list = [scan_layout for scan_layout in LaserScanLayout._registry if scan_layout.name == backend.name]
for scan_layout in scan_layout_list:
scan_layout.scanActionSignal.connect(backend.scan_action)
backend.scanStepSignal.connect(scan_layout.scan_step)
backend.scanEndSignal.connect(scan_layout.scan_end)
if __name__ == '__main__':
app = QtGui.QApplication([])
controlGui = ControlGui()
piezoA397 = anal_control_signal('piezoA397', channel=0, ao_type='cavity_piezo', out_minimum = 0, out_maximum = 4)
piezoB397 = anal_control_signal('piezoB397', channel=1, ao_type='cavity_piezo')
piezoA866 = anal_control_signal('piezoA866', channel=2, ao_type='cavity_piezo', out_minimum = 0, out_maximum = 4)
piezoB866 = anal_control_signal('piezoB866', channel=3, ao_type='cavity_piezo')
mcDAQthread = QtCore.QThread()
for ao in anal_control_signal._registry:
controlGui.make_connections(ao)
ao.make_connections(controlGui)
ao.moveToThread(mcDAQthread)
ao.scanTimer.moveToThread(mcDAQthread)
ao.scanTimer.timeout.connect(ao.scan_event)
mcDAQthread.start()
sys.exit(app.exec_())
\ No newline at end of file
...@@ -172,29 +172,17 @@ class anal_control_signal(QWidget): ...@@ -172,29 +172,17 @@ class anal_control_signal(QWidget):
self.scan_sb_start.setEnabled(True) self.scan_sb_start.setEnabled(True)
self.scan_sb_stop.setEnabled(True) self.scan_sb_stop.setEnabled(True)
else: else:
dt = 5.0e-3 dt = 5.0e-3
first_value = float(self.sb.val) first_value = float(self.sb.val)
self.scan_array = scanFunctions.create_scan_array(self.scan_sb_start.val, self.scan_sb_stop.val, self.scan_sb_period.val, first_value, dt) self.scan_array = scanFunctions.create_scan_array(self.scan_sb_start.val, self.scan_sb_stop.val, self.scan_sb_period.val, first_value, dt)
self.scan_array_gen = scanFunctions.yield_scan_array(self.scan_array) self.scan_array_gen = scanFunctions.yield_scan_array(self.scan_array)
self.scan_array_feedfoward = scanFunctions.create_scan_array(self.scan_sb_start.val, self.scan_sb_stop.val, self.scan_array_feedfoward = scanFunctions.create_scan_array(self.scan_sb_start.val, self.scan_sb_stop.val,
self.scan_sb_period.val, first_value, dt, self.scan_sb_period.val, first_value, dt,
normalized=True, normalization_constant = float(self.scan_feedfoward_sb.val) ) normalized=True, normalization_constant = float(self.scan_feedfoward_sb.val) )
self.scan_array_feedfoward_gen = scanFunctions.yield_scan_array(self.scan_array_feedfoward) self.scan_array_feedfoward_gen = scanFunctions.yield_scan_array(self.scan_array_feedfoward)
# import pylab as plt
# plt.figure()
# plt.plot(self.scan_array, label = 'scan')
# plt.plot(self.scan_array_feedfoward, label = 'feedfoward')
# plt.legend()
# plt.xlabel('u.a'), plt.ylabel('Voltaje [V]')
# plt.show()
#
if first_value > float(self.scan_sb_stop.val) or first_value < float(self.scan_sb_start.val): if first_value > float(self.scan_sb_stop.val) or first_value < float(self.scan_sb_start.val):
details = 'Remember remember the fifth of November.' + '\n' + 'Also remember that scan starts from the value of the corresponding spin box' details = 'Remember remember the fifth of November.' + '\n' + 'Also remember that scan starts from the value of the corresponding spin box'
show_warning('Scan can not start outside scan range and scan start should be lower than scan stop', details_text= details) show_warning('Scan can not start outside scan range and scan start should be lower than scan stop', details_text= details)
......
...@@ -2,13 +2,16 @@ from pyqtgraph import dockarea ...@@ -2,13 +2,16 @@ from pyqtgraph import dockarea
from pyqtgraph.Qt import QtGui, QtCore from pyqtgraph.Qt import QtGui, QtCore
from PyQt5.QtWidgets import QPushButton, QProgressBar, QLabel from PyQt5.QtWidgets import QPushButton, QProgressBar, QLabel
import pyqtgraph as pg import pyqtgraph as pg
import numpy as np
import scanFunctions
from messages import show_warning
class CustomSpinBox(pg.SpinBox): class CustomSpinBox(pg.SpinBox):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.opts['suffix'] == 'V': # fixing a context menu with some scales
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self._on_context_menu) self.customContextMenuRequested.connect(self._on_context_menu)
self.popMenu = QtGui.QMenu(self) self.popMenu = QtGui.QMenu(self)
...@@ -35,15 +38,17 @@ class LaserControlLayout(pg.LayoutWidget): ...@@ -35,15 +38,17 @@ class LaserControlLayout(pg.LayoutWidget):
""" """
A class for creating a layout with spinboxes and checkboxes to control a laser. A class for creating a layout with spinboxes and checkboxes to control a laser.
""" """
_registry = []
def __init__(self, name, spinboxes = ['sbA', 'sbB'], checkboxes = ['cbA', 'cbB']): def __init__(self, name, spinboxes = ['sbA', 'sbB'], checkboxes = ['cbA', 'cbB']):
super().__init__() super().__init__()
self._registry.append(self)
self.name = name self.name = name
self.layout.addWidget(QtGui.QLabel(self.name), 0, 0) self.layout.addWidget(QtGui.QLabel(self.name), 0, 0)
self.spinboxes = {} self.spinboxes = {}
self.checkboxes = {} self.checkboxes = {}
for i, sb_name in enumerate(spinboxes, start = 1): for i, sb_name in enumerate(spinboxes, start = 1):
self.spinboxes[sb_name] = CustomSpinBox() self.spinboxes[sb_name] = CustomSpinBox(siPrefix=True, suffix='V')
self.addWidget(QtGui.QLabel(sb_name), i, 0) self.addWidget(QtGui.QLabel(sb_name), i, 0)
self.addWidget(self.spinboxes[sb_name], i, 1) self.addWidget(self.spinboxes[sb_name], i, 1)
...@@ -59,15 +64,19 @@ class LaserScanLayout(pg.LayoutWidget): ...@@ -59,15 +64,19 @@ class LaserScanLayout(pg.LayoutWidget):
""" """
A class for creating a layout for scanning a laser piezo. A class for creating a layout for scanning a laser piezo.
""" """
def __init__(self, name, feedforward_enables = False): _registry = []
scanActionSignal = QtCore.pyqtSignal(object)
def __init__(self, name, signal_to_scan_layout, feedforward_enables = False):
super().__init__() super().__init__()
self._registry.append(self)
self.name = name self.name = name
self.signal_to_scan_layout = signal_to_scan_layout
self.addWidget(QtGui.QLabel(self.name), 0, 0) self.addWidget(QtGui.QLabel(self.name), 0, 0)
self.spinboxes = {} self.spinboxes = {}
self.spinboxes['start'] = CustomSpinBox() self.spinboxes['start'] = CustomSpinBox(siPrefix=True, suffix='V')
self.spinboxes['stop'] = CustomSpinBox() self.spinboxes['stop'] = CustomSpinBox(siPrefix=True, suffix='V')
self.spinboxes['period'] = CustomSpinBox() self.spinboxes['period'] = CustomSpinBox(siPrefix=True, suffix='s')
self.scan_button = QPushButton('Start scan') self.scan_button = QPushButton('Start scan')
self.scanpBar = QProgressBar(self) self.scanpBar = QProgressBar(self)
self.scanLabelValue = QLabel(self) self.scanLabelValue = QLabel(self)
...@@ -84,6 +93,56 @@ class LaserScanLayout(pg.LayoutWidget): ...@@ -84,6 +93,56 @@ class LaserScanLayout(pg.LayoutWidget):
self.addWidget(self.scanLabelValue, 5, 0) self.addWidget(self.scanLabelValue, 5, 0)
self.addWidget(self.scanpBar, 5, 1) self.addWidget(self.scanpBar, 5, 1)
self.scan_button.clicked.connect(self._scan_button_clicked)
def name(self):
return self.name
@QtCore.pyqtSlot()
def _scan_button_clicked(self):
start = self.spinboxes['start'].value()
stop = self.spinboxes['stop'].value()
period = self.spinboxes['period'].value()
dt = 5.0e-3
first_value = float(self.signal_to_scan_layout.spinboxes[self.name].value())
scan_array = scanFunctions.create_scan_array(start, stop, period, first_value, dt)
scan_array_gen = scanFunctions.yield_scan_array(scan_array)
if first_value > float(stop) or first_value < float(start):
details = 'Remember remember the fifth of November.' + '\n' + 'Also remember that scan starts from the value of the corresponding spin box'
show_warning('Scan can not start outside scan range and scan start should be lower than scan stop', details_text= details)
elif len(scan_array) < 5:
show_warning('%i steps are too few, you need at least 5 steps' % (len(scan_array)) )
elif stop==start:
show_warning('Oh dear, you might be trying to scan from 0 to 0. Plase never do that again.')
else:
self.scanActionSignal.emit(scan_array_gen)
self.scan_button.setText('Stop scan')
self.signal_to_scan_layout.spinboxes[self.name].setEnabled(False)
self.spinboxes['start'].setEnabled(False)
self.spinboxes['stop'].setEnabled(False)
self.scan_button.setStyleSheet("background-color: green")
self.scan_button.setText('Scanning')
@QtCore.pyqtSlot(float)
def scan_step(self, val):
self.pBarEvent(val)
@QtCore.pyqtSlot(float)
def scan_end(self, val):
self.signal_to_scan_layout.spinboxes[self.name].setValue(val)
self.scan_button.setText('Start scan')
self.scan_button.setStyleSheet('background-color: None')
self.signal_to_scan_layout.spinboxes[self.name].setEnabled(True)
self.spinboxes['start'].setEnabled(True)
self.spinboxes['stop'].setEnabled(True)
def pBarEvent(self, current_step):
start = self.spinboxes['start'].value()
stop = self.spinboxes['stop'].value()
self.scanpBar.setValue( 100 * float(current_step-float(start))/float(stop-start) )
self.scanLabelValue.setText("%.2f" % current_step + ' V')
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment