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