visualdynamics.core.author¶
author
¶
Writing and editing a specification sheet, at any channels.
A specification sheet is a set of breakpoints, a level per channel at each breakpoint, warning and abort bands in decibels below and above the target, and a cross term for each pair of channels. None of that depends on where the channels are, so one draft class is used for every way a sheet is opened (new at a shape set's modal coordinates, new at chosen physical DOFs or at a channel table's control channels, or opened from an existing specification) and for every way it is saved (as a new specification, or written back into the one it was opened from).
A specification written at the modal coordinates M1 … Mn and expanded
through the shape set becomes an exact control-channel CPSD, phase and
coherence included. The expansion makes no assumption: every number in
it comes from a value the author entered.
What an author enters in a SpecificationDraft:
- The channels, each with the quantity its density is of.
- The breakpoints: frequencies, and a level per channel at each.
Between breakpoints the level follows a power law, which is how a
written specification is read (
Specification.interpolation = 'log_log'). - Each pair's cross term, as a coherence and a phase, from which
S_ij = √(γ² S_ii S_jj) e^{iφ}. The entries must be able to hold together, which each in [0, 1] does not ensure: a sheet whose entries no set of signals has is refused (core.matrix_checks). A pair that has not been entered is not assumed to be zero; the specification made from the draft has no cross term for it. Independent channels are a statement too, and the author has to make it.with_all_pairsenters one coherence and phase for every pair at once. - The bands: warning and abort, in decibels below and above the
target, set per channel and per segment between breakpoints, under
each channel's
symmetricanduniformconstraints. - How the levels are typed (
entry): a level at every breakpoint, or a level at the first and a slope in decibels per octave into each breakpoint after it, the level there computed, as many written tables give them (core.breakpoints). The draft holds levels either way; the entry decides what an edit holds still.
The operations on a draft (scaled_db, with_band, with_band_edge,
shifted_band, constrained, with_breakpoint, without_breakpoint,
with_all_pairs, to_breakpoints, to_lines, with_entry,
with_slope, with_level, with_slope_breakpoint) each return a new draft
and leave the original unchanged, so a script reads as a sequence of
statements, and so does a session's journal.
Classes:
| Name | Description |
|---|---|
SpecificationDraft |
A specification being written, at any channels. |
Functions:
| Name | Description |
|---|---|
default_bands |
A channel's starting bands: ±3 dB warning, ±6 dB abort on every |
band_notes |
The notes a sheet opened on |
read_onto_lines |
A specification written at breakpoints, read onto evenly spaced |
uniform_spacing |
The spacing of evenly spaced lines, in Hz, or None when they are not. |
read_at_lines |
A specification record read at new lines. |
Classes¶
SpecificationDraft
dataclass
¶
SpecificationDraft(channels: list[str], dims: list[str], frequencies: list[float], levels: list[list[float]], pairs: dict[tuple[int, int], tuple[float, float] | None] = dict(), bands: list[dict[str, Any]] = list(), notes: list[str] = list(), sources: list[str] = list(), form: str = 'breakpoints', spacing: float | None = None, entry: str = 'levels')
A specification being written, at any channels.
Attributes:
channels: The DOF strings, one per channel: modal coordinates
(M1), physical DOFs (101Z+), or whatever the sheet was
opened at. Any name is accepted except an empty one.
dims: The quantity each channel's density is of
('acceleration', 'angular_acceleration', …), one per
channel; the density's dimension is its square per hertz.
frequencies: The breakpoints, in Hz, increasing.
levels: One list per channel, a density at each breakpoint,
in the channel's SI density unit.
pairs: {(i, j): (coherence, phase_degrees)} for every pair
i < j of channels, or None where the pair has not been
entered yet.
bands: One entry per channel: {'warning': [(below, above)
per segment], 'abort': [...], 'symmetric': bool, 'uniform':
bool}, the bands in decibels below and above the target,
where a segment is the span between two neighboring
breakpoints. The constraints belong to each channel:
symmetric holds the upper edge at minus the lower one,
and uniform holds every segment at one band. A breakpoint
belongs to the segment on its right, and the last
breakpoint to the segment on its left.
notes: What could not be carried over when the sheet was
opened (cross terms that varied with frequency, bands that
differed), listed so that nothing is dropped without
notice.
sources: The name of the specification each channel was opened
from, one per channel, when the sheet spans several
(across); empty when the sheet is one specification's.
Channels from different specifications have no cross term
between them, and the pair is not offered at all.
form: 'breakpoints', the few points a specification is written
from, or 'lines', the same requirement read onto evenly
spaced frequency lines, as a controller writes its target.
to_breakpoints and to_lines convert between the two.
The levels are edited on the breakpoints.
spacing: The frequency spacing in Hz of the lines form, or the
spacing remembered from the specification the sheet was
opened from. to_lines uses it when no spacing is given.
entry: 'levels', a level typed at every breakpoint, or
'slopes', a level at the first breakpoint and a slope in
decibels per octave into each one after it, the level
there computed. The levels are held either way. Under
'slopes', with_level holds every slope after the level
it changes, as with_slope does; under 'levels' it
changes that level alone.
Methods:
| Name | Description |
|---|---|
at_modal_coordinates |
A starter sheet at a shape set's modal coordinates |
at_dofs |
A starter sheet at chosen DOFs, with no pair entered. |
at_control_channels |
A starter sheet at a channel table's control channels. |
at_rows |
A starter sheet at picked rows of a channel table, whatever |
from_specification |
A sheet opened from an existing specification. |
across |
One sheet spanning several specifications' sheets. |
for_source |
The sheet of one of the specifications a combined sheet spans. |
validate |
Raise |
pairable |
Every pair |
unset_pairs |
The pairs that have no cross term entered yet. |
with_all_pairs |
The same draft with one coherence and phase entered for every pair. |
scaled_db |
The same draft with the target raised or lowered by |
segment_of |
The index of the segment each frequency lies in. |
band_db |
One channel's band, (below, above) in decibels, at each frequency. |
with_band |
The same draft with a band set to the given values. |
shifted_band |
The same draft with one edge of a band moved by |
with_band_edge |
The same draft with one edge of a band set to |
constrained |
The same draft with the channels' constraints set. |
sections |
One channel's segments grouped into its requirement's straight sections. |
band_runs |
One channel's segments grouped as the plot draws its band handles. |
with_breakpoint |
The same draft with a breakpoint added at |
without_breakpoint |
The same draft without the breakpoint at |
with_entry |
The same draft with its levels typed another way. |
slopes_db |
Each channel's slope in decibels per octave on each segment, |
with_slope |
The same draft with one segment's slope typed. |
with_level |
The same draft with one breakpoint's level typed, the way the |
with_slope_breakpoint |
The same draft with a breakpoint entered as a slope and the |
reading |
One channel's table read: each segment's slope in decibels |
to_breakpoints |
The same requirement as the few points it was written from. |
to_lines |
The same requirement read onto evenly spaced frequency lines. |
bands_differ |
Whether any channel's band changes from one segment to the next. |
with_band_corners |
The same draft with helper breakpoints where a band steps. |
make |
The specification this sheet describes. |
constraints |
Each channel's |
written_into |
|
preview |
The autospectra and their bands only, as the plot beside the sheet shows. |
as_dict |
A JSON-friendly form, for the provenance record. |
from_dict |
The draft a provenance record holds. |
Attributes:
| Name | Type | Description |
|---|---|---|
num_channels |
int
|
How many channels the draft covers. |
Attributes¶
Methods:¶
at_modal_coordinates
classmethod
¶
at_modal_coordinates(shapes: ShapeSet, quantity: str = 'acceleration', modes: Sequence[int] | None = None) -> SpecificationDraft
A starter sheet at a shape set's modal coordinates M1 … Mn.
The starter is the one at_dofs makes. Each channel's quantity
follows the transform's unit rule: per radian for a unit rigid
set's rotations, the modal quantity for a mass-normalized set.
A set with no mass unit gives its coordinates no unit, and a
specification with no unit is refused.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shapes
|
ShapeSet
|
The set the specification is written at. |
required |
quantity
|
str
|
The physical quantity the target is a density of. |
'acceleration'
|
modes
|
sequence of int
|
Which shapes get a channel, by index from 0 (the ones selected in the tree). All of them when omitted. A virtual point's target is usually its three translations alone. Expanded through the set, a shape with no channel contributes nothing, which is the same as a zero level, and a sheet holds only positive levels. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
No pair entered. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When no shape is selected, an index is out of range, or the set has no mass unit. |
Source code in src/visualdynamics/core/author.py
at_dofs
classmethod
¶
at_dofs(dofs: list[str], quantity: str | list[str] = 'acceleration') -> SpecificationDraft
A starter sheet at chosen DOFs, with no pair entered.
The starter is a flat line from 20 to 2000 Hz at one SI unit of density on every channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dofs
|
list of str
|
The channels. |
required |
quantity
|
str or list of str
|
The quantity each channel's density is of, one for all or one per channel. |
'acceleration'
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
The sheet to fill. |
Source code in src/visualdynamics/core/author.py
at_control_channels
classmethod
¶
at_control_channels(table: ChannelTable) -> SpecificationDraft
A starter sheet at a channel table's control channels.
Each channel is in the quantity its channel type declares, and
the starter is the one at_dofs makes. A flagged control
channel of any declared type is used: a test can be controlled
to a force or a voltage as well as to a motion, and a
specification written at a force is a force specification.
When the table flags no control channel, every motion channel
is used, since those are the likely control channels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
ChannelTable
|
The table. |
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
The sheet to fill. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the flagged channels declare no channel type, or when nothing is flagged and the table has no motion channel. |
Source code in src/visualdynamics/core/author.py
at_rows
classmethod
¶
at_rows(table: ChannelTable, rows: Sequence[int]) -> SpecificationDraft
A starter sheet at picked rows of a channel table, whatever their role: a force CPSD at the drives is written at the reference rows.
Each channel is in the quantity its channel type declares, and
the starter is the one at_dofs makes. A row with no node or
direction, or no channel type, is left out.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
ChannelTable
|
The table. |
required |
rows
|
sequence of int
|
The picked rows. |
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
The sheet to fill. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When no picked row has both a DOF and a channel type. |
Source code in src/visualdynamics/core/author.py
from_specification
classmethod
¶
from_specification(spec: Specification, channels: list[str] | None = None, source: str = '') -> SpecificationDraft
A sheet opened from an existing specification.
The autospectra's lines become the breakpoints. Lines at 0 Hz, or where any autospectrum is not positive, are left out, with a note. A cross term that is one coherence and phase over frequency becomes that pair's entry; one that varies is left unentered, with a note. The warning and abort limits become bands in decibels per segment, and a specification with no limits opens with the default bands. A specification on evenly spaced lines opens in the 'lines' form and remembers its spacing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Specification
|
The specification to open. |
required |
channels
|
list of str
|
Only these of its channels (the ones selected in the tree). All of them when omitted. |
None
|
source
|
str
|
The specification's name, for a sheet that will span
several ( |
''
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
Ready to edit. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When a named channel has no autospectrum, the specification has no autospectrum, a channel's units are not declared, or fewer than two lines have every autospectrum positive. |
Source code in src/visualdynamics/core/author.py
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | |
across
classmethod
¶
across(drafts: dict[str, SpecificationDraft]) -> SpecificationDraft
One sheet spanning several specifications' sheets.
An edit such as a scale or a band is then applied to all of
them at once. The sheets share one breakpoint list: the union
of their breakpoints over the range they all cover, each
sheet's levels read off its own power law (exact at its own
breakpoints). Pairs are offered only within one specification.
for_source returns each specification's own sheet, which
written_into writes back at that specification's own lines.
Raises ValueError when there are no sheets, or when they
share fewer than two breakpoints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
drafts
|
dict of str to SpecificationDraft
|
Each specification's sheet by its name. |
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
The combined sheet, |
Source code in src/visualdynamics/core/author.py
for_source
¶
for_source(source: str) -> SpecificationDraft
The sheet of one of the specifications a combined sheet spans.
It has that specification's channels and pairs only, and its
sources is empty. Raises ValueError when no channel is
from source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
The specification's name, as |
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
That specification's own sheet. |
Source code in src/visualdynamics/core/author.py
validate
¶
Raise ValueError for anything no specification could hold.
That is: no channels, a channel named twice, a channel with no
quantity, fewer than two breakpoints or breakpoints that are
not positive and increasing, a level that is not finite and
positive, a coherence outside [0, 1], coherence and phase
entries that cannot hold together (no set of signals has them;
the reason names the channels and the nearest entries that would
hold), a pair across two specifications, a band that is not
below and above the target, a band that breaks its channel's
symmetric or uniform constraint, a form other than
'breakpoints' or 'lines', a spacing that is not positive, or an
entry other than 'levels' or 'slopes'. Every draft is checked
when it is made.
Source code in src/visualdynamics/core/author.py
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 | |
pairable
¶
Every pair (i, j), i < j, that can have a cross term.
Those are the pairs of channels from the same specification.
Source code in src/visualdynamics/core/author.py
unset_pairs
¶
with_all_pairs
¶
with_all_pairs(coherence: float, phase_degrees: float = 0.0) -> SpecificationDraft
The same draft with one coherence and phase entered for every pair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coherence
|
float
|
The coherence between every two channels, 0 for independent, 1 for fully coherent. |
required |
phase_degrees
|
float
|
The phase of the later channel against the earlier, in degrees. |
0.0
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
scaled_db
¶
scaled_db(decibels: float, channels: list[str] | None = None) -> SpecificationDraft
The same draft with the target raised or lowered by decibels.
The change is applied to every channel, or to the named ones.
Raises ValueError for a channel the draft does not have.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
decibels
|
float
|
The change, positive to raise. |
required |
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
segment_of
¶
The index of the segment each frequency lies in.
A breakpoint belongs to the segment on its right, and the last breakpoint (and anything past the end) to the last segment. With no frequencies, the answer is for each breakpoint.
Source code in src/visualdynamics/core/author.py
band_db
¶
One channel's band, (below, above) in decibels, at each frequency.
Each frequency takes the band of the segment it lies in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
('warning', 'abort')
|
Which band. |
'warning'
|
channel
|
int
|
Which channel, by index. |
required |
frequencies
|
array - like
|
The frequencies in Hz; the breakpoints themselves when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
(ndarray, ndarray)
|
The band below and above the target, per frequency. |
Source code in src/visualdynamics/core/author.py
with_band
¶
with_band(kind: str, below: float, above: float, channels: Any = None, segments: Any = None) -> SpecificationDraft
The same draft with a band set to the given values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
('warning', 'abort')
|
Which band. |
'warning'
|
below
|
float
|
Decibels below (negative) and above (positive) the target. |
required |
above
|
float
|
Decibels below (negative) and above (positive) the target. |
required |
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
segments
|
list of int
|
Which segments, by index; all of them when omitted, and all of them regardless on a uniform channel. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
shifted_band
¶
shifted_band(kind: str, side: str, segments: Any, decibels: float, channels: Any = None, step: float = LIMIT_STEP_DB) -> SpecificationDraft
The same draft with one edge of a band moved by decibels.
This is a drag on the plot, applied. On a symmetric channel the
other edge moves to match, and on a uniform channel every
segment moves. The edge lands on a multiple of step (by
default LIMIT_STEP_DB, a quarter decibel) and is never nearer
the target than one step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
('warning', 'abort')
|
Which band. |
'warning'
|
side
|
('lower', 'upper')
|
Which edge was dragged. |
'lower'
|
segments
|
list of int
|
The segments under the drag. |
required |
decibels
|
float
|
How far, positive up. |
required |
channels
|
list of str
|
Which channels; all of them when omitted. The selected channels are the ones edited. |
None
|
step
|
float
|
The decibel grid the edge lands on. |
LIMIT_STEP_DB
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
with_band_edge
¶
with_band_edge(kind: str, side: str, segments: Any, decibels: float, channels: Any = None, step: float = LIMIT_STEP_DB) -> SpecificationDraft
The same draft with one edge of a band set to decibels.
This is a drag on the plot, applied. Every selected channel is
set to the same level: a drag from 3 to 4 dB puts a channel at
3 dB and one at 4 dB both at 4 dB, instead of moving each one
by 1 dB. On a symmetric channel the other edge is set to match,
and on a uniform channel every segment is set. The edge lands
on a multiple of step and is never nearer the target than
one step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
('warning', 'abort')
|
Which band. |
'warning'
|
side
|
('lower', 'upper')
|
Which edge. |
'lower'
|
segments
|
list of int
|
The segments under the drag. |
required |
decibels
|
float
|
The edge's level, positive above the target. |
required |
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
step
|
float
|
The decibel grid the edge lands on. |
LIMIT_STEP_DB
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
constrained
¶
constrained(channels: Any = None, symmetric: bool | None = None, uniform: bool | None = None) -> SpecificationDraft
The same draft with the channels' constraints set.
Turning symmetric on mirrors the band above the target to the one below, and turning uniform on gives every segment the first segment's band.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
symmetric
|
bool
|
The constraint to set; kept when omitted. |
None
|
uniform
|
bool
|
The constraint to set; kept when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
sections
¶
One channel's segments grouped into its requirement's straight sections.
In the breakpoints form each segment is its own section. In the
lines form a section is a run of segments on one power law,
between the bends that to_breakpoints finds; tolerance is
how much the log-log slope may change and still be one section.
Source code in src/visualdynamics/core/author.py
band_runs
¶
One channel's segments grouped as the plot draws its band handles.
A uniform channel has one run over the whole range. Otherwise
there is one run per section of the requirement (sections),
split again wherever the band already differs within a section.
Source code in src/visualdynamics/core/author.py
with_breakpoint
¶
with_breakpoint(frequency: float) -> SpecificationDraft
The same draft with a breakpoint added at frequency.
Its levels are read off the power law between its neighbors, or
are the end breakpoint's level outside the range. The segment it
splits keeps its band on both halves. A frequency that is
already a breakpoint gives an unchanged copy, and one that is
not positive raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequency
|
float
|
The frequency in Hz. |
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
without_breakpoint
¶
without_breakpoint(frequency: float) -> SpecificationDraft
The same draft without the breakpoint at frequency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequency
|
float
|
The frequency in Hz. It has to be one of the breakpoints,
and the draft has to have more than two; otherwise
|
required |
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. |
Source code in src/visualdynamics/core/author.py
with_entry
¶
with_entry(entry: str) -> SpecificationDraft
The same draft with its levels typed another way.
Nothing in the requirement changes: the draft holds levels
either way, and the entry decides what with_level holds
still.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry
|
('levels', 'slopes')
|
'levels', a level at every breakpoint, or 'slopes', a level at the first and a slope in decibels per octave into each breakpoint after it. |
'levels'
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. Any other entry raises
|
Source code in src/visualdynamics/core/author.py
slopes_db
¶
Each channel's slope in decibels per octave on each segment,
one row per channel, one fewer than the breakpoints: the table
as it is written by slope (core.breakpoints.segment_slopes).
Source code in src/visualdynamics/core/author.py
with_slope
¶
with_slope(segment: int, db_per_octave: float, channels: list[str] | None = None) -> SpecificationDraft
The same draft with one segment's slope typed.
The level at the segment's end is the one the slope reaches from its start, and every segment after it keeps its slope, so the levels past it move together. Bands, pairs and the levels before the segment are unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segment
|
int
|
The segment by index from 0: segment k runs from breakpoint k to breakpoint k + 1. |
required |
db_per_octave
|
float
|
The slope. Plus 3 is the documents' plus 3 dB per octave,
an exponent of 0.9966; |
required |
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. A segment the draft
does not have, or a channel it does not have, raises
|
Source code in src/visualdynamics/core/author.py
with_level
¶
with_level(breakpoint: int, level: float, channels: list[str] | None = None) -> SpecificationDraft
The same draft with one breakpoint's level typed, the way the
draft's entry says.
Under 'levels' that level changes and nothing else. Under 'slopes' the slope into the breakpoint changes and every slope after it is held, so the levels past it move by the same factor; typed at the first breakpoint, the whole table moves with it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
breakpoint
|
int
|
The breakpoint by index from 0. |
required |
level
|
float
|
The level, in the channel's SI density unit, positive. |
required |
channels
|
list of str
|
Which channels; all of them when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. A breakpoint or channel
the draft does not have, or a level that is not positive,
raises |
Source code in src/visualdynamics/core/author.py
with_slope_breakpoint
¶
with_slope_breakpoint(frequency: float, db_per_octave: float, channels: list[str] | None = None) -> SpecificationDraft
The same draft with a breakpoint entered as a slope and the next frequency, the level there computed.
This is the line of a table that reads "plus 3 dB per octave to
80 Hz": the slope runs from the breakpoint below frequency to
it. Past the last breakpoint the table grows by one segment.
Inside a segment the breakpoint splits it (with_breakpoint,
both halves wearing its band) and the slope is typed on the
lower half (with_slope), so the segments above keep their
slopes. At a frequency that is already a breakpoint, the slope
into it is typed. The channels not named take the level the
power law between their neighbors gives, or the last
breakpoint's past the end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequency
|
float
|
The next frequency, in Hz, above the first breakpoint. |
required |
db_per_octave
|
float
|
The slope from the breakpoint below it. |
required |
channels
|
list of str
|
Which channels the slope is typed for; all of them when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; this one is unchanged. A frequency at or below
the first breakpoint raises |
Source code in src/visualdynamics/core/author.py
reading
¶
reading(channel: int | str = 0) -> BreakpointReading
One channel's table read: each segment's slope in decibels
per octave, its area by the closed form, and the rms
accumulated from the lowest breakpoint
(core.breakpoints.read_breakpoints), in the channel's SI
units: areas in the square of its quantity, rms in its
quantity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
int or str
|
The channel by index or by name. |
0
|
Returns:
| Type | Description |
|---|---|
BreakpointReading
|
The slopes, the areas and the running rms. |
Raises:
| Type | Description |
|---|---|
ValueError
|
On the 'lines' form. A controller's lines are a density per
line, integrated as bins, and read as a power law between
them the areas add to an rms the specification does not
have; |
Source code in src/visualdynamics/core/author.py
to_breakpoints
¶
to_breakpoints(tolerance: float = 1e-06) -> SpecificationDraft
The same requirement as the few points it was written from.
The breakpoints kept are the first and last line, every line where the log-log slope of any channel changes, and every line where a band steps. This is exact for a specification that was read onto lines from breakpoints (a controller's target). A specification with no such structure keeps every line. Either way a note says how many lines became how many breakpoints, and another note is added if a band changed within a merged segment, which then takes the band at its start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tolerance
|
float
|
How much the slope may change between adjacent segments and still be one power law. |
1e-6
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft, |
Source code in src/visualdynamics/core/author.py
to_lines
¶
to_lines(spacing: float | None = None) -> SpecificationDraft
The same requirement read onto evenly spaced frequency lines.
The lines are multiples of spacing from 0 Hz, as a controller
lays out its lines, over the range the breakpoints cover, with
each channel on its own power law between breakpoints. Only the
lines inside that range are made: a sheet holds positive
levels, and the zeros a controller writes outside the band are
its own convention, filled in by its loader for any line the
file does not name. A note is added when an end breakpoint is
not on the grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spacing
|
float
|
The line spacing in Hz. Defaults to the spacing the sheet
remembers. With neither, |
None
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft, |
Source code in src/visualdynamics/core/author.py
bands_differ
¶
Whether any channel's band changes from one segment to the next.
Where it does, the specification needs a helper line to hold
the step (with_band_corners).
Source code in src/visualdynamics/core/author.py
with_band_corners
¶
with_band_corners(part: float = 1e-06) -> SpecificationDraft
The same draft with helper breakpoints where a band steps.
A helper is added just below each breakpoint whose two segments
have different bands, so the specification made from the draft
can hold the step. A limit array holds one value per line and a
breakpoint belongs to the segment on its right, so the segment
on its left needs its own line at the corner to carry its band
up to it. The helpers are removed again when the specification
is opened as a sheet, and to_breakpoints drops them, since
they lie on a straight section.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part
|
float
|
How far below the breakpoint the helper is, as a fraction of the breakpoint's frequency. The helper is on the same power law. |
1e-6
|
Returns:
| Type | Description |
|---|---|
SpecificationDraft
|
A new draft; the same one when no helper is needed. |
Source code in src/visualdynamics/core/author.py
make
¶
make(comment: str = '') -> Specification
The specification this sheet describes.
A pair with no cross term entered is left out of the
specification, not assumed to be zero. Where a band steps
between segments, helper lines are added first
(with_band_corners). The channels' symmetric and uniform
constraints are kept on the specification as
band_constraints, so a sheet reopens as it was set. Raises
ValueError when the sheet spans several specifications.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
comment
|
str
|
A comment for the records, such as where the sheet came from. Defaults to 'written as a specification sheet'. |
''
|
Returns:
| Type | Description |
|---|---|
Specification
|
The autospectra and the entered cross terms at the breakpoints, interpolated log-log between them, with the warning and abort limits on every autospectrum. |
Source code in src/visualdynamics/core/author.py
1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 | |
constraints
¶
Each channel's symmetric and uniform constraints, by name.
The specification keeps these beside its limits, so a sheet reopens as it was set.
Source code in src/visualdynamics/core/author.py
written_into
¶
written_into(spec: Specification, comment: str = '') -> Specification
spec with this sheet's channels rewritten in it, at its own lines.
The sheet's channels take the sheet's levels, cross terms and
bands over the sheet's range, read off its power law at each
line, and a breakpoint that is not one of the specification's
lines becomes a new line. Lines the sheet left out (0 Hz, a
zero level) keep what they had. A cross term the sheet has but
the specification never held is added, made from the
autospectra. Channels the sheet does not hold are unchanged,
read off their own curves at any new line. Raises ValueError
when the sheet spans several specifications; write each one
with for_source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Specification
|
The specification the sheet was opened from. |
required |
comment
|
str
|
The comment for each cross-term record the sheet adds; 'written as a specification sheet' when empty. Records the specification already had keep their own comments. |
''
|
Returns:
| Type | Description |
|---|---|
Specification
|
A new object; |
Source code in src/visualdynamics/core/author.py
1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 | |
preview
¶
preview() -> Specification
The autospectra and their bands only, as the plot beside the sheet shows.
Raises ValueError when the sheet spans several specifications.
Source code in src/visualdynamics/core/author.py
as_dict
¶
A JSON-friendly form, for the provenance record.
Source code in src/visualdynamics/core/author.py
from_dict
classmethod
¶
from_dict(data: dict[str, Any]) -> SpecificationDraft
The draft a provenance record holds.
Source code in src/visualdynamics/core/author.py
Functions:¶
default_bands
¶
A channel's starting bands: ±3 dB warning, ±6 dB abort on every segment, symmetric and uniform.
Source code in src/visualdynamics/core/author.py
band_notes
¶
band_notes(spec: Specification) -> list[str]
The notes a sheet opened on spec shows about bands it does not have.
A specification with no warning or abort limits opens with the default bands on the plot, ready to drag, and the first edit writes them to it. The notes are computed from the specification instead of being stored on the draft, so they stop once the limits exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Specification
|
The specification the sheet is open on. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
One note per band kind missing; empty when both are there. |
Source code in src/visualdynamics/core/author.py
read_onto_lines
¶
read_onto_lines(spec: Specification, spacing: float) -> tuple[Psd, list[str]]
A specification written at breakpoints, read onto evenly spaced lines as a PSD or CPSD to drive or predict with.
The reading is the specification sheet's own: the specification is
opened as a sheet (SpecificationDraft.from_specification), read
onto lines at spacing (SpecificationDraft.to_lines, each
channel on its power law between breakpoints, the lines multiples
of the spacing over the range the breakpoints cover) and made. The
warning and abort limits are left out, as a PSD cannot hold them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Specification
|
The specification, at breakpoints. |
required |
spacing
|
float
|
The line spacing in Hz. |
required |
Returns:
| Type | Description |
|---|---|
tuple of (Psd, list of str)
|
The density on lines, read as a density per line
( |
Raises:
| Type | Description |
|---|---|
ValueError
|
When a cross term varies with frequency (the sheet holds one
coherence and phase per pair, so it would be lost), or as
|
Source code in src/visualdynamics/core/author.py
uniform_spacing
¶
The spacing of evenly spaced lines, in Hz, or None when they are not.
A controller writes its target at multiples of one spacing; a
breakpoint specification is at whatever frequencies it was written
at. Helper lines (just below a breakpoint, holding a band step; see
SpecificationDraft.with_band_corners) are not on the grid and are
ignored. Fewer than three lines gives None.
Source code in src/visualdynamics/core/author.py
read_at_lines
¶
A specification record read at new lines.
At its own lines the record keeps its own values. Between them it
is interpolated the way a specification is read, so a line the
sheet added does not change what a channel the sheet does not hold
means: a cross term by compliance.cross_term_at (the magnitude
log-log between points above zero, straight through a zero, the
phase linearly), a real record by its magnitude log-log over the
points above zero. Outside its range it takes its end values.