Fri, 11 Jan 2008 18:49:00 +0100
improved hpgl parser : plot strings
# -*- coding: utf-8 -*- """ state_decoder ============= Module for decoding the internal state of the HP3562A DSA, using the GPIB command "DSBN" (Dump State BiNary). This file can be exectued as a python script. Use '-h' for more informations. """ from HP3562A import format_header, decode_float, decode_string, decode_header, read_trace from HP3562A.trace_decoder import decode_trace, HEADER as TRACE_HEADER from HP3562A.enum_types import * HEADER = [("Y coordinates", EYCOORD, 'h', 2), ("# of disp elements", int, "h", 2), ("First element", int, "h", 2), ("Total elements", int, 'h', 2), ("Display sampling", EDISPSMP, 'h', 2), ("Scaling", ESCAL, 'h', 2), ("Data pointer", long, 'l', 4), ("In data", long, 'l', 4), ("Log/linear x-axis", bool, 'h', 2), ("Sampled display data", bool, 'h', 2), ("Plot/Graph mode", bool, 'h', 2), ("Phase wrap", bool, 'h', 2), ("Not used", None, None, 36), ("X scale factor", decode_float, None, 4), ("Grid min Y scale", decode_float, None, 4), ("Grid max Y scale", decode_float, None, 4), ("/div", decode_float, None, 4), ("Min value of data", decode_float, None, 4), ("Max value of data", decode_float, None, 4), ("Y cumulative min", decode_float, None, 4), ("Y cumulative max", decode_float, None, 4), ("Y scale factor", decode_float, None, 4), ("Not used", None, None, 16), ("Stop value", decode_float, None, 8), ("Left grid", decode_float, None, 8), ("Right grid", decode_float, None, 8), ("Left data", decode_float, None, 8), ("Right data", decode_float, None, 8), ] def decode_coord(data): """ Decode the data (as generated by the HP3562A DSA in response to a "DSBN" command), and returns a dict (header) header is the dictionnary of the header of the dumped data block, """ header, idx = decode_header(data, HEADER) trace_header, idx = decode_header(data, TRACE_HEADER, idx) trace = read_trace(data, idx, trace_header["Number of elements"]) return header, trace_header, trace def main(): import sys import optparse import numpy opt = optparse.OptionParser("A simple tool for displaying dumped coord data block") opt.add_option('-f', '--filename', default=None, dest='filename', help='Output filename. If not set, read from stdin') opt.add_option('-m', '--mode', default='binary', dest='mode', help='Dumping mode (may be "binary" [default], "ascii" or "ansi")', ) opt.add_option('-d', '--display-header', default=False, action="store_true", dest="displayheader", help="Display the trace header") opt.add_option('-P', '--noplot-trace', default=True, action="store_false", dest="plot", help="Do not display the plot of the trace") opt.add_option('-x', '--xmode', default='lin', dest='xmode', help='X coordinate mode (may be "lin" [default] or "log")') opt.add_option('-y', '--ymode', default='lin', dest='ymode', help='Y coordinate mode (may be "lin" [default], "log" or "db")') options, argv = opt.parse_args(sys.argv) if options.filename is None: print "Can't deal stdin for now..." sys.exit(1) try: coord_header, header, data = decode_coord(open(options.filename, 'rb').read()) except Exception, e: print "ERROR: can't read %s an interpret it as a HP3562 trace"%options.filename print e sys.exit(1) if options.displayheader: print format_header(coord_header, HEADER, 100) print format_header(header, TRACE_HEADER, 100) if options.plot: f0 = header['Start freq value'] dx = header['Delta X-axis'] n = header['Number of elements'] x = numpy.linspace(f0, f0+dx*n, len(data)) y = data.copy() ym = coord_header['Min value of data'] yM = coord_header['Max value of data'] ys = coord_header['Y scale factor'] y[y<ym] = ym y *= ys import pylab pylab.ylabel(header['Amplitude units']) pylab.grid() pylab.plot(x, y) pylab.xlabel('frequency (%s)'%header["X axis units"]) pylab.ylabel("%s (%s)"%(coord_header['Y coordinates'], header['Amplitude units']) ) pylab.show() if __name__ == "__main__": main()