def test_write_read_direct_with_offset(self): fh = self._create_file(0, 2) r = DataReader().open(fh) r.raw_processor.suppress_mode = 'off' # d = np.right_shift(r.raw(5, 10), 2) data = r.get(5, 10, 1) np.testing.assert_allclose(np.arange(10, 20, 2), data[:, 0, 0])
def test_write_read_direct_with_sample_overscan_before(self): fh = self._create_file( 1, 3) # will be samples 120 to 250 (not 126 to 252) r = DataReader().open(fh) r.raw_processor.suppress_mode = 'off' data = r.get(0, 140, 1) np.testing.assert_allclose(np.arange(252, 532, 2), data[:, 0, 0])
def test_write_read_stats_over_samples(self): fh = self._create_file(0, 2) r = DataReader().open(fh) data = r.get(0, 50, 5) np.testing.assert_allclose(np.arange(4, 100, 10), data[:, 0, 0])
def test_write_read_direct(self): fh = self._create_file(0, 2) r = DataReader().open(fh) data = r.get(0, 10, 1) np.testing.assert_allclose(np.arange(0, 20, 2), data[:, 0, 0])
def test_write_read_reduction_indirect(self): fh = self._create_file(0, 2) r = DataReader().open(fh) data = r.get(0, 200, 20) np.testing.assert_allclose(np.arange(19, 400, 40), data[:, 0, 0])
def test_write_read_direct(self): fh = self._create_file(0, 2) r = DataReader().open(fh) r.raw_processor.suppress_mode = 'off' data = r.get(0, 10, 1) np.testing.assert_allclose(np.arange(0, 20, 2), data[:, 0, 0])
def test_write_read_stats_over_samples(self): fh = self._create_file(0, 2) r = DataReader().open(fh) r.raw_processor.suppress_mode = 'off' data = r.get(0, 50, 5) np.testing.assert_allclose(np.arange(4, 100, 10), data[:, 0, 0])
class RecordingViewerDevice: """A user-interface-compatible device that displays previous recorded data :param filename: The filename path to the pre-recorded data. """ def __init__(self, filename): self._filename = filename self.reader = None self.ui_action = None self.view = None # type: DataViewApi self.x_range = [0.0, 1.0] self.span = None self.x = None self.samples_per = 1 self._cache = None def __str__(self): return os.path.basename(self._filename) def __len__(self): if self.span is None: return 0 return self.span.length @property def sampling_frequency(self): if self.reader is None: return None return self.reader.sampling_frequency @property def calibration(self): if self.reader is None: return None return self.reader.calibration def open(self): self.view = self self.reader = DataReader().open(self._filename) f = self.reader.sampling_frequency r = self.reader.sample_id_range x_lim = [x / f for x in r] self.span = span.Span(x_lim, 1 / f, 100) self.x_range, self.samples_per, self.x = self.span.conform_discrete( x_lim) self._cache = None # invalidate log.info('RecordingViewerDevice.open: %s => %s, %s', r, self.x_range, self.samples_per) def close(self): if self.reader is not None: self.reader.close() self.reader = None if self.on_close is not None: self.on_close() self.view = None def on_x_change(self, cmd, kwargs): x_range = self.x_range if cmd == 'resize': # {pixels: int} length = kwargs['pixels'] if length is not None and length != self.span.length: log.info('resize %s', length) self.span.length = length self._cache = None # invalidate x_range, self.samples_per, self.x = self.span.conform_discrete( x_range) elif cmd == 'span_absolute': # {range: (start: float, stop: float)}] x_range, self.samples_per, self.x = self.span.conform_discrete( kwargs.get('range')) elif cmd == 'span_relative': # {pivot: float, gain: float}] x_range, self.samples_per, self.x = self.span.conform_discrete( x_range, gain=kwargs.get('gain'), pivot=kwargs.get('pivot')) elif cmd == 'span_pan': delta = kwargs.get('delta', 0.0) x_range = [x_range[0] + delta, x_range[-1] + delta] x_range, self.samples_per, self.x = self.span.conform_discrete( x_range) elif cmd == 'refresh': self._cache = None # invalidate return else: log.warning('on_x_change(%s) unsupported', cmd) return if self.x_range != x_range: self._cache = None # invalidate self.x_range = x_range log.info( 'cmd=%s, changed=%s, length=%s, span=%s, range=%s, samples_per=%s', cmd, self._cache is None, len(self), self.x_range, self.x_range[1] - self.x_range[0], self.samples_per) def update(self): if self._cache is not None: return False, self._cache f = self.reader.sampling_frequency log.info('update: x_range=%r', self.x_range) start, stop = [int(x * f) for x in self.x_range] log.info('update: x_range=%r => (%s, %s)', self.x_range, start, stop) data = self.reader.get(start, stop, self.samples_per) t_start = start / self.reader.sampling_frequency t_stop = stop / self.reader.sampling_frequency x = np.linspace(t_start, t_stop, len(data), dtype=np.float64) try: log.info('update: len=%d, x_range=>(%s, %s)', len(data), x[0], x[-1]) except: print(x.shape) self._cache = (x, data) return True, self._cache def time_to_sample_id(self, t): if self.reader is None: return None return self.reader.time_to_sample_id(t) def statistics_get(self, t1, t2): """Get the statistics for the collected sample data over a time range. :param t1: The starting time in seconds relative to the streaming start time. :param t2: The ending time in seconds. :return: The statistics data structure. """ if self.reader is None: return None return self.reader.statistics_get(t1, t2) def raw_get(self, start=None, stop=None): if self.reader is None: return None return self.reader.raw(start=start, stop=stop) def samples_get(self, start=None, stop=None): if self.reader is None: return None i, v = self.reader.get_calibrated(start=start, stop=stop) return { 'current': { 'value': i, 'units': 'A', }, 'voltage': { 'value': v, 'units': 'V', } }