visualdynamics.core.requirement¶
requirement
¶
A random test's requirement, and its result criterion by criterion.
A test is run to a requirement the plan copied from its governing
document: the control band, each control channel's band when several
are averaged, the overall rms, the duration, the degrees of freedom and
the line spacing the control must have, the cross-axis limits, and the
rule a miss is decided by. "Passed" without those is not a result. A
TestRequirement holds them as the plan states them, each number with
where it came from (the laboratory, the customer, or derived from
another), and evaluate reads a run against it, one row per criterion,
each worded met, not met or not judged.
- The control band. Under a single control channel, that channel
against the band; under a multi-point strategy, the composite the
controller held (
core.multi_point) against the composite band, and each control channel against its own wider band. A band is a pair of dB below and above the reference over a frequency range, so a band that steps (plus or minus 3 dB below 500 Hz and plus or minus 6 dB above) is two bands, each its own row. Every line is judged bycompliance.judge, the comparison every other random reading makes, on a one-record specification holding the band as its abort limits. - The decision rule. Either any line outside its band is a miss, or
N adjacent lines are combined, their powers added and judged against
the band's power over the same stretch at the group's degrees of
freedom (
core.chance.compare_chance), so the scatter of the estimate shrinks and a real excursion across neighboring lines remains. Some test documents allow the second; which one applies is the plan's choice, and the requirement names it. - Each miss is given by its band edges in hertz, how far past the band it went at worst in dB, and how many lines (or groups) it holds, so the row can be checked against the figure.
- The overall rms of the composite (or the one channel) against the
reference's over the band, in percent (
compliance.compare). - The duration at level against its nominal with a tolerance that may differ either side (minus 0, plus 10 percent in some documents). It is the controller's counter, typed for the run, since a PSD does not hold how long the run was at level.
- The degrees of freedom carried by the control channels' PSDs, the fewest of them, and the line spacing, each against the requirement.
- Cross-axis (
cross_axis_rows): each cross-axis channel named, with the in-axis control channel it is read against, as a percentage of that channel's ASD line by line over each limit's band, at the same degrees of freedom, the worst percentage and its frequency against the limit. - Limit channels (
limit_rows): for each response channel held under a limit profile, the band and depth over which it held its limit while the control fell below the reference, the as-run notch, each notch against the notches the plan names. A notch the plan does not name is a departure from it, and its row is not met.
The measurement's own uncertainty is held with the requirement too,
since the tolerance it is read against is the requirement's: each
control channel's contributions (the accelerometer's calibration from
its certificate, the conditioner and converter, transverse sensitivity
times the cross-axis share, the mount and the chain's response), each
an expanded uncertainty in percent on the acceleration with its
coverage factor. uncertainty_budget divides each by its own coverage
factor, combines them as the root of the sum of their squares, expands
the result at COVERAGE, and states it in percent on the acceleration,
in percent on the ASD and in dB, against one third of the tolerance
(the tightest band edge in dB, and the overall rms tolerance in
percent), the share some test documents allow the measurement. It is
not a criterion of the run, and a channel with nothing entered reads
not judged, never met.
A row that judged nothing says so and why, and is never met: a band the data do not reach, a channel with no finite line, a measurement that does not carry its degrees of freedom. A row with some lines not judged (a sample that is not a number) and none outside is not judged either, and its words say how many lines were judged. The results are met only when every row is.
Classes:
| Name | Description |
|---|---|
Band |
A band about the reference over a frequency range: |
CrossAxisLimit |
A cross-axis limit: the cross-axis response at most |
Source |
Where a number of the requirement came from: |
Contribution |
One contribution to a control channel's measurement uncertainty: |
LimitChannel |
A limit channel: the response at |
TestRequirement |
What a random test's run is accepted on, as the plan states it. |
Excursion |
One stretch of adjacent lines outside a band on one side. |
Offer |
The fact a row of the result table offers a findings register: |
Criterion |
One row of the result table. |
Results |
What |
Budget |
One control channel's measurement uncertainty against one third |
Functions:
| Name | Description |
|---|---|
duration_text |
'3 min 4 s', '45.5 s', '1 h 2 min'. |
evaluate |
Read a run against its requirement, one row per criterion. |
cross_axis_rows |
The rows of the requirement's cross-axis limits: one per limit |
limit_rows |
The rows of the requirement's limit channels: for each, the |
within |
One record of |
coverage_reach |
(low, high) Hz of what one-record |
unread |
How many lines of |
combined_percent |
The contributions' combined uncertainty, expanded at |
uncertainty_db |
An uncertainty in percent on the acceleration in dB on the ASD, |
uncertainty_budget |
Each control channel's uncertainty against one third of the |
Classes¶
Band
dataclass
¶
A band about the reference over a frequency range: below_db and
above_db (ten log ten, on a density) from low to high Hz.
low or high None reaches the specification's own end. An edge
may be infinite (no limit on that side), but not both.
Attributes:
| Name | Type | Description |
|---|---|---|
db_text |
str
|
'−3/+3 dB', an open edge written 'down' or 'up'. |
text |
str
|
'−3/+3 dB from 20 to 500 Hz'. |
CrossAxisLimit
dataclass
¶
A cross-axis limit: the cross-axis response at most percent of
the in-axis response from low to high Hz.
Source
dataclass
¶
Where a number of the requirement came from: origin (one of
ORIGINS) and its owner, the person or organization answerable
for it.
Contribution
dataclass
¶
One contribution to a control channel's measurement uncertainty:
its name, its expanded uncertainty percent on the acceleration
at coverage factor coverage, and where the number came from
(source: a calibration certificate, a data sheet).
A contribution is a percentage above 0 and under 100: a chain with no uncertainty, or one as large as the signal, is not a budget.
Attributes:
| Name | Type | Description |
|---|---|---|
standard |
float
|
The standard uncertainty, percent: |
text |
str
|
'calibration 2 % (k = 2, certificate C-1)'. |
LimitChannel
dataclass
¶
A limit channel: the response at channel (its response DOF)
held under its limit profile, an autospectrum at that DOF in the
object named profile ('' for the specification's own record
there), and the notches the plan names for it (notches, each
(low, high) Hz).
Methods:
| Name | Description |
|---|---|
planned |
Whether |
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
What the row requires, in words. |
TestRequirement
dataclass
¶
TestRequirement(document: str, composite_bands: tuple[Band, ...], revision: str = '', clause: str = '', strategy: str = 'single', channels: tuple[str, ...] = (), weights: tuple[float, ...] | None = None, individual_bands: tuple[Band, ...] = (), grms_percent: float | None = None, duration: float | None = None, duration_tolerance: tuple[float, float] | None = None, min_dof: float | None = None, max_line_spacing: float | None = None, cross_axis: tuple[CrossAxisLimit, ...] = (), rule: str = 'any_line', combine: int = 1, sources: Mapping[str, Source] = dict(), uncertainty: Mapping[str, tuple[Contribution, ...]] = dict(), cross_axis_channels: Mapping[str, str] = dict(), limit_channels: tuple[LimitChannel, ...] = ())
What a random test's run is accepted on, as the plan states it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
document
|
str
|
The governing document, as the plan names it. |
required |
composite_bands
|
sequence of Band or (low, high, below_db, above_db)
|
The control band: under a single control channel, that channel's; under a multi-point strategy, the composite's. One band per frequency range; ranges may not overlap. |
required |
revision
|
str
|
The document's revision. |
''
|
clause
|
str
|
The tolerance clause, as the plan copied it. |
''
|
strategy
|
str
|
One of |
'single'
|
channels
|
sequence of str
|
The control channels by response DOF. Empty takes them from the
channel table's Control flags, or the records that pair with the
specification ( |
()
|
weights
|
sequence of float
|
One per channel, under 'weighted' only. |
None
|
individual_bands
|
sequence of Band or tuple
|
Each control channel's band, under a multi-point strategy (and required there); none under 'single'. |
()
|
grms_percent
|
float
|
The overall rms tolerance, plus or minus, in percent of the reference's. |
None
|
duration
|
float
|
The nominal duration at level, seconds. |
None
|
duration_tolerance
|
(float, float)
|
The duration's tolerance below and above its nominal, in
percent; required with |
None
|
min_dof
|
float
|
The fewest statistical degrees of freedom the control may have. |
None
|
max_line_spacing
|
float
|
The widest the control's line spacing may be, Hz. |
None
|
cross_axis
|
sequence of CrossAxisLimit or (low, high, percent)
|
The cross-axis limits by band. |
()
|
cross_axis_channels
|
mapping of str to str
|
Each cross-axis channel's response DOF, to the in-axis control channel it is read against. |
dict()
|
limit_channels
|
sequence of LimitChannel or (channel, profile, notches)
|
The response channels held under a limit profile, each with the object its profile is in ('' for the specification) and the notches the plan names for it. |
()
|
rule
|
str
|
One of |
'any_line'
|
combine
|
int
|
How many adjacent lines are combined under 'combined' (two or more); 1 under 'any_line'. |
1
|
sources
|
mapping of str to Source or (origin, owner)
|
Where each number came from, by field ( |
dict()
|
uncertainty
|
mapping of str to sequence of Contribution or tuple
|
Each control channel's uncertainty contributions, by response
DOF, each (name, percent, coverage, source): an expanded
uncertainty in percent on the acceleration and its coverage
factor ( |
dict()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For anything the plan could not have meant: no document, no
control band, overlapping bands, a band not about the
reference, a strategy not in |
Methods:
| Name | Description |
|---|---|
as_record |
The requirement as plain values, for a file ( |
from_record |
A requirement from |
describe |
The requirement in words, a line each: the document and its |
Attributes:
| Name | Type | Description |
|---|---|---|
document_text |
str
|
'Test plan TP-12, revision B'. |
rule_text |
str
|
The decision rule in words. |
Attributes¶
Methods:¶
as_record
¶
The requirement as plain values, for a file (from_record).
Source code in src/visualdynamics/core/requirement.py
from_record
classmethod
¶
from_record(record: Mapping[str, Any]) -> TestRequirement
A requirement from as_record's values; refused as the
constructor refuses, and for a field it does not take.
Source code in src/visualdynamics/core/requirement.py
describe
¶
The requirement in words, a line each: the document and its clause, the strategy, each band, each tolerance, the decision rule, and where each number came from, with the sentence for a number the customer supplied.
Source code in src/visualdynamics/core/requirement.py
Excursion
dataclass
¶
Offer
dataclass
¶
The fact a row of the result table offers a findings register: what was measured, in words, and the channel and band it concerns.
A row offers one where the run departed from the plan: a notch the
plan does not name, and a cross-axis channel over its limit. The
report builds a fact draft from it, naming the record, and it
reaches a finding only through the register's one entry point for
drafts (report.findings.offer), which leaves it for the author to
accept, edit or discard.
Criterion
dataclass
¶
Criterion(key: str, name: str, required: str, measured: str, state: str, excursions: tuple[Excursion, ...] = (), channel: str = '', band: tuple[float, float] | None = None, finding: Offer | None = None)
One row of the result table.
Results
dataclass
¶
Results(requirement: TestRequirement, rows: tuple[Criterion, ...], scale_db: float, channels: tuple[str, ...], notes: tuple[str, ...] = ())
Budget
dataclass
¶
Budget(channel: str, contributions: tuple[Contribution, ...], acceleration_percent: float, asd_percent: float, db: float, band_limit_db: float, band_db: float, grms_limit_percent: float | None, state: str, words: str)
One control channel's measurement uncertainty against one third
of the tolerance (uncertainty_budget).
Functions:¶
duration_text
¶
'3 min 4 s', '45.5 s', '1 h 2 min'.
Source code in src/visualdynamics/core/requirement.py
evaluate
¶
evaluate(requirement: TestRequirement, specification: Specification, measured: Psd, *, table: Any = None, duration_run: float | None = None, spec_record: int | None = None, scale_db: float | None = None, profiles: Mapping[str, Any] | None = None) -> Results
Read a run against its requirement, one row per criterion.
The control channels are the requirement's, else the channel
table's Control flags, else the autospectra that pair with the
specification (core.multi_point.control_channels, and for a
single channel the one record that pairs). The reference is one
record of the specification, chosen as core.multi_point chooses
it, and the scale is resolved once for the run
(compliance.comparison_scale_db) and used for every row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requirement
|
TestRequirement
|
What the run is accepted on. |
required |
specification
|
Specification
|
The reference. |
required |
measured
|
Psd
|
The run's autospectra. |
required |
table
|
ChannelTable
|
The channel table, whose Control flags name the control channels when the requirement names none. |
None
|
duration_run
|
float
|
How long the run was at level, seconds: the controller's counter. Without it the duration row is not judged. |
None
|
spec_record
|
int
|
The reference record. |
None
|
scale_db
|
float
|
The comparison's scale; resolved as above when omitted. |
None
|
profiles
|
mapping of str to Psd
|
The objects the limit channels name for their profiles, by name. |
None
|
Returns:
| Type | Description |
|---|---|
Results
|
The rows and the notes. |
Raises:
| Type | Description |
|---|---|
TypeError
|
When the reference is not a random specification or the run not a measured PSD. |
ValueError
|
With the reason, for a run the requirement cannot be read against at all: control channels not found, ambiguous or a cross term, channels of different quantities, a weight per channel that does not fit them, or a duration that is not a positive number. A criterion that cannot be judged is a row saying why, not a refusal. |
Source code in src/visualdynamics/core/requirement.py
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 | |
cross_axis_rows
¶
cross_axis_rows(requirement: TestRequirement, specification: Specification, measured: Psd, table: Any = None, scale_db: float = 0.0, *, spec_record: int = 0) -> list[Criterion]
The rows of the requirement's cross-axis limits: one per limit and cross-axis channel.
Each cross-axis channel's autospectrum is read as a percentage of
its in-axis control channel's, line by line (a ratio of two
densities, so the comparison's scale cancels), over the limit's
band, which a limit left open at an end takes to the end the
specification writes. The row gives the worst percentage and its
frequency, how many lines were over the limit, and the degrees of
freedom the two were read at, which must be the same for the ratio
to be of like estimates. Met when no judged line is over. A line
where either density is not a finite number, or the in-axis one is
zero, is not judged; a row with such lines and none over is not
judged, as a band row is, and so is a cross-axis channel that
reads zero at every line, as a dead sensor does. A row with lines
over offers their reach to a findings register (Criterion.finding).
With no cross-axis channel named, each limit is one row saying so.
This is the one place the rows are made.
Source code in src/visualdynamics/core/requirement.py
limit_rows
¶
limit_rows(requirement: TestRequirement, specification: Specification, j: int, target: Psd, target_record: int, measured: Psd, scale_db: float, profiles: Mapping[str, Any] | None = None) -> list[Criterion]
The rows of the requirement's limit channels: for each, the notches it cut, the as-run notch.
A controller holds its control to the reference except where that
would put a limit channel over its profile; there it lowers the drive
until the limit channel sits on its profile, and the control falls
below the reference. So a line is notched where the limit channel is
at its profile (no more than HELD_DB under it) while the control is
more than HELD_DB under the reference, every curve read over the
measurement's lines the way core.limit_prediction reads them
(limit_prediction._density) and the measurement at the comparison's
scale. A run of at least limit_prediction.NARROW_LINES adjacent
notched lines is a notch, since a controller cuts no narrower and a
line or two of scatter is not one; it is given by its band, how far
under the reference the control went at worst, and its line count
(an Excursion below). The row is not met when a notch lies outside
every notch the plan names, and offers those notches to a findings
register (Criterion.finding); its words say how close the limit
channel came to its profile. A limit channel, profile or reference
not read, and a limit channel reading zero, are a row saying so.
profiles holds the objects a limit channel names for its profile,
by name; a limit channel naming none takes the specification's own
record at its DOF, as core.limit_prediction.predict_limits does.
Source code in src/visualdynamics/core/requirement.py
within
¶
within(specification: Specification, record: int, low: float | None, high: float | None) -> Specification
One record of specification cut to low to high Hz.
A specification of breakpoints gains a breakpoint at each edge,
interpolated log-log as it is read (compliance.log_interpolate),
so a line across an edge is judged in each range over its own part,
as compliance.cells cuts a cell to what is written. One on lines
or bands keeps the points from low to high. Raises ValueError
when the range holds nothing the specification writes.
Source code in src/visualdynamics/core/requirement.py
coverage_reach
¶
coverage_reach(specification: Specification) -> tuple[float, float]
(low, high) Hz of what one-record specification writes.
Source code in src/visualdynamics/core/requirement.py
unread
¶
unread(band: Specification, target: Psd, record: int) -> int
How many lines of target's record inside what band writes are
not a finite density, and so were not judged: a sample that is not a
number, or a line of a composite not formed.
Source code in src/visualdynamics/core/requirement.py
combined_percent
¶
combined_percent(contributions: Sequence[Contribution]) -> float
The contributions' combined uncertainty, expanded at COVERAGE,
in percent on the acceleration: each divided by its own coverage
factor, combined as the root of the sum of their squares, times
COVERAGE. NaN for none.
Source code in src/visualdynamics/core/requirement.py
uncertainty_db
¶
An uncertainty in percent on the acceleration in dB on the ASD,
taken on the side it is larger, below: −20 log10(1 − percent/100).
Infinite at 100 percent or more.
Source code in src/visualdynamics/core/requirement.py
uncertainty_budget
¶
uncertainty_budget(requirement: TestRequirement, channels: Sequence[str] | None = None) -> tuple[Budget, ...]
Each control channel's uncertainty against one third of the requirement's tolerance.
The combined uncertainty is combined_percent of the channel's
contributions, on the acceleration; on the ASD it is the same
decibels (uncertainty_db) as a power ratio less one. It is held
against one third of the tightest band edge of the requirement, in
dB (composite and individual bands alike, since every control
channel feeds the composite), and, with an overall rms tolerance,
against one third of it in percent on the acceleration. Met when it
is within both; a channel with nothing entered is not judged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requirement
|
TestRequirement
|
The requirement, with its contributions. |
required |
channels
|
sequence of str
|
The control channels, by response DOF: those |
None
|
Returns:
| Type | Description |
|---|---|
tuple of Budget
|
One per channel, in order. |
Source code in src/visualdynamics/core/requirement.py
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 | |