def __init__(self, parent): QtGui.QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(400) self.setMinimumHeight(400) self.setWindowTitle('Select Instrument') refreshButton = QtGui.QPushButton('Refresh Available Instrument List') acceptButton = QtGui.QPushButton(Shared.btn_label('confirm')) cancelButton = QtGui.QPushButton(Shared.btn_label('reject')) self.availableInst = QtGui.QLabel() instList, instStr = api_gen.list_inst() self.availableInst.setText(instStr) selInst = QtGui.QWidget() selInstLayout = QtGui.QFormLayout() self.selSyn = QtGui.QComboBox() self.selSyn.addItems(['N.A.']) self.selSyn.addItems(instList) self.selLockin = QtGui.QComboBox() self.selLockin.addItems(['N.A.']) self.selLockin.addItems(instList) self.selScope = QtGui.QComboBox() self.selScope.addItems(['N.A.']) self.selScope.addItems(instList) self.selMotor = QtGui.QComboBox() self.selMotor.addItems(['N.A.']) self.selMotor.addItems(instList) self.selPressure = QtGui.QComboBox() self.selPressure.addItems(['N.A.']) self.selPressure.addItems(instList) selInstLayout.addRow(QtGui.QLabel('Synthesizer'), self.selSyn) selInstLayout.addRow(QtGui.QLabel('Lock-in'), self.selLockin) selInstLayout.addRow(QtGui.QLabel('Oscilloscope'), self.selScope) selInstLayout.addRow(QtGui.QLabel('Step Motor'), self.selMotor) selInstLayout.addRow(QtGui.QLabel('CENTER TWO Pressure Readout'), self.selPressure) selInst.setLayout(selInstLayout) # Set main layout mainLayout = QtGui.QGridLayout() mainLayout.addWidget(self.availableInst, 0, 0, 1, 2) mainLayout.addWidget(refreshButton, 1, 0, 1, 2) mainLayout.addWidget(selInst, 2, 0, 1, 2) mainLayout.addWidget(cancelButton, 3, 0) mainLayout.addWidget(acceptButton, 3, 1) self.setLayout(mainLayout) refreshButton.clicked.connect(self.refresh) cancelButton.clicked.connect(self.reject) acceptButton.clicked.connect(self.accept)
def __init__(self, parent): QtGui.QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(400) self.setMinimumHeight(400) self.setWindowTitle('Close Instrument') inst = QtGui.QWidget() self.synToggle = QtGui.QCheckBox() self.liaToggle = QtGui.QCheckBox() self.pciToggle = QtGui.QCheckBox() self.motorToggle = QtGui.QCheckBox() self.pressureToggle = QtGui.QCheckBox() instLayout = QtGui.QFormLayout() instLayout.addRow(QtGui.QLabel('Instrument'), QtGui.QLabel('Status')) # only list currently connected instruments if self.parent.synHandle: self.synToggle.setCheckState(True) instLayout.addRow(QtGui.QLabel('Synthesizer'), self.synToggle) else: self.synToggle.setCheckState(False) if self.parent.liaHandle: self.liaToggle.setCheckState(True) instLayout.addRow(QtGui.QLabel('Lockin'), self.liaToggle) else: self.liaToggle.setCheckState(False) if self.parent.pciHandle: self.pciToggle.setCheckState(True) instLayout.addRow(QtGui.QLabel('Oscilloscope'), self.pciToggle) else: self.pciToggle.setCheckState(False) if self.parent.motorHandle: self.motorToggle.setCheckState(True) instLayout.addRow(QtGui.QLabel('Motor'), self.motorToggle) else: self.motorToggle.setCheckState(False) if self.parent.pressureHandle: self.pressureToggle.setCheckState(True) instLayout.addRow(QtGui.QLabel('Pressure Readout'), self.pressureToggle) else: self.pressureToggle.setCheckState(False) inst.setLayout(instLayout) okButton = QtGui.QPushButton(Shared.btn_label('complete')) mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(inst) mainLayout.addWidget( QtGui.QLabel( 'No command will be sent before you hit the accept button')) mainLayout.addWidget(okButton) self.setLayout(mainLayout) okButton.clicked.connect(self.accept)
def update_setting(self, entry_setting): ''' Update scan entry setting. Starts a scan after setting update. entry = (comment, start_freq <MHz>, stop_freq <MHz>, step <MHz>, averages [int], sens_index [int], timeConst [int], waittime <ms>, mod Mode index [int], mod freq <Hz>, mod Amp [float], harmonics [int], phase [float]) ''' self.x = Shared.gen_x_array(*entry_setting[1:4]) self.x_min = min(entry_setting[1], entry_setting[2]) self.step = entry_setting[3] self.current_x_index = 0 self.target_avg = entry_setting[4] self.acquired_avg = 0 self.sens_index = entry_setting[5] self.tc_index = entry_setting[6] self.waittime = entry_setting[7] self.waitTimer.setInterval(self.waittime) self.current_comment = entry_setting[0] self.y = np.zeros_like(self.x) self.y_sum = np.zeros_like(self.x) self.ySumCurve.setData(self.x, self.y_sum) total_pts = len(self.x) * self.target_avg self.pts_taken = 0 self.parent.currentProgBar.setRange(0, ceil(total_pts * self.waittime * 1e-3)) self.parent.currentProgBar.setValue(ceil(self.pts_taken * self.waittime * 1e-3)) # tune instrument self.tune_inst(entry_setting) # refresh [inst]Status Panels self.main.synStatus.print_info() self.main.liaStatus.print_info() # start daq timer self.waitTimer.start()
def on_scan_jpl(self): # when invoke this dialog, pause live lockin monitor in the main panel self.liaMonitor.stop() # if it is test mode, or real-run mode with instrument correctly connected if self.testModeAction.isChecked() or (self.synHandle and self.liaHandle): dconfig = ScanLockin.JPLScanConfig(main=self) entry_settings = None dconfig_result = dconfig.exec_() else: # instrument handle is None, pop up error msg = Shared.MsgError( self, 'Instrument Offline!', 'Connect to the synthesizer and lockin first before proceed.') msg.exec_() return None # this loop makes sure the config dialog does not disappear # unless the settings are all valid / or user hits cancel while dconfig_result: # if dialog accepted entry_settings, filename = dconfig.get_settings() if entry_settings: total_time = Shared.jpl_scan_time(entry_settings) now = datetime.datetime.today() length = datetime.timedelta(seconds=total_time) then = now + length text = 'This batch job is estimated to take {:s}.\nIt is expected to finish at {:s}.'.format( str(length), then.strftime('%I:%M %p, %m-%d-%Y (%a)')) q = Shared.MsgInfo(self, 'Time Estimation', text) q.addButton(QtGui.QMessageBox.Cancel) qres = q.exec_() if qres == QtGui.QMessageBox.Ok: break else: dconfig_result = dconfig.exec_() else: dconfig_result = dconfig.exec_() if entry_settings and dconfig_result: dscan = ScanLockin.JPLScanWindow(entry_settings, filename, main=self) dscan.exec_() else: pass
def finish(self): self.currentProgBar.setValue(self.currentProgBar.maximum()) self.totalProgBar.setValue(self.totalProgBar.maximum()) msg = Shared.MsgInfo( self, 'Job Finished!', 'Congratulations! Now it is time to grab some coffee.') msg.exec_() self.stop_timers() self.accept()
def __init__(self, entry_settings, filename, main=None): QtGui.QWidget.__init__(self, main) self.main = main self.setWindowTitle('Lockin scan monitor') self.setMinimumSize(1200, 600) self.entry_settings = entry_settings # set up batch list display self.batchListWidget = JPLBatchListWidget(entry_settings) batchArea = QtGui.QScrollArea() batchArea.setWidgetResizable(True) batchArea.setWidget(self.batchListWidget) batchDisplay = QtGui.QGroupBox() batchDisplay.setTitle('Batch List') batchLayout = QtGui.QVBoxLayout() batchLayout.addWidget(batchArea) batchDisplay.setLayout(batchLayout) # set up single scan monitor + daq class self.singleScan = SingleScan(filename, parent=self, main=self.main) # set up progress bar self.currentProgBar = QtGui.QProgressBar() self.totalProgBar = QtGui.QProgressBar() progressDisplay = QtGui.QWidget() progressLayout = QtGui.QGridLayout() progressLayout.addWidget(QtGui.QLabel('Current Progress'), 0, 0) progressLayout.addWidget(self.currentProgBar, 0, 1) progressLayout.addWidget(QtGui.QLabel('Total progress'), 1, 0) progressLayout.addWidget(self.totalProgBar, 1, 1) progressDisplay.setLayout(progressLayout) mainLayout = QtGui.QGridLayout() mainLayout.addWidget(batchDisplay, 0, 0, 1, 2) mainLayout.addWidget(self.singleScan, 0, 2, 1, 3) mainLayout.addWidget(progressDisplay, 1, 0, 1, 5) self.setLayout(mainLayout) # Initiate progress bar total_time = ceil(Shared.jpl_scan_time(entry_settings)) self.totalProgBar.setRange(0, total_time) self.totalProgBar.setValue(0) self.batch_time_taken = 0 # Start scan self.next_entry_signal.connect(self.next_entry) # this makes sure batch starts at index 0 self.current_entry_index = -1 self.next_entry_signal.emit()
def add_entry(self): ''' Add batch entry to this dialog window ''' # generate a new batch entry default_setting = ('default', self.main.synInfo.probFreq * 1e-6, self.main.synInfo.probFreq * 1e-6 + 10.000, 0.1, 1, self.main.liaInfo.sensIndex, self.main.liaInfo.tcIndex, 60, self.main.synInfo.modModeIndex, self.main.synInfo.modFreq, self.main.synInfo.modAmp, self.main.liaInfo.refHarm, self.main.liaInfo.refPhase) entry = Shared.JPLLIAScanEntry(self.main, default=default_setting) # get the current last entry if self.entryWidgetList: last_entry = self.entryWidgetList[-1] # set default values to be the same as the last one entry.commentFill.setText(last_entry.commentFill.text()) entry.startFreqFill.setText(last_entry.startFreqFill.text()) entry.stopFreqFill.setText(last_entry.stopFreqFill.text()) entry.stepFill.setText(last_entry.stepFill.text()) entry.avgFill.setText(last_entry.avgFill.text()) entry.sensSel.setCurrentIndex(last_entry.sensSel.currentIndex()) entry.tcSel.setCurrentIndex(last_entry.tcSel.currentIndex()) entry.waitTimeFill.setText(last_entry.waitTimeFill.text()) entry.modModeSel.setCurrentIndex( last_entry.modModeSel.currentIndex()) entry.modFreqFill.setText(last_entry.modFreqFill.text()) entry.modAmpFill.setText(last_entry.modAmpFill.text()) entry.harmSel.setCurrentIndex(last_entry.harmSel.currentIndex()) entry.refPhaseFill.setText(last_entry.refPhaseFill.text()) else: pass # add this entry to the layout and to the entry list self.entryWidgetList.append(entry) row = len(self.entryWidgetList) self.entryLayout.addWidget(entry.commentFill, row, 0) self.entryLayout.addWidget(entry.startFreqFill, row, 1) self.entryLayout.addWidget(entry.stopFreqFill, row, 2) self.entryLayout.addWidget(entry.stepFill, row, 3) self.entryLayout.addWidget(entry.avgFill, row, 4) self.entryLayout.addWidget(entry.sensSel, row, 5) self.entryLayout.addWidget(entry.tcSel, row, 6) self.entryLayout.addWidget(entry.waitTimeFill, row, 7) self.entryLayout.addWidget(entry.modModeSel, row, 8) self.entryLayout.addWidget(entry.modFreqFill, row, 9) self.entryLayout.addWidget(entry.modAmpFill, row, 10) self.entryLayout.addWidget(entry.modAmpUnitLabel, row, 11) self.entryLayout.addWidget(entry.harmSel, row, 12) self.entryLayout.addWidget(entry.refPhaseFill, row, 13)
def save_data(self): try: filename, _ = QtGui.QFileDialog.getSaveFileName( self, 'Save Data', './test_pressure.txt', 'Data File (*.txt)') if filename: np.savetxt( filename, self.data, comments='#', fmt=['%g', '%.3e'], header= 'Data collection starts at {:s} \ntime({:s}) pressure({:s})' .format( self.data_start_time.strftime( '%I:%M:%S %p, %m-%d-%Y (%a)'), self.updateRateUnitSel.currentText(), self.currentUnit.text())) else: pass except AttributeError: msg = Shared.MsgError(self, Shared.btn_label('error'), 'No data has been collected!') msg.exec_()
def stop(self): # can't find the correct way to check if the timer is connected, # this is a cheat try: self.timer.timeout.disconnect(self.update_plot) except TypeError: pass self.data_collecting = False # turn data collection status off # enable update rate QLineEdit self.updateRate.setReadOnly(False) self.updateRate.setStyleSheet( 'color: black; border: 1px solid {:s}'.format( Shared.msgcolor(self.msgcode)))
def display(self): self.acceptButton.setText(Shared.btn_label('accept')) if self.parent.synHandle: self.print_info() self.instGroup.show() self.rfGroup.show() self.modGroup.show() else: self.instGroup.hide() self.rfGroup.hide() self.modGroup.hide() self.exec_()
def __init__(self, entry_settings): QtGui.QWidget.__init__(self) self.batchLayout = QtGui.QGridLayout() self.batchLayout.setAlignment(QtCore.Qt.AlignTop) # set up batch list row header # put comment in the first column and make it editable self.batchLayout.addWidget(QtGui.QLabel('#'), 0, 0) self.batchLayout.addWidget(QtGui.QLabel('Comment'), 0, 1) self.batchLayout.addWidget(QtGui.QLabel('Start'), 0, 2) self.batchLayout.addWidget(QtGui.QLabel('Stop'), 0, 3) self.batchLayout.addWidget(QtGui.QLabel('Step'), 0, 4) self.batchLayout.addWidget(QtGui.QLabel('Avg'), 0, 5) self.batchLayout.addWidget(QtGui.QLabel('Sens'), 0, 6) self.batchLayout.addWidget(QtGui.QLabel('Time'), 0, 7) self.batchLayout.addWidget(QtGui.QLabel('Const'), 1, 7) self.batchLayout.addWidget(QtGui.QLabel('Modulation'), 0, 8) self.batchLayout.addWidget(QtGui.QLabel('Harmonics'), 0, 9) self.batchLayout.addWidget(QtGui.QLabel('(MHz)'), 1, 2) self.batchLayout.addWidget(QtGui.QLabel('(MHz)'), 1, 3) self.batchLayout.addWidget(QtGui.QLabel('(MHz)'), 1, 4) # add batch list entry self.entryList = [] for row in range(len(entry_settings)): # entry = (start, stop, step, avg, sens_idx, tc_idx, waittime, comment) current_setting = entry_settings[row] entry = Shared.JPLLIABatchListEntry(self, entry_setting=current_setting) # set up the batch number (row + 1) entry.numberLabel.setText(str(row + 1)) # add widgets to the dispaly panel layout self.batchLayout.addWidget(entry.numberLabel, row + 2, 0) self.batchLayout.addWidget(entry.commentFill, row + 2, 1) self.batchLayout.addWidget(entry.startFreqLabel, row + 2, 2) self.batchLayout.addWidget(entry.stopFreqLabel, row + 2, 3) self.batchLayout.addWidget(entry.stepLabel, row + 2, 4) self.batchLayout.addWidget(entry.avgLabel, row + 2, 5) self.batchLayout.addWidget(entry.sensLabel, row + 2, 6) self.batchLayout.addWidget(entry.tcLabel, row + 2, 7) self.batchLayout.addWidget(entry.modModeLabel, row + 2, 8) self.batchLayout.addWidget(entry.refHarmLabel, row + 2, 9) self.entryList.append(entry) self.setLayout(self.batchLayout)
def export_lwa(self): outputfile, _ = QtGui.QFileDialog.getSaveFileName( self, 'Save Data', '', 'SMAP File (*.lwa)') # prevent from overwriting if outputfile == self.filename: msg = Shared.MsgError( self, 'Cannot save!', 'Output file shall not overwrite source file') msg.exec_() elif outputfile: lwaparser.export(list(set(self.entry_id_to_export)), self.hd_line_num, src=self.filename, output=outputfile) else: pass
def daq(self): if self.main.testModeAction.isChecked(): self.current_p = np.random.rand() msgcode = 2 status_txt = 'Okay' else: msgcode, status_txt, self.current_p = api_pres.query_p( self.main.pressureHandle, self.channelSel.currentText()) self.currentP.setText('{:.3e}'.format(self.current_p)) self.currentStatus.setText(status_txt) self.currentStatus.setStyleSheet('color: {:s}'.format( Shared.msgcolor(msgcode))) if not msgcode: # if fatal, stop daq self.timer.stop() else: pass
def display(self): self.acceptButton.setText(Shared.btn_label('accept')) if self.parent.liaHandle: self.print_info() self.instGroup.show() self.refGroup.show() self.gainGroup.show() self.inputGroup.show() self.outputGroup.show() else: self.instGroup.hide() self.refGroup.hide() self.gainGroup.hide() self.inputGroup.hide() self.outputGroup.hide() self.exec_()
def get_settings(self): ''' Read batch settings from entries and proceed. Returns a list of seting tuples in the format of (comment, start_freq <MHz>, stop_freq <MHz>, step <MHz>, averages [int], sens_index [int], timeConst [int], waittime <ms>, mod Mode index [int], mod freq <Hz>, mod Amp [float], harmonics [int], phase [float]) ''' vdi_index = self.main.synCtrl.bandSel.currentIndex() entry_settings = [] no_error = True if self.filename == '': no_error = False else: # get settings from entry for entry in self.entryWidgetList: # if all validation status in this entry are True if (not list(entry.status.values()).count(False)): no_error *= True # read settings entry_setting = (entry.commentFill.text(), entry.startFreq, entry.stopFreq, entry.step, entry.avg, entry.sensSel.currentIndex(), entry.tcSel.currentIndex(), entry.waittime, entry.modModeSel.currentIndex(), entry.modFreq, entry.modAmp, entry.refHarm, entry.refPhase) # put the setting tuple into a list entry_settings.append(entry_setting) else: no_error *= False if no_error: return entry_settings, self.filename else: msg = Shared.MsgError( self.main, 'Invalid input!', 'Please fix invalid inputs before proceeding.') msg.exec_() return None, None
def on_scan_jpl(self): # when invoke this dialog, pause live lockin monitor in the main panel self.liaMonitor.stop() # if it is test mode, or real-run mode with instrument correctly connected if self.testModeAction.isChecked() or (self.synHandle and self.liaHandle): dconfig = ScanLockin.JPLScanConfig(main=self) entry_settings = None dconfig_result = dconfig.exec_() else: # instrument handle is None, pop up error msg = Shared.MsgError(self, 'Instrument Offline!', 'Connect to the synthesizer and lockin first before proceed.') msg.exec_() return None # this loop makes sure the config dialog does not disappear # unless the settings are all valid / or user hits cancel while dconfig_result: # if dialog accepted entry_settings, filename = dconfig.get_settings() if entry_settings: total_time = Shared.jpl_scan_time(entry_settings) now = datetime.datetime.today() length = datetime.timedelta(seconds=total_time) then = now + length text = 'This batch job is estimated to take {:s}.\nIt is expected to finish at {:s}.'.format(str(length), then.strftime('%I:%M %p, %m-%d-%Y (%a)')) q = Shared.MsgInfo(self, 'Time Estimation', text) q.addButton(QtGui.QMessageBox.Cancel) qres = q.exec_() if qres == QtGui.QMessageBox.Ok: break else: dconfig_result = dconfig.exec_() else: dconfig_result = dconfig.exec_() if entry_settings and dconfig_result: dscan = ScanLockin.JPLScanWindow(entry_settings, filename, main=self) dscan.exec_() else: pass
def remove_entry(self): ''' Remove last batch entry in this dialog window ''' # if there is only one entry, skip and pop up warning if len(self.entryWidgetList) == 1: msg = Shared.MsgWarning(self.main, 'Cannot remove batch!', 'At least one batch entry is required!') msg.exec_() else: # remove this entry entry = self.entryWidgetList.pop() self.entryLayout.removeWidget(entry.commentFill) entry.commentFill.deleteLater() self.entryLayout.removeWidget(entry.startFreqFill) entry.startFreqFill.deleteLater() self.entryLayout.removeWidget(entry.stopFreqFill) entry.stopFreqFill.deleteLater() self.entryLayout.removeWidget(entry.stepFill) entry.stepFill.deleteLater() self.entryLayout.removeWidget(entry.avgFill) entry.avgFill.deleteLater() self.entryLayout.removeWidget(entry.sensSel) entry.sensSel.deleteLater() self.entryLayout.removeWidget(entry.tcSel) entry.tcSel.deleteLater() self.entryLayout.removeWidget(entry.waitTimeFill) entry.waitTimeFill.deleteLater() self.entryLayout.removeWidget(entry.modModeSel) entry.modModeSel.deleteLater() self.entryLayout.removeWidget(entry.modFreqFill) entry.modFreqFill.deleteLater() self.entryLayout.removeWidget(entry.modAmpFill) entry.modAmpFill.deleteLater() self.entryLayout.removeWidget(entry.modAmpUnitLabel) entry.modAmpUnitLabel.deleteLater() self.entryLayout.removeWidget(entry.harmSel) entry.harmSel.deleteLater() self.entryLayout.removeWidget(entry.refPhaseFill) entry.refPhaseFill.deleteLater() entry.deleteLater()
def set_update_period(self): ''' Set wait time according to self.updateRate ''' # stop data collection and re-enable update rate QLineEdit self.stop() self.updateRate.setReadOnly(False) self.updateRate.setStyleSheet('color: black') tscalar = self._TIMEUNIT[self.updateRateUnitSel.currentIndex()] self.msgcode, self.waittime = api_val.val_float(self.updateRate.text(), safe=[('>=', 0.1 / tscalar)]) self.updateRate.setStyleSheet('border: 1px solid {:s}'.format( Shared.msgcolor(self.msgcode))) if self.msgcode == 2: self.pgPlot.setLabel('bottom', text='Time', units=self.updateRateUnitSel.currentText()) self.timer.setInterval(self.waittime * tscalar * 1000) else: pass
def update_setting(self, entry_setting): ''' Update scan entry setting. Starts a scan after setting update. entry = (comment, start_freq <MHz>, stop_freq <MHz>, step <MHz>, averages [int], sens_index [int], timeConst [int], waittime <ms>, mod Mode index [int], mod freq <Hz>, mod Amp [float], harmonics [int], phase [float]) ''' self.x = Shared.gen_x_array(*entry_setting[1:4]) self.x_min = min(entry_setting[1], entry_setting[2]) self.step = entry_setting[3] self.current_x_index = 0 self.target_avg = entry_setting[4] self.acquired_avg = 0 self.sens_index = entry_setting[5] self.tc_index = entry_setting[6] self.waittime = entry_setting[7] self.waitTimer.setInterval(self.waittime) self.current_comment = entry_setting[0] self.y = np.zeros_like(self.x) self.y_sum = np.zeros_like(self.x) self.ySumCurve.setData(self.x, self.y_sum) total_pts = len(self.x) * self.target_avg self.pts_taken = 0 self.parent.currentProgBar.setRange( 0, ceil(total_pts * self.waittime * 1e-3)) self.parent.currentProgBar.setValue( ceil(self.pts_taken * self.waittime * 1e-3)) # tune instrument self.tune_inst(entry_setting) # refresh [inst]Status Panels self.main.synStatus.print_info() self.main.liaStatus.print_info() # start daq timer self.waitTimer.start()
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self) # Set global window properties self.setWindowTitle('Yo! Go PySpec!') self.setMinimumWidth(1500) self.setMinimumHeight(840) self.testModeSignLabel = QtGui.QLabel( '[TEST MODE ACTIVE -- NOTHING IS REAL]!') self.testModeSignLabel.setStyleSheet('color: {:s}'.format( Shared.msgcolor(0))) self.testModeSignLabel.setAlignment(QtCore.Qt.AlignCenter) # Initiate pyvisa instrument objects self.synHandle = None self.liaHandle = None self.pciHandle = None self.motorHandle = None self.pressureHandle = None # Set menu bar actions exitAction = QtGui.QAction('Exit', self) exitAction.setShortcuts(['Ctrl+Q', 'Esc']) exitAction.setStatusTip('Exit program') exitAction.triggered.connect(self.on_exit) # instrument actions instSelAction = QtGui.QAction('Select Instrument', self) instSelAction.setShortcut('Ctrl+Shift+I') instSelAction.setStatusTip('Select instrument') instSelAction.triggered.connect(self.on_sel_inst) instStatViewAction = QtGui.QAction('View Instrument Status', self) instStatViewAction.setShortcut('Ctrl+Shift+V') instStatViewAction.setStatusTip( 'View status of currently connected instrument') instStatViewAction.triggered.connect(self.on_view_inst_stat) instCloseAction = QtGui.QAction('Close Instrument', self) instCloseAction.setStatusTip('Close individual instrument') instCloseAction.triggered.connect(self.on_close_sel_inst) # scan actions scanJPLAction = QtGui.QAction('JPL Scanning Routine', self) scanJPLAction.setShortcut('Ctrl+Shift+J') scanJPLAction.setStatusTip( 'Use the scanning style of the JPL scanning routine') scanJPLAction.triggered.connect(self.on_scan_jpl) scanPCIAction = QtGui.QAction('PCI Oscilloscope', self) scanPCIAction.setShortcut('Ctrl+Shift+S') scanPCIAction.setStatusTip( "Use the scanning style of Brian's NIPCI card routine") scanPCIAction.triggered.connect(self.on_scan_pci) scanCavityAction = QtGui.QAction('Cavity Enhanced', self) scanCavityAction.setShortcut('Ctrl+Shift+C') scanCavityAction.setStatusTip('Use cavity enhanced spectroscopy') scanCavityAction.triggered.connect(self.on_scan_cavity) presReaderAction = QtGui.QAction('Pressure Reader', self) presReaderAction.setShortcut('Ctrl+Shift+P') presReaderAction.setStatusTip( 'Record pressure measurements using the CENTER TWO pressure readout' ) presReaderAction.triggered.connect(self.on_pres_reader) # data process actions lwaParserAction = QtGui.QAction('.lwa preview and export', self) lwaParserAction.setStatusTip( 'Preview JPL .lwa file and export subset of scans') lwaParserAction.triggered.connect(self.on_lwa_parser) self.testModeAction = QtGui.QAction('Test Mode', self) self.testModeAction.setCheckable(True) self.testModeAction.setShortcut('Ctrl+T') self.testModeAction.setWhatsThis( 'Toggle the test mode to bypass all instrument communication for GUI development.' ) # Set menu bar self.statusBar() menuFile = self.menuBar().addMenu('&File') menuFile.addAction(exitAction) menuInst = self.menuBar().addMenu('&Instrument') menuInst.addAction(instSelAction) menuInst.addAction(instStatViewAction) menuInst.addAction(instCloseAction) menuScan = self.menuBar().addMenu('&Scan') menuScan.addAction(scanJPLAction) menuScan.addAction(scanPCIAction) menuScan.addAction(scanCavityAction) menuScan.addAction(presReaderAction) menuData = self.menuBar().addMenu('&Data') menuData.addAction(lwaParserAction) menuTest = self.menuBar().addMenu('&Test') menuTest.addAction(self.testModeAction) # Set classes to store all instrument info self.synInfo = Shared.SynInfo() self.liaInfo = Shared.LiaInfo() self.scopeInfo = Shared.ScopeInfo() self.motorInfo = Shared.MotorInfo() # Set main window widgets self.synStatus = Panels.SynStatus(self) self.liaStatus = Panels.LockinStatus(self) self.scopeStatus = Panels.ScopeStatus(self) self.synCtrl = Panels.SynCtrl(self) self.liaCtrl = Panels.LockinCtrl(self) self.scopeCtrl = Panels.ScopeCtrl(self) self.motorCtrl = Panels.MotorCtrl(self) self.scopeMonitor = Panels.ScopeMonitor(self) self.liaMonitor = Panels.LockinMonitor(self) self.specMonitor = Panels.SpectrumMonitor(self) # Set main window layout self.mainLayout = QtGui.QGridLayout() self.mainLayout.setSpacing(6) self.mainLayout.addWidget(self.synStatus, 0, 0, 3, 2) self.mainLayout.addWidget(self.liaStatus, 3, 0, 3, 2) self.mainLayout.addWidget(self.scopeStatus, 6, 0, 1, 2) self.mainLayout.addWidget(self.testModeSignLabel, 7, 0, 1, 2) self.mainLayout.addWidget(self.synCtrl, 0, 2, 3, 3) self.mainLayout.addWidget(self.liaCtrl, 3, 2, 2, 3) self.mainLayout.addWidget(self.scopeCtrl, 5, 2, 2, 3) self.mainLayout.addWidget(self.motorCtrl, 7, 2, 1, 3) self.mainLayout.addWidget(self.scopeMonitor, 0, 5, 2, 4) self.mainLayout.addWidget(self.liaMonitor, 2, 5, 4, 4) self.mainLayout.addWidget(self.specMonitor, 6, 5, 2, 4) # Enable main window self.mainWidget = QtGui.QWidget() self.mainWidget.setLayout(self.mainLayout) self.setCentralWidget(self.mainWidget) # Preload system dialog widgets self.load_dialogs() self.refresh_inst() self.testModeAction.toggled.connect(self.refresh_inst)
def __init__(self, parent, filename): QtGui.QDialog.__init__(self, parent) self.parent = parent self.filename = filename self.setMinimumWidth(1200) self.setMinimumHeight(600) self.setWindowTitle('LWA Preview & Parser') self.entry_id_to_export = [] self.mainLayout = QtGui.QVBoxLayout() self.mainLayout.setAlignment(QtCore.Qt.AlignTop) self.mainLayout.addWidget( QtGui.QLabel('Source file: {:s}'.format(filename))) # read lwa batch scan entry from file self.entry_settings, self.hd_line_num = lwaparser.scan_header(filename) if self.entry_settings: # set top buttons topButtons = QtGui.QWidget() self.exportButton = QtGui.QPushButton('Export selected scans') self.exportButton.clicked.connect(self.export_lwa) self.openFileButton = QtGui.QPushButton('Open New File') self.openFileButton.clicked.connect(self.open_new_file) topButtonLayout = QtGui.QHBoxLayout() topButtonLayout.addWidget(self.exportButton) topButtonLayout.addWidget(self.openFileButton) topButtons.setLayout(topButtonLayout) self.mainLayout.addWidget(topButtons) # set up a QButtonGroup to manage checkboxes self.entryGroup = QtGui.QButtonGroup() self.entryGroup.setExclusive(False) # set up the batch list area self.batchListWidget = QtGui.QWidget() batchArea = QtGui.QScrollArea() batchArea.setWidgetResizable(True) batchArea.setWidget(self.batchListWidget) self.batchLayout = QtGui.QGridLayout() self.batchLayout.setAlignment(QtCore.Qt.AlignTop) # row of names self.batchLayout.addWidget(QtGui.QLabel('Scan #'), 0, 0) self.batchLayout.addWidget(QtGui.QLabel('Comment'), 0, 1) self.batchLayout.addWidget(QtGui.QLabel('Date'), 0, 2) self.batchLayout.addWidget(QtGui.QLabel('Time'), 0, 3) self.batchLayout.addWidget(QtGui.QLabel('Start Freq (MHz)'), 0, 4) self.batchLayout.addWidget(QtGui.QLabel('Stop Freq (MHz)'), 0, 5) self.batchLayout.addWidget(QtGui.QLabel('Step Freq'), 0, 6) self.batchLayout.addWidget(QtGui.QLabel('Points'), 0, 7) self.batchLayout.addWidget(QtGui.QLabel('Average'), 0, 8) self.batchLayout.addWidget(QtGui.QLabel('Sensitivity'), 0, 9) self.batchLayout.addWidget(QtGui.QLabel('Time Const'), 0, 10) self.batchLayout.addWidget(QtGui.QLabel('Wait Time'), 0, 11) self.batchLayout.addWidget(QtGui.QLabel('Modulation'), 0, 12) self.batchLayout.addWidget(QtGui.QLabel('Harmonics'), 0, 13) self.batchLayout.addWidget(QtGui.QLabel('Mod Freq'), 0, 14) self.batchLayout.addWidget(QtGui.QLabel('Mod Amp'), 0, 15) self.batchLayout.addWidget(QtGui.QLabel('Phase'), 0, 16) for row in range(len(self.entry_settings)): current_setting = self.entry_settings[row] entry = Shared.LWAScanHdEntry(self, entry_setting=current_setting) # add entry number checkbox to the button group self.entryGroup.addButton(entry.scanNumLabel, row) # add widgets to the dispaly panel layout self.batchLayout.addWidget(entry.scanNumLabel, row + 1, 0) self.batchLayout.addWidget(entry.commentLabel, row + 1, 1) self.batchLayout.addWidget(entry.dateLabel, row + 1, 2) self.batchLayout.addWidget(entry.timeLabel, row + 1, 3) self.batchLayout.addWidget(entry.startFreqLabel, row + 1, 4) self.batchLayout.addWidget(entry.stopFreqLabel, row + 1, 5) self.batchLayout.addWidget(entry.stepLabel, row + 1, 6) self.batchLayout.addWidget(entry.ptsLabel, row + 1, 7) self.batchLayout.addWidget(entry.avgLabel, row + 1, 8) self.batchLayout.addWidget(entry.sensLabel, row + 1, 9) self.batchLayout.addWidget(entry.tcLabel, row + 1, 10) self.batchLayout.addWidget(entry.itLabel, row + 1, 11) self.batchLayout.addWidget(entry.modModeLabel, row + 1, 12) self.batchLayout.addWidget(entry.harmLabel, row + 1, 13) self.batchLayout.addWidget(entry.modFreqLabel, row + 1, 14) self.batchLayout.addWidget(entry.modAmpLabel, row + 1, 15) self.batchLayout.addWidget(entry.phaseLabel, row + 1, 16) self.batchListWidget.setLayout(self.batchLayout) self.mainLayout.addWidget(batchArea) self.entryGroup.buttonClicked[int].connect(self.add_to_list) else: self.mainLayout.addWidget( QtGui.QLabel('Invalid file! No scans found.')) self.setLayout(self.mainLayout)
def __init__(self, main=None): QtGui.QDialog.__init__(self, main) self.main = main self.setWindowTitle('Lockin scan configuration (JPL style)') self.setMinimumSize(1200, 600) # Add top buttons addBatchButton = QtGui.QPushButton('Add batch') removeBatchButton = QtGui.QPushButton('Remove last batch') saveButton = QtGui.QPushButton('Set File Directory') self.filename = 'default.lwa' self.fileLabel = QtGui.QLabel('Save Data to: {:s}'.format( self.filename)) self.fileLabel.setStyleSheet('QLabel {color: #003366}') topButtonLayout = QtGui.QGridLayout() topButtonLayout.addWidget(saveButton, 0, 0) topButtonLayout.addWidget(addBatchButton, 0, 1) topButtonLayout.addWidget(removeBatchButton, 0, 2) topButtonLayout.addWidget(self.fileLabel, 1, 0, 1, 3) topButtons = QtGui.QWidget() topButtons.setLayout(topButtonLayout) # Add bottom buttons cancelButton = QtGui.QPushButton(Shared.btn_label('reject')) acceptButton = QtGui.QPushButton(Shared.btn_label('confirm')) acceptButton.setDefault(True) bottomButtonLayout = QtGui.QHBoxLayout() bottomButtonLayout.addWidget(cancelButton) bottomButtonLayout.addWidget(acceptButton) bottomButtons = QtGui.QWidget() bottomButtons.setLayout(bottomButtonLayout) # Add freq config entries self.entryWidgetList = [] self.entryLayout = QtGui.QGridLayout() self.entryLayout.setAlignment(QtCore.Qt.AlignTop) # add entries self.entryLayout.addWidget(QtGui.QLabel('Comment'), 0, 0) self.entryLayout.addWidget(QtGui.QLabel('Start Freq (MHz)'), 0, 1) self.entryLayout.addWidget(QtGui.QLabel('Stop Freq (MHz)'), 0, 2) self.entryLayout.addWidget(QtGui.QLabel('Step (MHz)'), 0, 3) self.entryLayout.addWidget(QtGui.QLabel('Averages'), 0, 4) self.entryLayout.addWidget(QtGui.QLabel('Sensitivity'), 0, 5) self.entryLayout.addWidget(QtGui.QLabel('Time Const'), 0, 6) self.entryLayout.addWidget(QtGui.QLabel('Wait time (ms)'), 0, 7) self.entryLayout.addWidget(QtGui.QLabel('Modulation'), 0, 8) self.entryLayout.addWidget(QtGui.QLabel('Mod Freq (Hz)'), 0, 9) self.entryLayout.addWidget(QtGui.QLabel('Mod Depth/Dev'), 0, 10, 1, 2) self.entryLayout.addWidget(QtGui.QLabel('Harmonics'), 0, 12) self.entryLayout.addWidget(QtGui.QLabel('Phase'), 0, 13) self.add_entry() entryWidgets = QtGui.QWidget() entryWidgets.setLayout(self.entryLayout) entryArea = QtGui.QScrollArea() entryArea.setWidgetResizable(True) entryArea.setWidget(entryWidgets) # Set up main layout mainLayout = QtGui.QVBoxLayout(self) mainLayout.setSpacing(0) mainLayout.addWidget(topButtons) mainLayout.addWidget(entryArea) mainLayout.addWidget(bottomButtons) self.setLayout(mainLayout) cancelButton.clicked.connect(self.reject) acceptButton.clicked.connect(self.accept) saveButton.clicked.connect(self.set_file_directory) addBatchButton.clicked.connect(self.add_entry) removeBatchButton.clicked.connect(self.remove_entry)
def __init__(self, parent): QtGui.QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(600) self.setMinimumHeight(400) self.setWindowTitle('Lockin Amplifier Settings') self.instGroup = QtGui.QGroupBox() self.refGroup = QtGui.QGroupBox() self.inputGroup = QtGui.QGroupBox() self.gainGroup = QtGui.QGroupBox() self.outputGroup = QtGui.QGroupBox() self.instGroup.setTitle('Instrument Session') self.instNameLabel = QtGui.QLabel() self.instInterfaceLabel = QtGui.QLabel() self.instInterfaceNumLabel = QtGui.QLabel() instGroupLayout = QtGui.QFormLayout() instGroupLayout.addRow(QtGui.QLabel('Instrument Name'), self.instNameLabel) instGroupLayout.addRow(QtGui.QLabel('Interface Type'), self.instInterfaceLabel) instGroupLayout.addRow(QtGui.QLabel('Interface Number'), self.instInterfaceNumLabel) self.instGroup.setLayout(instGroupLayout) self.refGroup.setTitle('Reference and Phase') self.refSrcLabel = QtGui.QLabel() self.refFreqLabel = QtGui.QLabel() self.refHarmLabel = QtGui.QLabel() self.refPhaseLabel = QtGui.QLabel() refGroupLayout = QtGui.QFormLayout() refGroupLayout.addRow(QtGui.QLabel('Reference Source'), self.refSrcLabel) refGroupLayout.addRow(QtGui.QLabel('Reference Freq'), self.refFreqLabel) refGroupLayout.addRow(QtGui.QLabel('Harmonics'), self.refHarmLabel) refGroupLayout.addRow(QtGui.QLabel('Phase'), self.refPhaseLabel) self.refGroup.setLayout(refGroupLayout) self.inputGroup.setTitle('Input and Filter') self.inputConfigLabel = QtGui.QLabel() self.inputGroundingLabel = QtGui.QLabel() self.inputCoupleLabel = QtGui.QLabel() self.inputFilterLabel = QtGui.QLabel() inputGroupLayout = QtGui.QFormLayout() inputGroupLayout.addRow(QtGui.QLabel('Input Config'), self.inputConfigLabel) inputGroupLayout.addRow(QtGui.QLabel('Input Grounding'), self.inputGroundingLabel) inputGroupLayout.addRow(QtGui.QLabel('Input Coupling'), self.inputCoupleLabel) inputGroupLayout.addRow(QtGui.QLabel('Input Filter'), self.inputFilterLabel) self.inputGroup.setLayout(inputGroupLayout) self.gainGroup.setTitle('Gain') self.gainSensLabel = QtGui.QLabel() self.gainReserveLabel = QtGui.QLabel() self.gainTCLabel = QtGui.QLabel() self.lpSlopeLabel = QtGui.QLabel() gainGroupLayout = QtGui.QFormLayout() gainGroupLayout.addRow(QtGui.QLabel('Sensitivity'), self.gainSensLabel) gainGroupLayout.addRow(QtGui.QLabel('Time Constant'), self.gainTCLabel) gainGroupLayout.addRow(QtGui.QLabel('Reserve'), self.gainReserveLabel) gainGroupLayout.addRow(QtGui.QLabel('Low-pass Filter Slope'), self.lpSlopeLabel) self.gainGroup.setLayout(gainGroupLayout) self.outputGroup.setTitle('Display and Output') self.outputDisp1Label = QtGui.QLabel() self.outputDisp2Label = QtGui.QLabel() self.outputFront1Label = QtGui.QLabel() self.outputFront2Label = QtGui.QLabel() self.outputSRateLabel = QtGui.QLabel() outputGroupLayout = QtGui.QGridLayout() outputGroupLayout.addWidget(QtGui.QLabel('Chanel 1'), 0, 1) outputGroupLayout.addWidget(QtGui.QLabel('Chanel 2'), 0, 2) outputGroupLayout.addWidget(QtGui.QLabel('Display Output'), 1, 0) outputGroupLayout.addWidget(self.outputDisp1Label, 1, 1) outputGroupLayout.addWidget(self.outputDisp2Label, 1, 2) outputGroupLayout.addWidget(QtGui.QLabel('Front Panel Output'), 2, 0) outputGroupLayout.addWidget(self.outputFront1Label, 2, 1) outputGroupLayout.addWidget(self.outputFront2Label, 2, 2) outputGroupLayout.addWidget(QtGui.QLabel('Sampling Rate'), 3, 0) outputGroupLayout.addWidget(self.outputSRateLabel, 3, 1, 1, 2) self.outputGroup.setLayout(outputGroupLayout) self.refreshButton = QtGui.QPushButton('Manual Refresh') self.acceptButton = QtGui.QPushButton(Shared.btn_label('accept')) mainLayout = QtGui.QGridLayout() mainLayout.addWidget(self.instGroup, 0, 0, 1, 6) mainLayout.addWidget(self.inputGroup, 1, 0, 1, 3) mainLayout.addWidget(self.outputGroup, 1, 3, 1, 3) mainLayout.addWidget(self.refGroup, 2, 0, 1, 3) mainLayout.addWidget(self.gainGroup, 2, 3, 1, 3) mainLayout.addWidget(self.acceptButton, 3, 2, 1, 2) self.setLayout(mainLayout) self.refreshButton.clicked.connect(self.manual_refresh) self.acceptButton.clicked.connect(self.accept)
def __init__(self, parent): QtGui.QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(800) self.setMinimumHeight(400) self.setWindowTitle('Synthesizer Settings') self.instGroup = QtGui.QGroupBox() self.rfGroup = QtGui.QGroupBox() self.modGroup = QtGui.QGroupBox() self.instGroup.setTitle('Instrument Session') self.instNameLabel = QtGui.QLabel() self.instInterfaceLabel = QtGui.QLabel() self.instInterfaceNumLabel = QtGui.QLabel() self.instRemoteDispLabel = QtGui.QLabel() instGroupLayout = QtGui.QFormLayout() instGroupLayout.addRow(QtGui.QLabel('Instrument Name'), self.instNameLabel) instGroupLayout.addRow(QtGui.QLabel('Interface Type'), self.instInterfaceLabel) instGroupLayout.addRow(QtGui.QLabel('Interface Number'), self.instInterfaceNumLabel) instGroupLayout.addRow(QtGui.QLabel('Remote Display'), self.instRemoteDispLabel) self.instGroup.setLayout(instGroupLayout) self.rfGroup.setTitle('RF Settings') self.rfOutputLabel = QtGui.QLabel() self.modOutputLabel = QtGui.QLabel() self.synFreqLabel = QtGui.QLabel() rfGroupLayout = QtGui.QGridLayout() rfGroupLayout.addWidget(QtGui.QLabel('RF Output'), 0, 0) rfGroupLayout.addWidget(self.rfOutputLabel, 0, 1) rfGroupLayout.addWidget(QtGui.QLabel('Synth Frequency'), 0, 2) rfGroupLayout.addWidget(self.synFreqLabel, 0, 3) rfGroupLayout.addWidget(QtGui.QLabel('Modulation Output'), 0, 4) rfGroupLayout.addWidget(self.modOutputLabel, 0, 5) self.rfGroup.setLayout(rfGroupLayout) self.modGroup.setTitle('Modulation Settings') self.am1StateLabel = QtGui.QLabel() self.am2StateLabel = QtGui.QLabel() self.fm1StateLabel = QtGui.QLabel() self.fm2StateLabel = QtGui.QLabel() self.pm1StateLabel = QtGui.QLabel() self.pm2StateLabel = QtGui.QLabel() self.lfStateLabel = QtGui.QLabel() self.am1DepthLabel = QtGui.QLabel() self.am2DepthLabel = QtGui.QLabel() self.fm1DevLabel = QtGui.QLabel() self.fm2DevLabel = QtGui.QLabel() self.pm1DevLabel = QtGui.QLabel() self.pm2DevLabel = QtGui.QLabel() self.lfVolLabel = QtGui.QLabel() self.am1SrcLabel = QtGui.QLabel() self.am2SrcLabel = QtGui.QLabel() self.fm1SrcLabel = QtGui.QLabel() self.fm2SrcLabel = QtGui.QLabel() self.pm1SrcLabel = QtGui.QLabel() self.pm2SrcLabel = QtGui.QLabel() self.lfSrcLabel = QtGui.QLabel() self.am1FreqLabel = QtGui.QLabel() self.am2FreqLabel = QtGui.QLabel() self.fm1FreqLabel = QtGui.QLabel() self.fm2FreqLabel = QtGui.QLabel() self.pm1FreqLabel = QtGui.QLabel() self.pm2FreqLabel = QtGui.QLabel() self.am1WaveLabel = QtGui.QLabel() self.am2WaveLabel = QtGui.QLabel() self.fm1WaveLabel = QtGui.QLabel() self.fm2WaveLabel = QtGui.QLabel() self.pm1WaveLabel = QtGui.QLabel() self.pm2WaveLabel = QtGui.QLabel() modGroupLayout = QtGui.QGridLayout() modGroupLayout.addWidget(QtGui.QLabel('Channel'), 0, 0) modGroupLayout.addWidget(QtGui.QLabel('Source'), 0, 1) modGroupLayout.addWidget(QtGui.QLabel('State'), 0, 2) modGroupLayout.addWidget(QtGui.QLabel('Depth/Dev'), 0, 3) modGroupLayout.addWidget(QtGui.QLabel('Rate'), 0, 4) modGroupLayout.addWidget(QtGui.QLabel('Waveform'), 0, 5) modGroupLayout.addWidget(QtGui.QLabel('AM1'), 1, 0) modGroupLayout.addWidget(self.am1StateLabel, 1, 1) modGroupLayout.addWidget(self.am1SrcLabel, 1, 2) modGroupLayout.addWidget(self.am1DepthLabel, 1, 3) modGroupLayout.addWidget(self.am1FreqLabel, 1, 4) modGroupLayout.addWidget(self.am1WaveLabel, 1, 5) modGroupLayout.addWidget(QtGui.QLabel('AM2'), 2, 0) modGroupLayout.addWidget(self.am2StateLabel, 2, 1) modGroupLayout.addWidget(self.am2SrcLabel, 2, 2) modGroupLayout.addWidget(self.am2DepthLabel, 2, 3) modGroupLayout.addWidget(self.am2FreqLabel, 2, 4) modGroupLayout.addWidget(self.am2WaveLabel, 2, 5) modGroupLayout.addWidget(QtGui.QLabel('FM1'), 3, 0) modGroupLayout.addWidget(self.fm1StateLabel, 3, 1) modGroupLayout.addWidget(self.fm1SrcLabel, 3, 2) modGroupLayout.addWidget(self.fm1DevLabel, 3, 3) modGroupLayout.addWidget(self.fm1FreqLabel, 3, 4) modGroupLayout.addWidget(self.fm1WaveLabel, 3, 5) modGroupLayout.addWidget(QtGui.QLabel('FM2'), 4, 0) modGroupLayout.addWidget(self.fm2StateLabel, 4, 1) modGroupLayout.addWidget(self.fm2SrcLabel, 4, 2) modGroupLayout.addWidget(self.fm2DevLabel, 4, 3) modGroupLayout.addWidget(self.fm2FreqLabel, 4, 4) modGroupLayout.addWidget(self.fm2WaveLabel, 4, 5) modGroupLayout.addWidget(QtGui.QLabel('φM1'), 5, 0) modGroupLayout.addWidget(self.pm1StateLabel, 5, 1) modGroupLayout.addWidget(self.pm1SrcLabel, 5, 2) modGroupLayout.addWidget(self.pm1DevLabel, 5, 3) modGroupLayout.addWidget(self.pm1FreqLabel, 5, 4) modGroupLayout.addWidget(self.pm1WaveLabel, 5, 5) modGroupLayout.addWidget(QtGui.QLabel('φM2'), 6, 0) modGroupLayout.addWidget(self.pm2StateLabel, 6, 1) modGroupLayout.addWidget(self.pm2SrcLabel, 6, 2) modGroupLayout.addWidget(self.pm2DevLabel, 6, 3) modGroupLayout.addWidget(self.pm2FreqLabel, 6, 4) modGroupLayout.addWidget(self.pm2WaveLabel, 6, 5) modGroupLayout.addWidget(QtGui.QLabel('LF OUT'), 7, 0) modGroupLayout.addWidget(self.lfStateLabel, 7, 1) modGroupLayout.addWidget(self.lfSrcLabel, 7, 2) modGroupLayout.addWidget(self.lfVolLabel, 7, 3) self.modGroup.setLayout(modGroupLayout) self.refreshButton = QtGui.QPushButton('Manual Refresh') self.acceptButton = QtGui.QPushButton(Shared.btn_label('accept')) mainLayout = QtGui.QGridLayout() mainLayout.addWidget(self.instGroup, 0, 0, 1, 5) mainLayout.addWidget(self.rfGroup, 1, 0, 1, 5) mainLayout.addWidget(self.modGroup, 2, 0, 1, 5) mainLayout.addWidget(self.acceptButton, 3, 2, 1, 1) self.setLayout(mainLayout) self.refreshButton.clicked.connect(self.manual_refresh) self.acceptButton.clicked.connect(self.accept)
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self) # Set global window properties self.setWindowTitle('Yo! Go PySpec!') self.setMinimumWidth(1500) self.setMinimumHeight(840) self.testModeSignLabel = QtGui.QLabel('[TEST MODE ACTIVE -- NOTHING IS REAL]!') self.testModeSignLabel.setStyleSheet('color: {:s}'.format(Shared.msgcolor(0))) self.testModeSignLabel.setAlignment(QtCore.Qt.AlignCenter) # Initiate pyvisa instrument objects self.synHandle = None self.liaHandle = None self.pciHandle = None self.motorHandle = None self.pressureHandle = None # Set menu bar actions exitAction = QtGui.QAction('Exit', self) exitAction.setShortcuts(['Ctrl+Q', 'Esc']) exitAction.setStatusTip('Exit program') exitAction.triggered.connect(self.on_exit) # instrument actions instSelAction = QtGui.QAction('Select Instrument', self) instSelAction.setShortcut('Ctrl+Shift+I') instSelAction.setStatusTip('Select instrument') instSelAction.triggered.connect(self.on_sel_inst) instStatViewAction = QtGui.QAction('View Instrument Status', self) instStatViewAction.setShortcut('Ctrl+Shift+V') instStatViewAction.setStatusTip('View status of currently connected instrument') instStatViewAction.triggered.connect(self.on_view_inst_stat) instCloseAction = QtGui.QAction('Close Instrument', self) instCloseAction.setStatusTip('Close individual instrument') instCloseAction.triggered.connect(self.on_close_sel_inst) # scan actions scanJPLAction = QtGui.QAction('JPL Scanning Routine', self) scanJPLAction.setShortcut('Ctrl+Shift+J') scanJPLAction.setStatusTip('Use the scanning style of the JPL scanning routine') scanJPLAction.triggered.connect(self.on_scan_jpl) scanPCIAction = QtGui.QAction('PCI Oscilloscope', self) scanPCIAction.setShortcut('Ctrl+Shift+S') scanPCIAction.setStatusTip("Use the scanning style of Brian's NIPCI card routine") scanPCIAction.triggered.connect(self.on_scan_pci) scanCavityAction = QtGui.QAction('Cavity Enhanced', self) scanCavityAction.setShortcut('Ctrl+Shift+C') scanCavityAction.setStatusTip('Use cavity enhanced spectroscopy') scanCavityAction.triggered.connect(self.on_scan_cavity) presReaderAction = QtGui.QAction('Pressure Reader', self) presReaderAction.setShortcut('Ctrl+Shift+P') presReaderAction.setStatusTip('Record pressure measurements using the CENTER TWO pressure readout') presReaderAction.triggered.connect(self.on_pres_reader) # data process actions lwaParserAction = QtGui.QAction('.lwa preview and export', self) lwaParserAction.setStatusTip('Preview JPL .lwa file and export subset of scans') lwaParserAction.triggered.connect(self.on_lwa_parser) self.testModeAction = QtGui.QAction('Test Mode', self) self.testModeAction.setCheckable(True) self.testModeAction.setShortcut('Ctrl+T') self.testModeAction.setWhatsThis('Toggle the test mode to bypass all instrument communication for GUI development.') # Set menu bar self.statusBar() menuFile = self.menuBar().addMenu('&File') menuFile.addAction(exitAction) menuInst = self.menuBar().addMenu('&Instrument') menuInst.addAction(instSelAction) menuInst.addAction(instStatViewAction) menuInst.addAction(instCloseAction) menuScan = self.menuBar().addMenu('&Scan') menuScan.addAction(scanJPLAction) menuScan.addAction(scanPCIAction) menuScan.addAction(scanCavityAction) menuScan.addAction(presReaderAction) menuData = self.menuBar().addMenu('&Data') menuData.addAction(lwaParserAction) menuTest = self.menuBar().addMenu('&Test') menuTest.addAction(self.testModeAction) # Set classes to store all instrument info self.synInfo = Shared.SynInfo() self.liaInfo = Shared.LiaInfo() self.scopeInfo = Shared.ScopeInfo() self.motorInfo = Shared.MotorInfo() # Set main window widgets self.synStatus = Panels.SynStatus(self) self.liaStatus = Panels.LockinStatus(self) self.scopeStatus = Panels.ScopeStatus(self) self.synCtrl = Panels.SynCtrl(self) self.liaCtrl = Panels.LockinCtrl(self) self.scopeCtrl = Panels.ScopeCtrl(self) self.motorCtrl = Panels.MotorCtrl(self) self.scopeMonitor = Panels.ScopeMonitor(self) self.liaMonitor = Panels.LockinMonitor(self) self.specMonitor = Panels.SpectrumMonitor(self) # Set main window layout self.mainLayout = QtGui.QGridLayout() self.mainLayout.setSpacing(6) self.mainLayout.addWidget(self.synStatus, 0, 0, 3, 2) self.mainLayout.addWidget(self.liaStatus, 3, 0, 3, 2) self.mainLayout.addWidget(self.scopeStatus, 6, 0, 1, 2) self.mainLayout.addWidget(self.testModeSignLabel, 7, 0, 1, 2) self.mainLayout.addWidget(self.synCtrl, 0, 2, 3, 3) self.mainLayout.addWidget(self.liaCtrl, 3, 2, 2, 3) self.mainLayout.addWidget(self.scopeCtrl, 5, 2, 2, 3) self.mainLayout.addWidget(self.motorCtrl, 7, 2, 1, 3) self.mainLayout.addWidget(self.scopeMonitor, 0, 5, 2, 4) self.mainLayout.addWidget(self.liaMonitor, 2, 5, 4, 4) self.mainLayout.addWidget(self.specMonitor, 6, 5, 2, 4) # Enable main window self.mainWidget = QtGui.QWidget() self.mainWidget.setLayout(self.mainLayout) self.setCentralWidget(self.mainWidget) # Preload system dialog widgets self.load_dialogs() self.refresh_inst() self.testModeAction.toggled.connect(self.refresh_inst)
def __init__(self, main=None): QtGui.QDialog.__init__(self, main) self.main = main self.setWindowTitle('Lockin scan configuration (JPL style)') self.setMinimumSize(1200, 600) # Add top buttons addBatchButton = QtGui.QPushButton('Add batch') removeBatchButton = QtGui.QPushButton('Remove last batch') saveButton = QtGui.QPushButton('Set File Directory') self.filename = 'default.lwa' self.fileLabel = QtGui.QLabel('Save Data to: {:s}'.format(self.filename)) self.fileLabel.setStyleSheet('QLabel {color: #003366}') topButtonLayout = QtGui.QGridLayout() topButtonLayout.addWidget(saveButton, 0, 0) topButtonLayout.addWidget(addBatchButton, 0, 1) topButtonLayout.addWidget(removeBatchButton, 0, 2) topButtonLayout.addWidget(self.fileLabel, 1, 0, 1, 3) topButtons = QtGui.QWidget() topButtons.setLayout(topButtonLayout) # Add bottom buttons cancelButton = QtGui.QPushButton(Shared.btn_label('reject')) acceptButton = QtGui.QPushButton(Shared.btn_label('confirm')) acceptButton.setDefault(True) bottomButtonLayout = QtGui.QHBoxLayout() bottomButtonLayout.addWidget(cancelButton) bottomButtonLayout.addWidget(acceptButton) bottomButtons = QtGui.QWidget() bottomButtons.setLayout(bottomButtonLayout) # Add freq config entries self.entryWidgetList = [] self.entryLayout = QtGui.QGridLayout() self.entryLayout.setAlignment(QtCore.Qt.AlignTop) # add entries self.entryLayout.addWidget(QtGui.QLabel('Comment'), 0, 0) self.entryLayout.addWidget(QtGui.QLabel('Start Freq (MHz)'), 0, 1) self.entryLayout.addWidget(QtGui.QLabel('Stop Freq (MHz)'), 0, 2) self.entryLayout.addWidget(QtGui.QLabel('Step (MHz)'), 0, 3) self.entryLayout.addWidget(QtGui.QLabel('Averages'), 0, 4) self.entryLayout.addWidget(QtGui.QLabel('Sensitivity'), 0, 5) self.entryLayout.addWidget(QtGui.QLabel('Time Const'), 0, 6) self.entryLayout.addWidget(QtGui.QLabel('Wait time (ms)'), 0, 7) self.entryLayout.addWidget(QtGui.QLabel('Modulation'), 0, 8) self.entryLayout.addWidget(QtGui.QLabel('Mod Freq (Hz)'), 0, 9) self.entryLayout.addWidget(QtGui.QLabel('Mod Depth/Dev'), 0, 10, 1, 2) self.entryLayout.addWidget(QtGui.QLabel('Harmonics'), 0, 12) self.entryLayout.addWidget(QtGui.QLabel('Phase'), 0, 13) self.add_entry() entryWidgets = QtGui.QWidget() entryWidgets.setLayout(self.entryLayout) entryArea = QtGui.QScrollArea() entryArea.setWidgetResizable(True) entryArea.setWidget(entryWidgets) # Set up main layout mainLayout = QtGui.QVBoxLayout(self) mainLayout.setSpacing(0) mainLayout.addWidget(topButtons) mainLayout.addWidget(entryArea) mainLayout.addWidget(bottomButtons) self.setLayout(mainLayout) cancelButton.clicked.connect(self.reject) acceptButton.clicked.connect(self.accept) saveButton.clicked.connect(self.set_file_directory) addBatchButton.clicked.connect(self.add_entry) removeBatchButton.clicked.connect(self.remove_entry)