Beispiel #1
0
    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.  See :meth:`joulescope.driver.Driver.statistics_get`
            for details.
        """
        log.debug('statistics_get(%s, %s)', t1, t2)
        s1 = self.time_to_sample_id(t1)
        s2 = self.time_to_sample_id(t2)
        if s1 is None or s2 is None:
            return None

        (k1, k2), s = self._get_reduction_stats(s1, s2)
        if s1 < k1:
            length = k1 - s1
            s_start = self.get(s1, k1, increment=length)
            s.combine(Statistics(length=length, stats=s_start[0, :, :]))
        if s2 > k2:
            length = s2 - k2
            s_stop = self.get(k2, s2, increment=length)
            s.combine(Statistics(length=length, stats=s_stop[0, :, :]))

        t_start = s1 / self.sampling_frequency
        t_stop = s2 / self.sampling_frequency
        return stats_to_api(s.value, t_start, t_stop)
Beispiel #2
0
    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.  Here is an example:

            {
              "time": {
                "range": [4.2224105, 4.7224105],
                "delta": 0.5,
                "units": "s"
              },
              "signals": {
                "current": {
                  "statistics": {
                    "μ": 1.1410409683776379e-07,
                    "σ": 3.153094851882088e-08,
                    "min": 2.4002097531727884e-10,
                    "max": 2.77493541034346e-07,
                    "p2p": 2.772535200590287e-07
                  },
                  "units": "A",
                  "integral_units": "C"
                },
                "voltage": {
                  "statistics": {
                    "μ": 3.2984893321990967,
                    "σ": 0.0010323672322556376,
                    "min": 3.293551445007324,
                    "max": 3.3026282787323,
                    "p2p": 0.009076833724975586
                  },
                  "units": "V",
                  "integral_units": null
                },
                "power": {
                  "statistics": {
                    "μ": 3.763720144434046e-07,
                    "σ": 1.0400773930996365e-07,
                    "min": 7.916107769290193e-10,
                    "max": 9.155134534921672e-07,
                    "p2p": 9.147218427152382e-07
                  },
                  "units": "W",
                  "integral_units": "J"
                }
              }
            }

        Note: this same format is used by the :meth:`statistics_callback`.
        """
        v = self.view
        s1 = v.time_to_sample_id(t1)
        s2 = v.time_to_sample_id(t2)
        log.info('buffer %s, %s => %s, %s : %s', t1, t2, s1, s2, v.span)
        d = self.stream_buffer.stats_get(start=s1, stop=s2)
        t_start = s1 / self.sampling_frequency
        t_stop = s2 / self.sampling_frequency
        return stats_to_api(d, t_start, t_stop)
Beispiel #3
0
    def _statistics_get(self, start=None, stop=None, units=None):
        """Get the statistics for the collected sample data over a time range.

        :return: The statistics data structure.  Here is an example:
        """
        s1, s2 = self._convert_time_range_to_samples(start, stop, units)
        # self._log.debug('buffer %s, %s, %s => %s, %s', start, stop, units, s1, s2)
        d = self._stream_buffer.stats_get(start=s1, stop=s2)
        t_start = s1 / self.sampling_frequency
        t_stop = s2 / self.sampling_frequency
        return stats_to_api(d, t_start, t_stop)
Beispiel #4
0
    def _statistics_get(self, start=None, stop=None, units=None):
        """Get the statistics for the collected sample data over a time range.

        :return: The statistics data structure.
            See the :`statistics documentation <statistics.html>`_
            for details on the data format.
        """
        s1, s2 = self._convert_time_range_to_samples(start, stop, units)
        # self._log.debug('buffer %s, %s, %s => %s, %s', start, stop, units, s1, s2)
        d, x_range = self._stream_buffer.statistics_get(start=s1, stop=s2)
        t_start = x_range[0] / self.sampling_frequency
        t_stop = x_range[1] / self.sampling_frequency
        return stats_to_api(d, t_start, t_stop)
Beispiel #5
0
def data_array_to_update(x_limits, x, data_array):
    """Convert raw data buffer to a view update.

    :param x_limits: The list of [x_min, x_max] or None if unknown.
    :param x: The np.ndarray of x-axis times.
    :param data_array: The np.ndarray((N, STATS_FIELD_COUNT), dtype=STATS_DTYPE)
    """
    if len(x):
        s = stats_to_api(data_array[0, :], float(x[0]), float(x[-1]))
    else:
        s = stats_to_api(None, 0.0, 0.0)
    s['time']['x'] = {'value': x, 'units': 's'}
    s['time']['limits'] = {'value': x_limits, 'units': 's'}
    s['state'] = {'source_type': 'buffer'}  # ['realtime', 'buffer']
    for idx, signal in enumerate(s['signals'].values()):
        signal['µ']['value'] = data_array[:, idx]['mean'].copy()
        length = data_array[:, idx]['length'] - 1
        length[length < 1] = 1.0
        signal['σ2']['value'] = data_array[:, idx]['variance'] / length
        signal['min']['value'] = data_array[:, idx]['min'].copy()
        signal['max']['value'] = data_array[:, idx]['max'].copy()
        signal['p2p']['value'] = signal['max']['value'] - signal['min']['value']
    return s
 def _process(self, stream_buffer, start_id, end_id):
     d_id = end_id - start_id
     if d_id < SAMPLE_COUNT_MIN:
         return  # too short, debounced
     s = stream_buffer.statistics_get(start_id, end_id)[0]
     t_start = start_id / stream_buffer.output_sampling_frequency
     t_end = end_id / stream_buffer.output_sampling_frequency
     s = stats_to_api(s, t_start, t_end)
     duration = s['time']['delta']['value']
     charge = s['signals']['current']['∫']['value']
     energy = s['signals']['power']['∫']['value']
     timestamp = datetime.datetime.utcfromtimestamp(self.timestamp)
     timestamp_str = timestamp.isoformat()
     line = f'{timestamp_str},{duration:.6f},{charge},{energy}'
     print(line)
     if self._filehandle is not None:
         self._filehandle.write(line + '\n')
         self._filehandle.flush()
Beispiel #7
0
    def statistics_get(self, start=None, stop=None, units=None):
        """Get the statistics for the collected sample data over a time range.

        :param start: The starting time relative to the first sample.
        :param stop: The ending time.
        :param units: The units for start and stop.
            'seconds' is in floating point seconds relative to the view.
            'samples' or None is in stream buffer sample indices.
        :return: The statistics data structure.  See :meth:`joulescope.driver.Driver.statistics_get`
            for details.
        """
        log.debug('statistics_get(%s, %s, %s)', start, stop, units)
        s1, s2 = self.normalize_time_arguments(start, stop, units)
        if s1 == s2:
            s2 = s1 + 1  # always try to produce valid statistics
        s = self._stats_get(s1, s2)
        t_start = s1 / self.sampling_frequency
        t_stop = s2 / self.sampling_frequency
        return stats_to_api(s.value, t_start, t_stop)