|
|
@@ -25,11 +25,9 @@ class Layout(object): |
|
|
|
def parse(self, in_fields): |
|
|
|
"""Given in_fields as text, return a list of values |
|
|
|
converted to the correct types""" |
|
|
|
# Consider overriding this in subclasses for speed? |
|
|
|
# Consider overriding this in subclasses for speed. |
|
|
|
# In general it takes about 2/3 the time that way. |
|
|
|
out=[] |
|
|
|
if len(self.fields) != len(in_fields): |
|
|
|
raise IndexError(sprintf("wanted %d fields, got %d", |
|
|
|
len(self.fields), len(in_fields))) |
|
|
|
for (n, (name, type)) in enumerate(self.fields): |
|
|
|
if name == 'timestamp': |
|
|
|
# special case: parse float, save as int |
|
|
@@ -37,15 +35,24 @@ class Layout(object): |
|
|
|
elif type == 'float32': |
|
|
|
out.append(float(in_fields[n])) |
|
|
|
elif type == 'uint16': |
|
|
|
out.append(max(0, min(65535, int(in_fields[n], 10)))) |
|
|
|
x = int(in_fields[n], 10) |
|
|
|
if x < 0 or x > 65535: |
|
|
|
raise ValueError("data out of range") |
|
|
|
out.append(x) |
|
|
|
else: |
|
|
|
raise TypeError("can't parse type " + repr(type)) |
|
|
|
return out |
|
|
|
|
|
|
|
def parse_uint16(string): |
|
|
|
x = int(string, 10) |
|
|
|
if x < 0 or x > 65535: |
|
|
|
raise ValueError("data out of range") |
|
|
|
return x |
|
|
|
|
|
|
|
class PrepData(Layout): |
|
|
|
rate_hz = 120 |
|
|
|
fields = [ ( 'timestamp', 'int64' ), |
|
|
|
( 'p1', 'float32' ), |
|
|
|
( 'p1', 'float32'), |
|
|
|
( 'q1', 'float32'), |
|
|
|
( 'p3', 'float32'), |
|
|
|
( 'q3', 'float32'), |
|
|
@@ -53,6 +60,16 @@ class PrepData(Layout): |
|
|
|
( 'q5', 'float32'), |
|
|
|
( 'p7', 'float32'), |
|
|
|
( 'q7', 'float32') ] |
|
|
|
def parse(self, in_fields): |
|
|
|
return [ int(float(in_fields[0]) * 1e6), |
|
|
|
float(in_fields[1]), |
|
|
|
float(in_fields[2]), |
|
|
|
float(in_fields[3]), |
|
|
|
float(in_fields[4]), |
|
|
|
float(in_fields[5]), |
|
|
|
float(in_fields[6]), |
|
|
|
float(in_fields[7]), |
|
|
|
float(in_fields[8]) ] |
|
|
|
|
|
|
|
class RawData(Layout): |
|
|
|
rate_hz = 8000 |
|
|
@@ -63,12 +80,38 @@ class RawData(Layout): |
|
|
|
( 'ia', 'uint16'), |
|
|
|
( 'ib', 'uint16'), |
|
|
|
( 'ic', 'uint16') ] |
|
|
|
def parse(self, in_fields): |
|
|
|
return [ int(float(in_fields[0]) * 1e6), |
|
|
|
parse_uint16(in_fields[1]), |
|
|
|
parse_uint16(in_fields[2]), |
|
|
|
parse_uint16(in_fields[3]), |
|
|
|
parse_uint16(in_fields[4]), |
|
|
|
parse_uint16(in_fields[5]), |
|
|
|
parse_uint16(in_fields[6]) ] |
|
|
|
|
|
|
|
class RawNotchedData(Layout): |
|
|
|
rate_hz = 8000 |
|
|
|
fields = RawData.fields + [ ( 'notch_ia', 'uint16' ), |
|
|
|
( 'notch_ib', 'uint16' ), |
|
|
|
( 'notch_ic', 'uint16' ) ] |
|
|
|
fields = [ ( 'timestamp', 'int64'), |
|
|
|
( 'va', 'uint16'), |
|
|
|
( 'vb', 'uint16'), |
|
|
|
( 'vc', 'uint16'), |
|
|
|
( 'ia', 'uint16'), |
|
|
|
( 'ib', 'uint16'), |
|
|
|
( 'ic', 'uint16'), |
|
|
|
( 'notch_ia', 'uint16'), |
|
|
|
( 'notch_ib', 'uint16'), |
|
|
|
( 'notch_ic', 'uint16') ] |
|
|
|
def parse(self, in_fields): |
|
|
|
return [ int(float(in_fields[0]) * 1e6), |
|
|
|
parse_uint16(in_fields[1]), |
|
|
|
parse_uint16(in_fields[2]), |
|
|
|
parse_uint16(in_fields[3]), |
|
|
|
parse_uint16(in_fields[4]), |
|
|
|
parse_uint16(in_fields[5]), |
|
|
|
parse_uint16(in_fields[6]), |
|
|
|
parse_uint16(in_fields[7]), |
|
|
|
parse_uint16(in_fields[8]), |
|
|
|
parse_uint16(in_fields[9]) ] |
|
|
|
|
|
|
|
# Instantiate all layouts, indexed by their name |
|
|
|
named = {} |
|
|
@@ -97,8 +140,6 @@ class Parser(object): |
|
|
|
"""Parse the data, provided as lines of text, using the current |
|
|
|
layout, into an internal data structure.""" |
|
|
|
|
|
|
|
# This currently takes about 0.1 seconds for 1 megabyte of prep data, |
|
|
|
# 85 klines/sec. Could clearly be optimized a lot... |
|
|
|
indata = cStringIO.StringIO(textdata) |
|
|
|
n = 0 |
|
|
|
# Assume any parsing error is a real error. |
|
|
@@ -111,6 +152,9 @@ class Parser(object): |
|
|
|
|
|
|
|
# Parse and append |
|
|
|
fields = line.partition('#')[0].split() |
|
|
|
if len(fields) != len(self.layout.fields): |
|
|
|
raise IndexError(sprintf("wanted %d fields, got %d", |
|
|
|
len(self.layout.fields), len(fields))) |
|
|
|
out = self.layout.parse(fields) |
|
|
|
self.data.append(out) |
|
|
|
|
|
|
|