The rms check, beside the autospectrum it checks.
The RMS Check reading of a plain autospectrum compares the rms from the
area under it with the rms of the time history it came from
(core.rms_check), and this panel says what was found: the two rms in
the display unit, the gap between them in dB, the frames' own rms and
the window's share of the gap when the averaging is known, the lines
summed and the span the record was read over, then the verdict in
words and anything the reader should know under it. The plot carries
the judgment and the gap in its corner (plot.rms_check).
Two settings are made here. The time history defaults to the one the
spectrum was computed from (Project.rms_source), and any other record
in the project holding the same channel can be chosen instead, which is
how an imported spectrum, a controller's, is checked against its run.
The threshold is the gap beyond which the two are said to disagree, a
few hundredths of a decibel by default. Nothing is made, so there is no
Apply button: the reading is of a spectrum that already exists.
Classes:
| Name |
Description |
RmsCheckPanel |
The time history and the threshold, then the check. Edits are
|
Classes
RmsCheckPanel
RmsCheckPanel(parent: QWidget | None = None)
Bases: QWidget
The time history and the threshold, then the check. Edits are
emitted as {'history': name, 'threshold_db': dB}.
Methods:
| Name |
Description |
settings |
{'history': the time history's name or None, 'threshold_db':
|
set_choices |
Offer histories by name, chosen selected and source (the
|
show_check |
Write check, an RmsCheck, into the rows, its rms converted
|
Source code in src/visualdynamics/gui/rms_check_panel.py
| def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.title: QLabel = QLabel('RMS Check')
grid = panel_grid(self, self.title)
self._loading = False
self.history_box: QComboBox = QComboBox()
self.history_box.setToolTip(
'The time history the spectrum is checked against: the one '
'it was computed from, or another record holding the same '
'channel, such as the run an imported spectrum came from')
self.threshold_box: DoubleSpinBox = DoubleSpinBox()
self.threshold_box.setDecimals(3)
self.threshold_box.setRange(0.0, 20.0)
self.threshold_box.setSingleStep(0.01)
self.threshold_box.setSuffix(' dB')
self.threshold_box.setValue(GAP_DB)
self.threshold_box.setToolTip(
'The gap beyond which the spectrum and the record disagree. '
'A windowed average of a long random record lands within a '
"few hundredths of a decibel; a window's amplitude correction "
'applied to a density reads 1.76 dB high on Hann')
commit_on_enter(self.threshold_box)
add_settings(grid, [('Time history', self.history_box),
('Threshold', self.threshold_box)])
add_rule(grid, 3)
self.derived: dict[str, QLabel] = {
key: value for key, (_name, value)
in add_derived(grid, ROWS, 4).items()}
# the verdict in words, then the notes, under the numbers
self.verdict: QLabel = QLabel('')
self.verdict.setWordWrap(True)
font = self.verdict.font()
font.setBold(True)
self.verdict.setFont(font)
grid.addWidget(self.verdict, 4 + len(ROWS), 0, 1, 2)
self.notes: QLabel = QLabel('')
self.notes.setWordWrap(True)
grid.addWidget(self.notes, 5 + len(ROWS), 0, 1, 2)
grid.setRowStretch(6 + len(ROWS), 1)
self.history_box.currentIndexChanged.connect(self._edited)
self.threshold_box.valueChanged.connect(self._edited)
|
Methods:
settings
settings() -> dict[str, Any]
{'history': the time history's name or None, 'threshold_db':
the threshold in dB}.
Source code in src/visualdynamics/gui/rms_check_panel.py
| def settings(self) -> dict[str, Any]:
"""{'history': the time history's name or None, 'threshold_db':
the threshold in dB}."""
data = self.history_box.currentData()
return {'history': None if data is None else str(data),
'threshold_db': float(self.threshold_box.value())}
|
set_choices
set_choices(histories: Sequence[str], chosen: str | None, source: str | None, threshold_db: float) -> None
Offer histories by name, chosen selected and source (the
one the spectrum was computed from) marked as such, and show
threshold_db, without emitting.
Source code in src/visualdynamics/gui/rms_check_panel.py
| def set_choices(self, histories: Sequence[str], chosen: str | None,
source: str | None, threshold_db: float) -> None:
"""Offer `histories` by name, `chosen` selected and `source` (the
one the spectrum was computed from) marked as such, and show
`threshold_db`, without emitting."""
self._loading = True
try:
self.history_box.clear()
for name in histories:
said = f'{name} (computed from)' if name == source else name
self.history_box.addItem(said, name)
index = self.history_box.findData(chosen)
self.history_box.setCurrentIndex(max(index, 0))
self.threshold_box.setValue(float(threshold_db))
finally:
self._loading = False
|
show_check
show_check(check: Any, *, unit: str = '', scale: float = 1.0, refusal: str | None = None) -> None
Write check, an RmsCheck, into the rows, its rms converted
by scale into unit; None clears them, with refusal said in
its place when there is one.
Source code in src/visualdynamics/gui/rms_check_panel.py
| def show_check(self, check: Any, *, unit: str = '',
scale: float = 1.0, refusal: str | None = None) -> None:
"""Write `check`, an `RmsCheck`, into the rows, its rms converted
by `scale` into `unit`; None clears them, with `refusal` said in
its place when there is one."""
def rms(value: float | None) -> str | None:
if value is None:
return None
return f'{value * scale:.4g} {unit} rms'.replace(' ', ' ')
def db(value: float | None, digits: int = 3) -> str | None:
if value is None or not np.isfinite(value):
return None
return f'{value:+.{digits}f} dB'
values = dict.fromkeys(key for key, _name in ROWS)
if check is not None:
span = check.span
values.update(
channel=check.dof or None,
spectrum=rms(check.spectrum_rms),
time=rms(check.time_rms),
gap=db(check.gap_db),
framed=rms(check.framed_rms),
share=db(check.window_gap_db),
lines=f'{check.lines}, {check.spacing:.4g} Hz apart',
span=(None if span is None else
f'{span[0]:.4g} to {span[1]:.4g} s'),
window=('not known' if check.window is None else
f'{check.window}, {check.noise_bandwidth:.3g} lines'))
for key, value in values.items():
self.derived[key].setText('—' if value is None else value)
if check is None:
self.verdict.setText('' if refusal is None
else refusal[0].upper() + refusal[1:] + '.')
self.notes.setText('')
return
verdict = check.verdict
self.verdict.setText(verdict[0].upper() + verdict[1:] + '.')
self.notes.setText('\n'.join(note[0].upper() + note[1:] + '.'
for note in check.notes))
|
Functions: