|
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 |