`harmos-signal`
Purpose
Section titled “Purpose”This crate is the shared mathematics of measurement: the transform between a signal's two domains, the readings taken off each, the reductions that fit a long capture into a short display, and one mergeable fold of a run of samples.
It is kernels rather than containers. Every function takes the slices a caller
already has and answers a value, a Vec, or the indices it selected, so two
applications with two different series types share one implementation. Nothing here
owns, shares, locks, or caches anything.
It depends on rustfft and std. It does not depend on harmos, and it must
not: the runtime's read path stays algorithm-free, and this crate stays liftable
into a repository of its own unchanged.
Public Surface
Section titled “Public Surface”Thirty-eight names, counted by crates/harmos-signal/tests/census.rs.
The frequency domain:
transformturns real samples into one amplitude-normalizedSpectrum.reconstructinverts it, optionally through oneBand.Welchaverages overlapping periodograms into anEstimate.Taperis the window applied to samples before a transform.magnitude,phase, andbinsare the readings and the axis.peaks,harmonics,fundamental, andthdfind the components and the distortion.band_energy,band_rms,centroid,papr,rolloff, andoccupied_bandwidthmeasure one band.Decibelconverts against a reference, andScalesays what arithmetic between two columns lands in.
The time domain:
lttb,lttb_log,decimate,extrema, andabove_floorchoose which samples to keep.value_at,resample,resample_uniform,resample_count, andnearestread between them.derivativeandintegralare the rate and the accumulation.edgestriggers with hysteresis and answersEdgevalues;crossingis the plain first one.Summaryfolds a run of samples into accumulators that merge.
Data Flow
Section titled “Data Flow”A caller hands transform its samples and a sampling rate and receives a
Spectrum: a bin step and two columns, normalized so a tone landing on a bin
reads its own amplitude whichever taper measured it. reconstruct undoes
exactly that normalization, so a transform and its reconstruction return the
samples — and scaling the bins by a Band on the way through is how a
band-limited copy is produced without designing a filter. Welch runs the same
transform over overlapping segments and averages their power, which buys a
quieter estimate and spends the phase.
Every reading takes slices. A reducer answers the indices it selected, so the
caller gathers whichever of its own columns it keeps and reducers compose by
mapping one answer through the next. Summary is the only accumulator, and it
merges: the summary of two runs is a function of their two summaries, never of
their samples.
Design Rules
Section titled “Design Rules”- Kernels take slices and never a container; a caller's own series type is never converted to call one.
Spectrumis a transparent record — public fields, no identity, no cache — and exists because a transform must answer something, not to own data.- A reduction answers indices. Values would pick which columns matter, and the caller is the one that knows.
- An averaged estimate carries no phase. Welch's method discards it, and a spectrum with an invented zero imaginary part would reconstruct to something that was never measured.
- Degenerate input answers an empty or absent result. The crate has no error type, and therefore no error dependency.
- Statistics merge or they are not here:
Summarycarries the accumulators harmos'sBucketcarries, and its variance is Welford's rather than the difference of two large sums.
Known Gaps
Section titled “Known Gaps”This crate is measurement math, not a data engine. The test for anything proposed for it: does it compute a property of a signal — a spectrum, an envelope, a crossing, a reduction, a calibrated conversion — or does it arrange data? Tables, joins, group-by, lazy pipelines, generic aggregation frameworks, and columnar containers are a DataFrame's work, which meti left behind to arrive at exactly this content; an application needing relational row manipulation reaches for a DataFrame of its own, above the runtime's algorithm-free reads.
Interpolation is linear and clamps outside the sampled span. Statistics that cannot merge — medians and percentiles — are deliberately absent, as they are from the accumulators of harmos's served tier. There is no filter design, no resampling that band-limits, and no window overlap-add.