Beispiel #1
0
def on_cmd(args):
    r = DataReader().open(args.filename)
    print(r.summary_string())
    start = args.start
    stop = args.stop
    if stop < 0:
        stop = r.sample_id_range[1] + 1 + stop

    if args.export is not None:
        i, v = r.get_calibrated(start, stop)
        data = np.hstack((i.reshape((-1, 1)), (v.reshape((-1, 1)))))
        if args.export.endswith('npy'):
            np.save(args.export, data)
        else:
            np.savetxt(args.export, data, fmt='%.5g', delimiter=',')

    if args.plot:
        import matplotlib.pyplot as plt
        y = r.get_reduction(start, stop)
        x = np.arange(len(y)) * (r.config['samples_per_reduction'] /
                                 r.config['sampling_frequency'])
        f = plt.figure()
        for axis in range(3):
            ax = f.add_subplot(3, 1, axis + 1)
            ax.plot(x, y[:, axis, 0], color='blue')
            ax.plot(x, y[:, axis, 2], color='red')
            ax.plot(x, y[:, axis, 3], color='red')

        plt.show()
        plt.close(f)

    r.close()
    return 0
Beispiel #2
0
def on_cmd(args):
    r = DataReader().open(args.filename)
    print(r.summary_string())
    start = args.start
    stop = args.stop
    if stop < 0:
        stop = r.sample_id_range[1] + 1 + stop

    if args.export is not None:
        i, v = r.get_calibrated(start, stop, units='samples')
        data = np.hstack((i.reshape((-1, 1)), (v.reshape((-1, 1)))))
        if args.export.endswith('npy'):
            np.save(args.export, data)
        else:
            np.savetxt(args.export, data, fmt='%.5g', delimiter=',')

    if args.plot_reduction:
        import matplotlib.pyplot as plt
        y = r.get_reduction(start, stop)
        x = np.arange(len(y)) * (r.config['samples_per_reduction'] / r.config['sampling_frequency'])
        f = plt.figure()
        fields = r.config['reduction_fields']
        for axis, name in enumerate(fields):
            ax = f.add_subplot(len(fields), 1, axis + 1)
            ax.plot(x, y[:, axis, 0], color='blue')
            ax.plot(x, y[:, axis, 2], color='red')
            ax.plot(x, y[:, axis, 3], color='red')
            ax.set_ylabel(name)

        plt.show()
        plt.close(f)

    if args.plot:
        import matplotlib.pyplot as plt
        i, v = r.get_calibrated(start, stop)
        x = np.arange(len(i)) * (1.0 / r.config['sampling_frequency'])
        f = plt.figure()

        ax_i = f.add_subplot(2, 1, 1)
        ax_i.plot(x, i)
        ax_i.set_ylabel('Current (A)')
        ax_i.grid(True)

        ax_v = f.add_subplot(2, 1, 2, sharex=ax_i)
        ax_v.plot(x, v)
        ax_v.set_ylabel('Voltage (V)')
        ax_v.grid(True)

        ax_v.set_xlabel('Time (s)')

        plt.show()
        plt.close(f)

    if args.plot_raw:
        import matplotlib.pyplot as plt
        if stop - start > 2000000:
            print('Time range too long, cannot --plot-raw')
        else:
            plot_idx_total = len(args.plot_raw)
            link_axis = None
            plot_idx = 1
            d_raw, d_bits, d_cal = r.raw(start=start, stop=stop)
            i_raw = np.right_shift(d_raw[:, 0], 2)
            v_raw = np.right_shift(d_raw[:, 1], 2)
            x = np.arange(len(i_raw)) * (1.0 / r.config['sampling_frequency'])

            i_sel = np.bitwise_and(d_bits, 0x000F)
            f = plt.figure()
            f.suptitle('Joulescope Raw Data')

            for c in args.plot_raw:
                if c == 'i':
                    ax = f.add_subplot(plot_idx_total, 1, plot_idx, sharex=link_axis)
                    ax.plot(x, i_raw)
                    ax.set_ylabel('Current (LSBs)')
                elif c == 'v':
                    ax = f.add_subplot(plot_idx_total, 1, plot_idx, sharex=link_axis)
                    ax.plot(x, v_raw)
                    ax.set_ylabel('Voltage (LSBs)')
                elif c == 'r':
                    ax = f.add_subplot(plot_idx_total, 1, plot_idx, sharex=link_axis)
                    ax.plot(x, i_sel)
                    ax.set_ylabel('Current Range')
                else:
                    raise ValueError('unsupported plot: %s' % c)

                ax.grid(True)
                if link_axis is None:
                    link_axis = ax
                plot_idx += 1

            # plt.tight_layout()
            ax.set_xlabel('Time (s)')
            plt.show()
            plt.close(f)

    r.close()
    return 0
Beispiel #3
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',
            }
        }