Fri, 14 Dec 2007 00:21:47 +0100
several updates to the gpib module
0 | 1 | # -*- coding: utf-8 -*- |
2 | ||
3 | import struct | |
4 | ||
5 | ||
6 | def decode_float(s): | |
7 | assert len(s) in [4,8] | |
8 | # exponential term | |
9 | e = ord(s[-1]) | |
10 | if e & 0x80: | |
11 | e = e - 256 | |
12 | ||
13 | # mantissa | |
14 | m = [ord(x) for x in s[:-1]] | |
15 | M = 0. | |
16 | for i in range(len(s)-1): | |
17 | #M += m[i]<<(i*8) | |
18 | M += float(m[i])/2**((i+1)*8) | |
6
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
19 | # XXX how do we deal negative numbers? |
0 | 20 | #if m[0] & 0x80: |
21 | # M = M - 2^(len(s)) | |
22 | return M * 2**(e+1) | |
23 | ||
24 | def decode_string(s): | |
25 | nb = ord(s[0]) | |
26 | s = s[1:nb+2] | |
27 | r = "" | |
6
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
28 | # XXX why do we need to do this? It's not described in the manual... |
0 | 29 | for c in s: |
6
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
30 | r += chr(ord(c) & 0x7F) |
0 | 31 | return r |
32 | ||
33 | EDSP = {0: "No data", | |
34 | 1: "Frequency response", | |
35 | 2: "Power spectrum 1", | |
36 | 3: "Power spectrum 2", | |
37 | 4: "Coherence", | |
38 | 5: "Cross spectrum", | |
39 | 6: "Input time 1", | |
40 | 7: "Input time 2", | |
41 | 8: "Input linear spectrum 1", | |
42 | 9: "Input linear spectrum 2", | |
43 | 10: "Impulse response", | |
44 | 11: "Cross correlation", | |
45 | 12: "Auto correlation 1", | |
46 | 13: "Auto correlation 2", | |
47 | 14: "Histogram 1", | |
48 | 15: "Histogram 2", | |
49 | 16: "Cumulative density function 1", | |
50 | 17: "Cumulative density function 2", | |
51 | 18: "Probability density function 1", | |
52 | 19: "Probability density function 2", | |
53 | 20: "Average linear spectrum 1", | |
54 | 21: "Average linear spectrum 2", | |
55 | 22: "Average time record 1", | |
56 | 23: "Average time record 2", | |
57 | 24: "Synthesis pole-zeros", | |
58 | 25: "Synthesis pole-residue", | |
59 | 26: "Synthesis polynomial", | |
60 | 27: "Synthesis constant", | |
61 | 28: "Windowed time record 1", | |
62 | 29: "Windowed time record 2", | |
63 | 30: "Windowed linear spectrum 1", | |
64 | 31: "Windowed linear spectrum 2", | |
65 | 32: "Filtered time record 1", | |
66 | 33: "Filtered time record 2", | |
67 | 34: "Filtered linear spectrum 1", | |
68 | 35: "Filtered linear spectrum 2", | |
69 | 36: "Time capture buffer", | |
70 | 37: "Captured linear spectrum", | |
71 | 38: "Captured time record", | |
72 | 39: "Throughput time record 1", | |
73 | 40: "Throughput time record 2", | |
74 | 41: "Curve fit", | |
75 | 42: "Weighted function", | |
76 | 43: "Not used", | |
77 | 44: "Orbits", | |
78 | 45: "Demodulation polar", | |
79 | 46: "Preview demod record 1", | |
80 | 47: "Preview demod record 2", | |
81 | 48: "Preview demod linear spectrum 1", | |
82 | 49: "Preview demod linear spectrum 2", | |
83 | } | |
84 | ||
85 | ECH = {0: "Channel 1", | |
86 | 1: "Channel 2", | |
87 | 2: "Channel 1&2", | |
88 | 3: "No channel", | |
89 | } | |
90 | ||
91 | EOVR = ECH | |
92 | ||
93 | EDOM = {0: 'Time', | |
94 | 1: 'Frequency', | |
95 | 2: 'Voltage (amplitude)', | |
96 | } | |
97 | ||
98 | EVLT = {0: "Peak", | |
99 | 1: "RMS", | |
100 | 2: "Volt (indicates peak only)", | |
101 | } | |
102 | ||
103 | EAMP = {0: "Volts", | |
104 | 1: "Volts squared", | |
105 | 2: "PSD (V²/Hz)", | |
106 | 3: "ESD (V²s/Hz)", | |
107 | 4: "PSD¹² (V/Hz¹²)", | |
108 | 5: "No unit", | |
109 | 6: "Unit volts", | |
110 | 7: "Unit volts²", | |
111 | } | |
112 | ||
113 | EXAXIS= {0: "No units", | |
114 | 1: "Hertz", | |
115 | 2: "RPM", | |
116 | 3: "Orders", | |
117 | 4: "Seconds", | |
118 | 5: "Revs", | |
119 | 6: "Degrees", | |
120 | 7: "dB", | |
121 | 8: "dBV", | |
122 | 9: "Volts", | |
123 | 10: "V Hz¹²", | |
124 | 11: "Hz/s", | |
125 | 12: "V/EU", | |
126 | 13: "Vrms", | |
127 | 14: "V²/Hz", | |
128 | 15: "%", | |
129 | 16: "Points", | |
130 | 17: "Records", | |
131 | 18: "Ohms", | |
132 | 19: "Hertz/octave", | |
133 | 20: "Pulse/Rev", | |
134 | 21: "Decades", | |
135 | 22: "Minutes", | |
136 | 23: "V²s/Hz", | |
137 | 24: "Octave", | |
138 | 25: "Seconds/Decade", | |
139 | 26: "Seconds/Octave", | |
6
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
140 | 27: "Hz/Point", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
141 | 28: "Points/Sweep", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
142 | 29: "Points/Decade", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
143 | 30: "Points/Octave", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
144 | 31: "V/Vrms", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
145 | 32: "V²", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
146 | 33: "EU referenced to chan 1", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
147 | 34: "EU referenced to chan 2", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
148 | 35: "EU value", |
0 | 149 | } |
150 | ||
151 | EMEAS = {0: "Linear resolution", | |
152 | 1: "Log resolution", | |
153 | 2: "Swept sine", | |
154 | 3: "Time capture", | |
155 | 4: "Linear resolution throughput", | |
156 | } | |
157 | ||
158 | EDEMOD1 = {45: "AM", | |
159 | 46: "FM", | |
160 | 47: "PM", | |
161 | } | |
162 | ||
163 | EDEMOD2 = EDEMOD1 | |
164 | ||
165 | EAVG = {0: "No data", | |
166 | 1: "Not averaged", | |
167 | 2: "Averaged",} | |
168 | ||
169 | ||
170 | ||
171 | EWIN = {0: "N/A", | |
172 | 1: "Hann", | |
173 | 2: "Flat top", | |
6
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
174 | 3: "Uniforme", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
175 | 4: "Exponential", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
176 | 5: "Force", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
177 | 6: "Force chan 1/expon chan 2", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
178 | 7: "Expon chan 1/force chan 2", |
6b6dc68588b2
completed missing constants
David Douard <david.douard@logilab.fr>
parents:
0
diff
changeset
|
179 | 8: "User", |
0 | 180 | } |
181 | ||
182 | HEADER = [ ("Display function", EDSP, 'h', 2), | |
183 | ('Number of elements', int, 'h', 2), | |
184 | ('Displayed elements', int, 'h', 2), | |
185 | ('Number of averages', int, 'h', 2), | |
186 | ('Channel selection', ECH, 'h', 2), | |
187 | ('Overflow status', EOVR, 'h', 2), | |
188 | ('Overlap percentage', int, 'h', 2), | |
189 | ('Domain', EDOM, 'h', 2), | |
190 | ('Volts peak/rms', EVLT, 'h', 2), | |
191 | ('Amplitude units', EAMP, 'h', 2), | |
192 | ('X axis units', EXAXIS, 'h', 2), | |
193 | ('Auto math label', str, 's', 14), | |
194 | ('Trace label', str, 's', 22), | |
195 | ('EU label 1', str, 's', 6), | |
196 | ('EU label 2', str, 's', 6), | |
197 | ('Float/Interger', bool, 'h', 2), | |
198 | ('Complex/Real', bool, 'h', 2), | |
199 | ('Live/Recalled', bool, 'h', 2), | |
200 | ('Math result', bool, 'h', 2), | |
201 | ('Real/Complex input', bool, 'h', 2), | |
202 | ('Log/Linear data', bool, 'h', 2), | |
203 | ('Auto math', bool, 'h', 2), | |
204 | ('Real time status', bool, 'h', 2), | |
205 | ('Measurement mode', EMEAS, 'h', 2), | |
206 | ('Window', EWIN, 'h', 2), | |
207 | ('Demod type channel 1', EDEMOD1, 'h', 2), | |
208 | ('Demod type channel 2', EDEMOD2, 'h', 2), | |
209 | ('Demod active channel 1', bool, 'h', 2), | |
210 | ('Demod active channel 2', bool, 'h', 2), | |
211 | ('Average status', EAVG, 'h', 2), | |
212 | ('Not used', int, 'hh', 4), | |
213 | ('Samp freq/2 (real)', decode_float, None, 4), | |
214 | ('Samp freq/2 (imag)', decode_float, None, 4), | |
215 | ('Not used', decode_float, None, 4), | |
216 | ('Delta X-axis', decode_float, None, 4), | |
217 | ('Max range', decode_float, None, 4), | |
218 | ('Start time value', decode_float, None, 4), | |
219 | ('Expon wind const 1', decode_float, None, 4), | |
220 | ('Expon wind const 2', decode_float, None, 4), | |
221 | ('EU value chan 1', decode_float, None, 4), | |
222 | ('EU value chan 2', decode_float, None, 4), | |
223 | ('Trig delay chan 1', decode_float, None, 4), | |
224 | ('Trig delay chan 2', decode_float, None, 4), | |
225 | ('Start freq value', decode_float, None, 8), | |
226 | ('Start data value', decode_float, None, 8), | |
227 | ] | |
228 | ||
229 | def decode_file(filename): | |
230 | d = open(filename).read() | |
231 | ||
232 | typ = d[:2] | |
233 | assert typ == "#A" | |
234 | ||
235 | totlen = struct.unpack('>h', d[2:4])[0] | |
236 | idx = 4 | |
237 | tt=0 | |
238 | header = {} | |
239 | for i, (nam, dtype, fmt, nbytes) in enumerate(HEADER): | |
240 | if dtype == str: | |
241 | val = decode_string(d[idx:]) | |
242 | else: | |
243 | if fmt: | |
244 | v = struct.unpack('>'+fmt, d[idx: idx+nbytes])[0] | |
245 | if isinstance(dtype, dict): | |
246 | val = dtype.get(int(v), "N/A") | |
247 | else: | |
248 | val = dtype(v) | |
249 | else: | |
250 | val = dtype(d[idx: idx+nbytes]) | |
251 | ||
252 | print idx, hex(idx), nam, ":", val | |
253 | header[nam] = val | |
254 | idx += nbytes | |
255 | ||
256 | resu = [] | |
257 | ||
258 | for i in range(header["Number of elements"]): | |
259 | resu.append(decode_float(d[idx: idx+4])) | |
260 | idx += 4 | |
261 | ||
262 | #print "resu = ", resu | |
263 | #return | |
264 | import pylab | |
265 | import numpy | |
266 | resu = numpy.array(resu, dtype=float) | |
267 | print "max = ", max(resu) | |
268 | #xr = numpy.linspace(0, header['Delta X-axis'], len(resu)) | |
269 | sf = header['Start freq value'] | |
270 | xr = numpy.linspace(sf, sf+20000, len(resu)) | |
271 | mn = min(resu[resu>0]) | |
272 | resu[resu==0] = mn | |
273 | pylab.plot(xr, 10*numpy.log10(resu)) | |
274 | pylab.show() | |
275 | ||
276 | # tt=0 | |
277 | # for i, (nam, dtype, nbytes) in enumerate(HEADER): | |
278 | # if dtype == str: | |
279 | # nb = ord(struct.unpack('c', d[idx])[0]) | |
280 | # val = d[idx+1:idx+1+nb] | |
281 | # else: | |
282 | # v = struct.unpack('>d', d[idx: idx+(nbytes*4)])[0] | |
283 | # if isinstance(dtype, dict): | |
284 | # val = dtype.get(int(v), "N/A") | |
285 | # else: | |
286 | # val = dtype(v) | |
287 | # print idx, nam, ":", val | |
288 | # idx += nbytes*4 | |
289 | ||
290 | ||
291 | ||
292 | ||
293 | if __name__ == "__main__": | |
294 | import sys | |
295 | decode_file(sys.argv[1]) | |
296 | ||
297 | ||
298 | ||
299 |