Fundamental Utilities (fundamentals)

The fundamentals module provides core utility functions and signal processing tools used across the toolbox.

Sine Fitting

adctoolbox.fit_sine_4param(data, frequency_estimate=None, max_iterations=1, tolerance=1e-09, verbose=0)[源代码]

Fit sine wave: y = A*cos(wt) + B*sin(wt) + C.

参数:
  • data -- Input signal (1D or 2D array).

  • frequency_estimate -- Initial normalized frequency (0 to 0.5). If None, estimated via FFT.

  • max_iterations -- Iterations for frequency refinement.

  • tolerance -- Convergence threshold for frequency updates.

  • verbose -- Verbosity level (0=silent, >0=print iteration info).

返回:

  • fitted_signal: Reconstructed sine wave
    • residuals: Data - fitted_signal

    • frequency: Normalized frequency (0 to 0.5)

    • amplitude: sqrt(A² + B²)

    • phase: atan2(-B, A) in radians

    • dc_offset: DC component

    • rmse: Root mean square error

For 2D input, all values (except fitted_signal, residuals) are 1D arrays.

返回类型:

Dictionary with fitted parameters

Frequency Utilities

adctoolbox.find_coherent_frequency(fs, fin_target, n_fft, force_odd=True, search_radius=200)[源代码]

Calculate the precise coherent input frequency and bin index.

Supports Undersampling (Fin > Fs/2).

参数:
  • fs (float) -- Sampling frequency (Hz)

  • fin_target (float) -- Target input frequency (Hz)

  • n_fft (int) -- FFT size (number of points)

  • force_odd (bool, optional) -- If True, only search for odd bin indices (default: True)

  • search_radius (int, optional) -- Search radius around the ideal bin (default: 200)

返回:

(fin_actual, best_bin) - Coherent frequency and corresponding bin index

返回类型:

tuple

抛出:

ValueError -- If no valid coherent frequency is found within search radius

示例

>>> fin, bin_idx = find_coherent_frequency(800e6, 100e6, 8192)
>>> print(f"Coherent frequency: {fin/1e6:.6f} MHz at bin {bin_idx}")
adctoolbox.estimate_frequency(data, frequency_estimate=None, fs=1.0)[源代码]

Estimate the physical fundamental frequency (Hz) of a signal.

This is a wrapper around the robust fit_sine_4param algorithm. It converts the normalized frequency (0 ~ 0.5) returned by fit_sine into physical frequency (Hz) based on the sampling rate.

参数:
  • data (np.ndarray) -- Input signal data. 1D or 2D array.

  • fs (float, optional) -- Sampling frequency in Hz (default: 1.0)

返回:

Estimated frequency in Hz. (Scalar if input is 1D, Array if input is 2D)

返回类型:

float or np.ndarray

示例

>>> import numpy as np
>>> # Generate a 100 MHz sine wave sampled at 800 MHz
>>> t = np.arange(8192) / 800e6
>>> signal = np.sin(2 * np.pi * 100e6 * t)
>>> freq = estimate_frequency(signal, fs=800e6)
>>> print(f"Estimated frequency: {freq/1e6:.2f} MHz")
Estimated frequency: 100.00 MHz
adctoolbox.fold_frequency_to_nyquist(fin, fs)[源代码]

Calculate the aliased (folded) frequency in the first Nyquist zone.

The aliased frequency is the absolute difference between the input frequency and the nearest integer multiple of the sampling rate.

参数:
  • fin (float or np.ndarray) -- Input frequency (Hz). Can be positive or negative.

  • fs (float) -- Sampling frequency (Hz)

返回:

Aliased frequency in range [0, Fs/2]

返回类型:

float or np.ndarray

示例

>>> fold_frequency_to_nyquist(100e6, 800e6)
100000000.0
>>> fold_frequency_to_nyquist(900e6, 800e6)
100000000.0
adctoolbox.fold_bin_to_nyquist(bin_idx: float, n_fft: int) float[源代码]

Calculate the aliased bin index in the first Nyquist zone [0, n_fft/2].

For real signals, FFT bins above n_fft/2 are mirrored to the first Nyquist zone. This function handles the wrapping and mirroring.

参数:
  • bin_idx (float) -- Bin index (can be fractional, negative, or > n_fft)

  • n_fft (int) -- Total number of FFT bins

返回:

Aliased bin index in range [0, n_fft/2]

返回类型:

float

示例

>>> fold_bin_to_nyquist(100, 8192)
100.0
>>> fold_bin_to_nyquist(100.5, 8192)  # Fractional bins supported
100.5
>>> fold_bin_to_nyquist(5000, 8192)  # Above Nyquist, mirrors back
3192.0
>>> fold_bin_to_nyquist(-100, 8192)  # Negative wraps around
92.0

Unit Conversions

adctoolbox.db_to_mag(db)[源代码]

Convert dB to magnitude ratio: 10^(x/20)

adctoolbox.mag_to_db(mag)[源代码]

Convert magnitude ratio to dB: 20*log10(x)

adctoolbox.db_to_power(db)[源代码]

Convert dB to power ratio: 10^(x/10)

adctoolbox.power_to_db(power)[源代码]

Convert power ratio to dB: 10*log10(x)

adctoolbox.snr_to_enob(snr_db)[源代码]

Convert SNR/SNDR (dB) to ENOB (bits): (SNR - 1.76) / 6.02

adctoolbox.enob_to_snr(enob)[源代码]

Convert ENOB (bits) to ideal SNR (dB): ENOB * 6.02 + 1.76

adctoolbox.fundamentals.lsb_to_volts(lsb_count, vref, n_bits)[源代码]

Convert LSB count to voltage

adctoolbox.fundamentals.volts_to_lsb(volts, vref, n_bits)[源代码]

Convert voltage to LSB count

adctoolbox.fundamentals.bin_to_freq(bin_idx, fs, n_fft)[源代码]

Convert FFT bin index to frequency (Hz)

adctoolbox.fundamentals.freq_to_bin(freq, fs, n_fft)[源代码]

Convert frequency (Hz) to nearest FFT bin index

adctoolbox.fundamentals.dbm_to_vrms(dbm, z_load=50)[源代码]

Convert dBm to Vrms (assuming load impedance z_load)

adctoolbox.fundamentals.vrms_to_dbm(vrms, z_load=50)[源代码]

Convert Vrms to dBm

adctoolbox.fundamentals.dbm_to_mw(dbm)[源代码]

Convert dBm to mW: mW = 10^(dBm/10)

adctoolbox.fundamentals.mw_to_dbm(mw)[源代码]

Convert mW to dBm: dBm = 10*log10(mW)

adctoolbox.fundamentals.sine_amplitude_to_power(amplitude, z_load=50)[源代码]

Convert sine wave peak amplitude to power.

For sine wave: Vrms = A / sqrt(2) Power = Vrms^2 / Z = A^2 / (2*Z)

SNR/NSD Conversion

adctoolbox.amplitudes_to_snr(sig_amplitude: float | ndarray, noise_amplitude: float | ndarray, osr: float = 1, return_power: bool = False) float | ndarray | tuple[float | ndarray, ...][源代码]

Calculate Signal-to-Noise Ratio (SNR) in dB from sine wave peak amplitude and noise RMS.

This function computes SNR, assuming the signal is a pure sine wave and the noise is Gaussian (White Noise).

SNR is calculated based on the power ratio: SNR (dB) = 10 * log10(P_sig / P_noise). When oversampling is used, SNR improves by 10*log10(OSR).

参数:
  • sig_amplitude (float or array_like) -- Sine wave peak amplitude (A), in Volts (V).

  • noise_amplitude (float or array_like) -- Noise RMS amplitude (σ), in Volts (V).

  • osr (float, optional) -- Oversampling ratio. SNR improves by 10*log10(OSR) dB. Default is 1 (no oversampling).

  • return_power (bool, optional) -- If True, returns a tuple containing (snr_db, sig_power, noise_power). Default is False, returning only snr_db.

返回:

  • snr_db (float or ndarray) -- The calculated SNR in dB. Returns np.inf if noise_amplitude is zero.

  • (snr_db, sig_power, noise_power) (tuple (if return_power=True)) -- The SNR in dB, Signal Power (V^2), and Noise Power (V^2), respectively.

示例

>>> snr = amplitudes_to_snr(sig_amplitude=1.0, noise_amplitude=0.01)
>>> print(f"SNR = {snr:.2f} dB")
SNR = 40.00 dB
>>> snr, sig_pwr, noise_pwr = amplitudes_to_snr(1.0, 0.01, return_power=True)
>>> print(f"SNR = {snr:.2f} dB, Signal Power = {sig_pwr:.4f} V^2")
SNR = 40.00 dB, Signal Power = 0.5000 V^2
adctoolbox.snr_to_nsd(snr_db: float | ndarray, fs: float, osr: float = 1.0, psignal_dbfs: float = 0.0) float | ndarray[源代码]

Convert Signal-to-Noise Ratio (SNR) to Noise Spectral Density (NSD).

This function converts SNR in dB to NSD in dBFS/Hz, given the sampling frequency and oversampling ratio. It assumes a full-scale sine wave signal (0 dBFS) unless specified otherwise.

The relationship is derived from: - Signal power: P_signal = 10^(Psignal_dBFS / 10) - Noise power: P_noise = P_signal / 10^(SNR_dB / 10) - Noise bandwidth: BW = fs / (2 * OSR) - NSD = P_noise / BW (linear scale) - NSD_dBFS/Hz = 10 * log10(NSD)

参数:
  • snr_db (float or array_like) -- Signal-to-Noise Ratio in dB.

  • fs (float) -- Sampling frequency in Hz.

  • osr (float, optional) -- Oversampling ratio. Default is 1.0 (Nyquist sampling). The noise bandwidth is fs / (2 * OSR).

  • psignal_dbfs (float, optional) -- Signal power in dBFS. Default is 0.0 dBFS (full-scale signal).

返回:

nsd_dbfs_hz -- Noise Spectral Density in dBFS/Hz.

返回类型:

float or ndarray

示例

>>> # For a full-scale signal with 80 dB SNR, fs=1 MHz, OSR=256
>>> nsd = snr_to_nsd(snr_db=80, fs=1e6, osr=256)
>>> print(f"NSD = {nsd:.2f} dBFS/Hz")
NSD = -134.08 dBFS/Hz
>>> # For a -6 dBFS signal with 70 dB SNR, fs=100 kHz, Nyquist sampling
>>> nsd = snr_to_nsd(snr_db=70, fs=1e5, osr=1, psignal_dbfs=-6)
>>> print(f"NSD = {nsd:.2f} dBFS/Hz")
NSD = -122.99 dBFS/Hz
adctoolbox.fundamentals.nsd_to_snr(nsd_dbfs_hz: float | ndarray, fs: float, osr: float = 1.0, psignal_dbfs: float = 0.0) float | ndarray[源代码]

Convert Noise Spectral Density (NSD) to Signal-to-Noise Ratio (SNR).

This function converts NSD in dBFS/Hz to SNR in dB, given the sampling frequency and oversampling ratio. It assumes a full-scale sine wave signal (0 dBFS) unless specified otherwise.

The relationship is derived from: - NSD in linear scale: NSD_linear = 10^(NSD_dBFS/Hz / 10) - Noise bandwidth: BW = fs / (2 * OSR) - Noise power: P_noise = NSD_linear * BW - Signal power: P_signal = 10^(Psignal_dBFS / 10) - SNR = 10 * log10(P_signal / P_noise)

参数:
  • nsd_dbfs_hz (float or array_like) -- Noise Spectral Density in dBFS/Hz.

  • fs (float) -- Sampling frequency in Hz.

  • osr (float, optional) -- Oversampling ratio. Default is 1.0 (Nyquist sampling). The noise bandwidth is fs / (2 * OSR).

  • psignal_dbfs (float, optional) -- Signal power in dBFS. Default is 0.0 dBFS (full-scale signal).

返回:

snr_db -- Signal-to-Noise Ratio in dB.

返回类型:

float or ndarray

示例

>>> # For NSD = -134 dBFS/Hz, fs=1 MHz, OSR=256
>>> snr = nsd_to_snr(nsd_dbfs_hz=-134, fs=1e6, osr=256)
>>> print(f"SNR = {snr:.2f} dB")
SNR = 79.92 dB
>>> # For NSD = -123 dBFS/Hz, fs=100 kHz, Nyquist sampling, -6 dBFS signal
>>> snr = nsd_to_snr(nsd_dbfs_hz=-123, fs=1e5, osr=1, psignal_dbfs=-6)
>>> print(f"SNR = {snr:.2f} dB")
SNR = 70.01 dB

Validation

adctoolbox.fundamentals.validate_aout_data(aout_data, min_samples=100)[源代码]

Validate analog output data format.

Checks: Numeric, Real, Finite, Sufficient Length, Signal Variation.

adctoolbox.fundamentals.validate_dout_data(bits, min_samples=100)[源代码]

Validate digital output (bits) data format.

Checks: Binary (0/1), Dimensions, Stuck Bits. Expects: (N_samples, N_bits) matrix.

Figures of Merit

adctoolbox.fundamentals.calculate_walden_fom(power, fs, enob)[源代码]

Calculate Walden Figure of Merit (FoM_w).

Standard metric for medium-resolution ADCs. Lower is better.

Formula: Power / (2^ENOB * Fs)

参数:
  • power -- Power consumption (W)

  • fs -- Sampling frequency (Hz)

  • enob -- Effective number of bits

返回:

FoM_w in J/conv-step (Joules per conversion step)

adctoolbox.fundamentals.calculate_schreier_fom(power, sndr_db, bw)[源代码]

Calculate Schreier Figure of Merit (FoM_s).

Standard metric for high-resolution / Sigma-Delta ADCs. Higher is better.

Formula: SNDR + 10*log10(BW / Power)

参数:
  • power -- Power consumption (W)

  • sndr_db -- Signal-to-Noise and Distortion Ratio (dB)

  • bw -- Signal bandwidth (Hz)

返回:

FoM_s in dB

adctoolbox.fundamentals.calculate_thermal_noise_limit(cap_pf, v_fs=1.0)[源代码]

Calculate maximum achievable SNR limited by kT/C noise.

Thermal noise sets the fundamental limit for switched-capacitor circuits and sample-and-hold amplifiers.

参数:
  • cap_pf -- Sampling capacitance in pF

  • v_fs -- Full-scale voltage (Vpp), default 1.0V

返回:

Maximum SNR in dB

Theory:
  • Noise power = kT/C

  • Signal power (sine) = (Vfs/2)^2 / 2 = Vfs^2 / 8

  • SNR = 10*log10(P_signal / P_noise)

adctoolbox.fundamentals.calculate_jitter_limit(freq, jitter_rms_sec)[源代码]

Calculate maximum achievable SNR limited by aperture jitter.

Sampling jitter creates phase noise that limits SNR, especially at high input frequencies.

Formula: SNR = -20 * log10(2 * pi * fin * tj)

参数:
  • freq -- Input frequency (Hz)

  • jitter_rms_sec -- RMS jitter in seconds

返回:

Maximum SNR in dB