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])
Example #3
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])
Example #4
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])
Example #5
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])
Example #8
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',
            }
        }