--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HP3562A/coord_decoder.py Wed Dec 19 00:19:25 2007 +0100 @@ -0,0 +1,126 @@ +# -*- 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()