from PyQt4 import QtGui, QtCore, uic from numpy import * # from qtui.QCustomSpinBoxION import QCustomSpinBoxION from qtui.QCustomSpinBox import QCustomSpinBox from twisted.internet.defer import inlineCallbacks, returnValue import sys # sys.path.append('/home/cct/LabRAD/common/abstractdevices') from common.abstractdevices.DacConfiguration import hardwareConfiguration as hc UpdateTime = 100 # ms SIGNALID = 270836 SIGNALID2 = 270835 class MULTIPOLE_CONTROL(QtGui.QWidget): def __init__(self, reactor, parent=None): super(MULTIPOLE_CONTROL, self).__init__(parent) self.reactor = reactor self.connect() @inlineCallbacks def makeGUI(self): self.controls = {k: QCustomSpinBox(k, (-2.,2.)) for k in hc.multipoles} self.controls['U1'] = QCustomSpinBox('U1', (-2., 2.)) self.controls['U2'] = QCustomSpinBox('U2', (0., 20.)) self.controls['U3'] = QCustomSpinBox('U3', (-2., 2.)) self.multipoleValues = {k: 0.0 for k in hc.multipoles} self.ctrlLayout = QtGui.QVBoxLayout() for k in hc.multipoles: self.ctrlLayout.addWidget(self.controls[k]) self.multipoleFileSelectButton = QtGui.QPushButton('Set C File') self.ctrlLayout.addWidget(self.multipoleFileSelectButton) self.inputUpdated = False self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.sendToServer) self.timer.start(UpdateTime) for k in hc.multipoles: self.controls[k].onNewValues.connect(self.inputHasUpdated) self.multipoleFileSelectButton.released.connect(self.selectCFile) self.setLayout(self.ctrlLayout) yield self.followSignal(0, 0) @inlineCallbacks def connect(self): from labrad.wrappers import connectAsync from labrad.types import Error self.cxn = yield connectAsync() self.dacserver = yield self.cxn.dac_server yield self.setupListeners() yield self.makeGUI() def inputHasUpdated(self): self.inputUpdated = True for k in hc.multipoles: self.multipoleValues[k] = round(self.controls[k].spinLevel.value(), 3) def sendToServer(self): if self.inputUpdated: self.dacserver.set_multipole_values(self.multipoleValues.items()) self.inputUpdated = False @inlineCallbacks def selectCFile(self): fn = QtGui.QFileDialog().getOpenFileName() yield self.dacserver.set_multipole_control_file(str(fn)) self.inputHasUpdated() @inlineCallbacks def setupListeners(self): yield self.dacserver.signal__ports_updated(SIGNALID) yield self.dacserver.addListener(listener = self.followSignal, source = None, ID = SIGNALID) @inlineCallbacks def followSignal(self, x, s): try: multipoles = yield self.dacserver.get_multipole_values() for (k,v) in multipoles: self.controls[k].setValueNoSignal(v) except: print '...' def closeEvent(self, x): self.reactor.stop() class CHANNEL_CONTROL (QtGui.QWidget): def __init__(self, reactor, parent=None): super(CHANNEL_CONTROL, self).__init__(parent) self.reactor = reactor self.makeGUI() self.connect() def makeGUI(self): self.dacDict = dict(hc.elecDict.items() + hc.smaDict.items()) self.controls = {k: QCustomSpinBox(k, self.dacDict[k].allowedVoltageRange) for k in self.dacDict.keys()} layout = QtGui.QGridLayout() smaBox = QtGui.QGroupBox('SMA Out') smaLayout = QtGui.QVBoxLayout() smaBox.setLayout(smaLayout) elecBox = QtGui.QGroupBox('Electrodes') elecLayout = QtGui.QGridLayout() elecBox.setLayout(elecLayout) layout.addWidget(smaBox, 0, 0) layout.addWidget(elecBox, 0, 1) for s in hc.smaDict: smaLayout.addWidget(self.controls[s], alignment = QtCore.Qt.AlignRight) elecList = hc.elecDict.keys() elecList.sort() elecList.pop(hc.centerElectrode-1) for i,e in enumerate(elecList): if int(e) <= len(elecList)/2: elecLayout.addWidget(self.controls[e], len(elecList)/2 - int(i), 0) elif int(e) > len(elecList)/2: elecLayout.addWidget(self.controls[e], len(elecList) - int(i), 2) self.controls[str(hc.centerElectrode).zfill(2)].title.setText('CNT') elecLayout.addWidget(self.controls[str(hc.centerElectrode).zfill(2)], len(elecList)/2, 1) spacer = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.MinimumExpanding) smaLayout.addItem(spacer) self.inputUpdated = False self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.sendToServer) self.timer.start(UpdateTime) for k in self.dacDict.keys(): self.controls[k].onNewValues.connect(self.inputHasUpdated(k)) layout.setColumnStretch(1, 1) self.setLayout(layout) @inlineCallbacks def connect(self): from labrad.wrappers import connectAsync from labrad.types import Error self.cxn = yield connectAsync() self.dacserver = yield self.cxn.dac_server yield self.setupListeners() yield self.followSignal(0, 0) def inputHasUpdated(self, name): def iu(): self.inputUpdated = True self.changedChannel = name return iu def sendToServer(self): if self.inputUpdated: self.dacserver.set_individual_analog_voltages([(self.changedChannel, round(self.controls[self.changedChannel].spinLevel.value(), 3))]) self.inputUpdated = False @inlineCallbacks def setupListeners(self): yield self.dacserver.signal__ports_updated(SIGNALID2) yield self.dacserver.addListener(listener = self.followSignal, source = None, ID = SIGNALID2) @inlineCallbacks def followSignal(self, x, s): av = yield self.dacserver.get_analog_voltages() for (c, v) in av: self.controls[c].setValueNoSignal(v) def closeEvent(self, x): self.reactor.stop() class CHANNEL_MONITOR(QtGui.QWidget): def __init__(self, reactor, parent=None): super(CHANNEL_MONITOR, self).__init__(parent) self.reactor = reactor self.makeGUI() self.connect() def makeGUI(self): self.dacDict = dict(hc.elecDict.items() + hc.smaDict.items()) self.displays = {k: QtGui.QLCDNumber() for k in self.dacDict.keys()} layout = QtGui.QGridLayout() smaBox = QtGui.QGroupBox('SMA Out') smaLayout = QtGui.QGridLayout() smaBox.setLayout(smaLayout) elecBox = QtGui.QGroupBox('Electrodes') elecLayout = QtGui.QGridLayout() elecLayout.setColumnStretch(1, 2) elecLayout.setColumnStretch(3, 2) elecLayout.setColumnStretch(5, 2) elecBox.setLayout(elecLayout) layout.addWidget(smaBox, 0, 0) layout.addWidget(elecBox, 0, 1) for k in hc.smaDict: self.displays[k].setAutoFillBackground(True) smaLayout.addWidget(QtGui.QLabel(k), self.dacDict[k].smaOutNumber, 0) smaLayout.addWidget(self.displays[k], self.dacDict[k].smaOutNumber, 1) s = hc.smaDict[k].smaOutNumber+1 elecList = hc.elecDict.keys() elecList.sort() elecList.pop(hc.centerElectrode-1) for i,e in enumerate(elecList): self.displays[k].setAutoFillBackground(True) if int(i) < len(elecList)/2: elecLayout.addWidget(QtGui.QLabel(e), len(elecList)/2 - int(i), 0) elecLayout.addWidget(self.displays[e], len(elecList)/2 - int(i), 1) else: elecLayout.addWidget(QtGui.QLabel(e), len(elecList) - int(i), 4) elecLayout.addWidget(self.displays[e], len(elecList) - int(i), 5) elecLayout.addWidget(QtGui.QLabel('CNT'), len(elecList)/2 + 1, 2) elecLayout.addWidget(self.displays[str(hc.centerElectrode).zfill(2)], len(elecList)/2 + 1, 3) spacer = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.MinimumExpanding) smaLayout.addItem(spacer, s, 0,10, 2) self.setLayout(layout) @inlineCallbacks def connect(self): from labrad.wrappers import connectAsync from labrad.types import Error self.cxn = yield connectAsync() self.dacserver = yield self.cxn.dac_server self.ionInfo = {} yield self.setupListeners() yield self.followSignal(0, 0) @inlineCallbacks def setupListeners(self): yield self.dacserver.signal__ports_updated(SIGNALID2) yield self.dacserver.addListener(listener = self.followSignal, source = None, ID = SIGNALID2) @inlineCallbacks def followSignal(self, x, s): av = yield self.dacserver.get_analog_voltages() brightness = 210 darkness = 255 - brightness for (k, v) in av: self.displays[k].display(float(v)) if abs(v) > 30: self.displays[k].setStyleSheet("QWidget {background-color: orange }") else: R = int(brightness + v*darkness/30.) G = int(brightness - abs(v*darkness/30.)) B = int(brightness - v*darkness/30.) hexclr = '#%02x%02x%02x' % (R, G, B) self.displays[k].setStyleSheet("QWidget {background-color: "+hexclr+" }") def closeEvent(self, x): self.reactor.stop() class DAC_Control(QtGui.QMainWindow): def __init__(self, reactor, parent=None): super(DAC_Control, self).__init__(parent) self.reactor = reactor channelControlTab = self.buildChannelControlTab() multipoleControlTab = self.buildMultipoleControlTab() # scanTab = self.buildScanTab() tab = QtGui.QTabWidget() tab.addTab(multipoleControlTab,'&Multipoles') tab.addTab(channelControlTab, '&Channels') # tab.addTab(scanTab, '&Scans') self.setWindowTitle('DAC Control') self.setCentralWidget(tab) def buildMultipoleControlTab(self): widget = QtGui.QWidget() gridLayout = QtGui.QGridLayout() gridLayout.addWidget(CHANNEL_MONITOR(self.reactor),0,0) gridLayout.addWidget(MULTIPOLE_CONTROL(self.reactor),0,1) widget.setLayout(gridLayout) return widget def buildChannelControlTab(self): widget = QtGui.QWidget() gridLayout = QtGui.QGridLayout() gridLayout.addWidget(CHANNEL_CONTROL(self.reactor),0,0) widget.setLayout(gridLayout) return widget def buildScanTab(self): from SCAN_CONTROL import Scan_Control_Tickle widget = QtGui.QWidget() gridLayout = QtGui.QGridLayout() gridLayout.addWidget(Scan_Control_Tickle(self.reactor, 'Ex1'), 0, 0) gridLayout.addWidget(Scan_Control_Tickle(self.reactor, 'Ey1'), 0, 1) widget.setLayout(gridLayout) return widget def closeEvent(self, x): self.reactor.stop() if __name__ == "__main__": a = QtGui.QApplication( [] ) import qt4reactor qt4reactor.install() from twisted.internet import reactor DAC_Control = DAC_Control(reactor) DAC_Control.show() reactor.run()