1
0
mirror of https://github.com/ARM-software/devlib.git synced 2024-10-06 10:50:51 +01:00

MeasurementCsv: various enhancements

- Added values() and iter_values() methods. These return each row as a
  named tuple, with channel labels as the field names.
- __cmp__ has been made more generic by checking wether other has
  "value" attribute, rather than wether it is an instance of Measurment.
- MeasurementCsv no longer keeps an open handle to the file, and instead
  re-opens the file each time it needs it. This removes the need for
  managing the open handle, and alows parallel iterations over the
  values (each iteration will have it's own read handle into the files).
This commit is contained in:
Sergei Trofimov 2017-09-07 10:13:59 +01:00
parent 07ba177e58
commit 8479af48c4

View File

@ -127,7 +127,7 @@ class Measurement(object):
self.channel = channel self.channel = channel
def __cmp__(self, other): def __cmp__(self, other):
if isinstance(other, Measurement): if hasattr(other, 'value'):
return cmp(self.value, other.value) return cmp(self.value, other.value)
else: else:
return cmp(self.value, other) return cmp(self.value, other)
@ -147,26 +147,32 @@ class MeasurementsCsv(object):
self.path = path self.path = path
self.channels = channels self.channels = channels
self.sample_rate_hz = sample_rate_hz self.sample_rate_hz = sample_rate_hz
self._fh = open(path, 'rb')
if self.channels is None: if self.channels is None:
self._load_channels() self._load_channels()
headings = [chan.label for chan in self.channels]
self.data_tuple = collections.namedtuple('csv_entry', headings)
def measurements(self): def measurements(self):
return list(self.iter_measurements()) return list(self.iter_measurements())
def iter_measurements(self): def iter_measurements(self):
self._fh.seek(0) for row in self._iter_rows():
reader = csv.reader(self._fh)
reader.next() # headings
for row in reader:
values = map(numeric, row) values = map(numeric, row)
yield [Measurement(v, c) for (v, c) in zip(values, self.channels)] yield [Measurement(v, c) for (v, c) in zip(values, self.channels)]
def values(self):
return list(self.iter_values())
def iter_values(self):
for row in self._iter_rows():
values = map(numeric, row)
yield self.data_tuple(*values)
def _load_channels(self): def _load_channels(self):
self._fh.seek(0) header = []
reader = csv.reader(self._fh) with open(self.path, 'rb') as fh:
header = reader.next() reader = csv.reader(fh)
self._fh.seek(0) header = reader.next()
self.channels = [] self.channels = []
for entry in header: for entry in header:
@ -177,12 +183,23 @@ class MeasurementsCsv(object):
measure = mt measure = mt
break break
else: else:
site = entry if entry in MEASUREMENT_TYPES:
measure = 'unknown' site = None
measure = entry
else:
site = entry
measure = 'unknown'
chan = InstrumentChannel(site, measure) chan = InstrumentChannel(site, measure)
self.channels.append(chan) self.channels.append(chan)
def _iter_rows(self):
with open(self.path, 'rb') as fh:
reader = csv.reader(fh)
reader.next() # headings
for row in reader:
yield row
class InstrumentChannel(object): class InstrumentChannel(object):