# HG changeset patch # User David Douard # Date 1202769418 -3600 # Node ID c4bdd390918c858741a32a78fec0ad28cd21cfb3 # Parent a250bd7a20220e9b524ae436f6722ee89e1619ea added some forgoten files to Hg diff -r a250bd7a2022 -r c4bdd390918c pygpibtoolkit/HP3562A/datablockwidget.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pygpibtoolkit/HP3562A/datablockwidget.py Mon Feb 11 23:36:58 2008 +0100 @@ -0,0 +1,290 @@ +# +import re +import numpy +from itertools import izip, count as icount + +from PyQt4 import QtCore, QtGui +from PyQt4.QtCore import Qt, SIGNAL +import state_decoder +import trace_decoder +import coord_decoder +from pygpibtoolkit.qt4.mpl import QMplCanvas + +children = [ ] + +def getChild(datablock): + """ + Try to find the appropriate MDI child widget for the given datablock. + """ + for child in children: + if child.isValidDatablock(datablock): + print "using" , child + return child + return None + +class DatablockMDIChild(QtGui.QMainWindow): + seqnumber = 1 + _username = "Window" + + @classmethod + def isValidDatablock(cls, datablock): + return False + + def __init__(self, datablock, name=None): + QtGui.QMainWindow.__init__(self) + if name is not None: + self.username = name + else: + self.username = self.__class__._username + " " + str(self.seqnumber) + self.setAttribute(Qt.WA_DeleteOnClose) + self.isUntitled = True + self.dataIsModified = False + self.setDatablock(datablock) + self.setWindowTitle(self.username) + self.setupUI() + self.updateHeaderData() + + def setDatablock(self, datablock): + self.datablock = datablock + + def setupUI(self): + # setup headers views as a docked window + assert isinstance(self._header_struct, tuple) + self.headerDocks = [] + self.tables = [] + for i, header_struct in enumerate(self._header_struct): + dock = QtGui.QDockWidget("Header" + (i>0 and (' %s'%(i+1)) or ''), + self) + #dock.setFeatures(dock.NoDockWidgetFeatures) + sarea = QtGui.QScrollArea(dock) + dock.setWidget(sarea) + self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) + self.headerDocks.append(dock) + + l = QtGui.QVBoxLayout(sarea) + l.setContentsMargins(0,0,0,0) + table = QtGui.QTableWidget(sarea) + table.setAlternatingRowColors(True) + table.verticalHeader().hide() + l.addWidget(table, 1) + self.tables.append(table) + + def setupRowsHeight(self, table): + if table.verticalHeader().minimumSectionSize()>0: + cellsize = table.verticalHeader().minimumSectionSize() + else: + cellsize = 17 + table.verticalHeader().setDefaultSectionSize(cellsize) + + def updateHeaderData(self): + for header, table, header_struct in izip(self.header, self.tables, self._header_struct): + table.clear() + table.setRowCount(len(header_struct)) + table.setColumnCount(2) + table.setHorizontalHeaderLabels(['Parameter', 'Value']) + bool_re = re.compile(r'((?P.*) )?(?P\w+/\w+)( (?P.*))?') + item = QtGui.QTableWidgetItem() + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) + for i, row in enumerate(header_struct): + key = row[0] + typ = row[1] + if typ is None: + continue + val = header.get(key, "N/A") + if isinstance(val, basestring): + val = unicode(val) + elif typ is bool and isinstance(val, typ): + m = bool_re.match(key) + if m: + d = m.groupdict() + key = "" + if d['before']: + key += d['before'] + if d['after']: + key += d['after'] + key = key.capitalize() + val = d['flag'].split('/')[not val] + else: + val = str(val) + else: + val = str(val) + val = val.strip() + if val: + if val[0]+val[-1] in ['""',"''"]: + val = val[1:-1] + if val[0:2]+val[-1] in ['u""',"u''"]: + val = val[2:-1] + while val and val.endswith(chr(0)): + val = val[:-1] + item_ = QtGui.QTableWidgetItem(item) + item_.setText(key) + table.setItem(i, 0, item_) + item_ = QtGui.QTableWidgetItem(item) + item_.setText(val) + table.setItem(i, 1, item_) + table.resizeColumnsToContents() + table.resizeRowsToContents() + # self.setupRowsHeight(self.table) + + def userFriendlyName(self): + return self.username + + def closeEvent(self, event): + if self.maybeSave(): + event.accept() + else: + event.ignore() + + def maybeSave(self): + if self.dataIsModified: + ret = QtGui.QMessageBox.warning(self, self.tr("MDI"), + self.tr("'%1' has been modified.\n"\ + "Do you want to save your changes?") + .arg(self.userFriendlyCurrentFile()), + QtGui.QMessageBox.Yes | QtGui.QMessageBox.Default, + QtGui.QMessageBox.No, + QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Escape) + if ret == QtGui.QMessageBox.Yes: + return self.save() + elif ret == QtGui.QMessageBox.Cancel: + return False + return True + +class StateBinaryDatablockMDIChild(DatablockMDIChild): + _username = "State" + _header_struct = state_decoder.HEADER, + @classmethod + def isValidDatablock(cls, datablock): + try: + h = state_decoder.decode_state(datablock) + assert len(h)>0 + return True + except Exception, e: + return False + + def setDatablock(self, datablock): + DatablockMDIChild.setDatablock(self, datablock) + self.header = [state_decoder.decode_state(self.datablock)] + +class TraceBinaryDatablockMDIChild(DatablockMDIChild): + _username = "Trace" + _header_struct = trace_decoder.HEADER, + @classmethod + def isValidDatablock(cls, datablock): + try: + h, t = trace_decoder.decode_trace(datablock) + assert len(h)>0 + assert len(t) + return True + except Exception, e: + return False + + def __init__(self, datablock, name=None): + DatablockMDIChild.__init__(self, datablock, name) + self.updateTraceData() + + def setDatablock(self, datablock): + DatablockMDIChild.setDatablock(self, datablock) + self.header, self.trace = trace_decoder.decode_trace(self.datablock) + self.header = [self.header] + + def setupToolBar(self): + toolbar = QtGui.QToolBar(self) + self.addToolBar(toolbar) + self.ylogaction = QtGui.QAction(self.tr("Y Log"), self) + self.ylogaction.setCheckable(True) + self.connect(self.ylogaction, SIGNAL('toggled(bool)'), + self.updateTraceData) + toolbar.addAction(self.ylogaction) + + + def setupUI(self): + self.setupToolBar() + DatablockMDIChild.setupUI(self) + mainw = QtGui.QWidget(self) + l = QtGui.QVBoxLayout(mainw) + l.setMargin(0) + self.canvas = QMplCanvas(self) + l.addWidget(self.canvas, 1) + self.setCentralWidget(mainw) + + def updateTraceData(self): + #self.canvas.deleteLater() + #self.canvas = QMplCanvas() + #self.centralWidget().layout().addWidget(self.canvas, 1) + f0 = self.header[0]['Start freq value'] + dx = self.header[0]['Delta X-axis'] + n = self.header[0]['Number of elements'] + x = numpy.linspace(f0, f0+dx*n, len(self.trace)) + y = self.trace.copy() + if self.ylogaction.isChecked(): + minv = min(y[y>0]) + y[y==0] = minv + y = numpy.log10(y) + y = y*10 + self.canvas.axes.clear() + self.canvas.axes.plot(x, y, 'r') + self.canvas.axes.set_xlim(min(x), max(x)) + self.canvas.axes.set_xlabel("%s (%s)"%(self.header[0]['Domain'], + self.header[0]['X axis units'])) + if self.ylogaction.isChecked(): + self.canvas.axes.set_ylabel('db (%s)'%self.header[0]['Amplitude units']) + else: + self.canvas.axes.set_ylabel('%s'%self.header[0]['Amplitude units']) + self.canvas.axes.grid(True) + if self.header[0]['Display function']: + self.canvas.axes.set_title(self.header[0]['Display function']) + + self.canvas.repaint() + +class CoordBinaryDatablockMDIChild(TraceBinaryDatablockMDIChild): + _username = "Coord" + _header_struct = coord_decoder.TRACE_HEADER, coord_decoder.HEADER, + @classmethod + def isValidDatablock(cls, datablock): + try: + h1, h2, t = coord_decoder.decode_coord(datablock) + assert len(h1)>0 + assert len(h2)>0 + assert len(t)>0 + return True + except Exception, e: + return False + def setupToolBar(self): + pass + + def setDatablock(self, datablock): + DatablockMDIChild.setDatablock(self, datablock) + h1, h2, self.trace = coord_decoder.decode_coord(self.datablock) + self.header = [h2, h1] + + def updateTraceData(self): + f0 = self.header[0]['Start freq value'] + dx = self.header[0]['Delta X-axis'] + n = self.header[0]['Number of elements'] + x = numpy.linspace(f0, f0+dx*n, len(self.trace)) + y = self.trace.copy() + + y = y.clip(min=self.header[1]['Min value of data'], + max=self.header[1]['Max value of data'],) + + self.canvas.axes.clear() + self.canvas.axes.plot(x, y, 'r') + self.canvas.axes.set_xlim(min(x), max(x)) + self.canvas.axes.set_xlabel("%s (%s)"%(self.header[0]['Domain'], + self.header[0]['X axis units'])) + self.canvas.axes.set_ylabel('%s (%s)'%(self.header[1]['Y coordinates'], + self.header[0]['Amplitude units'])) + self.canvas.axes.grid(True) + if self.header[0]['Display function']: + self.canvas.axes.set_title(self.header[0]['Display function']) + + self.canvas.repaint() + + +children.append(CoordBinaryDatablockMDIChild) +children.append(TraceBinaryDatablockMDIChild) +children.append(StateBinaryDatablockMDIChild) + + + diff -r a250bd7a2022 -r c4bdd390918c pygpibtoolkit/HP3562A/dump_datablock_mockup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pygpibtoolkit/HP3562A/dump_datablock_mockup.py Mon Feb 11 23:36:58 2008 +0100 @@ -0,0 +1,24 @@ +import glob +import os +import time +import random + +class HP3562dumper: + """ + A mockup thet will find in a directory some HPGL files and feed them randomly + """ + def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, + address=5): + self._timeout = timeout + self.filenames = {} + self.filenames['state'] = glob.glob('examples/datablocks/state*.bin') + self.filenames['trace'] = glob.glob('examples/datablocks/trace*.bin') + self.filenames['coord'] = glob.glob('examples/datablocks/coord*.bin') + + def dump(self, mode='trace', format="binary"): + fn = random.choice(self.filenames[mode]) + ret = open(fn, 'rb').read() + if len(ret)>0: + time.sleep(random.randint(1,3)) + return ret + return None diff -r a250bd7a2022 -r c4bdd390918c pygpibtoolkit/qt4/__init__.py diff -r a250bd7a2022 -r c4bdd390918c pygpibtoolkit/qt4/mpl.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pygpibtoolkit/qt4/mpl.py Mon Feb 11 23:36:58 2008 +0100 @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +# stolen from: +# embedding_in_qt4.py --- Simple Qt4 application embedding matplotlib canvases +# +# Copyright (C) 2005 Florent Rougon +# 2006 Darren Dale +# +# This file is an example program for matplotlib. It may be used and +# modified with no restriction; raw copies as well as modified versions +# may be distributed without limitation. + +from PyQt4 import QtGui, QtCore + +from matplotlib.numerix import arange, sin, pi +from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.figure import Figure + +class QMplCanvas(FigureCanvas): + """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.).""" + def __init__(self, parent=None, width=5, height=4, dpi=100): + self.fig = Figure(figsize=(width, height), dpi=dpi) + self.axes = self.fig.add_subplot(111) + # We want the axes cleared every time plot() is called + self.axes.hold(False) + + FigureCanvas.__init__(self, self.fig) + self.setParent(parent) + + FigureCanvas.setSizePolicy(self, + QtGui.QSizePolicy.Expanding, + QtGui.QSizePolicy.Expanding) + FigureCanvas.updateGeometry(self) + + def sizeHint(self): + w, h = self.get_width_height() + return QtCore.QSize(w, h) + + def minimumSizeHint(self): + return QtCore.QSize(10, 10) + + def plot(self, xdata, ydata, color="r"): + self.axes.plot(xdata, ydata, color) +