visualdynamics.core.dwell¶
dwell
¶
A dwell read against time: how the level builds, holds and rings down.
A dwell holds one tone at one frequency, and what a test engineer wants from it is a picture against time rather than frequency. A sweep's level is read against frequency because the frequency is what changes; a dwell's frequency does not change, so against frequency its level is one point, and the story it tells is in time. At a resonance the response does not reach its steady height when the tone arrives: it builds cycle by cycle, and when the tone stops it rings down at the same pace. For a mode of quality factor Q driven at its own frequency from rest, the share of the steady height reached after n cycles is very nearly 1 - exp(-pi n / Q), so after Q cycles it is 1 - exp(-pi), 95.7 %, and after 2Q cycles 99.8 %, whatever the frequency or the Q; and n cycles after the tone stops, exp(-pi n / Q) of it remains. That count, about Q cycles to build and about Q to die away, is why a sweep must spend Q cycles near a resonance to read it, why a few cycles of a transient never bring a sharp mode to its full response, and how long a dwell's first seconds are spent arriving rather than holding.
read_dwell reads one dwell of a sine specification on one channel of
a recording with the tracking detectors of core.sine_tracking (the
peak over each cycle, unfiltered, by default; any SineTracking
setting may be given) at the end of every cycle of the dwell, and on at
the dwell's frequency after the tone stops, to the end of the record.
It returns a DwellReading: the level against time, the steady level
the dwell reached, the cycles it took to reach a stated share of it (95 %
by default), and the cycles after the stop for the level to fall to the
complement of that share (5 %), so the build-up and the ring-down are
read by one rule. DwellReading.share_at and remaining_at read the
level at any count of cycles into the dwell or after the stop.
The steady level is the median of the readings over the dwell's last
quarter, which is a reading of the record and not a model of it: a
dwell too short to settle, or a resonance that moved during it, reaches
a steady level that is not the mode's, and the reading says so
(DwellReading.settled, and a line in notes) rather than borrowing a
number from a formula. Two other things are said rather than hidden: a
dwell that a sweep runs into does not start from rest, so its build-up
is the rest of an arrival, and a dwell that a sweep leaves does not
stop, so nothing rings down from a stop and no ring-down is read.
The readings are taken at the dwell's own whole cycles, counted from its start in the record and, after the stop, from the stop, so the peak in cycle n covers exactly that cycle. A peak is the peak of the samples, as a sampled controller reads it, and under-reads a sine by at most cos(pi x frequency / sample rate), 0.01 % at 200 samples a cycle.
A reading is reported at the end of the span it reads, but it stands for
the response somewhere inside that span, and where depends on the
detector and on which way the level is going. The peak over a cycle of
a rising level is that cycle's last crest, at its end; over a cycle of a
falling level it is the first crest, at its start, a whole cycle before
the reading is reported. RMS and mean average the span and stand for
its middle either way; the band's own output stands at its instant, its
lag the filter's and the same both ways. Counted on the reported clock,
the peak detector's ring-down would read a cycle longer than the
build-up for no reason in the response. So each reading is also placed
at the instant it stands for
(DwellReading.stands, the reported time less LAG_RISING or
LAG_FALLING spans), and every number the reading gives is read on that
clock: the two counts, share_at and remaining_at, and the plot. The
build-up and the ring-down of one Q then read alike, and each number is
the response's rather than the detector's late report of it: Q cycles
after the stop, 4.3 % (exp(-pi)) remains, where the peak over the
thirtieth cycle after the stop, reported at its end, says 4.8 %.
References
The build-up and the free decay are the transient and the free response of a damped one-degree-of-freedom system, a standard result; these are where it and the dwell test it is read for are set out.
- Piersol, A. G., & Paez, T. L. (Eds.) (2010). Harris' Shock and Vibration Handbook, 6th ed. McGraw-Hill. Basic vibration theory: the free vibration of a damped one-degree-of-freedom system, decaying as exp(-zeta omega t) and read as the logarithmic decrement, and its response to a harmonic force.
- Department of Defense (2019). MIL-STD-810H, Environmental Engineering Considerations and Laboratory Tests. Method 514.8, paragraph 4.2.1.1: resonance dwells, held on the resonance as it moves by searching for the largest response or by holding the phase between the control and monitoring points.
Classes:
| Name | Description |
|---|---|
DwellReading |
One dwell's level against time on one channel: what |
Functions:
| Name | Description |
|---|---|
default_channel |
The channel |
read_dwell |
Read a dwell's level against time: the build-up, the steady |
Classes¶
DwellReading
dataclass
¶
DwellReading(*, tone: str, segment: int, dof: str, dimension: str, unit: str | None, setting: SineTracking, frequency: float, onset: float, start: float, stop: float, seconds: ndarray, level: ndarray, stands: ndarray, share: float, steady: float, settled: bool, built: float | None, rung: float | None, stops: bool, notes: tuple[str, ...] = ())
One dwell's level against time on one channel: what
read_dwell returns.
Times are seconds into the recording, from its first sample, the
clock onset is given on and SineLevel.seconds is stamped on.
seconds and level hold every reading, in the dwell and after
the stop, reported at the end of each whole cycle; level is in the
record's own units (SI), as the tracking detector read it, and
stands is the instant each reading stands for (the detector's lag
taken out, LAG_RISING in the dwell and LAG_FALLING after it).
steady is the level the dwell reached (the median over its last
STEADY_SPAN), and settled whether it held there (the median of
that span's second half within half of 1 - share of its first
half's). built is the cycles from the dwell's start to share of
it and rung the cycles from the stop down to 1 - share of it,
each interpolated on the stands clock, or None where the record
does not say (a record that starts after the dwell has built, a
dwell that a sweep leaves, a record that ends first).
unit is the unit the record declared, kept as metadata; the
numbers are SI whatever it says.
notes holds what the reading cannot be trusted for, as text, empty
when it is clean. Two of these compare equal only if they are the
same object, as TrackedWaveform does, since the arrays have no
single truth value.
Methods:
| Name | Description |
|---|---|
share_at |
The level |
remaining_at |
The level |
describe |
The reading in one line, such as 'steady 294.3 m/s², 95 % in |
Attributes:
| Name | Type | Description |
|---|---|---|
cycles |
ndarray
|
Each reading's count of the dwell's cycles since its start: |
held |
ndarray
|
True where a reading is inside the dwell (at or before the |
after |
ndarray
|
Each reading's count of cycles since the stop: negative |
built_seconds |
float | None
|
|
rung_seconds |
float | None
|
|
Attributes¶
cycles
property
¶
Each reading's count of the dwell's cycles since its start: whole numbers through the dwell, and on past the stop.
held
property
¶
True where a reading is inside the dwell (at or before the stop), False where it is in the ring-down.
after
property
¶
Each reading's count of cycles since the stop: negative inside the dwell, whole numbers in the ring-down.
Methods:¶
share_at
¶
The level cycles cycles into the dwell, as a share of the
steady level: the response itself, each reading placed where it
stands (stands) and interpolated between them. Raises
ValueError outside the dwell's readings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cycles
|
float
|
Cycles of the dwell's frequency since its start. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The share, 1.0 at the steady level. |
Source code in src/visualdynamics/core/dwell.py
remaining_at
¶
The level cycles cycles after the stop, as a share of the
steady level: what remains of the response once the tone has
gone, each reading placed where it stands (stands), so Q cycles
after the stop it is exp(-pi), 4.3 %, whatever the detector.
Raises ValueError where the ring-down was not read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cycles
|
float
|
Cycles of the dwell's frequency since the stop. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The share remaining. |
Source code in src/visualdynamics/core/dwell.py
describe
¶
The reading in one line, such as 'steady 294.3 m/s², 95 % in 28.6 cycles (1.43 s), down to 5 % 28.6 cycles after the stop'.
The steady level is in SI by default, or in a unit system's display units when one is given.
Source code in src/visualdynamics/core/dwell.py
Functions:¶
default_channel
¶
default_channel(history: Any, specification: SineSweepSpecification) -> str
The channel read_dwell reads when none is named: the first the
specification does not control, since a dwell's build-up is a
response's (the control is held at its level by the controller, and
barely builds), else the first control channel. Raises ValueError
when the recording carries neither.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
history
|
TimeHistory
|
The recording. |
required |
specification
|
SineSweepSpecification
|
Whose control channels are passed over. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The channel's DOF. |
Source code in src/visualdynamics/core/dwell.py
read_dwell
¶
read_dwell(history: Any, specification: SineSweepSpecification, *, tone: str | None = None, segment: int | None = None, channel: str | None = None, setting: SineTracking | None = None, share: float = DWELL_SHARE, onset: float | None = None, after: float | None = None) -> DwellReading
Read a dwell's level against time: the build-up, the steady level and the ring-down after the tone stops.
The tone is placed on the recording where it begins (found by
matched filter on the control channels, as track_sine finds it,
or at onset seconds into the recording), and the channel is read
with the tracking setting at the end of every whole cycle of the
dwell's frequency from the dwell's start to its stop, then from the
stop on at the same frequency until the record ends (or after
seconds past the stop). The steady level is the median of the
readings over the dwell's last STEADY_SPAN; share of it marks
the build-up and 1 - share the ring-down, each counted where the
readings stand (LAG_RISING, LAG_FALLING). A dwell is a segment
that sweeps no more than DWELL_SPAN of its frequency
(SineTone.is_dwell), the form SineTone.dwell and a controller's
file both give it.
Raises ValueError when no tone holds a dwell, when the named tone or
segment is not one, when share is not between zero and one, when
the recording is not evenly sampled or lacks the channel, when it
holds no whole cycle of the dwell, or when the channel reads no level
over the dwell's last quarter (zero, as a dead channel reads, or not
a number).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
history
|
TimeHistory
|
The recording, evenly sampled. |
required |
specification
|
SineSweepSpecification
|
What the drive followed; one of its tones holds the dwell. |
required |
tone
|
str
|
Which tone; the first that holds a dwell by default. |
None
|
segment
|
int
|
Which of the tone's segments; its first dwell by default. |
None
|
channel
|
str
|
The DOF read. By default the first channel the specification does not control, a response, since a controlled channel is held at its level and does not build; else the first control channel. |
None
|
setting
|
SineTracking
|
How each cycle is read: the peak over the cycle, unfiltered, by
default; any band and detector |
None
|
share
|
float
|
The share of the steady level the build-up is read to; the ring-down is read down to one minus it. |
`DWELL_SHARE`
|
onset
|
float
|
Seconds into the recording where the tone begins (its own time zero, not the dwell's when a sweep comes first). Found by matched filter when omitted. |
None
|
after
|
float
|
Seconds of ring-down to read past the stop; to the record's end by default. |
None
|
Returns:
| Type | Description |
|---|---|
DwellReading
|
The readings against time, the steady level and the two counts, with notes on anything they cannot be trusted for. |
Source code in src/visualdynamics/core/dwell.py
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 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 | |