The lines outside a random comparison's bands beside what chance puts
there, next to the plot that draws them.
The Chance reading of a specification with a measured PSD against it
draws one channel's miss from its target in dB (plot.chance). This
panel holds the two settings that reading is made under and what came
of it. The settings: how many adjacent lines are judged together (one,
or the number a test document allows to be combined for judging a
tolerance), and the degrees of freedom of one line, read from the PSD
when it says how it was averaged and typed here when it does not. The
readings: the DOF per line and per group judged, the lines judged, and
for each pair of limits the count outside beside the number chance
alone puts there, below and above.
Every edit redraws the plot at once. Nothing is made: the reading is of
two objects that already exist, as the RMS bars are, so there is no
Apply button. The same call a script makes,
core.chance.compare_chance, gives every number shown here.
Classes:
| Name |
Description |
ChancePanel |
The settings and the reading. Edits are emitted as settings().
|
Classes
ChancePanel
ChancePanel(parent: QWidget | None = None)
Bases: QWidget
The settings and the reading. Edits are emitted as settings().
Methods:
| Name |
Description |
settings |
The reading's arguments as compare_chance takes them:
|
set_settings |
Set the fields without a redraw per field, then emit once.
|
show_result |
Write a compare_chance result into the rows and a paragraph
|
Source code in src/visualdynamics/gui/chance_panel.py
| def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.title: QLabel = QLabel('Lines by Chance')
grid = panel_grid(self, self.title)
self._loading = False
self.combine_box: SpinBox = SpinBox()
self.combine_box.setRange(1, MOST_COMBINED)
self.combine_box.setValue(1)
self.combine_box.setToolTip(
'How many adjacent lines are judged together, their powers '
'added and set against the limits\' power over the same '
'band. Some test documents allow this for judging a '
'tolerance; each group is worth about this many times a '
'line\'s degrees of freedom, so chance puts fewer outside')
# zero stands for "the PSD's own count", said in words in the box
self.dof_box: DoubleSpinBox = number_box(
0.0, 1.0e6, value=0.0, decimals=1, step=10.0,
tip='The statistical degrees of freedom of one line. Left '
'at "from the PSD", the count the PSD was stamped with '
'when it was averaged; a PSD that does not say needs '
'one typed here')
self.dof_box.setSpecialValueText('from the PSD')
add_settings(grid, [('Combine lines', self.combine_box),
('DOF', self.dof_box)])
add_rule(grid, 3)
self.derived: dict[str, QLabel] = {
key: value for key, (_name, value)
in add_derived(grid, ROWS, 4).items()}
# a paragraph per pair of limits, as many as the specification
# carries, so a label that wraps rather than a fixed set of rows
self.readout: QLabel = QLabel('')
self.readout.setWordWrap(True)
grid.addWidget(self.readout, 4 + len(ROWS), 0, 1, 2)
grid.setRowStretch(5 + len(ROWS), 1)
self.combine_box.valueChanged.connect(self._edited)
self.dof_box.valueChanged.connect(self._edited)
|
Methods:
settings
settings() -> dict[str, Any]
The reading's arguments as compare_chance takes them:
'combine' and 'dof' (None for the PSD's own count).
Source code in src/visualdynamics/gui/chance_panel.py
| def settings(self) -> dict[str, Any]:
"""The reading's arguments as `compare_chance` takes them:
'combine' and 'dof' (None for the PSD's own count)."""
dof = float(self.dof_box.value())
return {'combine': int(self.combine_box.value()),
'dof': dof if dof > 0.0 else None}
|
set_settings
set_settings(combine: int | None = None, dof: float | None = None) -> None
Set the fields without a redraw per field, then emit once.
dof None returns the count to the PSD's own.
Source code in src/visualdynamics/gui/chance_panel.py
| def set_settings(self, combine: int | None = None,
dof: float | None = None) -> None:
"""Set the fields without a redraw per field, then emit once.
`dof` None returns the count to the PSD's own."""
self._loading = True
try:
if combine is not None:
self.combine_box.setValue(int(combine))
self.dof_box.setValue(0.0 if dof is None else float(dof))
finally:
self._loading = False
self._edited()
|
show_result
show_result(result: dict[str, Any] | None, reason: str = '') -> None
Write a compare_chance result into the rows and a paragraph
per pair of limits under them. None clears the rows and shows
reason instead, the words for why nothing was read.
Source code in src/visualdynamics/gui/chance_panel.py
| def show_result(self, result: dict[str, Any] | None,
reason: str = '') -> None:
"""Write a `compare_chance` result into the rows and a paragraph
per pair of limits under them. None clears the rows and shows
`reason` instead, the words for why nothing was read."""
if result is None:
for value in self.derived.values():
value.setText('—')
self.readout.setText(reason)
return
self.derived['dof'].setText(f'{result["dof"]:.4g}')
self.derived['judged_dof'].setText(f'{result["judged_dof"]:.4g}')
self.derived['lines'].setText(
str(result['lines']) if result['combine'] == 1
else f'{result["lines"]} groups of {result["combine"]}')
paragraphs = [describe_chance(result, pair)
for pair in PAIRS if f'{pair}_lines' in result]
if not paragraphs:
paragraphs = ['The specification carries no bands.']
# what the counts were read on the strength of (lines taken as
# independent, units undeclared) is part of the reading
note = result.get('note')
if note:
paragraphs.append(f'{note[0].upper()}{note[1:]}.')
self.readout.setText('\n\n'.join(paragraphs))
|
Functions: