|
@@ -0,0 +1,442 @@
|
|
|
+from PyQt4 import QtGui, QtCore
|
|
|
+import subprocess
|
|
|
+# import numpy as np
|
|
|
+# import pyqtgraph as pg
|
|
|
+# import cPickle
|
|
|
+import time
|
|
|
+import sys
|
|
|
+
|
|
|
+import kcg_remote_client as client
|
|
|
+
|
|
|
+def safe_call(cmd):
|
|
|
+ try:
|
|
|
+ return subprocess.check_output(cmd)
|
|
|
+ except subprocess.CalledProcessError as e:
|
|
|
+ pass
|
|
|
+ except OSError as e:
|
|
|
+ pass
|
|
|
+
|
|
|
+class settingHighlighter(QtGui.QSyntaxHighlighter):
|
|
|
+ def __init__( self, parent, theme):
|
|
|
+ super(settingHighlighter, self).__init__(parent)
|
|
|
+ self.parent = parent
|
|
|
+ self.highlightingRules = []
|
|
|
+
|
|
|
+
|
|
|
+ # equal = QtGui.QTextCharFormat()
|
|
|
+ # equal.setForeground(QtCore.Qt.green)
|
|
|
+ # equal.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ # pattern = QtCore.QRegExp("=")
|
|
|
+ # self.highlightingRules.append((pattern, equal))
|
|
|
+
|
|
|
+ number = QtGui.QTextCharFormat()
|
|
|
+ number.setForeground(QtCore.Qt.blue)
|
|
|
+ number.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?" )
|
|
|
+ pattern.setMinimal(True)
|
|
|
+ self.highlightingRules.append((pattern, number))
|
|
|
+
|
|
|
+ bool_true = QtGui.QTextCharFormat()
|
|
|
+ bool_true.setForeground(QtCore.Qt.darkGreen)
|
|
|
+ bool_true.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "True" )
|
|
|
+ self.highlightingRules.append((pattern, bool_true))
|
|
|
+
|
|
|
+ bool_false = QtGui.QTextCharFormat()
|
|
|
+ bool_false.setForeground(QtCore.Qt.darkRed)
|
|
|
+ bool_false.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "False" )
|
|
|
+ self.highlightingRules.append((pattern, bool_false))
|
|
|
+
|
|
|
+ failed = QtGui.QTextCharFormat()
|
|
|
+ failed.setForeground(QtCore.Qt.red)
|
|
|
+ failed.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "Failed|Connection Error" )
|
|
|
+ self.highlightingRules.append((pattern, failed))
|
|
|
+
|
|
|
+ success = QtGui.QTextCharFormat()
|
|
|
+ success.setForeground(QtGui.QColor(30, 210, 0))
|
|
|
+ success.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "Success" )
|
|
|
+ self.highlightingRules.append((pattern, success))
|
|
|
+
|
|
|
+ header = QtGui.QTextCharFormat()
|
|
|
+ header.setForeground(QtCore.Qt.black)
|
|
|
+ header.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp( "-----\[.*\]-----" )
|
|
|
+ pattern.setMinimal(True)
|
|
|
+ self.highlightingRules.append((pattern, header))
|
|
|
+
|
|
|
+ working = QtGui.QTextCharFormat()
|
|
|
+ working.setForeground(QtCore.Qt.black)
|
|
|
+ working.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ pattern = QtCore.QRegExp("Working...")
|
|
|
+ self.highlightingRules.append((pattern, working))
|
|
|
+
|
|
|
+ def setKeywords(self, kw):
|
|
|
+ keyword = QtGui.QTextCharFormat()
|
|
|
+ keyword.setForeground( QtCore.Qt.darkBlue)
|
|
|
+ # keyword.setFontWeight( QtGui.QFont.Bold )
|
|
|
+ keywords = QtCore.QStringList(kw)
|
|
|
+ for word in keywords:
|
|
|
+ pattern = QtCore.QRegExp("\\b" + word + "\\b")
|
|
|
+ self.highlightingRules.append((pattern, keyword))
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def highlightBlock( self, text ):
|
|
|
+ for pattern, format in self.highlightingRules:
|
|
|
+ # expression = QtCore.QRegExp( pattern )
|
|
|
+ # index = expression.indexIn( text )
|
|
|
+ index = pattern.indexIn(text)
|
|
|
+ while index >= 0:
|
|
|
+ length = pattern.matchedLength()
|
|
|
+ self.setFormat( index, length, format )
|
|
|
+ index = text.indexOf( pattern, index + length )
|
|
|
+ self.setCurrentBlockState( 0 )
|
|
|
+
|
|
|
+class customTextEdit(QtGui.QTextEdit):
|
|
|
+ def __init__(self):
|
|
|
+ super(customTextEdit, self).__init__()
|
|
|
+ self.highlighter = settingHighlighter(self, 'Classic')
|
|
|
+ def append(self, string):
|
|
|
+ # super(customTextEdit, self).append("---------------"*3)
|
|
|
+ super(customTextEdit, self).append("-----[ " + time.asctime() + " ]-----\n"+string+"\n")
|
|
|
+ self.ensureCursorVisible()
|
|
|
+ def setKeywords(self, kw):
|
|
|
+ self.highlighter.setKeywords(kw)
|
|
|
+
|
|
|
+class convenientGridLayout(QtGui.QGridLayout):
|
|
|
+ line = 0
|
|
|
+ column = 0
|
|
|
+ def addWidget(self, QWidget, newLine=False, line=None, col=None, rowSpan=1, colSpan=1):
|
|
|
+ if (line is not None) and (col is not None):
|
|
|
+ super(convenientGridLayout, self).addWidget(QWidget, line, col, rowSpan, colSpan)
|
|
|
+ return
|
|
|
+ elif line is not None:
|
|
|
+ super(convenientGridLayout, self).addWidget(QWidget, line, self.column, rowSpan, colSpan)
|
|
|
+ return
|
|
|
+ elif col is not None:
|
|
|
+ super(convenientGridLayout, self).addWidget(QWidget, self.line, col, rowSpan, colSpan)
|
|
|
+ return
|
|
|
+ if newLine:
|
|
|
+ self.line += 1
|
|
|
+ self.column = 0
|
|
|
+ super(convenientGridLayout, self).addWidget(QWidget, self.line, self.column, rowSpan, colSpan)
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ super(convenientGridLayout, self).addWidget(QWidget, self.line, self.column, rowSpan, colSpan)
|
|
|
+ self.column += 1
|
|
|
+ return
|
|
|
+
|
|
|
+ def newLine(self):
|
|
|
+ self.line += 1
|
|
|
+ self.column = 0
|
|
|
+ def skipCol(self, cols=1):
|
|
|
+ self.column += cols
|
|
|
+ def hLine(self, cols):
|
|
|
+ line = QtGui.QFrame()
|
|
|
+ line.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ if cols == 'full':
|
|
|
+ self.addWidget(line, newLine=True, colSpan=self.columnCount())
|
|
|
+ else:
|
|
|
+ self.addWidget(line, newLine=True, colSpan=cols)
|
|
|
+ def vLine(self, rows, perm=False):
|
|
|
+ line = QtGui.QFrame()
|
|
|
+ line.setFrameShape(QtGui.QFrame.VLine)
|
|
|
+ if rows == 'full':
|
|
|
+ self.addWidget(line, rowSpan=self.rowCount())
|
|
|
+ else:
|
|
|
+ self.addWidget(line, rowSpan=rows)
|
|
|
+
|
|
|
+
|
|
|
+class KCGRemote(QtGui.QMainWindow):
|
|
|
+ def __init__(self):
|
|
|
+ super(KCGRemote, self).__init__()
|
|
|
+ self.c = KCGCentral()
|
|
|
+ self.setCentralWidget(self.c)
|
|
|
+ self.statusText = QtGui.QLabel("Not Connected")
|
|
|
+ self.statusbar = self.statusBar()
|
|
|
+ self.statusbar.addPermanentWidget(self.statusText)
|
|
|
+ self.setWindowTitle("KCG Remote Control")
|
|
|
+ if len(sys.argv) > 1 and sys.argv[1] == 'blue':
|
|
|
+ styleSheet = ''
|
|
|
+ with open('KCG/style/blue.css') as f:
|
|
|
+ styleSheet += f.read()
|
|
|
+ self.setStyleSheet(styleSheet)
|
|
|
+
|
|
|
+
|
|
|
+class KCGCentral(QtGui.QWidget):
|
|
|
+ def __init__(self):
|
|
|
+ super(KCGCentral, self).__init__()
|
|
|
+
|
|
|
+ self.progressbar = QtGui.QProgressBar()
|
|
|
+ self.progressbar.hide()
|
|
|
+ # self.user_layout = QtGui.QGridLayout()
|
|
|
+ self.user_layout = convenientGridLayout()
|
|
|
+ self.layout = QtGui.QVBoxLayout()
|
|
|
+ self.layout.addLayout(self.user_layout)
|
|
|
+ self.setLayout(self.layout)
|
|
|
+
|
|
|
+ self.host_edit = QtGui.QLineEdit()
|
|
|
+ self.port_edit = QtGui.QLineEdit()
|
|
|
+ self.connect = QtGui.QPushButton("Connect")
|
|
|
+ self.connect.clicked.connect(self.conn)
|
|
|
+
|
|
|
+ self.host = None
|
|
|
+ self.port = None
|
|
|
+
|
|
|
+ self.cal_button = QtGui.QPushButton("Calibrate")
|
|
|
+ self.cal_button.clicked.connect(self.cal)
|
|
|
+ self.sync_button = QtGui.QPushButton("Synchronize")
|
|
|
+ self.sync_button.clicked.connect(self.sync)
|
|
|
+ self.set_def_button = QtGui.QPushButton("Set Defaults")
|
|
|
+ self.set_def_button.clicked.connect(self.set_def)
|
|
|
+ self.reset_button = QtGui.QPushButton("Reset")
|
|
|
+ self.reset_button.clicked.connect(self.reset)
|
|
|
+ self.acquire_button = QtGui.QPushButton("Toggle Acquisition")
|
|
|
+ self.acquire_button.clicked.connect(self.acq)
|
|
|
+ self.get_button = QtGui.QPushButton("Get Value")
|
|
|
+ self.get_button.clicked.connect(self.get)
|
|
|
+ self.set_button = QtGui.QPushButton("Set Value")
|
|
|
+ self.set_button.clicked.connect(self.set)
|
|
|
+ self.reinit_status_button = QtGui.QPushButton("Reinit Status")
|
|
|
+ self.reinit_status_button.clicked.connect(self.status)
|
|
|
+
|
|
|
+ self.get_image_button = QtGui.QPushButton("Get Image")
|
|
|
+ self.get_image_button.clicked.connect(self.get_image)
|
|
|
+
|
|
|
+ # self.get_field = QtGui.QLineEdit()
|
|
|
+ self.get_placeholder = QtGui.QLabel("Load possible keys first")
|
|
|
+ self.set_key_placeholder_button = QtGui.QPushButton("Load possible keys")
|
|
|
+ self.set_key_placeholder_button.clicked.connect(self.load_keys)
|
|
|
+ self.set_value_field = QtGui.QLineEdit()
|
|
|
+
|
|
|
+ self.get_image_type = QtGui.QComboBox()
|
|
|
+ self.get_image_type.addItems(['trains', 'fft', 'heatmap', 'combined'])
|
|
|
+ self.get_image_adc_field = QtGui.QSpinBox()
|
|
|
+ self.get_image_adc_field.setRange(1, 4)
|
|
|
+
|
|
|
+ self.single_read_button = QtGui.QPushButton("Single Read")
|
|
|
+ self.single_read_button.clicked.connect(self.single_read)
|
|
|
+
|
|
|
+ self.buttons = [self.cal_button,
|
|
|
+ self.sync_button,
|
|
|
+ self.set_def_button,
|
|
|
+ self.reset_button,
|
|
|
+ self.acquire_button,
|
|
|
+ self.get_button,
|
|
|
+ self.set_button,
|
|
|
+ self.get_image_button,
|
|
|
+ self.set_key_placeholder_button,
|
|
|
+ self.reinit_status_button,
|
|
|
+ self.get_image_type,
|
|
|
+ self.get_image_adc_field,
|
|
|
+ self.set_value_field,
|
|
|
+ self.single_read_button]
|
|
|
+ for b in self.buttons:
|
|
|
+ b.setEnabled(False)
|
|
|
+
|
|
|
+ # self.user_layout.addWidget(QtGui.QLabel("Host"), 0, 0)
|
|
|
+ # self.user_layout.addWidget(self.host_edit, 1, 0)
|
|
|
+ # self.user_layout.addWidget(QtGui.QLabel("Port"), 0, 1)
|
|
|
+ # self.user_layout.addWidget(self.port_edit, 1, 1)
|
|
|
+ # self.user_layout.addWidget(self.connect, 1, 3)
|
|
|
+ # line = QtGui.QFrame()
|
|
|
+ # line.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ # self.user_layout.addWidget(line, 2, 0, 1, 4)
|
|
|
+
|
|
|
+
|
|
|
+ # self.user_layout.addWidget(self.cal_button, 3, 0)
|
|
|
+ # self.user_layout.addWidget(self.sync_button, 3, 1)
|
|
|
+ # self.user_layout.addWidget(self.set_def_button, 4, 1)
|
|
|
+ # self.user_layout.addWidget(self.reset_button, 4, 0)
|
|
|
+ # line2 = QtGui.QFrame()
|
|
|
+ # line2.setFrameShape(QtGui.QFrame.VLine)
|
|
|
+ # self.user_layout.addWidget(line2, 3, 2, 2, 1)
|
|
|
+ # line3 = QtGui.QFrame()
|
|
|
+ # line3.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ # self.user_layout.addWidget(line3, 5, 0, 1, 4)
|
|
|
+
|
|
|
+
|
|
|
+ # self.user_layout.addWidget(self.acquire_button, 3, 3)
|
|
|
+ # self.user_layout.addWidget(self.reinit_status_button, 4, 3)
|
|
|
+ # self.user_layout.addWidget(self.get_image_type, 6, 0)
|
|
|
+ # self.user_layout.addWidget(self.get_image_adc_field, 6, 1)
|
|
|
+ # self.user_layout.addWidget(self.get_image_button, 6, 3)
|
|
|
+ # self.user_layout.addWidget(self.get_placeholder, 7, 1)
|
|
|
+ # self.user_layout.addWidget(self.get_button, 7, 3)
|
|
|
+ # self.user_layout.addWidget(self.set_key_placeholder_button, 8, 0)
|
|
|
+ # self.user_layout.addWidget(self.set_value_field, 8, 1)
|
|
|
+ # self.user_layout.addWidget(self.set_button, 8, 3)
|
|
|
+
|
|
|
+
|
|
|
+ self.user_layout.addWidget(QtGui.QLabel("Host"))
|
|
|
+ self.user_layout.addWidget(QtGui.QLabel("Port"))
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.host_edit)
|
|
|
+ self.user_layout.addWidget(self.port_edit)
|
|
|
+ self.user_layout.addWidget(self.connect)
|
|
|
+ # line = QtGui.QFrame()
|
|
|
+ # line.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ # self.user_layout.addWidget(line, newLine=True, colSpan=4)
|
|
|
+ self.user_layout.hLine('full')
|
|
|
+
|
|
|
+
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.cal_button)
|
|
|
+ self.user_layout.addWidget(self.sync_button)
|
|
|
+ # line2 = QtGui.QFrame()
|
|
|
+ # line2.setFrameShape(QtGui.QFrame.VLine)
|
|
|
+ # self.user_layout.addWidget(line2, rowSpan=2)
|
|
|
+ self.user_layout.vLine(2)
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.set_def_button)
|
|
|
+ self.user_layout.addWidget(self.reset_button)
|
|
|
+
|
|
|
+ # line3 = QtGui.QFrame()
|
|
|
+ # line3.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ # self.user_layout.addWidget(line3, newLine=True, colSpan=4)
|
|
|
+ self.user_layout.hLine('full')
|
|
|
+
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.acquire_button)
|
|
|
+ self.user_layout.addWidget(self.single_read_button)
|
|
|
+ self.user_layout.addWidget(self.reinit_status_button)
|
|
|
+
|
|
|
+ # line4 = QtGui.QFrame()
|
|
|
+ # line4.setFrameShape(QtGui.QFrame.HLine)
|
|
|
+ # self.user_layout.addWidget(line4, newLine=True, colSpan=4)
|
|
|
+ self.user_layout.hLine('full')
|
|
|
+
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.get_image_type)
|
|
|
+ self.user_layout.addWidget(self.get_image_adc_field)
|
|
|
+ self.user_layout.addWidget(self.get_image_button)
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.skipCol()
|
|
|
+ self.user_layout.addWidget(self.get_placeholder)
|
|
|
+ self.user_layout.addWidget(self.get_button)
|
|
|
+ self.user_layout.newLine()
|
|
|
+ self.user_layout.addWidget(self.set_key_placeholder_button)
|
|
|
+ self.user_layout.addWidget(self.set_value_field)
|
|
|
+ self.user_layout.addWidget(self.set_button)
|
|
|
+
|
|
|
+
|
|
|
+ self.output = customTextEdit()
|
|
|
+ self.output.setReadOnly(True)
|
|
|
+
|
|
|
+ self.layout.addWidget(self.output)
|
|
|
+
|
|
|
+ self.image = QtGui.QLabel()
|
|
|
+ self.image.hide()
|
|
|
+ # self.layout.addWidget(self.image)
|
|
|
+
|
|
|
+ def send(self, command):
|
|
|
+ bk = self.parent().statusText.text()
|
|
|
+ self.parent().statusText.setText("Working...")
|
|
|
+ QtGui.QApplication.processEvents()
|
|
|
+ r = client.send(command, self.host, self.port, p=False).strip()
|
|
|
+ self.parent().statusText.setText(bk)
|
|
|
+ return r
|
|
|
+
|
|
|
+ def conn(self):
|
|
|
+ try:
|
|
|
+ host = self.host_edit.text()
|
|
|
+ port = int(self.port_edit.text())
|
|
|
+ client.send('get status', host, port, p=False)
|
|
|
+ self.host = host
|
|
|
+ self.port = port
|
|
|
+ for button in self.buttons:
|
|
|
+ button.setEnabled(True)
|
|
|
+ self.parent().statusText.setText("Connected")
|
|
|
+ self.load_keys()
|
|
|
+ except:
|
|
|
+ self.output.append("Connection Error")
|
|
|
+
|
|
|
+ def load_keys(self):
|
|
|
+ r = self.send('get possible_keys')
|
|
|
+ idx1 = self.user_layout.getItemPosition(self.user_layout.indexOf(self.set_key_placeholder_button))
|
|
|
+ idx2 = self.user_layout.getItemPosition(self.user_layout.indexOf(self.get_placeholder))
|
|
|
+ self.user_layout.removeWidget(self.set_key_placeholder_button)
|
|
|
+ self.user_layout.removeWidget(self.get_placeholder)
|
|
|
+ self.set_key_placeholder_button.hide()
|
|
|
+ self.get_placeholder.hide()
|
|
|
+ self.set_key_field = QtGui.QComboBox()
|
|
|
+ self.get_field = QtGui.QComboBox()
|
|
|
+ self.get_field.addItem('all_acquisition')
|
|
|
+ self.set_key_field.addItems(r.split('\n'))
|
|
|
+ self.get_field.addItems(r.split('\n'))
|
|
|
+ self.user_layout.addWidget(self.set_key_field, line=idx1[0], col=idx1[1])
|
|
|
+ self.user_layout.addWidget(self.get_field, line=idx2[0], col=idx2[1])
|
|
|
+
|
|
|
+ syntax = r.split('\n')
|
|
|
+ syntax.extend(["Orbits Observed", "Orbits Skipped", "Count", "Wait Time", "Pilot Bunch Simulator", "Header"])
|
|
|
+ self.output.setKeywords(syntax)
|
|
|
+
|
|
|
+ def cal(self):
|
|
|
+ r = self.send('calibrate')
|
|
|
+ self.output.append(r)
|
|
|
+ def sync(self):
|
|
|
+ r = self.send('sync')
|
|
|
+ self.output.append(r)
|
|
|
+ def set_def(self):
|
|
|
+ r = self.send('set_defaults')
|
|
|
+ self.output.append(r)
|
|
|
+ def reset(self):
|
|
|
+ r = self.send('reset')
|
|
|
+ self.output.append(r)
|
|
|
+ def acq(self):
|
|
|
+ r = self.send('acquire')
|
|
|
+ self.output.append(r)
|
|
|
+ if 'started' in r:
|
|
|
+ self.parent().statusbar.addWidget(self.progressbar)
|
|
|
+ self.progressbar.show()
|
|
|
+ self.status()
|
|
|
+ else:
|
|
|
+ self.parent().statusbar.removeWidget(self.progressbar)
|
|
|
+ self.progressbar.hide()
|
|
|
+ def status(self):
|
|
|
+ r = self.send('get status')
|
|
|
+ if 'No' in r:
|
|
|
+ self.parent().statusbar.removeWidget(self.progressbar)
|
|
|
+ self.progressbar.hide()
|
|
|
+ self.output.append(r)
|
|
|
+ else:
|
|
|
+ if not self.progressbar in self.parent().statusbar.children():
|
|
|
+ self.parent().statusbar.addWidget(self.progressbar)
|
|
|
+ self.progressbar.show()
|
|
|
+ r = int(r.strip("%"))
|
|
|
+ self.progressbar.setValue(r)
|
|
|
+ timer = QtCore.QTimer()
|
|
|
+ timer.singleShot(1000, self.status)
|
|
|
+
|
|
|
+
|
|
|
+ def set(self):
|
|
|
+ r = self.send('set ' + str(self.set_key_field.currentText()) + " " + str(self.set_value_field.text()))
|
|
|
+ self.output.append(r)
|
|
|
+ def get(self):
|
|
|
+ r = self.send('get ' + str(self.get_field.currentText()))
|
|
|
+ self.output.append(r)
|
|
|
+
|
|
|
+ def get_image(self):
|
|
|
+ self.send('get_image '+str(self.get_image_type.currentText()) + ' ' + str(self.get_image_adc_field.value()))
|
|
|
+ pixmap = QtGui.QPixmap('/tmp/kcgimage.png')
|
|
|
+ self.image.setPixmap(pixmap.scaledToHeight(700, mode=QtCore.Qt.SmoothTransformation))
|
|
|
+ # self.image.setPixmap(pixmap)
|
|
|
+ self.image.setMinimumSize(self.image.pixmap().size())
|
|
|
+ self.image.show()
|
|
|
+
|
|
|
+ def single_read(self):
|
|
|
+ r = self.send("singleread")
|
|
|
+ self.output.append(r)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+app = QtGui.QApplication([])
|
|
|
+rem = KCGRemote()
|
|
|
+rem.show()
|
|
|
+app.exec_()
|