def __init__(self): ToggleObject.__init__(self,initialState=False) def callback(input,output): d = self._d = Deferred() self.stepped.emit((input,output)) return d closedToggle = self.closedToggle = ClosedToggle(False) self.deactivationRequested.connect(closedToggle.requestToggle) self.activated.connect(closedToggle.requestToggle) @inlineCallbacks def onStart(): yield Scan(self.input,self.output,callback).start() if closedToggle.isToggled(): closedToggle.requestToggle() self.toggle() closedToggle.activated.connect(onStart)
def __init__(self): ToggleObject.__init__(self, initialState=False) def callback(input, output): d = self._d = Deferred() self.stepped.emit((input, output)) return d closedToggle = self.closedToggle = ClosedToggle(False) self.deactivationRequested.connect(closedToggle.requestToggle) self.activated.connect(closedToggle.requestToggle) @inlineCallbacks def onStart(): yield Scan(self.input, self.output, callback).start() if closedToggle.isToggled(): closedToggle.requestToggle() self.toggle() closedToggle.activated.connect(onStart)
def init(): @inlineCallbacks def setText(channel): description = yield protocol.sendCommand( 'get-channel-parameter', channel, VM.DESCRIPTION) voltageRange = yield protocol.sendCommand( 'get-channel-parameter', channel, VM.VOLTAGE_RANGE) voltageRange = self.vrngk2v(voltageRange) decimalPlaces = int(-1 * log10(voltageRange)) + 1 formatString = '%.' + str( decimalPlaces if decimalPlaces > 0 else 0) + 'f' items[channel].setText('%s\t%s\t%s V' % (description, channel, (formatString) % voltageRange)) def rightClicked(listWidget, p): item = listWidget.itemAt(p) if item is None: return channel = item.data(self.ID_ROLE) editDialog = ChannelEditDialog(protocol, channel, colors[channel], self) editDialog.colorChanged.connect(partial(colorChanged, channel)) editDialog.show() def colorChanged(channel, color): colors[channel] = color items[channel].setBackground(color) plots[channel].setPen(pg.mkPen(color, width=2)) @inlineCallbacks def loop(): voltages = yield protocol.sendCommand('get-voltages') for channel, voltage in voltages.items(): xData, yData = data[channel] yData.pop(0) scale = yield protocol.sendCommand('get-channel-parameter', channel, VM.VOLTAGE_RANGE) scale = self.vrngk2v(scale) yData.append(voltage) plots[channel].setData(xData, yData) if recordToggle.isToggled(): with open(self.fileName, 'a') as file: file.write('%s\n' % '\t'.join( str(datum) for datum in ([time.time()] + [voltages[channel] for channel in recording]))) for channel in channels: item = items[channel] if item.checkState() is QtCore.Qt.CheckState.Checked: if channel not in checked: checked.append(channel) plotWidget.addItem(plots[channel]) elif channel in checked: checked.remove(channel) plotWidget.removeItem(plots[channel]) callbackRate = yield protocol.sendCommand('get-callback-rate') yield sleep(1.0 / callbackRate) loop() QtGui.QWidget.__init__(self) self.setLayout(QtGui.QHBoxLayout()) plotWidget = pg.PlotWidget() self.layout().addWidget(plotWidget, 1) controlsLayout = QtGui.QVBoxLayout() self.layout().addLayout(controlsLayout) listWidget = QtGui.QListWidget() listWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove) listWidget.setContextMenuPolicy( QtCore.Qt.ContextMenuPolicy.CustomContextMenu) listWidget.customContextMenuRequested.connect( partial(rightClicked, listWidget)) controlsLayout.addWidget(listWidget) controlsLayout.addStretch(1) channels = yield protocol.sendCommand('get-channels') channels = sorted( channels, key=lambda channel: int(re.search('\d+$', channel).group())) print[re.search('\d+$', channel).group() for channel in channels] data = { channel: (range(self.HISTORY), [0] * self.HISTORY) for index, channel in enumerate(channels) } colors = { channel: QtGui.QColor.fromHsv(int(255 * float(index) / len(channels)), 255, 255) for index, channel in enumerate(channels) } plots = { channel: pg.PlotDataItem(data[channel][0], data[channel][1], name=channel, pen=pg.mkPen(colors[channel], width=2)) for channel in channels } items = {} for index, channel in enumerate(channels): description = yield protocol.sendCommand( 'get-channel-parameter', channel, VM.DESCRIPTION) listWidgetItem = QtGui.QListWidgetItem() listWidgetItem.setData(self.ID_ROLE, channel) listWidgetItem.setBackground(QtGui.QBrush(colors[channel])) listWidget.addItem(listWidgetItem) items[channel] = listWidgetItem setText(channel) for index in range(listWidget.count()): listWidget.item(index).setCheckState( QtCore.Qt.CheckState.Unchecked) def onChannelParameterChanged(channel, parameter, value): setText(channel) protocol.messageSubscribe( 'channel-parameter-changed', partial(apply, onChannelParameterChanged)) checked = [] recording = [] recordToggle = ToggleObject() def onRecordStartRequested(): for channel in channels: item = items[channel] if item.checkState() is QtCore.Qt.CheckState.Checked: recording.append(channel) item.setForeground(QtGui.QBrush(QtGui.QColor('red'))) relPath, fileName = filenameGen(self.MEASUREMENT_TYPE) absPath = os.path.join(POOHDATAPATH, relPath) checkPath(absPath) self.fileName = os.path.join(absPath, fileName + '.txt') with open(self.fileName, 'w+') as file: file.write('%s\n' % '\t'.join(['time'] + [ items[channel].text().replace('\t', '_') for channel in recording ])) recordToggle.toggle() recordToggle.activationRequested.connect(onRecordStartRequested) def onRecordStopRequested(): while recording: items[recording.pop()].setForeground( QtGui.QBrush(QtGui.QColor('black'))) recordToggle.toggle() recordToggle.deactivationRequested.connect(onRecordStopRequested) controlsLayout.addWidget( ToggleWidget(recordToggle, ('record', 'stop'))) loop()
def __init__(self,wavelengthProtocol,stepperMotorProtocol): QtGui.QWidget.__init__(self) self.setLayout(QtGui.QVBoxLayout()) ########## ## goto ## ########## gotoWidget = GotoWidget( { MIN:24100, MAX:24800, PRECISION:2, SLIDER:2.0, POI:REMPI_POI } ) self.layout().addWidget(gotoWidget) # send command to tracking server when goto requested @inlineCallbacks def onGotoRequested(payload): position, deferred = payload yield wavelengthProtocol.sendCommand('set-wavelength',position) deferred.callback(None) gotoWidget.gotoRequested.connect(onGotoRequested) # handle update requests (should the position fall out of sync) def onUpdateReqested(): wavelengthProtocol.sendCommand('get-wavelength').addCallback(gotoWidget.setPosition) gotoWidget.updateRequested.connect(onUpdateReqested) # send cancel request when goto widget requests gotoWidget.cancelRequested.connect(partial(wavelengthProtocol.sendCommand,'cancel-wavelength-set')) # set goto widget position on pdl position change StepperMotorClient(stepperMotorProtocol,PDL).addListener( StepperMotorClient.POSITION, lambda _:wavelengthProtocol.sendCommand('get-wavelength').addCallback(gotoWidget.setPosition) ) # initialize position of goto widget wavelengthProtocol.sendCommand('get-wavelength').addCallback(gotoWidget.setPosition) # this bit below is for a future hardware change where the pdl sm is on a relay # disable the goto widget until the pdl is enabled # gotoWidget.setEnabled(False) # def toggleGoto(status): # if status == 'enabled': # gotoWidget.setEnabled(True) # elif status == 'disabled': # gotoWidget.setEnabled(False) # StepperMotorClient(stepperMotorProtocol,PDL).addListener(StepperMotorClient.ENABLE,toggleGoto) ######################### ## crystal calibration ## ######################### tuningGB = QtGui.QGroupBox('tune crystal') tuningLayout = QtGui.QHBoxLayout() tuningGB.setLayout(tuningLayout) # button to tune calibration # def calibKDP(): wavelengthProtocol.sendCommand('calibrate-crystal',KDP) tuningButtonKDP = QtGui.QPushButton('KDP tuned') tuningLayout.addWidget(tuningButtonKDP) tuningButtonKDP.clicked.connect(calibKDP) # tuningButtonKDP.setEnabled(False) # def toggleKDP(status): # if status == 'enabled': # tuningButtonKDP.setEnabled(True) # elif status == 'disabled': # tuningButtonKDP.setEnabled(False) # StepperMotorClient(stepperMotorProtocol,KDP).addListener(StepperMotorClient.ENABLE,toggleKDP) def calibBBO(): wavelengthProtocol.sendCommand('calibrate-crystal',BBO) tuningButtonBBO = QtGui.QPushButton('BBO tuned') tuningLayout.addWidget(tuningButtonBBO) tuningButtonBBO.clicked.connect(calibBBO) # tuningButtonBBO.setEnabled(False) # def toggleBBO(status): # if status == 'enabled': # tuningButtonBBO.setEnabled(True) # elif status == 'disabled': # tuningButtonBBO.setEnabled(False) # StepperMotorClient(stepperMotorProtocol,BBO).addListener(StepperMotorClient.ENABLE,toggleBBO) self.layout().addWidget(LabelWidget('tuning',tuningLayout)) ##################### ## tracking toggle ## ##################### toggleLayout = QtGui.QHBoxLayout() toggle = ToggleObject() # toggle tracking server on toggle request toggle.toggleRequested.connect( partial( wavelengthProtocol.sendCommand, 'toggle-tracking' ) ) # toggle widget upon receipt of tracking change server notification wavelengthProtocol.messageSubscribe( 'tracking-changed', lambda _:toggle.toggle() ) # create toggle widget toggleLayout.addWidget(ToggleWidget(toggle,('track','stop')),1) # have pretty light led = LEDWidget() toggle.toggled.connect(led.toggle) toggleLayout.addWidget(led) self.layout().addWidget(LabelWidget('tracking',toggleLayout)) # init tracking toggle def initTracking(tracking): if tracking: toggle.toggle() wavelengthProtocol.sendCommand('is-tracking').addCallback(initTracking)
def __init__(self, params={ MIN: 0, MAX: 100, PRECISION: 0, SLIDER: 20, POI: { 'none': 0 } }): QtGui.QWidget.__init__(self) layout = QtGui.QVBoxLayout() ## LCD ## lcdLayout = QtGui.QHBoxLayout() lcd = self.lcd = QtGui.QLCDNumber(8) lcd.setSmallDecimalPoint(True) lcd.setSegmentStyle(lcd.Flat) self.setPosition = lcd.display lcdLayout.addWidget(lcd, 1) refreshIcon = QtGui.QPushButton(QtGui.QIcon(REFRESH_ICON), '') refreshIcon.clicked.connect(self.updateRequested.emit) lcdLayout.addWidget(refreshIcon) layout.addWidget(LabelWidget('position', lcdLayout)) ## GOTO ## gotoLayout = QtGui.QVBoxLayout() toggle = ToggleObject(False) self.spin = QtGui.QDoubleSpinBox() self.spin.setMinimum(params[MIN]) self.spin.setMaximum(params[MAX]) self.spin.setSingleStep(10**(-1 * params[PRECISION])) self.spin.setDecimals(params[PRECISION]) gotoLayout.addWidget(self.spin) gotoToggleWidget = ToggleWidget(toggle, ('goto', 'stop')) gotoLayout.addWidget(gotoToggleWidget) toggle.activationRequested.connect(toggle.toggle) @inlineCallbacks def onActivated(): d = Deferred() self.gotoRequested.emit((self.spin.value(), d)) yield d toggle.toggle() toggle.activated.connect(onActivated) toggle.deactivationRequested.connect(self.cancelRequested.emit) ## POINTS OF INTEREST ## def popSpinbox(text): value = self.poiDict[text] self.spin.setValue(value) self.poiCombo = QtGui.QComboBox() gotoLayout.addWidget(self.poiCombo) self.poiDict = params[POI] for name in self.poiDict.keys(): self.poiCombo.addItem(name) self.poiCombo.activated[str].connect(popSpinbox) ## SLIDER ## slider = QtGui.QSlider() @inlineCallbacks def nudgeLoop(): delta = slider.value() if delta: delta = int(delta / abs(delta) * pow(params[SLIDER], (float(abs(delta)) - 1.0) / 99.0)) d = Deferred() self.gotoRequested.emit((lcd.value() + delta, d)) yield d yield sleep(self.NUDGE) if slider.isSliderDown(): yield nudgeLoop() else: self.cancelRequested.emit() slider.setMinimum(-100) slider.setMaximum(100) slider.setOrientation(QtCore.Qt.Horizontal) slider.setTickInterval(25) slider.setTickPosition(slider.TicksBelow) slider.sliderPressed.connect(nudgeLoop) slider.sliderPressed.connect( partial(gotoToggleWidget.setEnabled, False)) slider.sliderReleased.connect(partial(slider.setValue, 0)) slider.sliderReleased.connect( partial(gotoToggleWidget.setEnabled, True)) toggle.activated.connect(partial(slider.setEnabled, False)) toggle.deactivated.connect(partial(slider.setEnabled, True)) gotoLayout.addWidget(slider) layout.addWidget(LabelWidget('goto', gotoLayout)) self.setLayout(layout)