Harmonic spectrum#

Per-frequency harmonicity H(f) on a single signal. This is the H-only entry point of biotuner’s spectral resonance machinery.

Quick start#

from biotuner.harmonic_spectrum import compute_harmonic_spectrum

freqs, H, S, summary = compute_harmonic_spectrum(
    signal, precision_hz=0.5, fmin=2, fmax=30, fs=1000,
)
# H       — per-frequency harmonicity spectrum  (n_freqs,)
# S       — N×N kernel similarity matrix
# summary — dict of complexity metrics (flatness, entropy, higuchi, ...)

Sister modules#

For the full H × PC = R pipeline (with surrogate normalization, swappable kernels, and higher-order coupling extensions), use biotuner.resonance.compute_resonance().

For cross-channel analyses (two-or-more signals), use biotuner.harmonic_connectivity.

Public API#

  • compute_harmonic_spectrum() — main entry point

  • harmonicity_matrices() — N×N similarity matrix (legacy helper)

  • compute_harmonic_power() — probability-weighted reduction of S to H(f)

  • find_spectral_peaks() — peak detector (shared across the resonance package)

  • harmonic_entropy() — complexity DataFrame for H / PC / R together

  • get_harmonic_ratio() — best (n, m) within tolerance for a freq pair

  • count_theoretical_harmonic_partners() — bandwidth-correction helper

biotuner.harmonic_spectrum — harmonicity-field computations from PSDs.

Module type: Functions

This module is the H-only entry point of biotuner’s spectral resonance machinery. For per-frequency harmonicity H(f) on a single signal, this is the right module.

Quick start#

from biotuner.harmonic_spectrum import compute_harmonic_spectrum

freqs, H, S, summary = compute_harmonic_spectrum(
    signal, precision_hz=0.5, fmin=2, fmax=30, fs=1000,
)
# H        — per-frequency harmonicity spectrum  (n_freqs,)
# S        — N×N kernel similarity matrix
# summary  — dict of complexity metrics (flatness, entropy, higuchi, ...)

Sister modules#

  • biotuner.resonance — full H × PC = R pipeline with surrogate normalization, swappable kernels, and higher-order coupling extensions. Use compute_resonance(signal, sf, config=...) when you want the full per-frequency resonance spectrum, not just H(f).

  • biotuner.harmonic_connectivity — cross-channel analogs. Use compute_cross_resonance(sig1, sig2, sf) for two signals, harmonic_connectivity(...).compute_cross_resonance_connectivity(...) for N-channel matrices.

Public API#

compute_harmonic_spectrum(signal, precision_hz, *, fmin=1, fmax=30, fs=1000, noverlap=1, smoothness=1, smoothness_harm=1, power_law_remove=True, harmonic_kernel='harmsim', harmonic_kernel_params=None, n_peaks=5, normalize=True, bandwidth_correction=False, psd_normalization='minmax_prob', legacy_self_pair_subtract=True)[source]#

Compute the harmonicity spectrum H(f) and its complexity summary.

This is the narrow, H-only entry point — replaces the harmonicity portion of the legacy compute_global_harmonicity. For the full H/PC/R triple use biotuner.resonance.compute_resonance().

Under the hood this dispatches the harmonic kernel from the biotuner.resonance registry, so all kernels added in later phases (sethares, stolzenburg, harmonic_entropy, hopf, lorentzian) become available automatically by name.

Parameters:
  • signal (1-D array)

  • precision_hz (float)

  • fmin, fmax (float)

  • fs (int, sampling frequency)

  • noverlap (int, STFT overlap)

  • smoothness (float, divides STFT nperseg)

  • smoothness_harm (float, Gaussian smoothing on H before summary)

  • power_law_remove (bool, FOOOF aperiodic removal)

  • harmonic_kernel (str, name in biotuner.resonance.registry.HARMONIC_KERNELS) – 'harmsim' (default) | 'subharm_tension' (legacy) | future kernels.

  • harmonic_kernel_params (dict, passed to the kernel)

  • n_peaks (int, peaks returned by the summary)

  • normalize (bool, legacy normalize flag for the per-bin reducer)

  • bandwidth_correction (bool, legacy bandwidth correction)

  • psd_normalization (‘minmax_prob’ (legacy) | ‘prob’ | ‘none’)

  • legacy_self_pair_subtract (bool, reproduce legacy self-pair-subtract reducer)

Returns:

  • freqs (ndarray (n_freqs,))

  • H_values (ndarray (n_freqs,) – the harmonicity spectrum)

  • harmonicity_matrix (ndarray (n_freqs, n_freqs) – the kernel similarity matrix)

  • summary (dict) – spectrum_complexity output: flatness, entropy, spread, higuchi, peaks, peak_indices, avg, max, peaks_avg, peak_harmsim, peak_harmsim_avg, peak_harmsim_max.

Examples

>>> freqs, H, M, summary = compute_harmonic_spectrum(signal, 0.5, fmin=2, fmax=30)
>>> summary['flatness'], summary['entropy'], summary['peaks']
harmonicity_matrices(freqs, metric='harmsim', n_harms=5, delta_lim=150, min_notes=2)[source]#

Compute harmonicity matrix of frequencies.

Parameters:
  • freqs (ndarray) – Array of frequencies.

  • metric (str, optional) – The metric to compute dyad similarity. Default is ‘harmsim’.

  • n_harms (int, optional) – The number of harmonics. Default is 5.

  • delta_lim (int, optional) – The delta limit. Default is 150.

  • min_notes (int, optional) – The minimum number of notes. Default is 2.

Returns:

ndarray – The harmonicity matrix.

See also

biotuner.resonance.kernels_harmonic.kernel_harmsim

new strategy-registry version with the same numerics, plus support for additional kernels (sethares, stolzenburg, harmonic_entropy, hopf, lorentzian) in later phases.

compute_harmonic_power(freqs, dyad_similarities, psd_clean, normalize=True, bandwidth_correction=False, fmin=1, fmax=30)[source]#

Compute harmonicity as probability-weighted average of dyad similarities.

The harmonicity of frequency i represents the expected harmonic similarity with other frequencies, weighted by the joint probability of observing each frequency pair. This formulation is scale-invariant and not sensitive to spectral shape or total power distribution.

Parameters:
  • freqs (ndarray) – Array of frequencies.

  • dyad_similarities (ndarray) – Dyad similarities matrix.

  • psd_clean (ndarray) – The cleaned Power Spectral Density (PSD).

  • normalize (bool, default=True) – If True, compute harmonicity as weighted average (recommended). If False, compute as sum of weighted harmonic contributions.

  • bandwidth_correction (bool, default=False) – If True, apply correction for bandwidth bias where lower frequencies have more potential harmonic partners within the analysis range.

  • fmin (float, default=1) – Minimum frequency of analysis bandwidth (used for bandwidth correction).

  • fmax (float, default=30) – Maximum frequency of analysis bandwidth (used for bandwidth correction).

Returns:

tuple of ndarrays – The harmonicity values and the harmonicity matrix.

See also

biotuner.resonance.coupling.reduce_matrix_to_spectrum

strategy-registry version supporting both the legacy self-pair-subtract reduction and the clean off-diagonal-mask reduction recommended for new code.

Notes

The weighting uses psd_prob[i] * psd_prob[j] which requires both frequencies to have high power for high harmonicity contribution.

find_spectral_peaks(values, freqs, n_peaks, prominence_threshold=0.5)[source]#

Identify the prominent spectral peaks in a frequency spectrum.

This function uses the peak prominence to select the most notable peaks, and returns their frequencies and indices. Prominence is a measure of how much a peak stands out due to its intrinsic height and its location relative to other peaks.

Parameters:
  • values (array_like) – 1-D array of values for the frequency spectrum.

  • freqs (array_like) – 1-D array of frequencies corresponding to the values in ‘values’.

  • n_peaks (int) – The number of top prominent peaks to return.

  • prominence_threshold (float, default=0.5) – The minimum prominence a peak must have to be considered notable.

Returns:

  • peak_frequencies (ndarray) – Frequencies of the ‘n_peaks’ most prominent peaks.

  • prominent_peaks (ndarray) – Indices in ‘values’ and ‘freqs’ of the ‘n_peaks’ most prominent peaks.

See also

scipy.signal.find_peaks, scipy.signal.peak_prominences

Examples

>>> values = np.array([0, 1, 0, 2, 0, 3, 0, 2, 0, 1, 0])
>>> freqs = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110])
>>> find_spectral_peaks(values, freqs, n_peaks=3)
(array([60, 40, 80]), array([5, 3, 7]))
harmonic_entropy(freqs, harmonicity_values, phase_coupling_values, resonance_values)[source]#

Compute spectral features and Higuchi Fractal Dimension of Harmonicity, Phase Coupling, and Resonance spectra.

This function calculates several spectral properties: flatness, entropy, spread, and Higuchi Fractal Dimension for three input spectra: Harmonicity, Phase Coupling, and Resonance. Results are returned as a pandas DataFrame.

Parameters:
  • freqs (array_like) – 1-D array of frequencies common for all the spectra.

  • harmonicity_values (array_like) – 1-D array of spectral values for the Harmonicity spectrum.

  • phase_coupling_values (array_like) – 1-D array of spectral values for the Phase Coupling spectrum.

  • resonance_values (array_like) – 1-D array of spectral values for the Resonance spectrum.

Returns:

harmonic_complexity (DataFrame) – A pandas DataFrame with spectral flatness, entropy, spread, and Higuchi Fractal Dimension for each of the Harmonicity, Phase Coupling, and Resonance spectra.

See also

biotuner.metrics.spectrum_complexity

single-spectrum version returning a dict; used by both this function and the resonance orchestrator.

get_harmonic_ratio(freq_i, freq_j, max_n=3, max_m=3, tolerance=0.05)[source]#

Identify if two frequencies are at an n:m harmonic ratio.

Parameters:
  • freq_i (float) – First frequency.

  • freq_j (float) – Second frequency.

  • max_n (int, default=3) – Maximum value for n in n:m ratio.

  • max_m (int, default=3) – Maximum value for m in n:m ratio.

  • tolerance (float, default=0.05) – Relative tolerance for ratio matching (5%).

Returns:

tuple or None – (n, m) if frequencies are harmonically related, None otherwise.

See also

biotuner.resonance.kernels_ratio.binary_nm_kernel

vectorized version operating on freq arrays (returns W, N, M matrices).

count_theoretical_harmonic_partners(freq, fmin, fmax, max_ratio=5)[source]#

Count theoretical maximum number of harmonic partners within bandwidth.

This function counts how many frequencies at simple n:m ratios (up to max_ratio) would fall within the analysis bandwidth [fmin, fmax] for a given frequency. Lower frequencies have more potential partners, creating systematic bias.

Parameters:
  • freq (float) – The frequency to analyze.

  • fmin (float) – Minimum frequency of analysis bandwidth.

  • fmax (float) – Maximum frequency of analysis bandwidth.

  • max_ratio (int, default=5) – Maximum value for n and m in n:m ratios to consider.

Returns:

int – Number of theoretical harmonic partners within bandwidth.