Commit a1922349 authored by Martin Drechsler's avatar Martin Drechsler

starting to build new gui

parent f00ff9e8
# -*- coding: utf-8 -*-
"""
This is a temporary script file.
Here the class of control signals are created. There are two types: analog and digital.
"""
import numpy as np
from ADoutputs import daq_AO, daq_DO
from PyQt5 import QtCore
from subclasses.controllayouts import LaserControlLayout
from subclasses.controllayouts import LaserScanLayout
AO_TYPES = ['cavity_piezo', 'electrode', 'laser_piezo']
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):
super().__init__()
......@@ -21,13 +24,62 @@ class anal_control_signal(QtCore.QObject):
self.name = name
self.ch = channel
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.initial_value = 0
self.max = out_maximum
self.min = out_minimum
self.step = out_step
self.siPrefix = True
self.suffix = 'V'
\ No newline at end of file
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):
self.scan_sb_start.setEnabled(True)
self.scan_sb_stop.setEnabled(True)
else:
dt = 5.0e-3
dt = 5.0e-3
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_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_sb_period.val, first_value, dt,
normalized=True, normalization_constant = float(self.scan_feedfoward_sb.val) )
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):
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)
......
......@@ -2,30 +2,33 @@ from pyqtgraph import dockarea
from pyqtgraph.Qt import QtGui, QtCore
from PyQt5.QtWidgets import QPushButton, QProgressBar, QLabel
import pyqtgraph as pg
import numpy as np
import scanFunctions
from messages import show_warning
class CustomSpinBox(pg.SpinBox):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self._on_context_menu)
self.popMenu = QtGui.QMenu(self)
self.act_2_step = QtGui.QAction('2 mV step', self)
self.act_5_step = QtGui.QAction('5 mV step', self)
self.act_10_step = QtGui.QAction('10 mV step', self)
self.act_100_step = QtGui.QAction('100 mV step', self)
self.popMenu.addAction(self.act_2_step)
self.popMenu.addAction(self.act_5_step)
self.popMenu.addAction(self.act_10_step)
self.popMenu.addAction(self.act_100_step)
self.act_2_step.triggered.connect(lambda: self.setSingleStep(0.002))
self.act_5_step.triggered.connect(lambda: self.setSingleStep(0.005))
self.act_10_step.triggered.connect(lambda: self.setSingleStep(0.01))
self.act_100_step.triggered.connect(lambda: self.setSingleStep(0.1))
if self.opts['suffix'] == 'V': # fixing a context menu with some scales
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self._on_context_menu)
self.popMenu = QtGui.QMenu(self)
self.act_2_step = QtGui.QAction('2 mV step', self)
self.act_5_step = QtGui.QAction('5 mV step', self)
self.act_10_step = QtGui.QAction('10 mV step', self)
self.act_100_step = QtGui.QAction('100 mV step', self)
self.popMenu.addAction(self.act_2_step)
self.popMenu.addAction(self.act_5_step)
self.popMenu.addAction(self.act_10_step)
self.popMenu.addAction(self.act_100_step)
self.act_2_step.triggered.connect(lambda: self.setSingleStep(0.002))
self.act_5_step.triggered.connect(lambda: self.setSingleStep(0.005))
self.act_10_step.triggered.connect(lambda: self.setSingleStep(0.01))
self.act_100_step.triggered.connect(lambda: self.setSingleStep(0.1))
def _on_context_menu(self, point):
# show context menu
......@@ -35,15 +38,17 @@ class LaserControlLayout(pg.LayoutWidget):
"""
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']):
super().__init__()
self._registry.append(self)
self.name = name
self.layout.addWidget(QtGui.QLabel(self.name), 0, 0)
self.spinboxes = {}
self.checkboxes = {}
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(self.spinboxes[sb_name], i, 1)
......@@ -59,15 +64,19 @@ class LaserScanLayout(pg.LayoutWidget):
"""
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__()
self._registry.append(self)
self.name = name
self.signal_to_scan_layout = signal_to_scan_layout
self.addWidget(QtGui.QLabel(self.name), 0, 0)
self.spinboxes = {}
self.spinboxes['start'] = CustomSpinBox()
self.spinboxes['stop'] = CustomSpinBox()
self.spinboxes['period'] = CustomSpinBox()
self.spinboxes['start'] = CustomSpinBox(siPrefix=True, suffix='V')
self.spinboxes['stop'] = CustomSpinBox(siPrefix=True, suffix='V')
self.spinboxes['period'] = CustomSpinBox(siPrefix=True, suffix='s')
self.scan_button = QPushButton('Start scan')
self.scanpBar = QProgressBar(self)
self.scanLabelValue = QLabel(self)
......@@ -84,7 +93,57 @@ class LaserScanLayout(pg.LayoutWidget):
self.addWidget(self.scanLabelValue, 5, 0)
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__':
import sys
......
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