def update_energy(self, duration, energy, charge): v = self._cmdp.convert_units('energy', energy, self._units_short) energy, prefix, _ = unit_prefix(v['value']) units = f'{prefix}{v["units"]}' self.unitLabel.setText(units) energy_str = ('%+6f' % energy)[:8] self.valueLabel.setText(energy_str) self.on_update.emit( [energy_str, '0.0000', energy_str, energy_str, '0.0000'], units) charge_c, prefix_c, _ = unit_prefix(charge) self.stdName.setText(f"{prefix_c}C") self.stdLabel.setText(('%+6f' % charge_c)[:8]) charge_ah, prefix_ah, _ = unit_prefix(charge / 3600.0) self.minName.setText(f"{prefix_ah}Ah") self.minLabel.setText(('%+6f' % charge_ah)[:8]) self.maxName.setText('') self.maxLabel.setText('') time_parts = self._cmdp.elapsed_time_formatter(duration).split(' ') if len(time_parts) > 1: self.p2pLabel.setText(time_parts[0]) self.p2pName.setText(time_parts[1]) else: self.p2pLabel.setText(time_parts[0]) self.p2pName.setText('')
def _update_ui(self): values = [self.v_mean, self.v_std_dev, self.v_min, self.v_max] max_value = max(*[abs(x) for x in values]) _, prefix, scale = unit_prefix(max_value) scale = 1.0 / scale if not len(prefix): prefix = ' ' units = f'{prefix}{self._units_short}' self.unitLabel.setText(f"<html> {units} </html>") fields = [ [self.v_mean, self.valueLabel], [self.v_std_dev, self.stdLabel], [self.v_min, self.minLabel], [self.v_max, self.maxLabel], [self.v_p2p, self.p2pLabel], ] values = [] for v, label in fields: v *= scale if abs(v) < 0.000005: # minimum display resolution v = 0 v_str = ('%+6f' % v)[:8] # v_str = v_str.replace('+', '') label.setText(v_str) values.append(v_str) self.on_update.emit(values, units)
def _update(self): if not len(self._statistics): return if self.fieldComboBox.count() == 0: fields = list(self._statistics['signals'].keys()) + \ list(self._statistics['accumulators'].keys()) block_signals_state = self.fieldComboBox.blockSignals(True) for field in fields: self.fieldComboBox.addItem(field) self._on_state(None, None) # restore self.fieldComboBox.blockSignals(block_signals_state) field = self.fieldComboBox.currentText() if field in self._statistics['signals']: self.statisticComboBox.setEnabled(True) stat_user = self.statisticComboBox.currentText() stat = STATISTICS_TRANSLATE[stat_user] value = self._statistics['signals'][field][stat]['value'] units = self._statistics['signals'][field][stat]['units'] if stat == 'σ2': value = math.sqrt(value) elif field in self._statistics['accumulators']: self.statisticComboBox.setEnabled(False) value = self._statistics['accumulators'][field]['value'] units = self._statistics['accumulators'][field]['units'] else: log.warning('unsupported field: %s', field) return v = self._cmdp.convert_units(field, value, units) value, units = v['value'], v['units'] _, prefix, scale = unit_prefix(value) value /= scale value_str = ('%+6f' % value)[:8] self.valueLabel.setText(value_str) self.unitLabel.setText(f"{prefix}{units}")
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)
def _update(self): if not len(self._statistics): return if self.fieldComboBox.count() == 0: fields = list(self._statistics['signals'].keys()) + \ list(self._statistics['accumulators'].keys()) block_signals_state = self.fieldComboBox.blockSignals(True) for field in fields: self.fieldComboBox.addItem(field) self._on_state(None, None) # restore self.fieldComboBox.blockSignals(block_signals_state) field = self.fieldComboBox.currentText() if field in self._statistics['signals']: self.statisticComboBox.setEnabled(True) stat = self.statisticComboBox.currentText() s = self._statistics['signals'][field]['statistics'] units = self._statistics['signals'][field]['units'] value = STATISTICS_TRANSLATE[stat](s) elif field in self._statistics['accumulators']: self.statisticComboBox.setEnabled(False) value = self._statistics['accumulators'][field]['value'] units = self._statistics['accumulators'][field]['units'] else: log.warning('unsupported field: %s', field) return _, prefix, scale = unit_prefix(value) value /= scale value_str = ('%+6f' % value)[:8] self.valueLabel.setText(value_str) self.unitLabel.setText(f"<html> {prefix}{units} </html>")
def test_scaled(self): self.assertClose((10.0, 'G', 1e9), units.unit_prefix(10e9)) self.assertClose((10.0, 'M', 1e6), units.unit_prefix(10e6)) self.assertClose((10.0, 'k', 1e3), units.unit_prefix(10e3)) self.assertClose((100.0, 'm', 0.001), units.unit_prefix(0.1)) self.assertClose((100.0, 'µ', 0.000001), units.unit_prefix(0.0001)) self.assertClose((10.0, 'n', 1e-9), units.unit_prefix(10e-9)) self.assertClose((10.0, 'p', 1e-12), units.unit_prefix(10e-12))
def update_energy(self, duration, energy, charge): v = self._cmdp.convert_units('energy', energy, self._units_short) energy, prefix, _ = unit_prefix(v['value']) units = f'{prefix}{v["units"]}' self.unitLabel.setText(units) energy_str = ('%+6f' % energy)[:8] self.valueLabel.setText(energy_str) self.on_update.emit( [energy_str, '0.0000', energy_str, energy_str, '0.0000'], units) charge_c, prefix_c, _ = unit_prefix(charge) self.stdName.setText(f"{prefix_c}C") self.stdLabel.setText(('%+6f' % charge_c)[:8]) charge_ah, prefix_ah, _ = unit_prefix(charge / 3600.0) self.minName.setText(f"{prefix_ah}Ah") self.minLabel.setText(('%+6f' % charge_ah)[:8]) self.maxName.setText('') self.maxLabel.setText('') self.p2pName.setText('s') self.p2pLabel.setText(f'{duration:.1f}')
def update_energy(self, duration, energy, charge): energy, prefix, _ = unit_prefix(energy) units = f'{prefix}{self._units_short}' self.unitLabel.setText(f"<html> {units} </html>") energy_str = ('%+6f' % energy)[:8] self.valueLabel.setText(energy_str) self.on_update.emit( [energy_str, '0.0000', energy_str, energy_str, '0.0000'], units) charge_c, prefix_c, _ = unit_prefix(charge) self.stdName.setText(f"<html> {prefix_c}C </html>") self.stdLabel.setText(('%+6f' % charge_c)[:8]) charge_ah, prefix_ah, _ = unit_prefix(charge / 3600.0) self.minName.setText(f"<html> {prefix_ah}Ah </html>") self.minLabel.setText(('%+6f' % charge_ah)[:8]) self.maxName.setText('') self.maxLabel.setText('') duration_c, prefix_t, _ = unit_prefix(duration) self.p2pName.setText(f"<html> {prefix_t}s </html>") self.p2pLabel.setText(('%.1f' % duration_c))
def si_format(labels, units=None): if units is None: units = '' values = np.array([z for z in labels.values()]) max_value = float(np.max(np.abs(values))) _, prefix, scale = unit_prefix(max_value) scale = 1.0 / scale if not len(prefix): prefix = ' ' units_suffix = f'{prefix}{units}' results = [] for lbl, v in labels.items(): v *= scale if abs(v) < 0.000005: # minimum display resolution v = 0 v_str = ('%+6f' % v)[:8] results.append('%s=%s %s' % (lbl, v_str, units_suffix)) return results
def _si_format(names, values, units): results = [] if units is None: units = '' if len(values): values = np.array(values) max_value = float(np.max(np.abs(values))) _, prefix, scale = unit_prefix(max_value) scale = 1.0 / scale if not len(prefix): prefix = ' ' units_suffix = f'{prefix}{units}' for lbl, v in zip(names, values): v *= scale if abs(v) < 0.000005: # minimum display resolution v = 0 v_str = ('%+6f' % v)[:8] results.append('%s=%s %s' % (lbl, v_str, units_suffix)) return results
def on_marker(self, x=None): if x is None: x = self.vb.vline.getPos()[0] if self._x is not None and len(self._x): values = ['t=%.6f' % (x, )] idx = np.argmax(self._x >= x) y = self._y[idx, self._column, :].tolist() y[1] = np.sqrt(y[1]) if np.isfinite(y[2]): labels = ['μ', 'σ', 'min', 'max'] elif np.isfinite(y[0]): labels = ['μ'] y = y[:1] else: y = [0.0] labels = [] max_value = float(np.max(np.abs(y))) _, prefix, scale = unit_prefix(max_value) scale = 1.0 / scale if not len(prefix): prefix = ' ' units = f'{prefix}{self._units}' for lbl, v in zip(labels, y): v *= scale if abs(v) < 0.000005: # minimum display resolution v = 0 v_str = ('%+6f' % v)[:8] values.append('%s=%s %s' % (lbl, v_str, units)) s = '<br>'.join(values) html = '<div><span style="color: #FFF;">%s</span></div>' % (s, ) ymin, ymax = self.vb.viewRange()[1] self.x_label.setPos(x, ymax) else: html = "" if self._show_vline: self.x_label.setHtml(html) #self.vb.vline.label.setHtml(html) #self.vb.vline.label.setFormat(html) # self.x_pos.setAnchor([0.5, 0.5]) self.vb.vline.setPos(x)
def test_no_change(self): self.assertClose((0.0, '', 1), units.unit_prefix(0.0)) self.assertClose((1.0, '', 1), units.unit_prefix(1.0)) self.assertClose((5.0, '', 1), units.unit_prefix(5.0))