class TcpS(QDialog, Ui_TcpServer): """ Class documentation goes here. """ sendFileName = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(TcpS, self).__init__(parent) self.setupUi(self) self.payloadSize = 64 * 1024 self.totalBytes = 0 self.bytesWritten = 0 self.bytesToWrite = 0 self.theFileName = "" self.fileName = "" self.localFile = QFile() self.outBlock = QByteArray() self.time = QTime() self.initServer() def initServer(self): """ 网络设置初始化 """ self.tcpPort = 7788 self.tcpServer = QTcpServer(self) self.clientConnection = QTcpSocket(self) self.tcpServer.newConnection.connect(self.sendMessage) self.serverStatuslabel.setText("请选择要传送的文件") self.progressBar.reset() self.serverOpenBtn.setEnabled(True) self.serverSendBtn.setEnabled(False) self.tcpServer.close() def refused(self): """ 对端拒绝接收文件 """ self.tcpServer.close() self.serverStatuslabel.setText("对方拒绝接收") def closeEvent(self, event): """ 关闭事件 """ self.on_serverCloseBtn_clicked() def sendMessage(self): """ 发送文件 """ self.serverSendBtn.setEnabled(False) self.clientConnection = self.tcpServer.nextPendingConnection() self.clientConnection.bytesWritten.connect(self.updateClientProgress) self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName)) self.localFile = QFile(self.fileName) if not (self.localFile.open(QFile.ReadOnly)): errorMsg = "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString()) QMessageBox.warning(self, "应用程序", errorMsg) return self.serverCloseBtn.setText("取消") self.totalBytes = self.localFile.size() #单位:字节 sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly) sendOut.setVersion(QDataStream.Qt_5_4) self.time.start() currentFile = self.fileName.split("/")[-1] sendOut.writeInt64(0) sendOut.writeInt64(0) sendOut.writeQString(currentFile) self.totalBytes += self.outBlock.size() sendOut.device().seek(0) sendOut.writeInt64(self.totalBytes) sendOut.writeInt64(self.outBlock.size() - 2) self.bytesToWrite = self.totalBytes - self.clientConnection.write( self.outBlock) self.outBlock.resize(0) def updateClientProgress(self, numBytes): """ 发送进度显示 """ qApp.processEvents() self.bytesWritten += numBytes if self.bytesWritten > 0: self.block = self.localFile.read( min(self.bytesToWrite, self.payloadSize)) self.bytesToWrite -= self.clientConnection.write(self.block) else: self.localFile.close() byteSent = self.bytesWritten / (1024 * 1024) useTime = self.time.elapsed() / 1000 speed = self.bytesWritten / useTime / (1024 * 1024) total = self.totalBytes / (1024 * 1024) left = (total - byteSent) / speed if byteSent < 0.01: byteSent = self.bytesWritten / 1024 speed = self.bytesWritten / useTime / 1024 total = self.totalBytes / 1024 if left > 0: sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format( byteSent, speed, total, useTime, left) else: sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format( byteSent, speed, total, useTime) else: if left > 0: sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format( byteSent, speed, total, useTime, left) else: sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format( byteSent, speed, total, useTime) self.progressBar.setMaximum(total) self.progressBar.setValue(byteSent) if self.bytesWritten == self.totalBytes: self.serverCloseBtn.setText("关闭") self.serverStatuslabel.setText(sendInfo) @pyqtSlot() def on_serverOpenBtn_clicked(self): """ 打开文件 """ self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0] if self.fileName: self.theFileName = self.fileName.split("/")[-1] self.serverStatuslabel.setText("要传送的文件为:{}".format( self.theFileName)) self.serverSendBtn.setEnabled(True) self.serverOpenBtn.setEnabled(False) @pyqtSlot() def on_serverSendBtn_clicked(self): """ 发送文件 """ if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)): errorMsg = self.tcpServer.errorString() QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg)) self.TcpServer.close() return self.serverStatuslabel.setText("等待对方接收... ...") self.serverSendBtn.setEnabled(False) self.sendFileName.emit(self.theFileName) @pyqtSlot() def on_serverCloseBtn_clicked(self): """ 取消或者关闭 """ if self.tcpServer.isListening(): self.tcpServer.close() if self.localFile.isOpen(): self.localFile.close() self.clientConnection.abort() if self.serverCloseBtn.text() == "取消": self.serverCloseBtn.setText("关闭") else: self.close() self.serverOpenBtn.setEnabled(True) self.serverSendBtn.setEnabled(False) self.progressBar.reset() self.totalBytes = 0 self.bytesWritten = 0 self.bytesToWrite = 0 self.serverStatuslabel.setText("请选择要传送的文件")
class TcpC(QDialog, Ui_TcpClient): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(TcpC, self).__init__(parent) self.setupUi(self) self.TotalBytes = 0 self.bytesReceive = 0 self.fileNameSize = 0 self.bytesToReceive = 0 self.fileName = "" self.tcpClient = QTcpSocket(self) self.tcpPort = 7788 self.time = QTime() self.tcpClient.readyRead.connect(self.readMessage) self.tcpClient.error.connect(self.displayError) def setHostAddress(self, address): """ 设置服务器地址 """ self.hostAddress = address self.newConnect() def setFileName(self, file): """ 待接收文件的文件名 """ self.localFile = QFile(file) def closeEvent(self, event): """ 关闭事件 """ self.on_tcpClientCloseBtn_clicked() def newConnect(self): """ 连接服务器并开始计时 """ self.tcpClient.abort() self.tcpClient.connectToHost(self.hostAddress, self.tcpPort) self.time.start() def readMessage(self): """ 读取文件数据 """ receiver = QDataStream(self.tcpClient) receiver.setVersion(QDataStream.Qt_5_4) if self.bytesReceive <= 2: if self.tcpClient.bytesAvailable() >= 2 and self.fileNameSize == 0: self.TotalBytes = receiver.readInt64() self.fileNameSize = receiver.readInt64() self.bytesReceive += 2 if self.tcpClient.bytesAvailable() >= self.fileNameSize and self.fileNameSize != 0: self.fileName = receiver.readQString() self.bytesReceive += self.fileNameSize if not(self.localFile.open(QFile.WriteOnly)): QMessageBox.warning(self, "应用程序", "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString())) return else: return if self.bytesReceive < self.TotalBytes: self.bytesReceive += self.tcpClient.bytesAvailable() inBlock = self.tcpClient.readAll() self.localFile.write(inBlock) inBlock.resize(0) useTime = self.time.elapsed() / 1000 bytesReceived = self.bytesReceive / (1024*1024) speed = bytesReceived / useTime total = self.TotalBytes / (1024*1024) left = (total - bytesReceived) / speed if bytesReceived < 0.01: bytesReceived = self.bytesReceive / 1024 speed = bytesReceived / useTime / 1024 total = self.TotalBytes / 1024 if left > 0: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) else: if left > 0: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) self.progressBar.setMaximum(total) self.progressBar.setValue(bytesReceived) self.tcpClientStatuslabel.setText(msg) if self.bytesReceive == self.TotalBytes: self.localFile.close() self.tcpClient.close() self.tcpClientStatuslabel.setText("接收文件{}完毕".format(self.fileName)) self.tcpClientBtn.setEnabled(False) def displayError(self, socketError): """ 显示错误 """ if socketError == QAbstractSocket.RemoteHostClosedError: pass else: errorMsg = self.tcpClient.errorString() QMessageBox.warning(self, "应用程序", errorMsg) return @pyqtSlot() def on_tcpClientBtn_clicked(self): """ 取消接收 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.tcpClientBtn.setEnabled(False) @pyqtSlot() def on_tcpClientCloseBtn_clicked(self): """ 关闭 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.close() self.tcpClientBtn.setEnabled(True)
class MainWindow(QMainWindow): WaitingAnimation = [' |', ' /', ' -', ' \\'] WaitingAnimationFrameDurationMs = 100 ConnectionTimerTimeoutMs = 5000 DataExchangeTimerTimeoutMs = 250 def __init__(self): super().__init__() self.targetAddr = '0.0.0.0' self.targetPort = 0 QSettings.setPath(QSettings.IniFormat, QSettings.UserScope, QDir.currentPath()) self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'config') self.readSettings() self.connectionSettings = ConnectionSettings(self.targetAddr, self.targetPort, self) self.connectionSettings.settingsChanged.connect( self.onConnectionSettingsSettingsChanged) self.socket = QTcpSocket(self) self.socket.stateChanged.connect(self.onSocketStateChanged) self.socket.readyRead.connect(self.onSocketReadyRead) self.frameLength = 0 self.lastSocketState = QAbstractSocket.UnconnectedState self.animationTimer = QTimer(self) self.animationTimer.timeout.connect(self.onAnimationTimerTimeout) self.animationCounter = 0 self.connectionTimer = QTimer(self) self.connectionTimer.setSingleShot(True) self.connectionTimer.timeout.connect(self.onConnectionTimerTimeout) self.dataExchangeTimer = QTimer(self) self.dataExchangeTimer.timeout.connect(self.onDataExchangeTimerTimeout) self.initUI() self.onConnectionSettingsSettingsChanged(self.targetAddr, self.targetPort) self.onSocketStateChanged() # self.cap = cv2.VideoCapture(0) # self.dispTimer = QTimer(self) # self.dispTimer.timeout.connect(self.onDispTimerTimeout) # self.dispTimer.start(100) # @pyqtSlot() # def onDispTimerTimeout(self): # ret, frame = self.cap.read() # image = self.cvToQtIm(frame) # pixmap = QPixmap.fromImage(image) # self.streamDisp.setPixmap(pixmap) def initUI(self): self.setGeometry(300, 300, 300, 300) self.setWindowTitle('Diag Tool') statusBar = QStatusBar(self) self.targetInfo = QLabel(self) self.connectionStatus = QLabel(self) statusBar.addWidget(self.targetInfo, 0) statusBar.addWidget(self.connectionStatus, 1) self.setStatusBar(statusBar) self.streamDisp = QLabel(self) self.streamDisp.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) layout = QGridLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.streamDisp, 0, 0, 0, 4) self.setCentralWidget(QWidget(self)) self.centralWidget().setLayout(layout) self.menuTarget = self.menuBar().addMenu('Target') self.menuTargetConnect = QAction('Connect', self) self.menuTargetConnect.triggered.connect(self.onMenuTargetConnect) self.menuTargetSettings = QAction('Settings', self) self.menuTargetSettings.triggered.connect(self.onMenuTargetSettings) self.menuTarget.addAction(self.menuTargetConnect) self.menuTarget.addAction(self.menuTargetSettings) def closeEvent(self, event): self.writeSettings() def cvToQtIm(self, cvIm): cvIm = cv2.cvtColor(cvIm, cv2.COLOR_BGR2RGB) return QImage(cvIm.data, cvIm.shape[1], cvIm.shape[0], QImage.Format_RGB888) def readSettings(self): value = self.settings.value('target/addr') if value: self.targetAddr = str(value) value = self.settings.value('target/port') if value: self.targetPort = int(value) def writeSettings(self): self.settings.setValue('target/addr', self.targetAddr) self.settings.setValue('target/port', self.targetPort) @pyqtSlot() def onMenuTargetConnect(self): if QAbstractSocket.UnconnectedState == self.socket.state(): self.menuTargetConnect.setEnabled(False) self.connectionSettings.setUserInputEnabled(False) self.socket.connectToHost(QHostAddress(self.targetAddr), self.targetPort) self.connectionTimer.start(self.ConnectionTimerTimeoutMs) elif QAbstractSocket.ConnectedState == self.socket.state(): self.menuTargetConnect.setEnabled(False) self.socket.disconnectFromHost() @pyqtSlot() def onMenuTargetSettings(self): self.connectionSettings.show() @pyqtSlot() def onSocketStateChanged(self): #print(self.socket.state()) if QAbstractSocket.UnconnectedState == self.socket.state(): self.dataExchangeTimer.timeout.emit() self.dataExchangeTimer.start(self.DataExchangeTimerTimeoutMs) self.animationTimer.stop() self.menuTargetConnect.setText('Connect') self.menuTargetConnect.setEnabled(True) self.connectionStatus.setText('Offline') self.connectionSettings.setUserInputEnabled(True) if QAbstractSocket.ConnectingState == self.lastSocketState: QMessageBox.warning(self, 'Warning', 'Unable to connect!') elif QAbstractSocket.ConnectedState == self.socket.state(): self.connectionTimer.stop() self.animationTimer.stop() self.dataExchangeTimer.start() self.menuTargetConnect.setText('Disconnect') self.menuTargetConnect.setEnabled(True) self.connectionStatus.setText('Online') elif QAbstractSocket.ConnectingState == self.socket.state(): self.connectionStatus.setText('Connecting') self.animationCounter = 0 self.animationTimer.start(self.WaitingAnimationFrameDurationMs) elif QAbstractSocket.ClosingState == self.socket.state(): self.connectionStatus.setText('Disconnecting') self.animationCounter = 0 self.animationTimer.start(self.WaitingAnimationFrameDurationMs) self.lastSocketState = self.socket.state() @pyqtSlot() def onSocketReadyRead(self): if 0 == self.frameLength: if self.socket.canReadLine(): data = self.socket.readLine()[:-1] self.frameLength = int(data) if self.frameLength != 0: if self.socket.bytesAvailable() >= self.frameLength: data = self.socket.read(self.frameLength) arr = np.frombuffer(data, dtype=np.uint8) cvIm = cv2.imdecode(arr, cv2.IMREAD_COLOR) self.frameLength = 0 image = self.cvToQtIm(cvIm) pixmap = QPixmap.fromImage(image) self.streamDisp.setPixmap(pixmap) @pyqtSlot(str, int) def onConnectionSettingsSettingsChanged(self, addr, port): self.targetInfo.setText('Target (' + addr + ':' + str(port) + ')') self.targetAddr = addr self.targetPort = port @pyqtSlot() def onAnimationTimerTimeout(self): if QAbstractSocket.ConnectingState == self.socket.state(): text = 'Connecting' else: text = 'Disconnecting' text += self.WaitingAnimation[self.animationCounter] self.animationCounter = (self.animationCounter + 1) % len( self.WaitingAnimation) self.connectionStatus.setText(text) @pyqtSlot() def onConnectionTimerTimeout(self): self.socket.abort() @pyqtSlot() def onDataExchangeTimerTimeout(self): if QAbstractSocket.ConnectedState == self.socket.state(): self.socket.writeData('get\n'.encode())
class VNA(QMainWindow, Ui_VNA): max_size = 16383 formatter = matplotlib.ticker.FuncFormatter(lambda x, pos: '%1.1fM' % (x * 1e-6) if abs(x) >= 1e6 else '%1.1fk' % (x * 1e-3) if abs(x) >= 1e3 else '%1.1f' % x if abs(x) >= 1e0 else '%1.1fm' % (x * 1e+3) if abs(x) >= 1e-3 else '%1.1fu' % (x * 1e+6) if abs(x) >= 1e-6 else '%1.1f' % x) def __init__(self): super(VNA, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # sweep parameters self.sweep_start = 100 self.sweep_stop = 60000 self.sweep_size = 600 self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 # buffer and offset for the incoming samples self.buffer = bytearray(32 * VNA.max_size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) self.adc1 = np.zeros(VNA.max_size, np.complex64) self.adc2 = np.zeros(VNA.max_size, np.complex64) self.dac1 = np.zeros(VNA.max_size, np.complex64) self.open = np.zeros(VNA.max_size, np.complex64) self.short = np.zeros(VNA.max_size, np.complex64) self.load = np.zeros(VNA.max_size, np.complex64) self.dut = np.zeros(VNA.max_size, np.complex64) self.mode = 'dut' # create figure self.figure = Figure() self.figure.set_facecolor('none') self.canvas = FigureCanvas(self.figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.sweepFrame.setEnabled(False) self.dutSweep.setEnabled(False) self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) self.openSweep.clicked.connect(self.sweep_open) self.shortSweep.clicked.connect(self.sweep_short) self.loadSweep.clicked.connect(self.sweep_load) self.dutSweep.clicked.connect(self.sweep_dut) self.s1pButton.clicked.connect(self.write_s1p) self.startValue.valueChanged.connect(self.set_start) self.stopValue.valueChanged.connect(self.set_stop) self.sizeValue.valueChanged.connect(self.set_size) self.openPlot.clicked.connect(self.plot_open) self.shortPlot.clicked.connect(self.plot_short) self.loadPlot.clicked.connect(self.plot_load) self.dutPlot.clicked.connect(self.plot_dut) self.smithPlot.clicked.connect(self.plot_smith) self.impPlot.clicked.connect(self.plot_imp) self.rcPlot.clicked.connect(self.plot_rc) self.swrPlot.clicked.connect(self.plot_swr) self.rlPlot.clicked.connect(self.plot_rl) # create timer self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.offset = 0 self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(True) self.dutSweep.setEnabled(False) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_start(self.startValue.value()) self.set_stop(self.stopValue.value()) self.set_size(self.sizeValue.value()) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(True) self.dutSweep.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 32 * self.sweep_size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:32 * self.sweep_size] = self.socket.read(32 * self.sweep_size - self.offset) self.offset = 0 self.adc1 = self.data[0::4] self.adc2 = self.data[1::4] self.dac1 = self.data[2::4] getattr(self, self.mode)[0:self.sweep_size] = self.adc1[0:self.sweep_size] / self.dac1[0:self.sweep_size] self.sweepFrame.setEnabled(True) self.selectFrame.setEnabled(True) getattr(self, 'plot_%s' % self.mode)() def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'VNA', 'Error: connection timeout.') else: QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString()) self.stop() def set_start(self, value): self.sweep_start = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000))) def set_stop(self, value): self.sweep_stop = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000))) def set_size(self, value): self.sweep_size = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 2<<28 | int(value))) def sweep(self): if self.idle: return self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(False) self.socket.write(struct.pack('<I', 3<<28)) def sweep_open(self): self.mode = 'open' self.sweep() def sweep_short(self): self.mode = 'short' self.sweep() def sweep_load(self): self.mode = 'load' self.sweep() def sweep_dut(self): self.mode = 'dut' self.sweep() def impedance(self): return 50.0 * (self.open[0:self.sweep_size] - self.load[0:self.sweep_size]) * (self.dut[0:self.sweep_size] - self.short[0:self.sweep_size]) / ((self.load[0:self.sweep_size] - self.short[0:self.sweep_size]) * (self.open[0:self.sweep_size] - self.dut[0:self.sweep_size])) def gamma(self): z = self.impedance() return (z - 50.0)/(z + 50.0) def plot_magphase(self, data): matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(top = 0.98, right = 0.88) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(VNA.formatter) axes1.yaxis.set_major_formatter(VNA.formatter) axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') axes1.plot(self.xaxis, np.absolute(data), color = 'blue') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes1.set_xlabel('Hz') axes1.set_ylabel('Magnitude') axes2.set_ylabel('Phase angle') axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red') self.canvas.draw() def plot_open(self): self.plot_magphase(self.open[0:self.sweep_size]) def plot_short(self): self.plot_magphase(self.short[0:self.sweep_size]) def plot_load(self): self.plot_magphase(self.load[0:self.sweep_size]) def plot_dut(self): self.plot_magphase(self.dut[0:self.sweep_size]) def plot_smith(self): matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(top = 0.90, right = 0.90) axes = self.figure.add_subplot(111, projection = 'smith', axes_radius = 0.55, axes_scale = 50.0) axes.cla() axes.plot(self.impedance()) self.canvas.draw() def plot_imp(self): self.plot_magphase(self.impedance()) def plot_rc(self): self.plot_magphase(self.gamma()) def plot_swr(self): matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(top = 0.98, right = 0.88) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(VNA.formatter) axes1.yaxis.set_major_formatter(VNA.formatter) axes1.set_xlabel('Hz') axes1.set_ylabel('SWR') magnitude = np.absolute(self.gamma()) swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude))) axes1.plot(self.xaxis, swr, color = 'blue') self.canvas.draw() def plot_rl(self): matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(top = 0.98, right = 0.88) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(VNA.formatter) axes1.set_xlabel('Hz') axes1.set_ylabel('Return loss, dB') magnitude = np.absolute(self.gamma()) axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue') self.canvas.draw() def write_cfg(self): name = QFileDialog.getSaveFileName(self, 'Write configuration settings', '.', '*.ini') settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): name = QFileDialog.getOpenFileName(self, 'Read configuration settings', '.', '*.ini') settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) def write_cfg_settings(self, settings): settings.setValue('start', self.startValue.value()) settings.setValue('stop', self.stopValue.value()) size = self.sizeValue.value() settings.setValue('size', size) for i in range(0, size): settings.setValue('open_real_%d' % i, float(self.open.real[i])) settings.setValue('open_imag_%d' % i, float(self.open.imag[i])) for i in range(0, size): settings.setValue('short_real_%d' % i, float(self.short.real[i])) settings.setValue('short_imag_%d' % i, float(self.short.imag[i])) for i in range(0, size): settings.setValue('load_real_%d' % i, float(self.load.real[i])) settings.setValue('load_imag_%d' % i, float(self.load.imag[i])) for i in range(0, size): settings.setValue('dut_real_%d' % i, float(self.dut.real[i])) settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i])) def read_cfg_settings(self, settings): self.startValue.setValue(settings.value('start', 100, type = int)) self.stopValue.setValue(settings.value('stop', 60000, type = int)) size = settings.value('size', 600, type = int) self.sizeValue.setValue(size) for i in range(0, size): real = settings.value('open_real_%d' % i, 0.0, type = float) imag = settings.value('open_imag_%d' % i, 0.0, type = float) self.open[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('short_real_%d' % i, 0.0, type = float) imag = settings.value('short_imag_%d' % i, 0.0, type = float) self.short[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('load_real_%d' % i, 0.0, type = float) imag = settings.value('load_imag_%d' % i, 0.0, type = float) self.load[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('dut_real_%d' % i, 0.0, type = float) imag = settings.value('dut_imag_%d' % i, 0.0, type = float) self.dut[i] = real + 1.0j * imag def write_s1p(self): name = QFileDialog.getSaveFileName(self, 'Write s1p file', '.', '*.s1p') fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close()
class VNA(QMainWindow, Ui_VNA): max_size = 16384 def __init__(self): super(VNA, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variables self.idle = True self.reading = False # sweep parameters self.sweep_start = 100 self.sweep_stop = 60000 self.sweep_size = 600 self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 # buffer and offset for the incoming samples self.buffer = bytearray(24 * VNA.max_size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) self.adc1 = np.zeros(VNA.max_size, np.complex64) self.adc2 = np.zeros(VNA.max_size, np.complex64) self.dac1 = np.zeros(VNA.max_size, np.complex64) self.open = np.zeros(VNA.max_size, np.complex64) self.short = np.zeros(VNA.max_size, np.complex64) self.load = np.zeros(VNA.max_size, np.complex64) self.dut = np.zeros(VNA.max_size, np.complex64) self.mode = 'dut' # create figure self.figure = Figure() self.figure.set_facecolor('none') self.canvas = FigureCanvas(self.figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # initialize cursor self.cursor = None # remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.sweepFrame.setEnabled(False) self.dutSweep.setEnabled(False) self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) self.openSweep.clicked.connect(self.sweep_open) self.shortSweep.clicked.connect(self.sweep_short) self.loadSweep.clicked.connect(self.sweep_load) self.dutSweep.clicked.connect(self.sweep_dut) self.csvButton.clicked.connect(self.write_csv) self.s1pButton.clicked.connect(self.write_s1p) self.s2pButton.clicked.connect(self.write_s2p) self.startValue.valueChanged.connect(self.set_start) self.stopValue.valueChanged.connect(self.set_stop) self.sizeValue.valueChanged.connect(self.set_size) self.rateValue.addItems(['500', '100', '50', '10', '5', '1']) self.rateValue.lineEdit().setReadOnly(True) self.rateValue.lineEdit().setAlignment(Qt.AlignRight) for i in range(0, self.rateValue.count()): self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole) self.rateValue.currentIndexChanged.connect(self.set_rate) self.corrValue.valueChanged.connect(self.set_corr) self.levelValue.valueChanged.connect(self.set_level) self.openPlot.clicked.connect(self.plot_open) self.shortPlot.clicked.connect(self.plot_short) self.loadPlot.clicked.connect(self.plot_load) self.dutPlot.clicked.connect(self.plot_dut) self.smithPlot.clicked.connect(self.plot_smith) self.impPlot.clicked.connect(self.plot_imp) self.rcPlot.clicked.connect(self.plot_rc) self.swrPlot.clicked.connect(self.plot_swr) self.rlPlot.clicked.connect(self.plot_rl) self.gainPlot.clicked.connect(self.plot_gain) # create timer self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(True) self.dutSweep.setEnabled(False) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_start(self.startValue.value()) self.set_stop(self.stopValue.value()) self.set_size(self.sizeValue.value()) self.set_rate(self.rateValue.currentIndex()) self.set_corr(self.corrValue.value()) self.set_level(self.levelValue.value()) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.sweepFrame.setEnabled(True) self.dutSweep.setEnabled(True) def read_data(self): if not self.reading: self.socket.readAll() return size = self.socket.bytesAvailable() self.progress.setValue((self.offset + size) / 24) limit = 24 * (self.sweep_size + 1) if self.offset + size < limit: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:limit] = self.socket.read(limit - self.offset) self.adc1 = self.data[0::3] self.adc2 = self.data[1::3] self.dac1 = self.data[2::3] getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1] getattr(self, 'plot_%s' % self.mode)() self.reading = False self.sweepFrame.setEnabled(True) self.selectFrame.setEnabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'VNA', 'Error: connection timeout.') else: QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString()) self.stop() def set_start(self, value): self.sweep_start = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000))) def set_stop(self, value): self.sweep_stop = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000))) def set_size(self, value): self.sweep_size = value self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True) self.xaxis *= 1000 if self.idle: return self.socket.write(struct.pack('<I', 2<<28 | int(value))) def set_rate(self, value): if self.idle: return rate = [1, 5, 10, 50, 100, 500][value] self.socket.write(struct.pack('<I', 3<<28 | int(rate))) def set_corr(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4<<28 | int(value))) def set_level(self, value): if self.idle: return self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0)))) def sweep(self): if self.idle: return self.sweepFrame.setEnabled(False) self.selectFrame.setEnabled(False) self.socket.write(struct.pack('<I', 6<<28)) self.offset = 0 self.reading = True self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1) self.progress.setModal(True) self.progress.setMinimumDuration(1000) self.progress.canceled.connect(self.cancel) def cancel(self): self.offset = 0 self.reading = False self.socket.write(struct.pack('<I', 7<<28)) self.sweepFrame.setEnabled(True) self.selectFrame.setEnabled(True) def sweep_open(self): self.mode = 'open' self.sweep() def sweep_short(self): self.mode = 'short' self.sweep() def sweep_load(self): self.mode = 'load' self.sweep() def sweep_dut(self): self.mode = 'dut' self.sweep() def gain(self): size = self.sweep_size return self.dut[0:size]/self.short[0:size] def impedance(self): size = self.sweep_size return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size])) def gamma(self): z = self.impedance() return (z - 50.0)/(z + 50.0) def plot_gain(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') gain = self.gain() axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes1.set_xlabel('Hz') axes1.set_ylabel('Gain, dB') axes2.set_ylabel('Phase angle') axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_magphase(self, data): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.tick_params('y', color = 'blue', labelcolor = 'blue') axes1.yaxis.label.set_color('blue') axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude') axes2 = axes1.twinx() axes2.spines['left'].set_color('blue') axes2.spines['right'].set_color('red') axes1.set_xlabel('Hz') axes1.set_ylabel('Magnitude') axes2.set_ylabel('Phase angle') axes2.tick_params('y', color = 'red', labelcolor = 'red') axes2.yaxis.label.set_color('red') axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_open(self): self.plot_magphase(self.open[0:self.sweep_size]) def plot_short(self): self.plot_magphase(self.short[0:self.sweep_size]) def plot_load(self): self.plot_magphase(self.load[0:self.sweep_size]) def plot_dut(self): self.plot_magphase(self.dut[0:self.sweep_size]) def plot_smith_grid(self, axes, color): load = 50.0 ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0]) for tick in ticks * load: axis = np.logspace(-4, np.log10(1.0e3), 200) * load z = tick + 1.0j * axis gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) z = axis + 1.0j * tick gamma = (z - load)/(z + load) axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3) if tick == 0.0: axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0) axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0) continue lab = u'%d\u03A9' % tick x = (tick - load) / (tick + load) axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0) lab = u'j%d\u03A9' % tick z = 1.0j * tick gamma = (z - load)/(z + load) * 1.05 x = gamma.real y = gamma.imag angle = np.angle(gamma) * 180.0 / np.pi - 90.0 axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0) lab = u'-j%d\u03A9' % tick axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0) def plot_smith(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0) axes1 = self.figure.add_subplot(111) self.plot_smith_grid(axes1, 'blue') gamma = self.gamma() plot, = axes1.plot(gamma.real, gamma.imag, color = 'red') axes1.axis('equal') axes1.set_xlim(-1.12, 1.12) axes1.set_ylim(-1.12, 1.12) axes1.xaxis.set_visible(False) axes1.yaxis.set_visible(False) for loc, spine in axes1.spines.items(): spine.set_visible(False) self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple') self.canvas.draw() def plot_imp(self): self.plot_magphase(self.impedance()) def plot_rc(self): self.plot_magphase(self.gamma()) def plot_swr(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.set_xlabel('Hz') axes1.set_ylabel('SWR') magnitude = np.absolute(self.gamma()) swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude))) axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def plot_rl(self): if self.cursor is not None: self.cursor.hide().disable() matplotlib.rcdefaults() self.figure.clf() self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98) axes1 = self.figure.add_subplot(111) axes1.cla() axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix)) axes1.set_xlabel('Hz') axes1.set_ylabel('Return loss, dB') magnitude = np.absolute(self.gamma()) axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss') self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple') self.canvas.draw() def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) def write_cfg_settings(self, settings): settings.setValue('addr', self.addrValue.text()) settings.setValue('start', self.startValue.value()) settings.setValue('stop', self.stopValue.value()) settings.setValue('rate', self.rateValue.currentIndex()) settings.setValue('corr', self.corrValue.value()) size = self.sizeValue.value() settings.setValue('size', size) for i in range(0, size): settings.setValue('open_real_%d' % i, float(self.open.real[i])) settings.setValue('open_imag_%d' % i, float(self.open.imag[i])) for i in range(0, size): settings.setValue('short_real_%d' % i, float(self.short.real[i])) settings.setValue('short_imag_%d' % i, float(self.short.imag[i])) for i in range(0, size): settings.setValue('load_real_%d' % i, float(self.load.real[i])) settings.setValue('load_imag_%d' % i, float(self.load.imag[i])) for i in range(0, size): settings.setValue('dut_real_%d' % i, float(self.dut.real[i])) settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i])) def read_cfg_settings(self, settings): self.addrValue.setText(settings.value('addr', '192.168.1.100')) self.startValue.setValue(settings.value('start', 100, type = int)) self.stopValue.setValue(settings.value('stop', 60000, type = int)) self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int)) self.corrValue.setValue(settings.value('corr', 0, type = int)) size = settings.value('size', 600, type = int) self.sizeValue.setValue(size) for i in range(0, size): real = settings.value('open_real_%d' % i, 0.0, type = float) imag = settings.value('open_imag_%d' % i, 0.0, type = float) self.open[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('short_real_%d' % i, 0.0, type = float) imag = settings.value('short_imag_%d' % i, 0.0, type = float) self.short[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('load_real_%d' % i, 0.0, type = float) imag = settings.value('load_imag_%d' % i, 0.0, type = float) self.load[i] = real + 1.0j * imag for i in range(0, size): real = settings.value('dut_real_%d' % i, 0.0, type = float) imag = settings.value('dut_imag_%d' % i, 0.0, type = float) self.dut[i] = real + 1.0j * imag def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(0, size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i])) fh.close() def write_s1p(self): dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p') dialog.setDefaultSuffix('s1p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close() def write_s2p(self): dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p') dialog.setDefaultSuffix('s2p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') gain = self.gain() gamma = self.gamma() size = self.sizeValue.value() fh.write('# GHz S MA R 50\n') for i in range(0, size): fh.write('0.0%.8d %8.6f %7.2f %8.6f %7.2f 0.000000 0.00 0.000000 0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True))) fh.close()
class Scanner(QMainWindow, Ui_Scanner): def __init__(self): super(Scanner, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp( '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.xsize = self.xsizeValue.value() self.ysize = self.xsizeValue.value() self.size = self.xsize * self.ysize self.x = np.arange(self.xsize) #X array for plotting self.y = np.arange(self.ysize) #Y array for plotting self.freq = 125.0 figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) self.change_scan_size() self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.connectButton.clicked.connect(self.start) self.scanButton.clicked.connect(self.scan) self.periodValue.valueChanged.connect(self.set_period) self.trgtimeValue.valueChanged.connect(self.set_trgtime) self.trginvCheck.stateChanged.connect(self.set_trginv) self.shdelayValue.valueChanged.connect(self.set_shdelay) self.shtimeValue.valueChanged.connect(self.set_shtime) self.shinvCheck.stateChanged.connect(self.set_shinv) self.acqdelayValue.valueChanged.connect(self.set_acqdelay) self.samplesValue.valueChanged.connect(self.set_samples) self.pulsesValue.valueChanged.connect(self.set_pulses) self.xsizeValue.valueChanged.connect(self.set_xsize) self.ysizeValue.valueChanged.connect(self.set_ysize) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.meshTimer = QTimer(self) self.meshTimer.timeout.connect(self.update_mesh) # set default values self.periodValue.setValue(200.0) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.offset = 0 self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_period(self.periodValue.value()) self.set_trgtime(self.trgtimeValue.value()) self.set_trginv(self.trginvCheck.checkState()) self.set_shdelay(self.shdelayValue.value()) self.set_shtime(self.shtimeValue.value()) self.set_shinv(self.shinvCheck.checkState()) self.set_acqdelay(self.acqdelayValue.value()) self.set_samples(self.samplesValue.value()) self.set_pulses(self.pulsesValue.value()) # start pulse generators self.socket.write(struct.pack('<I', 11 << 28)) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size # plt.figure() # plt.plot(np.frombuffer(self.buffer, np.int32)[0::2]) # plt.show() else: self.meshTimer.stop() self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 self.update_mesh() plt.figure() plt.plot(self.data[0::2]) plt.show() self.scanButton.setEnabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'Scanner', 'Error: connection timeout.') else: QMessageBox.information(self, 'Scanner', 'Error: %s.' % self.socket.errorString()) self.stop() def set_period(self, value): # set maximum delays and times to half period maximum = int(value * 5.0 + 0.5) / 10.0 self.trgtimeValue.setMaximum(maximum) self.shdelayValue.setMaximum(maximum) self.shtimeValue.setMaximum(maximum) self.acqdelayValue.setMaximum(maximum) # set maximum number of samples per pulse maximum = int(value * 500.0 + 0.5) / 10.0 if maximum > 256.0: maximum = 256.0 self.samplesValue.setMaximum(maximum) shdelay = value * 0.25 samples = value * 0.5 if self.idle: return self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq))) def set_trgtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq))) def set_trginv(self, checked): if self.idle: return self.socket.write( struct.pack('<I', 2 << 28 | int(checked == Qt.Checked))) def set_shdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq))) def set_shtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq))) def set_shinv(self, checked): if self.idle: return self.socket.write( struct.pack('<I', 5 << 28 | int(checked == Qt.Checked))) def set_acqdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq))) def set_samples(self, value): if self.idle: return self.socket.write(struct.pack('<I', 7 << 28 | int(value))) def set_pulses(self, value): if self.idle: return self.socket.write(struct.pack('<I', 8 << 28 | int(value))) def set_xsize(self, value): self.xsize = value self.size = self.xsize * self.ysize self.y = np.arange(self.xsize) self.change_scan_size() def set_ysize(self, value): self.ysize = value self.size = self.xsize * self.ysize self.y = np.arange(self.ysize) self.change_scan_size() def change_scan_size(self): self.x = np.arange(self.xsize) #X array for plotting self.y = np.arange(self.ysize) #Y array for plotting # buffer and offset for the incoming samples self.buffer = bytearray(8 * self.xsize * self.ysize) self.offset = 0 self.data = np.frombuffer(self.buffer, np.int32) # create figure self.axes.axis((0.0, self.ysize, 0.0, self.xsize)) x, y = np.meshgrid(np.linspace(0.0, self.ysize, self.ysize + 1), np.linspace(0.0, self.xsize, self.xsize + 1)) z = x / self.xsize + y * 0.0 self.mesh = self.axes.pcolormesh(x, y, z, cmap=cm.gray, vmin=0, vmax=1) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() if int(matplotlib.__version__[0]) < 2: self.toolbar.removeAction(actions[7]) else: self.toolbar.removeAction(actions[6]) self.canvas.draw() # def set_coordinates(self): # if self.idle: return # self.socket.write(struct.pack('<I', 9<<28)) # for i in range(self.xsize): # for j in range(self.ysize): # value = (i + 0 << 18) | (j << 4) # self.socket.write(struct.pack('<I', 10<<28 | int(value))) def set_coordinates(self): if self.idle: return self.socket.write(struct.pack('<I', 9 << 28)) for i in range(self.xco.size): value = (self.xco_prop[i] + 0 << 18) | (self.yco_prop[i] << 4) self.socket.write(struct.pack('<I', 10 << 28 | int(value))) def scan(self): if self.idle: return print('start scanning') self.scanButton.setEnabled(False) scan_name = self.comboBoxScan.currentText() xco, yco = spc.LoadScanPattern(scan_name, self.xsize, self.ysize) #Change the coordinate such that we scan the full fov self.propx = int(np.ceil(512 / (self.xsize))) self.propy = int(np.ceil(512 / (self.ysize))) self.xco = xco self.yco = yco self.xco_prop = self.propx * self.xco self.yco_prop = self.propy * self.yco self.data[:] = np.zeros(2 * self.xsize * self.ysize, np.int32) self.update_mesh() self.set_coordinates() self.socket.write(struct.pack('<I', 12 << 28)) self.meshTimer.start(500) def update_mesh(self): result = self.data[0::2] / (self.samplesValue.value() * self.pulsesValue.value() * 8192.0) result = result - np.min(result) result = result.reshape(self.xsize, self.ysize) result = result[self.x[self.xco], self.y[self.yco]] self.mesh.set_array(result.reshape(self.xsize * self.ysize)) self.mesh.set_clim(vmin=result.min(), vmax=result.max()) self.canvas.draw()
class Client(QDialog): def __init__(self, parent=None): super(Client, self).__init__(parent) self.networkSession = None self.blockSize = 0 self.currentFortune = '' hostLabel = QLabel("&Server name:") portLabel = QLabel("S&erver port:") self.hostCombo = QComboBox() self.hostCombo.setEditable(True) name = QHostInfo.localHostName() if name != '': self.hostCombo.addItem(name) domain = QHostInfo.localDomainName() if domain != '': self.hostCombo.addItem(name + '.' + domain) if name != 'localhost': self.hostCombo.addItem('localhost') ipAddressesList = QNetworkInterface.allAddresses() for ipAddress in ipAddressesList: if not ipAddress.isLoopback(): self.hostCombo.addItem(ipAddress.toString()) for ipAddress in ipAddressesList: if ipAddress.isLoopback(): self.hostCombo.addItem(ipAddress.toString()) self.portLineEdit = QLineEdit() self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) hostLabel.setBuddy(self.hostCombo) portLabel.setBuddy(self.portLineEdit) self.statusLabel = QLabel("This examples requires that you run " "the Fortune Server example as well.") self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) self.getFortuneButton.setEnabled(False) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.tcpSocket = QTcpSocket(self) self.hostCombo.editTextChanged.connect(self.enableGetFortuneButton) self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.tcpSocket.readyRead.connect(self.readFortune) self.tcpSocket.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostCombo, 0, 1) mainLayout.addWidget(portLabel, 1, 0) mainLayout.addWidget(self.portLineEdit, 1, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Fortune Client") self.portLineEdit.setFocus() manager = QNetworkConfigurationManager() if manager.capabilities( ) & QNetworkConfigurationManager.NetworkSessionRequired: settings = QSettings(QSettings.UserScope, 'QtProject') settings.beginGroup('QtNetwork') id = settings.value('DefaultNetworkConfiguration') settings.endGroup() config = manager.configurationFromIdentifier(id) if config.state() & QNetworkConfiguration.Discovered == 0: config = manager.defaultConfiguration() self.networkSession = QNetworkSession(config, self) self.networkSession.opened.connect(self.sessionOpened) self.getFortuneButton.setEnabled(False) self.statusLabel.setText("Opening network session.") self.networkSession.open() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.blockSize = 0 self.tcpSocket.abort() self.tcpSocket.connectToHost(self.hostCombo.currentText(), int(self.portLineEdit.text())) def readFortune(self): instr = QDataStream(self.tcpSocket) instr.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.tcpSocket.bytesAvailable() < 2: return self.blockSize = instr.readUInt16() if self.tcpSocket.bytesAvailable() < self.blockSize: return nextFortune = instr.readQString() if nextFortune == self.currentFortune: QTimer.singleShot(0, self.requestNewFortune) return self.currentFortune = nextFortune self.statusLabel.setText(self.currentFortune) self.getFortuneButton.setEnabled(True) def displayError(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass elif socketError == QAbstractSocket.HostNotFoundError: QMessageBox.information( self, "Fortune Client", "The host was not found. Please check the host name and " "port settings.") elif socketError == QAbstractSocket.ConnectionRefusedError: QMessageBox.information( self, "Fortune Client", "The connection was refused by the peer. Make sure the " "fortune server is running, and check that the host name " "and port settings are correct.") else: QMessageBox.information( self, "Fortune Client", "The following error occurred: %s." % self.tcpSocket.errorString()) self.getFortuneButton.setEnabled(True) def enableGetFortuneButton(self): self.getFortuneButton.setEnabled( (self.networkSession is None or self.networkSession.isOpen()) and self.hostCombo.currentText() != '' and self.portLineEdit.text() != '') def sessionOpened(self): config = self.networkSession.configuration() if config.type() == QNetworkConfiguration.UserChoice: id = self.networkSession.sessionProperty('UserChoiceConfiguration') else: id = config.identifier() settings = QSettings(QSettings.UserScope, 'QtProject') settings.beginGroup('QtNetwork') settings.setValue('DefaultNetworkConfiguration', id) settings.endGroup() self.statusLabel.setText("This examples requires that you run the " "Fortune Server example as well.") self.enableGetFortuneButton()
class Client(QDialog): def __init__(self, parent=None): super(Client, self).__init__(parent) self.networkSession = None self.blockSize = 0 self.currentFortune = "" hostLabel = QLabel("&Server name:") portLabel = QLabel("S&erver port:") self.hostCombo = QComboBox() self.hostCombo.setEditable(True) name = QHostInfo.localHostName() if name != "": self.hostCombo.addItem(name) domain = QHostInfo.localDomainName() if domain != "": self.hostCombo.addItem(name + "." + domain) if name != "localhost": self.hostCombo.addItem("localhost") ipAddressesList = QNetworkInterface.allAddresses() for ipAddress in ipAddressesList: if not ipAddress.isLoopback(): self.hostCombo.addItem(ipAddress.toString()) for ipAddress in ipAddressesList: if ipAddress.isLoopback(): self.hostCombo.addItem(ipAddress.toString()) self.portLineEdit = QLineEdit() self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) hostLabel.setBuddy(self.hostCombo) portLabel.setBuddy(self.portLineEdit) self.statusLabel = QLabel("This examples requires that you run " "the Fortune Server example as well.") self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) self.getFortuneButton.setEnabled(False) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.tcpSocket = QTcpSocket(self) self.hostCombo.editTextChanged.connect(self.enableGetFortuneButton) self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.tcpSocket.readyRead.connect(self.readFortune) self.tcpSocket.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostCombo, 0, 1) mainLayout.addWidget(portLabel, 1, 0) mainLayout.addWidget(self.portLineEdit, 1, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Fortune Client") self.portLineEdit.setFocus() manager = QNetworkConfigurationManager() if manager.capabilities() & QNetworkConfigurationManager.NetworkSessionRequired: settings = QSettings(QSettings.UserScope, "QtProject") settings.beginGroup("QtNetwork") id = settings.value("DefaultNetworkConfiguration") settings.endGroup() config = manager.configurationFromIdentifier(id) if config.state() & QNetworkConfiguration.Discovered == 0: config = manager.defaultConfiguration() self.networkSession = QNetworkSession(config, self) self.networkSession.opened.connect(self.sessionOpened) self.getFortuneButton.setEnabled(False) self.statusLabel.setText("Opening network session.") self.networkSession.open() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.blockSize = 0 self.tcpSocket.abort() self.tcpSocket.connectToHost(self.hostCombo.currentText(), int(self.portLineEdit.text())) def readFortune(self): instr = QDataStream(self.tcpSocket) instr.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.tcpSocket.bytesAvailable() < 2: return self.blockSize = instr.readUInt16() if self.tcpSocket.bytesAvailable() < self.blockSize: return nextFortune = instr.readQString() if nextFortune == self.currentFortune: QTimer.singleShot(0, self.requestNewFortune) return self.currentFortune = nextFortune self.statusLabel.setText(self.currentFortune) self.getFortuneButton.setEnabled(True) def displayError(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass elif socketError == QAbstractSocket.HostNotFoundError: QMessageBox.information( self, "Fortune Client", "The host was not found. Please check the host name and " "port settings." ) elif socketError == QAbstractSocket.ConnectionRefusedError: QMessageBox.information( self, "Fortune Client", "The connection was refused by the peer. Make sure the " "fortune server is running, and check that the host name " "and port settings are correct.", ) else: QMessageBox.information( self, "Fortune Client", "The following error occurred: %s." % self.tcpSocket.errorString() ) self.getFortuneButton.setEnabled(True) def enableGetFortuneButton(self): self.getFortuneButton.setEnabled( (self.networkSession is None or self.networkSession.isOpen()) and self.hostCombo.currentText() != "" and self.portLineEdit.text() != "" ) def sessionOpened(self): config = self.networkSession.configuration() if config.type() == QNetworkConfiguration.UserChoice: id = self.networkSession.sessionProperty("UserChoiceConfiguration") else: id = config.identifier() settings = QSettings(QSettings.UserScope, "QtProject") settings.beginGroup("QtNetwork") settings.setValue("DefaultNetworkConfiguration", id) settings.endGroup() self.statusLabel.setText("This examples requires that you run the " "Fortune Server example as well.") self.enableGetFortuneButton()
class Main(QMainWindow): def __init__(self, *args): super(Main, self).__init__(*args) loadUi('mainwindow.ui', self) self.host.setText("localhost") self.port.setText("11010") self.prompt.setText("M114") self.conn = QTcpSocket(self) self.conn.readyRead.connect(self.readSocket) self.conn.error.connect(self.socketError) self.conn.connected.connect(self.socketConnect) self.conn.disconnected.connect(self.socketDisconnect) self.connected = False self.actionSave.triggered.connect(self.save) self.prompt.setFocus() self.do_connect() def append(self, text): self.text.append(text) if self.autoscroll.isChecked(): c = self.text.textCursor() c.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) self.text.setTextCursor(c) def readSocket(self): r = self.conn.readAll() if r: r = str(r).strip() for chunk in r.splitlines(): if chunk: if chunk[0] == '<': self.text.setTextColor(QColor(200, 0, 0)) elif chunk[0] == '>': self.text.setTextColor(QColor(0, 200, 0)) else: self.text.setTextColor(QColor(0, 0, 200)) self.append(chunk) def info(self, errtext): self.text.setTextColor(QColor(20, 20, 20)) self.append(errtext) def err(self, errtext): self.text.setTextColor(QColor(100, 0, 0)) self.append(errtext) def socketDisconnect(self): self.connected = False self.err("Disconnected") def socketConnect(self): self.connected = True self.info("Connected") def socketError(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass elif socketError == QAbstractSocket.HostNotFoundError: self.err("The host was not found. Please check the host name and " "port settings.") elif socketError == QAbstractSocket.ConnectionRefusedError: self.err("The connection was refused by the peer. Make sure the " "server is running, and check that the host name " "and port settings are correct.") else: self.err("The following error occurred: {0}" .format(self.conn.errorString())) def save(self): fname, sel = QFileDialog.getSaveFileName( self, 'Save Log',) #'/path/to/default/directory', FIXME: lastused #selectedFilter='*.txt') if fname: with open(fname, 'w+') as f: f.write(self.text.toPlainText()) def do_connect(self): self.conn.abort() self.conn.connectToHost(self.host.text(), int(self.port.text())) @pyqtSlot() def on_connect_clicked(self): self.do_connect() self.prompt.setFocus() @pyqtSlot() def on_send_clicked(self): if not self.connected: self.err("Not connected") return out = (self.prompt.text() + '\n').encode('ascii') self.conn.write(out) @pyqtSlot() def on_right_on_clicked(self): self.action("e1")
class MuoScope(QMainWindow, Ui_MuoScope): def __init__(self): super(MuoScope, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp( '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variables self.idle = True self.reading = False # buffer and offset for the incoming samples self.buffer = bytearray(84) self.offset = 0 self.data = np.frombuffer(self.buffer, np.float32) # configure widgets self.discValue = {} self.discFeedback = {} self.monoValue = {} self.monoFeedback = {} self.dlyValue = {} for i in range(0, 8): label = QLabel('CH' + str(i)) label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.discLayout.addWidget(label, (i // 4) * 3 + 0, i % 4) self.discValue[i] = QSpinBox() self.discValue[i].setMaximum(511) self.discValue[i].valueChanged.connect(partial(self.set_disc, i)) self.discLayout.addWidget(self.discValue[i], (i // 4) * 3 + 1, i % 4) self.discFeedback[i] = QLineEdit() self.discFeedback[i].setReadOnly(True) self.discLayout.addWidget(self.discFeedback[i], (i // 4) * 3 + 2, i % 4) for i in range(0, 8): label = QLabel('CH' + str(i)) label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.monoLayout.addWidget(label, (i // 4) * 3 + 0, i % 4) self.monoValue[i] = QSpinBox() self.monoValue[i].setMaximum(1023) self.monoValue[i].valueChanged.connect(partial(self.set_mono, i)) self.monoLayout.addWidget(self.monoValue[i], (i // 4) * 3 + 1, i % 4) self.monoFeedback[i] = QLineEdit() self.monoFeedback[i].setReadOnly(True) self.monoLayout.addWidget(self.monoFeedback[i], (i // 4) * 3 + 2, i % 4) for i in range(0, 4): label = QLabel(chr(ord('A') + i)) label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.dlyLayout.addWidget(label, 0, i) self.dlyValue[i] = QSpinBox() self.dlyValue[i].setMaximum(15) self.dlyValue[i].valueChanged.connect(partial(self.set_dly, i)) self.dlyLayout.addWidget(self.dlyValue[i], 1, i) self.voltageValue.valueChanged.connect(partial(self.set_hv, 0)) self.currentValue.valueChanged.connect(partial(self.set_hv, 1)) self.stateValue.stateChanged.connect(self.set_state) self.wndValue.valueChanged.connect(self.set_wnd) self.cutValue.valueChanged.connect(self.set_cut) # read settings settings = QSettings('muoscope.ini', QSettings.IniFormat) self.read_cfg_settings(settings) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from widgets self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.adcTimer = QTimer(self) self.adcTimer.timeout.connect(self.get_adc) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.adcTimer.stop() self.idle = True self.socket.abort() self.connectButton.setText('Connect') self.connectButton.setEnabled(True) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) for i, item in self.discValue.items(): self.set_disc(i, item.value()) for i, item in self.monoValue.items(): self.set_mono(i, item.value()) self.set_hv(0, self.voltageValue.value()) self.set_hv(1, self.currentValue.value()) self.set_state(self.stateValue.isChecked()) self.set_dly(0) self.set_wnd(self.wndValue.value()) self.set_cut(self.cutValue.value()) self.adcTimer.start(200) def timeout(self): self.display_error('timeout') def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'MuoScope', 'Error: connection timeout.') else: QMessageBox.information(self, 'MuoScope', 'Error: %s.' % self.socket.errorString()) self.stop() def read_data(self): while (self.socket.bytesAvailable() > 0): if not self.reading: self.socket.readAll() return size = self.socket.bytesAvailable() limit = 84 if self.offset + size < limit: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:limit] = self.socket.read(limit - self.offset) self.reading = False for i, item in self.discFeedback.items(): item.setText('%.3f' % self.data[i + i // 2 * 2 + 0]) for i, item in self.monoFeedback.items(): item.setText('%.3f' % self.data[i + i // 2 * 2 + 2]) self.voltageFeedback.setText('%.3f' % self.data[17]) self.currentFeedback.setText('%.3f' % self.data[16]) self.stateFeedback.setText('%.0f' % self.data[20]) def get_adc(self): if self.idle: return self.reading = True self.socket.write(struct.pack('<I', 0 << 24)) def set_disc(self, channel, value): if self.idle: return self.socket.write( struct.pack( '<I', 1 << 24 | int(channel + channel // 2 * 2 + 0) << 16 | int(value))) def set_mono(self, channel, value): if self.idle: return self.socket.write( struct.pack( '<I', 1 << 24 | int(channel + channel // 2 * 2 + 2) << 16 | int(value))) def set_hv(self, channel, value): if self.idle: return self.socket.write( struct.pack('<I', 2 << 24 | int(channel) << 16 | int(value))) def set_state(self, state): if self.idle: return self.socket.write( struct.pack('<I', 3 << 24 | int(self.stateValue.isChecked()))) def set_dly(self, value): if self.idle: return value = self.dlyValue[3].value() << 12 | self.dlyValue[2].value( ) << 8 | self.dlyValue[1].value() << 4 | self.dlyValue[0].value() self.socket.write(struct.pack('<I', 4 << 24 | int(value))) def set_wnd(self, value): if self.idle: return self.socket.write(struct.pack('<I', 5 << 24 | int(value))) def set_cut(self, value): if self.idle: return self.socket.write(struct.pack('<I', 6 << 24 | int(value))) def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('muoscope.ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('muoscope.ini') dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) def write_cfg_settings(self, settings): settings.setValue('addr', self.addrValue.text()) for i, item in self.discValue.items(): settings.setValue('disc_%d' % i, item.value()) for i, item in self.monoValue.items(): settings.setValue('mono_%d' % i, item.value()) for i, item in self.dlyValue.items(): settings.setValue('dly_%d' % i, item.value()) settings.setValue('voltage', self.voltageValue.value()) settings.setValue('current', self.currentValue.value()) settings.setValue('cut', self.cutValue.value()) settings.setValue('wnd', self.wndValue.value()) def read_cfg_settings(self, settings): self.addrValue.setText(settings.value('addr', '192.168.42.1')) for i, item in self.discValue.items(): item.setValue(settings.value('disc_%d' % i, 100, type=int)) for i, item in self.monoValue.items(): item.setValue(settings.value('mono_%d' % i, 100, type=int)) for i, item in self.dlyValue.items(): item.setValue(settings.value('dly_%d' % i, 0, type=int)) self.voltageValue.setValue(settings.value('voltage', 0, type=int)) self.currentValue.setValue(settings.value('current', 4095, type=int)) self.cutValue.setValue(settings.value('cut', 1, type=int)) self.wndValue.setValue(settings.value('wnd', 3, type=int))
class Main(QMainWindow): def __init__(self, *args): super(Main, self).__init__(*args) loadUi('mainwindow.ui', self) self.host.setText("localhost") self.port.setText("11010") self.prompt.setText("M114") self.conn = QTcpSocket(self) self.conn.readyRead.connect(self.readSocket) self.conn.error.connect(self.socketError) self.conn.connected.connect(self.socketConnect) self.conn.disconnected.connect(self.socketDisconnect) self.connected = False self.actionSave.triggered.connect(self.save) self.prompt.setFocus() self.do_connect() def append(self, text): self.text.append(text) if self.autoscroll.isChecked(): c = self.text.textCursor() c.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) self.text.setTextCursor(c) def readSocket(self): r = self.conn.readAll() if r: r = str(r).strip() for chunk in r.splitlines(): if chunk: if chunk[0] == '<': self.text.setTextColor(QColor(200, 0, 0)) elif chunk[0] == '>': self.text.setTextColor(QColor(0, 200, 0)) else: self.text.setTextColor(QColor(0, 0, 200)) self.append(chunk) def info(self, errtext): self.text.setTextColor(QColor(20, 20, 20)) self.append(errtext) def err(self, errtext): self.text.setTextColor(QColor(100, 0, 0)) self.append(errtext) def socketDisconnect(self): self.connected = False self.err("Disconnected") def socketConnect(self): self.connected = True self.info("Connected") def socketError(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass elif socketError == QAbstractSocket.HostNotFoundError: self.err("The host was not found. Please check the host name and " "port settings.") elif socketError == QAbstractSocket.ConnectionRefusedError: self.err("The connection was refused by the peer. Make sure the " "server is running, and check that the host name " "and port settings are correct.") else: self.err("The following error occurred: {0}".format( self.conn.errorString())) def save(self): fname, sel = QFileDialog.getSaveFileName( self, 'Save Log', ) #'/path/to/default/directory', FIXME: lastused #selectedFilter='*.txt') if fname: with open(fname, 'w+') as f: f.write(self.text.toPlainText()) def do_connect(self): self.conn.abort() self.conn.connectToHost(self.host.text(), int(self.port.text())) @pyqtSlot() def on_connect_clicked(self): self.do_connect() self.prompt.setFocus() @pyqtSlot() def on_send_clicked(self): if not self.connected: self.err("Not connected") return out = (self.prompt.text() + '\n').encode('ascii') self.conn.write(out) @pyqtSlot() def on_right_on_clicked(self): self.action("e1")
class Crossing(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Výroba ovládacích prvků self.connectButton = QPushButton(self, text="Start") self.connectButton.clicked.connect(self.connect) self.disconnectButton = QPushButton(self, text="Stop") self.disconnectButton.clicked.connect(self.disconnect) self.backButton = QPushButton(self, text="Return", enabled=False) self.backButton.clicked.connect(self.sendBack) self.presentObjects = QComboBox(self) self.backAllButton = QPushButton(self, text="Return All") self.backAllButton.clicked.connect(self.sendBackAll) self.messageLabel = QLabel(self) self.statusLabel = QLabel(self) self.statusLabel.setText('Disconnected') self.statLabel = QLabel(self) # Rozložení ovládacích prvků self.layout = QVBoxLayout(self) self.startLayout = QHBoxLayout() self.startLayout.addWidget(self.connectButton) self.startLayout.addWidget(self.disconnectButton) self.layout.addLayout(self.startLayout) self.backLayout = QHBoxLayout() self.backLayout.addWidget(self.presentObjects) self.backLayout.addWidget(self.backButton) self.backLayout.addWidget(self.backAllButton) self.layout.addLayout(self.backLayout) self.layout.addWidget(self.messageLabel) self.layout.addWidget(self.statusLabel) self.layout.addWidget(self.statLabel) # Příprava TCP socketu self.socket = QTcpSocket(self) self.socket.readyRead.connect(self.read) self.socket.connected.connect(self.connected) self.readBuffer = bytearray() self.disconnecting = False # Zobrazení self.setLayout(self.layout) self.show() def disconnect(self): self.socket.write("BYE\n".encode()) self.disconnecting = True self.read() def softDisconnect(self): # Odpojí se od servru self.socket.disconnectFromHost() self.statusLabel.setText('Disconnected') def connect(self): # Nejdřív se odpoj, pokud už # spojení běží self.socket.abort() # A znovu se připoj self.socket.connectToHost("ksp.mff.cuni.cz", 48888) self.statusLabel.setText("Connecting") def connected(self): # Pozdravíme server self.socket.write("HELLO\n".encode()) self.statusLabel.setText("Connected") self.disconnecting = False def read(self): # Přečteme všechno, co jsme dostali while self.socket.bytesAvailable() > 0: self.readBuffer += self.socket.read(128) # Rozdělíme na řádky lines = self.readBuffer.split(b"\n") # Zbytek uložíme na příště self.readBuffer = lines.pop() # Zpracujeme řádky, které dorazily for l in lines: text = l.decode().rstrip() if "STAT" not in text: self.backButton.setEnabled(True) self.presentObjects.addItem(text) self.messageLabel.setText(text) else: self.statLabel.setText(text) if self.disconnecting: self.softDisconnect() def sendBack(self): text = self.presentObjects.currentText() + "\n" if not text == "": index = self.presentObjects.currentIndex() self.socket.write(text.encode()) self.presentObjects.removeItem(index) if self.presentObjects.currentText() == "": self.backButton.setEnabled(False) def sendBackAll(self): allItems = [ self.presentObjects.itemText(i) for i in range(self.presentObjects.count()) ] for item in allItems: text = item + "\n" self.socket.write(text.encode()) self.presentObjects.clear()
class TcpC(QDialog, Ui_TcpClient): """ Tcp客户端 """ def __init__(self, parent=None): """ 一些初始设置 """ super(TcpC, self).__init__(parent) self.setupUi(self) self.TotalBytes = 0 self.bytesReceive = 0 self.fileNameSize = 0 self.bytesToReceive = 0 self.fileName = "" self.tcpClient = QTcpSocket(self) self.tcpPort = 7788 self.time = QTime() self.tcpClient.readyRead.connect(self.readMessage) # 每当新数据可用于从设备的当前读取通道读取时,readyRead信号就会发出一次。 self.tcpClient.error.connect(self.displayError) # 当网络连接出现问题时调用displayError()函数。 def setHostAddress(self, address): """ 设置服务器地址 """ self.hostAddress = address self.newConnect() # 设置服务器地址,同时调用newConnect()函数。 def setFileName(self, file): """ 待接收文件的文件名 """ self.localFile = QFile(file) # 设置待接收文件的文件名,这个函数是放在主程序里面调用的。 def closeEvent(self, event): """ 关闭事件 """ self.on_tcpClientCloseBtn_clicked() def newConnect(self): """ 连接服务器并开始计时 """ self.tcpClient.abort() self.tcpClient.connectToHost(self.hostAddress, self.tcpPort) self.time.start() # abort()中止当前连接并重置套接字。与disconnectFromHost()不同,此函数立即关闭套接字,丢弃写缓冲区中的任何挂起数据。 # connectToHost()尝试与self.hostAddress的self.tcpPort端口建立连接。 def readMessage(self): """ 读取文件数据 """ receiver = QDataStream(self.tcpClient) receiver.setVersion(QDataStream.Qt_5_4) if self.bytesReceive <= 2: if self.tcpClient.bytesAvailable() >= 2 and self.fileNameSize == 0: self.TotalBytes = receiver.readInt64() self.fileNameSize = receiver.readInt64() self.bytesReceive += 2 # 当接收的字节数小于等2,同时套接字返回等待读取的传入字节数大于2而文件名大小不确定时,传输的总大小receiver.readInt64(),文件名大小是receiver.readInt64()。 if self.tcpClient.bytesAvailable() >= self.fileNameSize and self.fileNameSize != 0: self.fileName = receiver.readQString() self.bytesReceive += self.fileNameSize # 当我们接收的字节数一定后,我们读取文件名receiver.readQString(),自然收到的字节数要加上文件名大小。 if not(self.localFile.open(QFile.WriteOnly)): QMessageBox.warning(self, "应用程序", "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString())) return # 要是写文件存在问题就报错。 else: return if self.bytesReceive < self.TotalBytes: self.bytesReceive += self.tcpClient.bytesAvailable() inBlock = self.tcpClient.readAll() self.localFile.write(inBlock) inBlock.resize(0) useTime = self.time.elapsed() / 1000 bytesReceived = self.bytesReceive / (1024*1024) speed = bytesReceived / useTime total = self.TotalBytes / (1024*1024) left = (total - bytesReceived) / speed if bytesReceived < 0.01: # 要是我们收到的文件太小了,我们设定成KB为单位 bytesReceived = self.bytesReceive / 1024 speed = bytesReceived / useTime / 1024 total = self.TotalBytes / 1024 if left > 0: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) else: # 要是文件比较大,我们设定成MB为单位 if left > 0: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) self.progressBar.setMaximum(total) self.progressBar.setValue(bytesReceived) self.tcpClientStatuslabel.setText(msg) if self.bytesReceive == self.TotalBytes: self.localFile.close() self.tcpClient.close() self.tcpClientStatuslabel.setText("接收文件{}完毕".format(self.fileName)) self.tcpClientBtn.setEnabled(False) # 当我们接收的大小和文件总大小一致时,关闭网络连接、文件,提示接收完毕。 def displayError(self, socketError): """ 显示错误 """ if socketError == QAbstractSocket.RemoteHostClosedError: pass else: errorMsg = self.tcpClient.errorString() QMessageBox.warning(self, "应用程序", errorMsg) return # 网络错误的处理。 @pyqtSlot() def on_tcpClientBtn_clicked(self): """ 取消接收 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.tcpClientBtn.setEnabled(False) # 点击取消时传输终止 @pyqtSlot() def on_tcpClientCloseBtn_clicked(self): """ 关闭 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.close() self.tcpClientBtn.setEnabled(True) # 关闭网络连接,相关设置复位。
class VNA(QMainWindow, Ui_VNA): graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open'] def __init__(self): super(VNA, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variables self.idle = True self.reading = False self.auto = False # sweep parameters self.sweep_start = 10 self.sweep_stop = 60000 self.sweep_size = 6000 # buffer and offset for the incoming samples self.buffer = bytearray(16 * 32768) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) # create measurements self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.mode = 'open' # create figures self.tabs = {} for i in range(len(self.graphs)): layout = getattr(self, '%sLayout' % self.graphs[i]) self.tabs[i] = FigureTab(layout, self) # configure widgets self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1']) self.rateValue.lineEdit().setReadOnly(True) self.rateValue.lineEdit().setAlignment(Qt.AlignRight) for i in range(self.rateValue.count()): self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole) self.set_enabled(False) self.stopSweep.setEnabled(False) # read settings settings = QSettings('vna.ini', QSettings.IniFormat) self.read_cfg_settings(settings) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from widgets self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) self.openSweep.clicked.connect(partial(self.sweep, 'open')) self.shortSweep.clicked.connect(partial(self.sweep, 'short')) self.loadSweep.clicked.connect(partial(self.sweep, 'load')) self.singleSweep.clicked.connect(partial(self.sweep, 'dut')) self.autoSweep.clicked.connect(self.sweep_auto) self.stopSweep.clicked.connect(self.cancel) self.csvButton.clicked.connect(self.write_csv) self.s1pButton.clicked.connect(self.write_s1p) self.s2pshortButton.clicked.connect(self.write_s2p_short) self.s2popenButton.clicked.connect(self.write_s2p_open) self.startValue.valueChanged.connect(self.set_start) self.stopValue.valueChanged.connect(self.set_stop) self.sizeValue.valueChanged.connect(self.set_size) self.rateValue.currentIndexChanged.connect(self.set_rate) self.corrValue.valueChanged.connect(self.set_corr) self.phase1Value.valueChanged.connect(self.set_phase1) self.phase2Value.valueChanged.connect(self.set_phase2) self.level1Value.valueChanged.connect(self.set_level1) self.level2Value.valueChanged.connect(self.set_level2) self.tabWidget.currentChanged.connect(self.update_tab) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.sweepTimer = QTimer(self) self.sweepTimer.timeout.connect(self.sweep_timeout) def set_enabled(self, enabled): widgets = [self.rateValue, self.level1Value, self.level2Value, self.corrValue, self.phase1Value, self.phase2Value, self.startValue, self.stopValue, self.sizeValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep] for entry in widgets: entry.setEnabled(enabled) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.cancel() self.socket.abort() self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.set_enabled(False) self.stopSweep.setEnabled(False) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_rate(self.rateValue.currentIndex()) self.set_corr(self.corrValue.value()) self.set_phase1(self.phase1Value.value()) self.set_phase2(self.phase2Value.value()) self.set_level1(self.level1Value.value()) self.set_level2(self.level2Value.value()) self.set_gpio(1) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.set_enabled(True) self.stopSweep.setEnabled(True) def read_data(self): while(self.socket.bytesAvailable() > 0): if not self.reading: self.socket.readAll() return size = self.socket.bytesAvailable() self.progressBar.setValue((self.offset + size) / 16) limit = 16 * self.sweep_size if self.offset + size < limit: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:limit] = self.socket.read(limit - self.offset) adc1 = self.data[0::2] adc2 = self.data[1::2] attr = getattr(self, self.mode) start = self.sweep_start stop = self.sweep_stop size = self.sweep_size attr.freq = np.linspace(start, stop, size) attr.data = adc1[0:size].copy() self.update_tab() self.reading = False if not self.auto: self.progressBar.setValue(0) self.set_enabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'VNA', 'Error: connection timeout.') else: QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString()) self.stop() def set_start(self, value): self.sweep_start = value def set_stop(self, value): self.sweep_stop = value def set_size(self, value): self.sweep_size = value def set_rate(self, value): if self.idle: return rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value] self.socket.write(struct.pack('<I', 3<<28 | int(rate))) def set_corr(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4<<28 | int(value))) def set_phase1(self, value): if self.idle: return self.socket.write(struct.pack('<I', 5<<28 | int(value))) def set_phase2(self, value): if self.idle: return self.socket.write(struct.pack('<I', 6<<28 | int(value))) def set_level1(self, value): if self.idle: return data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0)) self.socket.write(struct.pack('<I', 7<<28 | int(data))) def set_level2(self, value): if self.idle: return data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0)) self.socket.write(struct.pack('<I', 8<<28 | int(data))) def set_gpio(self, value): if self.idle: return self.socket.write(struct.pack('<I', 9<<28 | int(value))) def sweep(self, mode): if self.idle: return self.set_enabled(False) self.mode = mode self.offset = 0 self.reading = True self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000))) self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000))) self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size))) self.socket.write(struct.pack('<I', 10<<28)) self.progressBar.setMinimum(0) self.progressBar.setMaximum(self.sweep_size) self.progressBar.setValue(0) def cancel(self): self.sweepTimer.stop() self.auto = False self.reading = False self.socket.write(struct.pack('<I', 11<<28)) self.progressBar.setValue(0) self.set_enabled(True) def sweep_auto(self): self.auto = True self.sweepTimer.start(100) def sweep_timeout(self): if not self.reading: self.sweep('dut') def update_tab(self): index = self.tabWidget.currentIndex() self.tabs[index].update(self.graphs[index]) def interp(self, freq, meas): real = np.interp(freq, meas.freq, meas.data.real, period = meas.period) imag = np.interp(freq, meas.freq, meas.data.imag, period = meas.period) return real + 1j * imag def gain_short(self, freq): short = self.interp(freq, self.short) dut = self.interp(freq, self.dut) return np.divide(dut, short) def gain_open(self, freq): open = self.interp(freq, self.open) dut = self.interp(freq, self.dut) return np.divide(dut, open) def impedance(self, freq): open = self.interp(freq, self.open) short = self.interp(freq, self.short) load = self.interp(freq, self.load) dut = self.interp(freq, self.dut) z = np.divide(50.0 * (open - load) * (dut - short), (load - short) * (open - dut)) z = np.asarray(z) z.real[z.real < 1.0e-2] = 9.99e-3 return z def gamma(self, freq): z = self.impedance(freq) return np.divide(z - 50.0, z + 50.0) def swr(self, freq): magnitude = np.absolute(self.gamma(freq)) swr = np.divide(1.0 + magnitude, 1.0 - magnitude) return np.clip(swr, 1.0, 99.99) def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('vna.ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('vna.ini') dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) window.update_tab() def write_cfg_settings(self, settings): settings.setValue('addr', self.addrValue.text()) settings.setValue('rate', self.rateValue.currentIndex()) settings.setValue('corr', self.corrValue.value()) settings.setValue('phase_1', self.phase1Value.value()) settings.setValue('phase_2', self.phase2Value.value()) settings.setValue('level_1', self.level1Value.value()) settings.setValue('level_2', self.level2Value.value()) settings.setValue('open_start', int(self.open.freq[0])) settings.setValue('open_stop', int(self.open.freq[-1])) settings.setValue('open_size', self.open.freq.size) settings.setValue('short_start', int(self.short.freq[0])) settings.setValue('short_stop', int(self.short.freq[-1])) settings.setValue('short_size', self.short.freq.size) settings.setValue('load_start', int(self.load.freq[0])) settings.setValue('load_stop', int(self.load.freq[-1])) settings.setValue('load_size', self.load.freq.size) settings.setValue('dut_start', int(self.dut.freq[0])) settings.setValue('dut_stop', int(self.dut.freq[-1])) settings.setValue('dut_size', self.dut.freq.size) for i in range(len(FigureTab.cursors)): settings.setValue('cursor_%d' % i, FigureTab.cursors[i]) data = self.open.data for i in range(self.open.freq.size): settings.setValue('open_real_%d' % i, float(data.real[i])) settings.setValue('open_imag_%d' % i, float(data.imag[i])) data = self.short.data for i in range(self.short.freq.size): settings.setValue('short_real_%d' % i, float(data.real[i])) settings.setValue('short_imag_%d' % i, float(data.imag[i])) data = self.load.data for i in range(self.load.freq.size): settings.setValue('load_real_%d' % i, float(data.real[i])) settings.setValue('load_imag_%d' % i, float(data.imag[i])) data = self.dut.data for i in range(self.dut.freq.size): settings.setValue('dut_real_%d' % i, float(data.real[i])) settings.setValue('dut_imag_%d' % i, float(data.imag[i])) def read_cfg_settings(self, settings): self.addrValue.setText(settings.value('addr', '192.168.1.100')) self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int)) self.corrValue.setValue(settings.value('corr', 0, type = int)) self.phase1Value.setValue(settings.value('phase_1', 0, type = int)) self.phase2Value.setValue(settings.value('phase_2', 0, type = int)) self.level1Value.setValue(settings.value('level_1', 0, type = int)) self.level2Value.setValue(settings.value('level_2', -90, type = int)) open_start = settings.value('open_start', 10, type = int) open_stop = settings.value('open_stop', 60000, type = int) open_size = settings.value('open_size', 6000, type = int) short_start = settings.value('short_start', 10, type = int) short_stop = settings.value('short_stop', 60000, type = int) short_size = settings.value('short_size', 6000, type = int) load_start = settings.value('load_start', 10, type = int) load_stop = settings.value('load_stop', 60000, type = int) load_size = settings.value('load_size', 6000, type = int) dut_start = settings.value('dut_start', 10, type = int) dut_stop = settings.value('dut_stop', 60000, type = int) dut_size = settings.value('dut_size', 6000, type = int) self.startValue.setValue(dut_start) self.stopValue.setValue(dut_stop) self.sizeValue.setValue(dut_size) for i in range(len(FigureTab.cursors)): FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int) self.open.freq = np.linspace(open_start, open_stop, open_size) self.open.data = np.zeros(open_size, np.complex64) for i in range(open_size): real = settings.value('open_real_%d' % i, 0.0, type = float) imag = settings.value('open_imag_%d' % i, 0.0, type = float) self.open.data[i] = real + 1.0j * imag self.short.freq = np.linspace(short_start, short_stop, short_size) self.short.data = np.zeros(short_size, np.complex64) for i in range(short_size): real = settings.value('short_real_%d' % i, 0.0, type = float) imag = settings.value('short_imag_%d' % i, 0.0, type = float) self.short.data[i] = real + 1.0j * imag self.load.freq = np.linspace(load_start, load_stop, load_size) self.load.data = np.zeros(load_size, np.complex64) for i in range(load_size): real = settings.value('load_real_%d' % i, 0.0, type = float) imag = settings.value('load_imag_%d' % i, 0.0, type = float) self.load.data[i] = real + 1.0j * imag self.dut.freq = np.linspace(dut_start, dut_stop, dut_size) self.dut.data = np.zeros(dut_size, np.complex64) for i in range(dut_size): real = settings.value('dut_real_%d' % i, 0.0, type = float) imag = settings.value('dut_imag_%d' % i, 0.0, type = float) self.dut.data[i] = real + 1.0j * imag def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') f = self.dut.freq o = self.interp(f, self.open) s = self.interp(f, self.short) l = self.interp(f, self.load) d = self.dut.data fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(f.size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i])) fh.close() def write_s1p(self): dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p') dialog.setDefaultSuffix('s1p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') freq = self.dut.freq gamma = self.gamma(freq) fh.write('# GHz S MA R 50\n') for i in range(freq.size): fh.write('0.0%.8d %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close() def write_s2p(self, gain): dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p') dialog.setDefaultSuffix('s2p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') freq = self.dut.freq gamma = self.gamma(freq) fh.write('# GHz S MA R 50\n') for i in range(freq.size): fh.write('0.0%.8d %8.6f %7.2f %8.6f %7.2f 0.000000 0.00 0.000000 0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True))) fh.close() def write_s2p_short(self): self.write_s2p(self.gain_short(self.dut.freq)) def write_s2p_open(self): self.write_s2p(self.gain_open(self.dut.freq))
class Scanner(QMainWindow, Ui_Scanner): def __init__(self): super(Scanner, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.size = 512 * 512 self.freq = 143.0 # buffer and offset for the incoming samples self.buffer = bytearray(8 * self.size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.int32) # create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) self.axes.axis((0.0, 512.0, 0.0, 512.0)) x, y = np.meshgrid(np.linspace(0.0, 512.0, 513), np.linspace(0.0, 512.0, 513)) z = x / 512.0 + y * 0.0 self.mesh = self.axes.pcolormesh(x, y, z, cmap = cm.plasma) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() if int(matplotlib.__version__[0]) < 2: self.toolbar.removeAction(actions[7]) else: self.toolbar.removeAction(actions[6]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.connectButton.clicked.connect(self.start) self.scanButton.clicked.connect(self.scan) self.periodValue.valueChanged.connect(self.set_period) self.trgtimeValue.valueChanged.connect(self.set_trgtime) self.trginvCheck.stateChanged.connect(self.set_trginv) self.shdelayValue.valueChanged.connect(self.set_shdelay) self.shtimeValue.valueChanged.connect(self.set_shtime) self.shinvCheck.stateChanged.connect(self.set_shinv) self.acqdelayValue.valueChanged.connect(self.set_acqdelay) self.samplesValue.valueChanged.connect(self.set_samples) self.pulsesValue.valueChanged.connect(self.set_pulses) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.meshTimer = QTimer(self) self.meshTimer.timeout.connect(self.update_mesh) # set default values self.periodValue.setValue(200.0) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.offset = 0 self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_period(self.periodValue.value()) self.set_trgtime(self.trgtimeValue.value()) self.set_trginv(self.trginvCheck.checkState()) self.set_shdelay(self.shdelayValue.value()) self.set_shtime(self.shtimeValue.value()) self.set_shinv(self.shinvCheck.checkState()) self.set_acqdelay(self.acqdelayValue.value()) self.set_samples(self.samplesValue.value()) self.set_pulses(self.pulsesValue.value()) # start pulse generators self.socket.write(struct.pack('<I', 9<<28)) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.meshTimer.stop() self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 self.update_mesh() self.scanButton.setEnabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'Scanner', 'Error: connection timeout.') else: QMessageBox.information(self, 'Scanner', 'Error: %s.' % self.socket.errorString()) self.stop() def set_period(self, value): # set maximum delays and times to half period maximum = int(value * 5.0 + 0.5) / 10.0 self.trgtimeValue.setMaximum(maximum) self.shdelayValue.setMaximum(maximum) self.shtimeValue.setMaximum(maximum) self.acqdelayValue.setMaximum(maximum) # set maximum number of samples per pulse maximum = int(value * 500.0 + 0.5) / 10.0 if maximum > 256.0: maximum = 256.0 self.samplesValue.setMaximum(maximum) shdelay = value * 0.25 samples = value * 0.5 if self.idle: return self.socket.write(struct.pack('<I', 0<<28 | int(value * self.freq))) def set_trgtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 1<<28 | int(value * self.freq))) def set_trginv(self, checked): if self.idle: return self.socket.write(struct.pack('<I', 2<<28 | int(checked == Qt.Checked))) def set_shdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 3<<28 | int(value * self.freq))) def set_shtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4<<28 | int(value * self.freq))) def set_shinv(self, checked): if self.idle: return self.socket.write(struct.pack('<I', 5<<28 | int(checked == Qt.Checked))) def set_acqdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 6<<28 | int(value * self.freq))) def set_samples(self, value): if self.idle: return self.socket.write(struct.pack('<I', 7<<28 | int(value))) def set_pulses(self, value): if self.idle: return self.socket.write(struct.pack('<I', 8<<28 | int(value))) def scan(self): if self.idle: return self.scanButton.setEnabled(False) self.data[:] = np.zeros(2 * 512 * 512, np.int32) self.update_mesh() self.socket.write(struct.pack('<I', 10<<28)) self.meshTimer.start(1000) def update_mesh(self): self.mesh.set_array(self.data[0::2]/(self.samplesValue.value() * self.pulsesValue.value() * 8192.0)) self.canvas.draw()
class Scanner(QMainWindow, Ui_Scanner): def __init__(self): super(Scanner, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp( '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.size = 512 * 512 self.freq = 143.0 # buffer and offset for the incoming samples self.buffer = bytearray(8 * self.size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.int32) # create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) self.axes.axis((0.0, 512.0, 0.0, 512.0)) x, y = np.meshgrid(np.linspace(0.0, 512.0, 513), np.linspace(0.0, 512.0, 513)) z = x / 512.0 + y * 0.0 self.mesh = self.axes.pcolormesh(x, y, z, cmap=cm.plasma) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() if int(matplotlib.__version__[0]) < 2: self.toolbar.removeAction(actions[7]) else: self.toolbar.removeAction(actions[6]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.connectButton.clicked.connect(self.start) self.scanButton.clicked.connect(self.scan) self.periodValue.valueChanged.connect(self.set_period) self.trgtimeValue.valueChanged.connect(self.set_trgtime) self.trginvCheck.stateChanged.connect(self.set_trginv) self.shdelayValue.valueChanged.connect(self.set_shdelay) self.shtimeValue.valueChanged.connect(self.set_shtime) self.shinvCheck.stateChanged.connect(self.set_shinv) self.acqdelayValue.valueChanged.connect(self.set_acqdelay) self.samplesValue.valueChanged.connect(self.set_samples) self.pulsesValue.valueChanged.connect(self.set_pulses) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.meshTimer = QTimer(self) self.meshTimer.timeout.connect(self.update_mesh) # set default values self.periodValue.setValue(200.0) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.socket.abort() self.offset = 0 self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_period(self.periodValue.value()) self.set_trgtime(self.trgtimeValue.value()) self.set_trginv(self.trginvCheck.checkState()) self.set_shdelay(self.shdelayValue.value()) self.set_shtime(self.shtimeValue.value()) self.set_shinv(self.shinvCheck.checkState()) self.set_acqdelay(self.acqdelayValue.value()) self.set_samples(self.samplesValue.value()) self.set_pulses(self.pulsesValue.value()) # start pulse generators self.socket.write(struct.pack('<I', 9 << 28)) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.scanButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.meshTimer.stop() self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 self.update_mesh() self.scanButton.setEnabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'Scanner', 'Error: connection timeout.') else: QMessageBox.information(self, 'Scanner', 'Error: %s.' % self.socket.errorString()) self.stop() def set_period(self, value): # set maximum delays and times to half period maximum = int(value * 5.0 + 0.5) / 10.0 self.trgtimeValue.setMaximum(maximum) self.shdelayValue.setMaximum(maximum) self.shtimeValue.setMaximum(maximum) self.acqdelayValue.setMaximum(maximum) # set maximum number of samples per pulse maximum = int(value * 500.0 + 0.5) / 10.0 if maximum > 256.0: maximum = 256.0 self.samplesValue.setMaximum(maximum) shdelay = value * 0.25 samples = value * 0.5 if self.idle: return self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq))) def set_trgtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq))) def set_trginv(self, checked): if self.idle: return self.socket.write( struct.pack('<I', 2 << 28 | int(checked == Qt.Checked))) def set_shdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq))) def set_shtime(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq))) def set_shinv(self, checked): if self.idle: return self.socket.write( struct.pack('<I', 5 << 28 | int(checked == Qt.Checked))) def set_acqdelay(self, value): if self.idle: return self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq))) def set_samples(self, value): if self.idle: return self.socket.write(struct.pack('<I', 7 << 28 | int(value))) def set_pulses(self, value): if self.idle: return self.socket.write(struct.pack('<I', 8 << 28 | int(value))) def scan(self): if self.idle: return self.scanButton.setEnabled(False) self.data[:] = np.zeros(2 * 512 * 512, np.int32) self.update_mesh() self.socket.write(struct.pack('<I', 10 << 28)) self.meshTimer.start(1000) def update_mesh(self): self.mesh.set_array( self.data[0::2] / (self.samplesValue.value() * self.pulsesValue.value() * 8192.0)) self.canvas.draw()
class PulsedNMR(QMainWindow, Ui_PulsedNMR): rates = {0:25.0e3, 1:50.0e3, 2:125.0e3, 3:250.0e3, 4:500.0e3, 5:1250.0e3} def __init__(self): super(PulsedNMR, self).__init__() self.setupUi(self) self.rateValue.addItems(['25', '50', '125', '250', '500', '1250']) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|rp-[0-9A-Fa-f]{6}\.local$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.size = 50000 # buffer and offset for the incoming samples self.buffer = bytearray(16 * self.size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.int32) # create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() if int(matplotlib.__version__[0]) < 2: self.toolbar.removeAction(actions[7]) else: self.toolbar.removeAction(actions[6]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.startButton.clicked.connect(self.start) self.freqValue.valueChanged.connect(self.set_freq) self.deltaValue.valueChanged.connect(self.set_delta) self.rateValue.currentIndexChanged.connect(self.set_rate) # set rate self.rateValue.setCurrentIndex(3) # create timer for the repetitions self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.timer = QTimer(self) self.timer.timeout.connect(self.start_sequence) def start(self): if self.idle: self.startButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.timer.stop() self.socket.abort() self.offset = 0 self.startButton.setText('Start') self.startButton.setEnabled(True) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_freq(self.freqValue.value()) self.set_rate(self.rateValue.currentIndex()) self.start_sequence() self.timer.start(self.deltaValue.value()) self.startButton.setText('Stop') self.startButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 16 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:16 * self.size] = self.socket.read(16 * self.size - self.offset) self.offset = 0 # plot the signal envelope self.curve.set_ydata(np.abs(self.data.astype(np.float32).view(np.complex64)[0::2] / (1 << 30))) self.canvas.draw() def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'PulsedNMR', 'Error: connection timeout.') else: QMessageBox.information(self, 'PulsedNMR', 'Error: %s.' % self.socket.errorString()) self.stop() def set_freq(self, value): if self.idle: return self.socket.write(struct.pack('<Q', 0<<60 | int(1.0e6 * value))) self.socket.write(struct.pack('<Q', 1<<60 | int(1.0e6 * value))) def set_rate(self, index): # time axis rate = float(PulsedNMR.rates[index]) time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size) # reset toolbar self.toolbar.home() self.toolbar.update() # reset plot self.axes.clear() self.axes.grid() # plot zeros and get store the returned Line2D object self.curve, = self.axes.plot(time, np.zeros(self.size)) x1, x2, y1, y2 = self.axes.axis() # set y axis limits self.axes.axis((x1, x2, -0.1, 1.1)) self.axes.set_xlabel('time, ms') self.canvas.draw() if self.idle: return self.socket.write(struct.pack('<Q', 2<<60 | int(125.0e6 / rate / 2))) def set_delta(self, value): if self.idle: return self.timer.stop() self.timer.start(value) def clear_pulses(self): if self.idle: return self.socket.write(struct.pack('<Q', 7<<60)) def add_delay(self, width): if self.idle: return self.socket.write(struct.pack('<Q', 8<<60 | int(width - 4))) def add_pulse(self, level, phase, width): if self.idle: return self.socket.write(struct.pack('<Q', 8<<60 | int(width))) self.socket.write(struct.pack('<Q', 9<<60 | int(phase << 16 | level))) def start_sequence(self): if self.idle: return awidth = 125 * self.awidthValue.value() bwidth = 125 * self.bwidthValue.value() delay = 125 * self.delayValue.value() size = self.size self.clear_pulses() self.add_pulse(32766, 0, awidth) self.add_delay(delay) self.add_pulse(32766, 0, bwidth) self.socket.write(struct.pack('<Q', 10<<60 | int(size)))
class TcpS(QDialog, Ui_TcpServer): """ 文件传输服务器 """ sendFileName = pyqtSignal(str) def __init__(self, parent=None): """ 一些初始设置 """ super(TcpS, self).__init__(parent) self.setupUi(self) self.payloadSize = 64 * 1024 # 读取数据64KB self.totalBytes = 0 # 总大小 self.bytesWritten = 0 # 保存的数据 self.bytesToWrite = 0 # 每次减少连接写的数据量大小 self.theFileName = "" # 文件名(不含路径) self.fileName = "" # 文件全名 self.localFile = QFile() self.outBlock = QByteArray() # QByteArray()的对象,即字节数组 self.time = QTime() self.initServer() def initServer(self): """ 网络设置初始化 """ self.tcpPort = 7788 # 指定了TCP端口为7788 self.tcpServer = QTcpServer(self) self.clientConnection = QTcpSocket(self) # 创建一个Tcp服务器和一个Tcp套接字 self.tcpServer.newConnection.connect(self.sendMessage) # 当有新的连接来的时候发出newConnection信号,我们连接到sendMessage()函数。 self.serverStatuslabel.setText("请选择要传送的文件") self.progressBar.reset() self.serverOpenBtn.setEnabled(True) self.serverSendBtn.setEnabled(False) self.tcpServer.close() # 显示我们开始创建的对话框,打开按钮是可用的,发送按钮是不可用的,进度条复位,先关闭服务器。 def refused(self): """ 对端拒绝接收文件,主程序会调用服务器的refused()函数,关闭服务器。 """ self.tcpServer.close() self.serverStatuslabel.setText("对方拒绝接收") def closeEvent(self, event): """ 关闭事件 """ self.on_serverCloseBtn_clicked() # 产生关闭事件,直接调用关闭窗口按钮函数。 def sendMessage(self): """ 发送文件 """ self.serverSendBtn.setEnabled(False) # 发送按钮不可用 self.clientConnection = self.tcpServer.nextPendingConnection() # self.clientConnection作为连接的QTcpSocket对象返回下一个挂起的连接。 self.clientConnection.bytesWritten.connect(self.updateClientProgress) # 当连接中每次将数据有效载荷写入设备的当前写通道时,都会发出此信号。在此有效负载中写入的数据量为字节数。 self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName)) self.localFile = QFile(self.fileName) if not (self.localFile.open(QFile.ReadOnly)): errorMsg = "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString()) QMessageBox.warning(self, "应用程序", errorMsg) return # 尝试打开文件,要是存在问题就报错。 self.serverCloseBtn.setText("取消") self.totalBytes = self.localFile.size() # 记录一下需要传输的文件大小。单位:字节 sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly) # 这里的self.outBlock是QByteArray()的对象,即字节数组;QIODevice的模式为WriteOnly sendOut.setVersion(QDataStream.Qt_5_4) # 设定QDataStream的版本为Qt_5_4 self.time.start() # 开始计时 currentFile = self.fileName.split("/")[-1] # 传输的文件名 sendOut.writeInt64(0) sendOut.writeInt64(0) sendOut.writeQString(currentFile) self.totalBytes += self.outBlock.size() # 在sendOut中写入文件名以及文件名和文件的大小,大小都是以字节为单位的。 sendOut.device().seek(0) sendOut.writeInt64(self.totalBytes) sendOut.writeInt64(self.outBlock.size() - 2) # QIODevice读写位置移动到0。然后分别写入总的大小和文件名大小。 self.bytesToWrite = self.totalBytes - self.clientConnection.write( self.outBlock) # 待传输文件的大小。 self.outBlock.resize(0) # outBlock清零。 def updateClientProgress(self, numBytes): """ 发送进度显示 """ qApp.processEvents() # 长时间工作用,以免窗口假死 self.bytesWritten += numBytes if self.bytesWritten > 0: self.block = self.localFile.read( min(self.bytesToWrite, self.payloadSize)) self.bytesToWrite -= self.clientConnection.write(self.block) else: self.localFile.close() # 当我们待写入的字节数大于0时,我们每次读取的数据都是小于等于self.payloadSize的,这个self.payloadSize我们定义是64KB。 # self.bytesToWrite每次减少连接写的数据量大小。 # 要是待写入的字节数小于等于0,则关闭文件。 byteSent = self.bytesWritten / (1024 * 1024) # 已经写了多少文件 useTime = self.time.elapsed() / 1000 # 传输用了多长时间 speed = self.bytesWritten / useTime / (1024 * 1024) # 传输速度 total = self.totalBytes / (1024 * 1024) # 总大小 left = (total - byteSent) / speed # 表示剩余时间 if byteSent < 0.01: byteSent = self.bytesWritten / 1024 speed = self.bytesWritten / useTime / 1024 total = self.totalBytes / 1024 if left > 0: sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format( byteSent, speed, total, useTime, left) else: sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format( byteSent, speed, total, useTime) else: if left > 0: sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format( byteSent, speed, total, useTime, left) else: sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format( byteSent, speed, total, useTime) self.progressBar.setMaximum(total) self.progressBar.setValue(byteSent) if self.bytesWritten == self.totalBytes: self.serverCloseBtn.setText("关闭") # 进度条显示的方式,以及当传输的字节数等于总的字节数的时候,按钮就显示关闭。 self.serverStatuslabel.setText(sendInfo) @pyqtSlot() def on_serverOpenBtn_clicked(self): """ 打开文件准备发送 """ self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0] if self.fileName: self.theFileName = self.fileName.split("/")[-1] self.serverStatuslabel.setText("要传送的文件为:{}".format( self.theFileName)) self.serverSendBtn.setEnabled(True) self.serverOpenBtn.setEnabled(False) @pyqtSlot() def on_serverSendBtn_clicked(self): """ 发送文件,等待接收 """ if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)): errorMsg = self.tcpServer.errorString() QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg)) self.TcpServer.close() return self.serverStatuslabel.setText("等待对方接收... ...") self.serverSendBtn.setEnabled(False) self.sendFileName.emit(self.theFileName) @pyqtSlot() def on_serverCloseBtn_clicked(self): """ 取消或者关闭 """ if self.tcpServer.isListening(): self.tcpServer.close() if self.localFile.isOpen(): self.localFile.close() self.clientConnection.abort() if self.serverCloseBtn.text() == "取消": self.serverCloseBtn.setText("关闭") else: self.close() self.serverOpenBtn.setEnabled(True) self.serverSendBtn.setEnabled(False) self.progressBar.reset() self.totalBytes = 0 self.bytesWritten = 0 self.bytesToWrite = 0 self.serverStatuslabel.setText("请选择要传送的文件")
class Crossing(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Výroba ovládacích prvků self.connectButton = QPushButton(self, text="Start") self.connectButton.clicked.connect(self.connect) self.disconnectButton = QPushButton(self, text="Stop") self.disconnectButton.clicked.connect(self.disconnect) # Rozložení ovládacích prvků self.layout = QVBoxLayout(self) self.layout.addWidget(self.connectButton) self.layout.addWidget(self.disconnectButton) # Příprava TCP socketu self.socket = QTcpSocket(self) self.socket.readyRead.connect(self.read) self.socket.connected.connect(self.connected) self.readBuffer = bytearray() self.travellers = {} # Zobrazení self.setLayout(self.layout) self.show() def disconnect(self): self.socket.write("BYE\n".encode()) def connect(self): # Nejdřív se odpoj, # pokud už spojení běží self.socket.abort() # A znovu se připoj self.socket.connectToHost("ksp.mff.cuni.cz", 48888) def connected(self): # Pozdravíme server self.socket.write("HELLO\n".encode()) def read(self): # Přečteme všechno, co jsme dostali while self.socket.bytesAvailable() > 0: self.readBuffer += self.socket.read(128) # Rozdělíme na řádky lines = self.readBuffer.split(b"\n") # Zbytek uložíme na příště self.readBuffer = lines.pop() # Zpracujeme řádky, které dorazily for l in lines: stripped = l.decode().rstrip() args = stripped.split(" ") travellerType = args.pop(0) argmap = dict(map(lambda x: x.split("="), args)) if travellerType == "CAR": self.addTraveller(Car(**argmap)) elif travellerType == "PEDESTRIAN": self.addTraveller(Pedestrian(**argmap)) def addTraveller(self, traveller): # Uložíme si cestovatele self.travellers[traveller.id] = traveller # Nechť cestovatel vstoupí do oblasti traveller.start(self) def sendBack(self, traveller): # Cestovatel opouští sledovanou oblast self.travellers[traveller.id] = None # Vrátíme cestovatele serveru text = str(traveller) + "\n" self.socket.write(text.encode())
class VNA(QMainWindow, Ui_VNA): graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open'] def __init__(self): super(VNA, self).__init__() self.setupUi(self) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variables self.idle = True self.reading = False self.auto = False # sweep parameters self.sweep_start = 10 self.sweep_stop = 60000 self.sweep_size = 6000 # buffer and offset for the incoming samples self.buffer = bytearray(16 * 32768) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) # create measurements self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size) self.mode = 'open' # create figures self.tabs = {} for i in range(len(self.graphs)): layout = getattr(self, '%sLayout' % self.graphs[i]) self.tabs[i] = FigureTab(layout, self.open, self.short, self.load, self.dut) # configure widgets self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1']) self.rateValue.lineEdit().setReadOnly(True) self.rateValue.lineEdit().setAlignment(Qt.AlignRight) for i in range(self.rateValue.count()): self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole) self.set_enabled(False) # read settings settings = QSettings('vna.ini', QSettings.IniFormat) self.read_cfg_settings(settings) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from widgets self.connectButton.clicked.connect(self.start) self.writeButton.clicked.connect(self.write_cfg) self.readButton.clicked.connect(self.read_cfg) self.openSweep.clicked.connect(partial(self.sweep, 'open')) self.shortSweep.clicked.connect(partial(self.sweep, 'short')) self.loadSweep.clicked.connect(partial(self.sweep, 'load')) self.singleSweep.clicked.connect(partial(self.sweep, 'dut')) self.autoSweep.clicked.connect(self.sweep_auto) self.stopSweep.clicked.connect(self.cancel) self.csvButton.clicked.connect(self.write_csv) self.s1pButton.clicked.connect(self.write_s1p) self.s2pshortButton.clicked.connect(self.write_s2p_short) self.s2popenButton.clicked.connect(self.write_s2p_open) self.startValue.valueChanged.connect(self.set_start) self.stopValue.valueChanged.connect(self.set_stop) self.sizeValue.valueChanged.connect(self.set_size) self.rateValue.currentIndexChanged.connect(self.set_rate) self.corrValue.valueChanged.connect(self.set_corr) self.levelValue.valueChanged.connect(self.set_level) self.tabWidget.currentChanged.connect(self.update_tab) # create timers self.startTimer = QTimer(self) self.startTimer.timeout.connect(self.timeout) self.sweepTimer = QTimer(self) self.sweepTimer.timeout.connect(self.sweep_timeout) def set_enabled(self, enabled): widgets = [self.corrValue, self.rateValue, self.levelValue, self.sizeValue, self.stopValue, self.startValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep] for entry in widgets: entry.setEnabled(enabled) def start(self): if self.idle: self.connectButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) self.startTimer.start(5000) else: self.stop() def stop(self): self.idle = True self.cancel() self.socket.abort() self.connectButton.setText('Connect') self.connectButton.setEnabled(True) self.set_enabled(False) def timeout(self): self.display_error('timeout') def connected(self): self.startTimer.stop() self.idle = False self.set_rate(self.rateValue.currentIndex()) self.set_corr(self.corrValue.value()) self.set_level(self.levelValue.value()) self.set_gpio(1) self.connectButton.setText('Disconnect') self.connectButton.setEnabled(True) self.set_enabled(True) def read_data(self): while(self.socket.bytesAvailable() > 0): if not self.reading: self.socket.readAll() return size = self.socket.bytesAvailable() self.progressBar.setValue((self.offset + size) / 16) limit = 16 * self.sweep_size if self.offset + size < limit: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:limit] = self.socket.read(limit - self.offset) adc1 = self.data[0::2] adc2 = self.data[1::2] attr = getattr(self, self.mode) start = self.sweep_start stop = self.sweep_stop size = self.sweep_size attr.freq = np.linspace(start, stop, size) attr.data = adc1[0:size].copy() self.update_tab() self.reading = False if not self.auto: self.progressBar.setValue(0) self.set_enabled(True) def display_error(self, socketError): self.startTimer.stop() if socketError == 'timeout': QMessageBox.information(self, 'VNA', 'Error: connection timeout.') else: QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString()) self.stop() def set_start(self, value): self.sweep_start = value def set_stop(self, value): self.sweep_stop = value def set_size(self, value): self.sweep_size = value def set_rate(self, value): if self.idle: return rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value] self.socket.write(struct.pack('<I', 3<<28 | int(rate))) def set_corr(self, value): if self.idle: return self.socket.write(struct.pack('<I', 4<<28 | int(value))) def set_level(self, value): if self.idle: return self.socket.write(struct.pack('<I', 5<<28 | int(32766 * np.power(10.0, value / 20.0)))) self.socket.write(struct.pack('<I', 6<<28 | int(0))) def set_gpio(self, value): if self.idle: return self.socket.write(struct.pack('<I', 7<<28 | int(value))) def sweep(self, mode): if self.idle: return self.set_enabled(False) self.mode = mode self.offset = 0 self.reading = True self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000))) self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000))) self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size))) self.socket.write(struct.pack('<I', 8<<28)) self.progressBar.setMinimum(0) self.progressBar.setMaximum(self.sweep_size) self.progressBar.setValue(0) def cancel(self): self.sweepTimer.stop() self.auto = False self.reading = False self.socket.write(struct.pack('<I', 9<<28)) self.progressBar.setValue(0) self.set_enabled(True) def sweep_auto(self): self.auto = True self.sweepTimer.start(100) def sweep_timeout(self): if not self.reading: self.sweep('dut') def update_tab(self): index = self.tabWidget.currentIndex() self.tabs[index].update(self.graphs[index]) def write_cfg(self): dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('vna.ini') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.write_cfg_settings(settings) def read_cfg(self): dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini') dialog.setDefaultSuffix('ini') dialog.selectFile('vna.ini') dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() settings = QSettings(name[0], QSettings.IniFormat) self.read_cfg_settings(settings) window.update_tab() def write_cfg_settings(self, settings): settings.setValue('addr', self.addrValue.text()) settings.setValue('rate', self.rateValue.currentIndex()) settings.setValue('corr', self.corrValue.value()) settings.setValue('level', self.levelValue.value()) settings.setValue('open_start', int(self.open.freq[0])) settings.setValue('open_stop', int(self.open.freq[-1])) settings.setValue('open_size', self.open.freq.size) settings.setValue('short_start', int(self.short.freq[0])) settings.setValue('short_stop', int(self.short.freq[-1])) settings.setValue('short_size', self.short.freq.size) settings.setValue('load_start', int(self.load.freq[0])) settings.setValue('load_stop', int(self.load.freq[-1])) settings.setValue('load_size', self.load.freq.size) settings.setValue('dut_start', int(self.dut.freq[0])) settings.setValue('dut_stop', int(self.dut.freq[-1])) settings.setValue('dut_size', self.dut.freq.size) for i in range(len(FigureTab.cursors)): settings.setValue('cursor_%d' % i, FigureTab.cursors[i]) data = self.open.data for i in range(self.open.freq.size): settings.setValue('open_real_%d' % i, float(data.real[i])) settings.setValue('open_imag_%d' % i, float(data.imag[i])) data = self.short.data for i in range(self.short.freq.size): settings.setValue('short_real_%d' % i, float(data.real[i])) settings.setValue('short_imag_%d' % i, float(data.imag[i])) data = self.load.data for i in range(self.load.freq.size): settings.setValue('load_real_%d' % i, float(data.real[i])) settings.setValue('load_imag_%d' % i, float(data.imag[i])) data = self.dut.data for i in range(self.dut.freq.size): settings.setValue('dut_real_%d' % i, float(data.real[i])) settings.setValue('dut_imag_%d' % i, float(data.imag[i])) def read_cfg_settings(self, settings): self.addrValue.setText(settings.value('addr', '192.168.1.100')) self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int)) self.corrValue.setValue(settings.value('corr', 0, type = int)) self.levelValue.setValue(settings.value('level', 0, type = int)) open_start = settings.value('open_start', 10, type = int) open_stop = settings.value('open_stop', 60000, type = int) open_size = settings.value('open_size', 6000, type = int) short_start = settings.value('short_start', 10, type = int) short_stop = settings.value('short_stop', 60000, type = int) short_size = settings.value('short_size', 6000, type = int) load_start = settings.value('load_start', 10, type = int) load_stop = settings.value('load_stop', 60000, type = int) load_size = settings.value('load_size', 6000, type = int) dut_start = settings.value('dut_start', 10, type = int) dut_stop = settings.value('dut_stop', 60000, type = int) dut_size = settings.value('dut_size', 6000, type = int) self.startValue.setValue(dut_start) self.stopValue.setValue(dut_stop) self.sizeValue.setValue(dut_size) for i in range(len(FigureTab.cursors)): FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int) self.open.freq = np.linspace(open_start, open_stop, open_size) self.open.data = np.zeros(open_size, np.complex64) for i in range(open_size): real = settings.value('open_real_%d' % i, 0.0, type = float) imag = settings.value('open_imag_%d' % i, 0.0, type = float) self.open.data[i] = real + 1.0j * imag self.short.freq = np.linspace(short_start, short_stop, short_size) self.short.data = np.zeros(short_size, np.complex64) for i in range(short_size): real = settings.value('short_real_%d' % i, 0.0, type = float) imag = settings.value('short_imag_%d' % i, 0.0, type = float) self.short.data[i] = real + 1.0j * imag self.load.freq = np.linspace(load_start, load_stop, load_size) self.load.data = np.zeros(load_size, np.complex64) for i in range(load_size): real = settings.value('load_real_%d' % i, 0.0, type = float) imag = settings.value('load_imag_%d' % i, 0.0, type = float) self.load.data[i] = real + 1.0j * imag self.dut.freq = np.linspace(dut_start, dut_stop, dut_size) self.dut.data = np.zeros(dut_size, np.complex64) for i in range(dut_size): real = settings.value('dut_real_%d' % i, 0.0, type = float) imag = settings.value('dut_imag_%d' % i, 0.0, type = float) self.dut.data[i] = real + 1.0j * imag def write_csv(self): dialog = QFileDialog(self, 'Write csv file', '.', '*.csv') dialog.setDefaultSuffix('csv') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') f = self.dut.freq o = np.interp(f, self.open.freq, self.open.data, period = self.open.period) s = np.interp(f, self.short.freq, self.short.data, period = self.short.period) l = np.interp(f, self.load.freq, self.load.data, period = self.load.period) d = self.dut.data fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n') for i in range(f.size): fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i])) fh.close() def write_s1p(self): dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p') dialog.setDefaultSuffix('s1p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') freq = self.dut.freq gamma = self.gamma(freq) fh.write('# GHz S MA R 50\n') for i in range(freq.size): fh.write('0.0%.8d %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True))) fh.close() def write_s2p(self, gain): dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p') dialog.setDefaultSuffix('s2p') dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setOptions(QFileDialog.DontConfirmOverwrite) if dialog.exec() == QDialog.Accepted: name = dialog.selectedFiles() fh = open(name[0], 'w') freq = self.dut.freq gamma = self.gamma(freq) fh.write('# GHz S MA R 50\n') for i in range(freq.size): fh.write('0.0%.8d %8.6f %7.2f %8.6f %7.2f 0.000000 0.00 0.000000 0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True))) fh.close() def write_s2p_short(self): self.write_s2p(self.gain_short(self.dut.freq)) def write_s2p_open(self): self.write_s2p(self.gain_open(self.dut.freq))
class Scanner_module(): def __init__(self): self.xsize = 512 self.ysize = 512 self.size = self.xsize * self.ysize self.freq = 125.0 self.period = 200 self.trgtime = 100 self.trginv = 0 self.shdelay = 1.5 self.shtime = 0.1 self.shinv = 0 self.acqdelay = 10 self.samples = 32 self.pulses = 2 self.idle = True self.socket = QTcpSocket() self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) # self.socket.error.connect(self.display_error) X, Y = np.meshgrid(np.arange(self.xsize),np.arange(self.ysize)) self.xco = X self.yco = Y self.buffer = bytearray(8 * self.xsize*self.ysize) self.data = np.frombuffer(self.buffer, np.int32) def ConnectIPAdress(self, ip): if self.idle: self.socket.connectToHost(ip, 1001) if self.socket.waitForConnected(1000): print ("Connected!") else: self.stop() def stop(self): self.idle = True self.socket.abort() self.offset = 0 def connected(self): self.idle = False self.send_period(self.period) self.send_trgtime(self.trgtime) self.send_trginv(self.trginv) self.send_shdelay(self.shdelay) self.send_shtime(self.shtime) self.send_shinv(self.shinv) self.send_acqdelay(self.acqdelay) self.send_samples(self.samples) self.send_pulses(self.pulses) # start pulse generators self.socket.write(struct.pack('<I', 11 << 28)) def set_coordinates(self): x = self.xco.flatten() y = self.yco.flatten() if self.idle: return self.socket.write(struct.pack('<I', 9 << 28)) for i in range(x.size): xco = x[i] yco = y[i] value = (xco << 18) | (yco << 4) self.socket.write(struct.pack('<I', 10 << 28 | int(value))) def scan(self): if self.idle: return self.data[:] = np.zeros(2 * 512 * 512, np.int32) self.set_coordinates() self.socket.write(struct.pack('<I', 12 << 28)) print('scan send') def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 def send_period(self, value): # value = self.period if self.idle: return self.socket.write(struct.pack('<I', 0 << 28 | int(value * self.freq))) print('period send') def send_trgtime(self, value): # value = self.trgtime if self.idle: return self.socket.write(struct.pack('<I', 1 << 28 | int(value * self.freq))) def send_trginv(self, checked): # checked = self.trginv if self.idle: return self.socket.write(struct.pack('<I', 2 << 28 | int(checked))) def send_shdelay(self, value): # value = self.shdelay if self.idle: return self.socket.write(struct.pack('<I', 3 << 28 | int(value * self.freq))) def send_shtime(self, value): # value = self.shtime if self.idle: return self.socket.write(struct.pack('<I', 4 << 28 | int(value * self.freq))) def send_shinv(self, checked): # checked = self.shinv if self.idle: return self.socket.write(struct.pack('<I', 5 << 28 | int(checked))) def send_acqdelay(self, value): # value = self.acqdelay if self.idle: return self.socket.write(struct.pack('<I', 6 << 28 | int(value * self.freq))) def send_samples(self, value): # value = self.samples if self.idle: return self.socket.write(struct.pack('<I', 7 << 28 | int(value))) def send_pulses(self, value): # value = self.pulses if self.idle: return self.socket.write(struct.pack('<I', 8 << 28 | int(value)))