HP3562A/coord_decoder.py

changeset 16
de9122b5680a
equal deleted inserted replaced
15:b930440af354 16:de9122b5680a
1 # -*- coding: utf-8 -*-
2 """
3 state_decoder
4 =============
5
6 Module for decoding the internal state of the HP3562A DSA, using the
7 GPIB command "DSBN" (Dump State BiNary).
8
9 This file can be exectued as a python script. Use '-h' for more informations.
10 """
11
12 from HP3562A import format_header, decode_float, decode_string, decode_header, read_trace
13 from HP3562A.trace_decoder import decode_trace, HEADER as TRACE_HEADER
14 from HP3562A.enum_types import *
15
16 HEADER = [("Y coordinates", EYCOORD, 'h', 2),
17 ("# of disp elements", int, "h", 2),
18 ("First element", int, "h", 2),
19 ("Total elements", int, 'h', 2),
20 ("Display sampling", EDISPSMP, 'h', 2),
21 ("Scaling", ESCAL, 'h', 2),
22 ("Data pointer", long, 'l', 4),
23 ("In data", long, 'l', 4),
24 ("Log/linear x-axis", bool, 'h', 2),
25 ("Sampled display data", bool, 'h', 2),
26 ("Plot/Graph mode", bool, 'h', 2),
27 ("Phase wrap", bool, 'h', 2),
28 ("Not used", None, None, 36),
29 ("X scale factor", decode_float, None, 4),
30 ("Grid min Y scale", decode_float, None, 4),
31 ("Grid max Y scale", decode_float, None, 4),
32 ("/div", decode_float, None, 4),
33 ("Min value of data", decode_float, None, 4),
34 ("Max value of data", decode_float, None, 4),
35 ("Y cumulative min", decode_float, None, 4),
36 ("Y cumulative max", decode_float, None, 4),
37 ("Y scale factor", decode_float, None, 4),
38 ("Not used", None, None, 16),
39 ("Stop value", decode_float, None, 8),
40 ("Left grid", decode_float, None, 8),
41 ("Right grid", decode_float, None, 8),
42 ("Left data", decode_float, None, 8),
43 ("Right data", decode_float, None, 8),
44 ]
45
46 def decode_coord(data):
47 """
48 Decode the data (as generated by the HP3562A DSA in response to a
49 "DSBN" command), and returns a dict (header)
50
51 header is the dictionnary of the header of the dumped data block,
52 """
53 header, idx = decode_header(data, HEADER)
54 trace_header, idx = decode_header(data, TRACE_HEADER, idx)
55 trace = read_trace(data, idx, trace_header["Number of elements"])
56 return header, trace_header, trace
57
58
59 def main():
60 import sys
61 import optparse
62 import numpy
63
64 opt = optparse.OptionParser("A simple tool for displaying dumped coord data block")
65 opt.add_option('-f', '--filename', default=None,
66 dest='filename',
67 help='Output filename. If not set, read from stdin')
68 opt.add_option('-m', '--mode', default='binary',
69 dest='mode',
70 help='Dumping mode (may be "binary" [default], "ascii" or "ansi")',
71 )
72 opt.add_option('-d', '--display-header', default=False,
73 action="store_true",
74 dest="displayheader",
75 help="Display the trace header")
76 opt.add_option('-P', '--noplot-trace', default=True,
77 action="store_false",
78 dest="plot",
79 help="Do not display the plot of the trace")
80 opt.add_option('-x', '--xmode', default='lin',
81 dest='xmode',
82 help='X coordinate mode (may be "lin" [default] or "log")')
83 opt.add_option('-y', '--ymode', default='lin',
84 dest='ymode',
85 help='Y coordinate mode (may be "lin" [default], "log" or "db")')
86
87 options, argv = opt.parse_args(sys.argv)
88
89
90 if options.filename is None:
91 print "Can't deal stdin for now..."
92 sys.exit(1)
93 try:
94 coord_header, header, data = decode_coord(open(options.filename, 'rb').read())
95 except Exception, e:
96 print "ERROR: can't read %s an interpret it as a HP3562 trace"%options.filename
97 print e
98 sys.exit(1)
99
100 if options.displayheader:
101 print format_header(coord_header, HEADER, 100)
102 print format_header(header, TRACE_HEADER, 100)
103 if options.plot:
104 f0 = header['Start freq value']
105 dx = header['Delta X-axis']
106 n = header['Number of elements']
107 x = numpy.linspace(f0, f0+dx*n, len(data))
108 y = data.copy()
109
110 ym = coord_header['Min value of data']
111 yM = coord_header['Max value of data']
112 ys = coord_header['Y scale factor']
113
114 y[y<ym] = ym
115 y *= ys
116
117 import pylab
118 pylab.ylabel(header['Amplitude units'])
119 pylab.grid()
120 pylab.plot(x, y)
121 pylab.xlabel('frequency (%s)'%header["X axis units"])
122 pylab.ylabel("%s (%s)"%(coord_header['Y coordinates'], header['Amplitude units']) )
123 pylab.show()
124
125 if __name__ == "__main__":
126 main()

mercurial