visualdynamics.core.time_statistics¶
time_statistics
¶
The statistics of a record read off its time history.
A random test is specified as a spectrum, and the spectrum keeps only how the mean square is spread across frequency. Squaring throws away the sign, the frequency axis throws away when things happened, and the average over frames dilutes anything that happened in a few of them. Clipping, dropouts, spikes, offsets and a loosening mount live in what was thrown away, and the time history still has them. So a record is read in the time domain before its spectrum is trusted, and these are the numbers that reading is made of:
- The mean, against the standard deviation. A vibration record sits on zero; a mean well away from it is a bias, a channel still settling, or a zero shift. The rms barely moves with it, which is why the mean is read on its own.
- The rms, the standard deviation, the skewness and the kurtosis: the
second, third and fourth moments. A Gaussian record has a skewness of
0 and a (Pearson) kurtosis of 3 (
core.kurtosis). - The crest factor, the largest excursion over the rms, with the largest peak and the time it happened.
- How many separate excursions reach the record's own peak, and, when the channel's range is given, how many samples sit on the rail: within a stated margin of the range. A Gaussian record reaches its peak once; a clipped one has a flat top on every excursion that reached the edge. Excursions are counted, not samples, because a record sampled well above its band puts several samples on the top of every peak.
- How many samples are not finite. They are left out of every other number, and counted so that leaving them out is never silent.
- The share of samples beyond 3, 4 and 5 standard deviations, beside the share a Gaussian puts there (0.27 %, 0.0063 % and 0.000057 %).
- The rate the record crosses its mean going upward, counted, and the same rate from its spectrum by Rice's formula, the square root of the spectrum's second moment over its area.
- The expected largest peak of a Gaussian process at that rate over a stated duration, in standard deviations: sqrt(2 ln(nu0 T)). It grows with the length of a run, slowly: at 1,000 crossings a second about 4.7 for a minute and 5.5 for an hour.
- The kurtosis frame by frame. A short fault barely moves the kurtosis of a long record, and the frame it is in stands out. A frame that does not vary at all, a dropout, has no kurtosis and is outside its band.
record_statistics reads one channel of a TimeHistory (also
TimeHistory.time_statistics) over the same span core.kurtosis reads
it over, so the kurtosis here and the kurtosis bars agree to the last
digit. time_statistics reads a plain array. Both return a
TimeStatistics, which carries every number, the bands each was judged
against and which ones fell outside.
The bands. Each judged statistic has a band, and every band is an argument, because a band is a choice a procedure makes and no number here can make it for the reader:
- the kurtosis of the record,
KURTOSIS_BAND, 2 to 4 by default, the kurtosis bars' own band. It is set for rattles and spikes, and it does not see clipping: a Gaussian record clipped at 2.8 standard deviations reads about 2.86 and one clipped at 2.5 about 2.76, both inside it, and a real record at 2.86 is ordinary. Clipping is found by the samples on the rail and the crest factor, which is why they are read beside it. A procedure that wants the kurtosis to see a clip sets the band tighter: a whole record scatters little about 3 (the estimator's standard error is about sqrt(24/N), 0.02 at 60,000 samples), so 2.9 to 3.1 holds a clean record of ordinary length. - the kurtosis of each frame,
FRAME_BAND, 2 to 4,core.kurtosis's own band. A frame's scatter is set by how many independent values it holds, which is its length times the record's statistical bandwidth (statistical_bandwidth), so the frame is sized from the bandwidth: at leastFRAME_SECONDS, and long enough to holdFRAME_PRODUCTbandwidth-seconds, where its kurtosis scatters by about 0.15. A narrow-band record needs long frames, and a record shorter than one frame has none to judge. - the skewness,
SKEWNESS_BAND, and the mean as a share of the standard deviation,OFFSET_SHARE. - the crest factor,
CREST_BAND, 3 to 6. Below 3 the peaks were cut off somewhere; above 6 a Gaussian record practically never goes, and spikes do. - the samples on the rail,
RAIL_SAMPLES: none. A sample that reached the edge of the range is a sample whose true value is not known. - the excursions at the record's own peak,
PEAK_RUNS: two, since a second peak can come within the margin of the first. - the samples that are not finite: none.
- the share beyond each sigma, judged against the Gaussian's share when
a Gaussian would put at least
MIN_EXPECTEDindependent values there, and flagged when the two differ by more thanTAIL_RATIOeither way. Independent values, not samples, because neighboring samples of a record are not independent: one excursion beyond the level puts several samples there, and a narrow-band record's excursions come in clumps, a few cycles of one swell of its envelope. A record holds about twice its statistical bandwidth times its length in independent values, however fast it was sampled.
References
The moments, the Gaussian tails, the crossing rate and the expected
largest peak are standard results; this is where they are set out. The
skewness and kurtosis are core.kurtosis's estimators, which cites
them.
- Bendat, J. S., & Piersol, A. G. (2010). Random Data: Analysis and Measurement Procedures, 4th ed. Wiley. The moments of a record, the Gaussian probability density, Rice's zero-crossing rate from the spectrum's moments, the expected largest peak of a stationary Gaussian process over a duration, and the statistical bandwidth that sets how many independent values a stretch of record holds.
Classes:
| Name | Description |
|---|---|
Tail |
The samples beyond one multiple of the standard deviation. |
TimeStatistics |
Every number the time-domain reading of one record gives, the |
Functions:
| Name | Description |
|---|---|
gaussian_share |
The share of a Gaussian's values further than |
rice_rate |
Upward crossings of the mean per second of a Gaussian process |
statistical_bandwidth |
The statistical bandwidth of a process with this one-sided |
expected_largest_peak |
The expected largest peak of a Gaussian process, in standard |
statistic_name |
The name a table gives a judged statistic, by its key: a tail |
time_statistics |
Read one record's statistics in the time domain. |
record_statistics |
Read one channel of a time history in the time domain. |
Classes¶
Tail
dataclass
¶
Tail(sigmas: float, count: int, share: float, expected: float, judged: bool, ratio: float = TAIL_RATIO, independent: float = float('nan'))
The samples beyond one multiple of the standard deviation.
share is the record's, expected the Gaussian's, both as
fractions of the samples read. independent is how many
independent values a Gaussian of the record's bandwidth and length
would put there; judged says that is enough for the comparison
to mean something (MIN_EXPECTED), and flagged that it was judged
and the two shares differ by more than ratio either way.
Attributes:
| Name | Type | Description |
|---|---|---|
flagged |
bool
|
Whether the share beyond is outside the Gaussian's by more |
TimeStatistics
dataclass
¶
TimeStatistics(samples: int, sample_rate: float, mean: float, rms: float, std: float, skewness: float, kurtosis: float, peak: float, peak_time: float, peak_sigmas: float, at_peak: int, rail: int | None, full_scale: float | None, margin: float, tails: tuple[Tail, ...], crossings: float, spectral_crossings: float, duration: float, bandwidth: float, frame_length: int, frame_times: ndarray, frame_kurtosis: ndarray, kurtosis_band: tuple[float, float] = KURTOSIS_BAND, frame_band: tuple[float, float] = FRAME_BAND, skewness_band: tuple[float, float] = SKEWNESS_BAND, offset_share: float = OFFSET_SHARE, crest_band: tuple[float, float] = CREST_BAND, rail_samples: int = RAIL_SAMPLES, peak_runs: int = PEAK_RUNS, nonfinite: int = 0)
Every number the time-domain reading of one record gives, the bands they were judged against, and which fell outside.
Values (mean, rms, std, peak, full_scale) are in the
record's own units: SI for a channel of a TimeHistory, as it is
stored. Shares are fractions, rates are per second, times are on
the record's clock in seconds. rail is None when no range was
given.
Methods:
| Name | Description |
|---|---|
flags |
Each judged statistic, by key, and whether it fell outside |
describe |
The judgement in words: what fell outside its band, or that |
Attributes:
| Name | Type | Description |
|---|---|---|
record_length |
float
|
The seconds read: the samples over the sample rate. |
crest |
float
|
The crest factor: the largest excursion over the rms. |
rail_share |
float | None
|
The samples on the rail, as a share; None without a range. |
headroom |
float | None
|
The range over the largest excursion; None without a range. |
expected_peak |
float
|
The expected largest peak over |
expected_peak_here |
float
|
The same over the record's own length, to set beside |
worst_frame |
tuple[float, float] | None
|
(time, kurtosis) of the frame furthest from 3; None when the |
frames_outside_mask |
ndarray
|
Which frames are outside |
frames_outside |
int
|
How many frames read outside |
flagged |
list[str]
|
The keys of the statistics outside their bands, in |
Attributes¶
rail_share
property
¶
The samples on the rail, as a share; None without a range.
headroom
property
¶
The range over the largest excursion; None without a range. Below one, the range was reached.
expected_peak
property
¶
The expected largest peak over duration, in standard
deviations, at the spectrum's crossing rate.
expected_peak_here
property
¶
The same over the record's own length, to set beside
peak_sigmas.
worst_frame
property
¶
(time, kurtosis) of the frame furthest from 3; None when the record is shorter than a frame. A frame with no kurtosis (one that does not vary, a dropout) is furthest of all, and is given with a kurtosis of NaN.
frames_outside_mask
property
¶
Which frames are outside frame_band, a frame with no
kurtosis among them.
frames_outside
property
¶
How many frames read outside frame_band, a frame with no
kurtosis counted as outside it.
flagged
property
¶
The keys of the statistics outside their bands, in
STATISTICS order.
Methods:¶
flags
¶
Each judged statistic, by key, and whether it fell outside
its band. The keys are STATISTICS keys; the rail is judged
only when a range was given, the frames only when the record
holds one, and a tail only where a Gaussian crosses into it
often enough for the count to mean something. A moment
that has no value (a dead channel's kurtosis, a crest factor
with no rms) is outside its band: a record with no variance is
not a Gaussian one.
Source code in src/visualdynamics/core/time_statistics.py
describe
¶
The judgement in words: what fell outside its band, or that nothing did.
Source code in src/visualdynamics/core/time_statistics.py
Functions:¶
gaussian_share
¶
The share of a Gaussian's values further than sigmas standard
deviations from its mean, either side: 0.27 % beyond 3.
rice_rate
¶
Upward crossings of the mean per second of a Gaussian process with this one-sided spectrum: sqrt(m2 / m0), Rice's formula.
density is any one-sided spectrum of the process on the
frequencies frequency in Hz (an autospectrum, a specification's
levels on a fine grid, a periodogram), evenly spaced or not: the
moments are taken by the trapezoid rule, so the units and the line
spacing cancel. A flat profile from 20 to 2,000 Hz crosses about
1,160 times a second. NaN when the spectrum has no area.
Source code in src/visualdynamics/core/time_statistics.py
statistical_bandwidth
¶
The statistical bandwidth of a process with this one-sided spectrum, in Hz: the square of its area over the area of its square, (integral G)^2 / integral G^2.
It is the width of the flat band that holds as many independent values a second, and so it sets how much an estimate made over a stretch of the record scatters. A flat band is its own width; a single mode of natural frequency fn and damping ratio zeta is 2 pi zeta fn, 12.6 Hz at 100 Hz and 2 %. NaN when the spectrum has no area.
Source code in src/visualdynamics/core/time_statistics.py
expected_largest_peak
¶
The expected largest peak of a Gaussian process, in standard
deviations, over duration seconds at rate upward crossings a
second: sqrt(2 ln(rate * duration)).
The leading term of the standard result; a run typically reaches a little more. About 4.7 for a minute and 5.5 for an hour at 1,000 crossings a second. NaN when the run holds one crossing or fewer, where the formula says nothing.
Source code in src/visualdynamics/core/time_statistics.py
statistic_name
¶
The name a table gives a judged statistic, by its key: a tail
beyond a sigma SIGMAS does not hold is named as the others are.
Source code in src/visualdynamics/core/time_statistics.py
time_statistics
¶
time_statistics(values: ArrayLike, sample_rate: float, *, start: float = 0.0, spans: Sequence[tuple[int, int]] | None = None, full_scale: float | None = None, margin: float = RAIL_MARGIN, frame: float | None = None, duration: float | None = None, kurtosis_band: Sequence[float] | None = None, frame_band: Sequence[float] | None = None, skewness_band: Sequence[float] | None = None, offset_share: float = OFFSET_SHARE, crest_band: Sequence[float] | None = None, rail_samples: int = RAIL_SAMPLES, peak_runs: int = PEAK_RUNS, sigmas: Sequence[float] = SIGMAS, tail_ratio: float = TAIL_RATIO) -> TimeStatistics
Read one record's statistics in the time domain.
The moments, the crest factor and its peak, the excursions at the peak, the samples on the rail and those not finite, the tails beyond each sigma, the crossing rates, the expected largest peak and the kurtosis frame by frame, each judged against its band (the module docstring says what each is and why its band is where it is).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
array_like
|
The record, one channel, evenly sampled. Complex values are
read by their real part, as |
required |
sample_rate
|
float
|
Samples per second. |
required |
start
|
float
|
The first sample's time, in seconds, so the peak and the frames are placed on the record's own clock. |
0.0
|
spans
|
sequence of (int, int)
|
Sample ranges to read, first inclusive and last exclusive; the
whole record by default. Several are read together, as
|
None
|
full_scale
|
float
|
The channel's range, in the units of |
None
|
margin
|
float
|
How close to the range, and to the record's own peak, a sample counts as on it, as a share. |
`RAIL_MARGIN`
|
frame
|
float
|
Seconds to a frame for the kurtosis against time; rounded to
whole samples. By default it is sized from the record's
statistical bandwidth: |
None
|
duration
|
float
|
Seconds the expected largest peak is for; the record's length by default. |
None
|
kurtosis_band
|
(float, float)
|
The bands, |
None
|
frame_band
|
(float, float)
|
The bands, |
None
|
skewness_band
|
(float, float)
|
The bands, |
None
|
crest_band
|
(float, float)
|
The bands, |
None
|
offset_share
|
float
|
How far the mean may sit from zero, as a share of the standard deviation. |
`OFFSET_SHARE`
|
rail_samples
|
int
|
The most samples allowed on the rail. |
`RAIL_SAMPLES`
|
peak_runs
|
int
|
The most separate excursions allowed at the record's own peak. |
`PEAK_RUNS`
|
sigmas
|
sequence of float
|
The multiples of the standard deviation the tails are counted beyond. |
`SIGMAS`
|
tail_ratio
|
float
|
How far a tail's share may be from the Gaussian's, as a ratio either way. |
`TAIL_RATIO`
|
Returns:
| Type | Description |
|---|---|
TimeStatistics
|
Every number, the bands and the flags. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the record has fewer than two samples, the sample rate is not positive, a band runs backwards, the range is not positive, or the frame holds fewer than two samples. |
Source code in src/visualdynamics/core/time_statistics.py
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 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 776 777 778 779 780 781 782 783 784 785 786 787 788 789 | |
record_statistics
¶
record_statistics(history: TimeHistory, record: int = 0, **options) -> TimeStatistics
Read one channel of a time history in the time domain.
Over the span core.kurtosis.analyzed_span names (the frames the
spectra are averaged over, the shock windows, or the whole record),
so the kurtosis here is the kurtosis bar's to the last digit. Values
are in SI, as the record stores them, and so is full_scale: a
25 g range on an acceleration channel is 25 * 9.80665.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
history
|
TimeHistory
|
The record. |
required |
record
|
int
|
Which channel, counting from 0. |
0
|
**options
|
As |
{}
|
Returns:
| Type | Description |
|---|---|
TimeStatistics
|
Every number, the bands and the flags. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the record is not evenly sampled, or as |