Пример #1
0
    def paint(self, p, opt, widget):
        vb = self._view()
        color = self._cmdp[self._instance_prefix + 'color']
        p.resetTransform()
        vb_rect = vb.geometry()
        y = self.scene_pos_y()
        p1 = pg.Point(vb_rect.left(), y)
        p2 = pg.Point(vb_rect.right(), y)

        pen = pg.mkPen(color)
        pen.setWidth(1)
        p.setPen(pen)
        p.drawLine(p1, p2)

        show_stats = self.statistics_show
        if show_stats != 'off':
            pen = pg.mkPen([255, 255, 255, 255])
            p.setPen(pen)
            if self.pair is None:
                txt = three_sig_figs(self.y, self._units)
            else:
                dy = abs(self.y - self.pair.y)
                t1 = three_sig_figs(self.y, self._units)
                t2 = three_sig_figs(dy, self._units)
                txt = f'{t1}, Δ={t2}'
            if show_stats == 'bottom':
                font = QtGui.QFont()
                h = QtGui.QFontMetrics(font).height()
                p1 += pg.Point(0, h)
            else:
                p1 += pg.Point(0, -2)

            p.drawText(p1, txt)
Пример #2
0
 def _statistics_to_user_str(self):
     if self._statistics is None:
         return "no statistics"
     duration = self._statistics['time']['range']
     charge = self._statistics['accumulators']['charge']
     energy = self._statistics['accumulators']['energy']
     duration_str = f"{int(duration['value'][0])} {duration['units']}"
     charge_str = three_sig_figs(charge['value'], charge['units'])
     energy_str = three_sig_figs(energy['value'], energy['units'])
     msg = f'duration = {duration_str}, charge = {charge_str}, energy = {energy_str}'
     return msg
    def _on_device_statistics(self, topic, statistics):
        """Update the multimeter display

        :param statistics: The statistics data structure
        """
        if not statistics:
            return
        if self.accumulateButton.isChecked():
            self._accumulate_duration += statistics['time']['delta']['value']
            if self._accumulate_start is None:
                self._accumulate_start = datetime.datetime.now().isoformat(
                ).split('.')[0]
            elapsed_time = self._cmdp.elapsed_time_formatter(
                self._accumulate_duration)
            accum_txt = f'{elapsed_time} | Started at {self._accumulate_start}'
        else:
            self._accumulate_duration = statistics['time']['delta']['value']
            accum_txt = three_sig_figs(self._accumulate_duration, 's')
        for name, field in statistics['signals'].items():
            if name not in self.values:
                continue
            self.values[name].update_value(field)
        accum_time = statistics['time']['accumulator']
        energy = statistics['accumulators']['energy']['value']
        charge = statistics['accumulators']['charge']['value']
        self.values['energy'].update_energy(accum_time['value'], energy,
                                            charge)
        self.accumulateDurationLabel.setText(accum_txt)
        self.accumulateDurationLabel.mousePressEvent = self._on_accumulate_duration_mouse_press
Пример #4
0
 def _on_device_state_status(self, topic, status):
     for root_key, root_value in status.items():
         if root_key == 'endpoints':
             root_value = root_value.get('2', {})
         for key, value in root_value.items():
             # print(f'{root_key}.{key} = {value}')
             s = self._status.get(key)
             if s is None:  # create
                 # print(f'Create {key} : {self._status_row}')
                 label_name = QtWidgets.QLabel(self._device_status_widget)
                 label_value = QtWidgets.QLabel(self._device_status_widget)
                 label_units = QtWidgets.QLabel(self._device_status_widget)
                 self._device_status_layout.addWidget(label_name, self._status_row, 0, 1, 1)
                 self._device_status_layout.addWidget(label_value, self._status_row, 1, 1, 1)
                 self._device_status_layout.addWidget(label_units, self._status_row, 2, 1, 1)
                 label_name.setText(key)
                 min_height = label_name.sizeHint().height() + 5
                 label_name.setMinimumHeight(min_height)
                 self._device_status_layout.setRowMinimumHeight(self._status_row, min_height)
                 self._status_row += 1
                 s = [label_name, label_value, label_units]
                 self._status[key] = s
             fmt = value.get('format', None)
             v = value['value']
             c = ''
             if fmt is None:
                 v, c, _ = unit_prefix(v)
                 k = three_sig_figs(v)
             else:
                 k = fmt.format(v)
             units = str(c + value['units'])
             s[1].setText(k)
             s[2].setText(units)
Пример #5
0
 def _on_device_state(self, topic, data):
     if topic == 'Device/#state/statistics':
         v = data.get('accumulators', {}).get('energy')
         v = self._cmdp.convert_units('energy', v)
         s = three_sig_figs(v['value'], v['units'])
         self._ui.energyValueLabel.setText(s)
     elif topic == 'Device/#state/source':
         if data in 'USB':
             self._ui.playButton.setEnabled(True)
             self._ui.iRangeComboBox.setEnabled(True)
             self._ui.vRangeComboBox.setEnabled(True)
         elif data == 'Buffer':
             self._ui.playButton.setEnabled(True)
             self._ui.recordButton.setEnabled(False)
             self._ui.iRangeComboBox.setEnabled(False)
             self._ui.vRangeComboBox.setEnabled(False)
         else:
             self._ui.playButton.setChecked(False)
             self._ui.playButton.setEnabled(False)
             self._ui.recordButton.setChecked(False)
             self._ui.recordButton.setEnabled(False)
             self._ui.iRangeComboBox.setEnabled(False)
             self._ui.vRangeComboBox.setEnabled(False)
     elif self._cmdp['Device/#state/source'] in ['USB', 'Buffer']:
         if topic == 'Device/#state/play':
             self._ui.playButton.setChecked(data)
             self._ui.recordButton.setEnabled(data)
         elif topic == 'Device/#state/record':
             self._ui.recordButton.setChecked(data)
Пример #6
0
 def accum_update(self):
     field = self._cmdp['Units/accumulator']
     if self._accum_history is None:
         txt = '0 s'
     else:
         time_str = self._accum_history['time_str']
         a = self._accum_history['accumulators']
         v = a[field]
         units = self._cmdp.preferences.get('Units/' + field, default=v['units'])
         v = convert_units(v['value'], v['units'], units)
         s = three_sig_figs(v['value'], v['units'])
         txt = ACCUM_TEMPLATE.format(field=field.capitalize(), value=s, time=time_str)
     self._accumLabel.setText(txt)
Пример #7
0
    def paint(self, p, opt, widget):
        vb = self._view()
        color = self._cmdp[self._instance_prefix + 'color']
        p.resetTransform()
        vb_rect = vb.geometry()
        y = self.scene_pos_y()
        p1 = pg.Point(vb_rect.left(), y)
        p2 = pg.Point(vb_rect.right(), y)

        pen = pg.mkPen(color)
        pen.setWidth(1)
        p.setPen(pen)
        p.drawLine(p1, p2)

        pen = pg.mkPen([255, 255, 255, 255])
        p.setPen(pen)
        if self.pair is None:
            txt = three_sig_figs(self._y, self._units)
        else:
            dy = abs(self._y - self.pair._y)
            t1 = three_sig_figs(self._y, self._units)
            t2 = three_sig_figs(dy, self._units)
            txt = f'y={t1}, Δ={t2}'
        p.drawText(p1 - 2, txt)
Пример #8
0
def run():
    statistics_queue = queue.Queue()  # resynchronize to main thread

    def stop_fn(*args, **kwargs):
        statistics_queue.put(None)  # None signals quit

    signal.signal(signal.SIGINT, stop_fn)  # also quit on CTRL-C

    with scan_require_one(config='auto') as device:
        device.statistics_callback = statistics_queue.put  # put data in queue
        device.start(stop_fn=stop_fn)
        print('CTRL-C to exit')
        while True:
            data = statistics_queue.get()
            if data is None:
                break
            energy = data['accumulators']['energy']
            print(three_sig_figs(energy['value'], units=energy['units']))
Пример #9
0
    def _on_device_statistics(self, topic, statistics):
        """Update the multimeter display

        :param statistics: The statistics data structure
        """
        if not statistics:
            return
        if self.accumulateButton.isChecked():
            self._accumulate_duration += statistics['time']['delta']['value']
        else:
            self._accumulate_duration = statistics['time']['delta']['value']
        for name, field in statistics['signals'].items():
            if name not in self.values:
                continue
            self.values[name].update_value(field)
        accum_time = statistics['time']['accumulator']
        energy = statistics['accumulators']['energy']['value']
        charge = statistics['accumulators']['charge']['value']
        self.values['energy'].update_energy(accum_time['value'], energy,
                                            charge)
        self.accumulateDurationLabel.setText(
            three_sig_figs(self._accumulate_duration, 's'))
Пример #10
0
 def _update_delta_time(self):
     if self.is_left:
         style = self._time_style()
         axis = self._axis()
         if axis is None:
             return
         axis_top = axis.geometry().top()
         vb = axis.linkedView()
         if vb is None:
             return
         x_left = self._x
         x_right = self._pair._x
         if x_left is None or x_right is None:
             self._delta_time_text.setHtml('')
             return
         dx = abs(x_right - x_left)
         x_center = (x_left + x_right) / 2
         x_scene = vb.mapViewToScene(pg.Point(x_center, 0.0)).x()
         dx_str = three_sig_figs(dx, 's')
         self._delta_time_text.setHtml(f'<div><span style="{style}">Δt={dx_str}</span></div>')
         self._delta_time_text.setPos(x_scene, axis_top)
     elif self.is_right:
         self._pair._update_delta_time()
def run():
    statistics_queue = queue.Queue()  # resynchronize to main thread

    def stop_fn(*args, **kwargs):
        statistics_queue.put(None)  # None signals quit

    signal.signal(signal.SIGINT, stop_fn)  # also quit on CTRL-C

    with scan_require_one(config='off') as device:
        device.statistics_callback_register(statistics_queue.put, 'sensor')
        device.parameter_set('i_range', 'auto')
        device.parameter_set('v_range', '15V')
        print('CTRL-C to exit')
        while True:
            device.status()
            time.sleep(0.1)
            try:
                data = statistics_queue.get(block=False)
                if data is None:
                    break
                energy = data['accumulators']['energy']
                print(three_sig_figs(energy['value'], units=energy['units']))
            except queue.Empty:
                pass
Пример #12
0
 def test_negative_numbers(self):
     self.assertEqual('-1.50 A', units.three_sig_figs(-1.5, 'A'))
     self.assertEqual('-150 mA', units.three_sig_figs(-0.15, 'A'))
     self.assertEqual('-15.0 mA', units.three_sig_figs(-0.015, 'A'))
     self.assertEqual('-1.50 mA', units.three_sig_figs(-0.0015, 'A'))
Пример #13
0
 def test_three_sig_figs_boundary(self):
     self.assertEqual('1.00 A', units.three_sig_figs(1.0, 'A'))
     self.assertEqual('100 mA', units.three_sig_figs(0.10, 'A'))
     self.assertEqual('10.0 mA', units.three_sig_figs(0.010, 'A'))
     self.assertEqual('1.00 mA', units.three_sig_figs(0.0010, 'A'))
     self.assertEqual('100 µA', units.three_sig_figs(0.00010, 'A'))
Пример #14
0
 def test_three_sig_figs_with_units(self):
     self.assertEqual('1.50 A', units.three_sig_figs(1.5, 'A'))
     self.assertEqual('150 mA', units.three_sig_figs(0.15, 'A'))
     self.assertEqual('15.0 mA', units.three_sig_figs(0.015, 'A'))
     self.assertEqual('1.50 mA', units.three_sig_figs(0.0015, 'A'))
     self.assertEqual('150 µA', units.three_sig_figs(0.00015, 'A'))
Пример #15
0
 def test_three_sig_figs_no_units(self):
     self.assertEqual('1.50', units.three_sig_figs(1.5))
     self.assertEqual('150m', units.three_sig_figs(0.15))
     self.assertEqual('150µ', units.three_sig_figs(0.00015))
     self.assertEqual('1.50k', units.three_sig_figs(1500))
     self.assertEqual('1.50M', units.three_sig_figs(1500000))
    def update(self, x, data):
        if not self.widget.isVisible():
            return
        self._x = x
        self._y = data
        if x is not None and data is not None:
            z_mean = data[:, self._column, 0]
            self._curve_mean.updateData(x, z_mean)
            if self._show_min_max:
                self._curve_min.updateData(x,  data[:, self._column, 2])
                self._curve_max.updateData(x, data[:, self._column, 3])

            z_valid = np.isfinite(z_mean)
            z_mean = z_mean[z_valid]

            z_var = data[z_valid, self._column, 1]
            z_min = data[z_valid, self._column, 2]
            z_max = data[z_valid, self._column, 3]

            if not len(z_mean):
                v_mean = np.nan
                v_std = np.nan
                v_min = np.nan
                v_max = np.nan
            else:
                v_mean = np.mean(z_mean)
                v_min = np.min(z_min)
                if not np.isfinite(v_min):
                    v_min = np.min(z_mean)
                v_max = np.max(z_max)
                if not np.isfinite(v_max):
                    v_max = np.max(z_mean)
                mean_delta = z_mean - v_mean
                # combine variances across the combined samples
                v_std = np.sqrt(np.sum(np.square(mean_delta, out=mean_delta) + z_var) / len(z_mean))
                if self.ui.zoomAutoYButton.isChecked():
                    _, (vb_min, vb_max) = self.vb.viewRange()
                    vb_range = vb_max - vb_min
                    v_range = v_max - v_min
                    update_range = (v_max > vb_max) or (v_min < vb_min)
                    if vb_range > 0:
                        update_range |= (v_range / vb_range) < AUTO_RANGE_FRACT
                    if update_range:
                        self.vb.setYRange(v_min, v_max)

            self.ui.meanValue.setText(three_sig_figs(v_mean, self._units))
            self.ui.stdValue.setText(three_sig_figs(v_std, self._units))
            self.ui.p2pValue.setText(three_sig_figs(v_max - v_min, self._units))
            self.ui.minValue.setText(three_sig_figs(v_min, self._units))
            self.ui.maxValue.setText(three_sig_figs(v_max, self._units))
            self.vb.setXRange(x[0], x[-1], padding=0.0)
            self.plot.update()
            self.on_marker()
            return

        self._curve_min.clear()
        self._curve_min.update()
        self._curve_max.clear()
        self._curve_max.update()
        self._curve_mean.clear()
        self._curve_mean.update()
        self.ui.meanValue.setText('')
        self.ui.stdValue.setText('')
        self.ui.p2pValue.setText('')
        self.ui.minValue.setText('')
        self.ui.maxValue.setText('')
        self.plot.update()