Analog Output Analysis (aout)
The aout module provides comprehensive tools for analyzing analog ADC outputs.
Error Analysis by Value
- adctoolbox.analyze_error_by_value(signal: ndarray, norm_freq: float = None, n_bins: int = 100, clip_percent: float = 0.01, value_range: tuple[float, float | None] = None, create_plot: bool = True, axes=None, ax=None, title: str = None) dict[str, Any][源代码]
Analyze error binned by value (INL/DNL/Noise).
Combines core computation and optional plotting.
- 参数:
signal (np.ndarray) -- Input signal (1D array).
norm_freq (float, optional) -- Normalized frequency (f/fs). If None, auto-detected.
n_bins (int, default=100) -- Number of bins for analysis (x-axis resolution).
clip_percent (float, default=0.01) -- Ratio of values to clip from edges.
value_range (tuple(min, max), optional) -- Physical range mapping to bin 0 and bin (N-1).
create_plot (bool, default=True) -- Whether to display result plot.
axes (tuple or array, optional) -- Tuple of (ax1, ax2) to plot on.
ax (matplotlib.axes.Axes, optional) -- Single axis to plot on (will be split).
title (str, optional) -- Test setup description for title.
- 返回:
results -- Dictionary containing 'error_mean', 'error_rms', 'bin_centers', etc.
- 返回类型:
- adctoolbox.aout.rearrange_error_by_value(signal: ndarray, norm_freq: float = None, n_bins: int = 100, clip_percent: float = 0.01, value_range: tuple[float, float | None] = None) dict[str, Any][源代码]
Compute value-binned error metrics. Maps input signal linearly to [0, n_bins-1].
- adctoolbox.aout.plot_rearranged_error_by_value(results: dict, axes=None, ax=None, title: str = None)[源代码]
Plot Mean Error (INL) and RMS Error (Noise) vs Bin Index.
Creates a comprehensive visualization showing: - Top panel: Scatter of raw error vs bin index with mean error overlay - Bottom panel: RMS error vs bin index as bar chart
- 参数:
results (dict) -- Dictionary from rearrange_error_by_value().
axes (tuple or array, optional) -- Tuple of (ax1, ax2) for top and bottom panels.
ax (matplotlib.axes.Axes, optional) -- Single axis to split into 2 panels.
title (str, optional) -- Test setup description for title.
Error Analysis by Phase
- adctoolbox.analyze_error_by_phase(signal: ndarray, norm_freq: float = None, n_bins: int = 100, include_base_noise: bool = True, create_plot: bool = True, axes=None, ax=None, title: str = None) dict[str, Any][源代码]
Analyze phase error using AM/PM decomposition.
Uses dual-track parallel design: - Path A (Raw): Fit all N samples → highest precision AM/PM values + r_squared_raw - Path B (Binned): Compute binned statistics → visualization - Cross-validation: Path A coeffs predict Path B trend → r_squared_binned
- 参数:
signal (np.ndarray) -- Input signal (1D array).
norm_freq (float, optional) -- Normalized frequency (f/fs), range (0, 0.5). If None, auto-detected via FFT.
n_bins (int, default=100) -- Number of phase bins for visualization.
include_base_noise (bool, default=True) -- Include base noise term in fitting model.
create_plot (bool, default=True) -- Whether to display result plot.
axes (tuple, optional) -- Tuple of (ax1, ax2) for top and bottom panels.
ax (matplotlib.axes.Axes, optional) -- Single axis to split into 2 panels.
title (str, optional) -- Test setup description for title.
- 返回:
Numerics: am_noise_rms_v, pm_noise_rms_v, pm_noise_rms_rad, base_noise_rms_v, total_rms_v Validation: r_squared_raw (energy ratio), r_squared_binned (model confidence) Visualization: bin_error_rms_v, bin_error_mean_v, phase_bin_centers_rad Metadata: amplitude, dc_offset, norm_freq, fitted_signal, error, phase
- 返回类型:
- adctoolbox.aout.rearrange_error_by_phase(signal: ndarray, norm_freq: float = None, n_bins: int = 100, include_base_noise: bool = True) dict[str, ndarray][源代码]
Rearrange error by phase using dual-track AM/PM separation.
- 参数:
signal (np.ndarray) -- Input signal, 1D numpy array.
norm_freq (float, optional) -- Normalized frequency (f/fs), range 0-0.5. If None, auto-detected via FFT.
n_bins (int, default=100) -- Number of phase bins for visualization.
include_base_noise (bool, default=True) -- Include base noise floor in fitting model.
- 返回:
- Numerics (from raw fitting):
am_noise_rms_v, pm_noise_rms_v, pm_noise_rms_rad, noise_floor_rms_v, total_rms_v
- Validation (dual R²):
r_squared_raw: AM/PM energy ratio in total noise (typically low, ~0.05) r_squared_binned: Model fit quality on binned trend (typically high, ~0.95)
- Visualization (binned):
bin_error_rms_v, bin_error_mean_v, phase_bin_centers_rad, bin_counts
- Metadata:
amplitude, dc_offset, norm_freq, fitted_signal, error, phase
- 返回类型:
- adctoolbox.aout.plot_rearranged_error_by_phase(results: dict, axes=None, ax=None, title: str | None = None)[源代码]
Plot phase error analysis results.
- 参数:
results (dict) -- Dictionary from rearrange_error_by_phase().
axes (tuple, optional) -- Tuple of (ax1, ax2) for top and bottom panels.
ax (matplotlib.axes.Axes, optional) -- Single axis to split into 2 panels.
title (str, optional) -- Test setup description for title.
Statistical Error Analysis
- adctoolbox.analyze_error_pdf(signal, resolution=12, full_scale=None, frequency=None, create_plot: bool = True, ax=None, title: str | None = None)[源代码]
Compute and optionally plot error probability density function using KDE.
This function automatically fits an ideal sine to the signal, computes the error, and analyzes its probability distribution.
- 参数:
signal (np.ndarray) -- ADC output signal (1D array)
resolution (int, default=12) -- ADC resolution in bits
full_scale (float, optional) -- Full-scale range. If None, inferred from signal range (max - min)
frequency (float, optional) -- Normalized frequency (0-0.5). If None, auto-detected
create_plot (bool, default=True) -- If True, plot the PDF on current axes
ax (matplotlib.axes.Axes, optional) -- Axes to plot on. If None, uses current axes (plt.gca())
title (str, optional) -- Title for the plot. If None, no title is set
- 返回:
result -- Dictionary containing PDF analysis results: - 'err_lsb': Error in LSB units (1D array) - 'mu': Mean of error distribution (LSB) - 'sigma': Standard deviation of error distribution (LSB) - 'kl_divergence': KL divergence from Gaussian distribution - 'x': Sample points for PDF - 'pdf': KDE-estimated PDF values - 'gauss_pdf': Fitted Gaussian PDF values
- 返回类型:
备注
Error = signal - ideal_sine (fitted using fit_sine_4param)
Uses Kernel Density Estimation (KDE) with Silverman's bandwidth rule
KL divergence measures how different the actual error PDF is from Gaussian
Spectrum-Based Error Analysis
- adctoolbox.analyze_error_spectrum(signal, fs=1, frequency=None, create_plot: bool = True, ax=None, title: str = None)[源代码]
Compute error spectrum directly from the error signal.
This function fits an ideal sine to the signal, computes the error, and analyzes the spectrum of the error signal (not envelope).
- 参数:
signal (np.ndarray) -- ADC output signal (1D array)
fs (float, default=1) -- Sampling frequency in Hz
frequency (float, optional) -- Normalized frequency (0-0.5). If None, auto-detected
create_plot (bool, default=True) -- If True, plot the error spectrum on current axes
ax (matplotlib.axes.Axes, optional) -- Axes to plot on. If None, uses current axes (plt.gca())
title (str, optional) -- Title for the plot. If None, no title is set
- 返回:
result -- Dictionary containing spectrum analysis results: - 'enob': Effective Number of Bits - 'sndr_db': Signal-to-Noise and Distortion Ratio (dB) - 'sfdr_db': Spurious-Free Dynamic Range (dB) - 'snr_db': Signal-to-Noise Ratio (dB) - 'thd_db': Total Harmonic Distortion (dB) - 'sig_pwr_dbfs': Signal power (dBFS) - 'noise_floor_dbfs': Noise floor (dBFS) - 'error_signal': Error signal (signal - fitted sine)
- 返回类型:
备注
Error = signal - ideal_sine (fitted using fit_sine_4param)
Analyzes spectrum of error directly (no envelope extraction)
Reveals frequency components in the error signal
- adctoolbox.analyze_error_envelope_spectrum(signal, fs=1, frequency=None, create_plot: bool = True, ax=None, title: str = None)[源代码]
Compute envelope spectrum using Hilbert transform.
This function fits an ideal sine to the signal, computes the error, extracts the error envelope using Hilbert transform, and analyzes its spectrum to reveal amplitude modulation patterns.
- 参数:
signal (np.ndarray) -- ADC output signal (1D array)
fs (float, default=1) -- Sampling frequency in Hz
frequency (float, optional) -- Normalized frequency (0-0.5). If None, auto-detected
create_plot (bool, default=True) -- If True, plot the envelope spectrum on current axes
ax (matplotlib.axes.Axes, optional) -- Axes to plot on. If None, uses current axes (plt.gca())
title (str, optional) -- Title for the plot. If None, no title is set
- 返回:
result -- Dictionary with keys: - 'enob': Effective Number of Bits - 'sndr_db': Signal-to-Noise and Distortion Ratio (dB) - 'sfdr_db': Spurious-Free Dynamic Range (dB) - 'snr_db': Signal-to-Noise Ratio (dB) - 'thd_db': Total Harmonic Distortion (dB) - 'sig_pwr_dbfs': Signal power (dBFS) - 'noise_floor_dbfs': Noise floor (dBFS) - 'error_signal': Error signal (signal - fitted sine) - 'envelope': Error envelope extracted via Hilbert transform
- 返回类型:
备注
Error = signal - ideal_sine (fitted using fit_sine_4param)
Envelope = |Hilbert(error)|
Analyzes spectrum of envelope to reveal AM patterns
- adctoolbox.analyze_error_autocorr(signal, frequency=None, max_lag=50, normalize=True, create_plot: bool = True, ax=None, title: str = None)[源代码]
Compute and optionally plot autocorrelation function (ACF) of error signal.
This function fits an ideal sine to the signal, computes the error, and analyzes its autocorrelation to detect temporal correlation patterns.
- 参数:
signal (np.ndarray) -- ADC output signal (1D array)
frequency (float, optional) -- Normalized frequency (0-0.5). If None, auto-detected
max_lag (int, default=50) -- Maximum lag in samples
normalize (bool, default=True) -- Normalize ACF so ACF[0] = 1
create_plot (bool, default=True) -- If True, plot the autocorrelation
ax (matplotlib.axes.Axes, optional) -- Axes to plot on. If None, uses current axes (plt.gca())
title (str, optional) -- Title for the plot. If None, uses default title
- 返回:
result -- Dictionary containing: - 'acf': Autocorrelation values - 'lags': Lag indices (-max_lag to +max_lag) - 'error_signal': Error signal (signal - fitted sine)
- 返回类型:
备注
Error = signal - ideal_sine (fitted using fit_sine_4param)
ACF reveals temporal correlation in the error signal
White noise shows ACF ≈ 0 for all lags except 0
Correlated errors show non-zero ACF at specific lags
Harmonic Decomposition
- adctoolbox.analyze_decomposition_time(signal: ndarray, harmonic: int = 5, n_cycles: float = 5.0, create_plot: bool = True, ax=None, title: str = None) dict[str, Any][源代码]
Analyze harmonic decomposition with time-domain visualization.
Combines core computation and optional plotting.
- 参数:
signal (np.ndarray) -- Input signal (1D array).
harmonic (int, default=5) -- Number of harmonics to extract.
n_cycles (float, default=5.0) -- Number of cycles to display in the time-domain plot.
create_plot (bool, default=True) -- Whether to display result plot.
ax (matplotlib.axes.Axes, optional) -- Axis to plot on (will be split for multi-panel).
title (str, optional) -- Custom title for the plot.
- 返回:
results -- Dictionary containing decomposition results from decompose_harmonic_error().
- 返回类型:
- adctoolbox.analyze_decomposition_polar(signal: ndarray, harmonic: int = 5, create_plot: bool = True, ax=None, title: str = None) dict[str, Any][源代码]
Analyze harmonic decomposition with polar visualization.
Combines core computation and optional plotting.
- 参数:
signal (np.ndarray) -- Input signal (1D array).
harmonic (int, default=5) -- Number of harmonics to extract.
create_plot (bool, default=True) -- Whether to display result plot.
ax (matplotlib.axes.Axes, optional) -- Polar axis to plot on.
title (str, optional) -- Custom title for the plot.
- 返回:
results -- Dictionary containing decomposition results from decompose_harmonic_error().
- 返回类型:
- adctoolbox.aout.decompose_harmonic_error(signal: ndarray, n_harmonics: int = 5) dict[str, Any][源代码]
Decompose ADC error into harmonic distortion and other errors using least-squares fitting.
This is a pure calculation function that extracts harmonic components from ADC signal using least-squares fitting. Works directly in the signal's original units without normalization.
- 参数:
signal (np.ndarray) -- Input ADC signal, shape (N,) for single run or (M, N) for M runs For multi-run data, runs are averaged before decomposition
n_harmonics (int, optional) -- Number of harmonics to extract (default: 5)
- 返回:
Dictionary containing decomposition results:
- 'magnitudes': np.ndarray, shape (n_harmonics,)
Magnitude of each harmonic (1 to n_harmonics)
- 'phases': np.ndarray, shape (n_harmonics,)
Phase of each harmonic in radians (relative to fundamental)
- 'magnitudes_db': np.ndarray, shape (n_harmonics,)
Magnitude in dB relative to full scale
- 'residual_rms': float
RMS power of residual noise
- 'noise_db': float
Noise floor in dB relative to full scale
- 'fundamental_freq': float
Detected fundamental frequency (normalized, 0 to 1)
- 'noise_residual': np.ndarray, shape (N,)
Residual signal after removing all harmonics (centered at 0, no DC)
- 'reconstructed_signal': np.ndarray, shape (N,)
Reconstructed signal with all harmonics (includes DC offset)
- 'fundamental_signal': np.ndarray, shape (N,)
Reconstructed fundamental component only (includes DC offset)
- 'harmonic_signal': np.ndarray, shape (N,)
Reconstructed harmonic components 2nd to nth (centered at 0, no DC)
- 返回类型:
备注
Algorithm: 1. Average multiple runs if provided 2. Normalize signal to full scale 3. Find fundamental frequency using 4-parameter sine fit 4. Build sine/cosine basis for harmonics: cos(k*ω*t), sin(k*ω*t) 5. Solve least squares: W = (A^T A)^(-1) A^T * signal 6. Extract magnitude and phase for each harmonic (vectorized) 7. Rotate phases relative to fundamental (vectorized) 8. Calculate residual and noise floor
Phase Convention: - Phases are relative to fundamental - Each harmonic phase = phase_of_harmonic - (phase_of_fundamental * harmonic_order) - Wrapped to [-π, π]
- adctoolbox.aout.plot_decomposition_time(results: dict, signal: ndarray, n_cycles: float = 1.5, axes=None, ax=None, title: str = None)[源代码]
Create a time-domain plot of harmonic decomposition results.
This is a pure visualization function that displays the signal and its decomposed components (fundamental, harmonics, and other errors).
- 参数:
results (dict) -- Dictionary from decompose_harmonic_error() containing: - 'fundamental_signal': Reconstructed fundamental component - 'harmonic_signal': Harmonic distortion components (2nd through nth) - 'noise_residual': Other errors not captured by harmonics - 'fundamental_freq': Normalized fundamental frequency
signal (np.ndarray) -- Original signal data
n_cycles (float, default=1.5) -- Number of cycles to display in the time-domain plot
axes (tuple or array, optional) -- Tuple of (ax1, ax2) for top and bottom panels.
ax (matplotlib.axes.Axes, optional) -- Single axis to split into 2 panels. If None, uses plt.gca() and splits it.
title (str, optional) -- Custom title for the plot
备注
Two-panel layout: top panel shows signal and fitted sinewave, bottom panel shows decomposed errors
Top panel: signal (black 'x' markers) and fundamental sinewave (gray line)
Bottom panel: harmonic distortions (red line) and other errors (blue line)
Display range automatically limits to first few periods, centered on largest error
10% margin applied to y-axis limits for better visualization
- adctoolbox.aout.plot_decomposition_polar(results: dict, harmonic: int = 5, ax=None, title: str = None) Axes[源代码]
Create a polar plot of harmonic decomposition results.
This is a pure visualization function that displays harmonics on a polar plot with a noise circle reference.
- 参数:
results (dict) -- Dictionary from decompose_harmonic_error() containing: - 'magnitudes': Magnitude of each harmonic - 'phases': Phase of each harmonic in radians (relative to fundamental) - 'magnitudes_db': Magnitude in dB relative to full scale - 'noise_db': Noise floor in dB (for noise circle)
harmonic (int, default=5) -- Number of harmonics to display.
ax (matplotlib.axes.Axes, optional) -- Pre-configured Matplotlib Axes object with polar projection. If None, a new figure and axes will be created.
title (str, optional) -- Custom title for the plot.
- 返回:
The configured polar axes object containing the plot
- 返回类型:
备注
Fundamental shown as filled blue circle at phase 0
Harmonics shown as hollow blue squares
Noise circle (dashed line) shows residual error level
Harmonics outside noise circle indicate significant distortion
Radius in dB with automatic scaling
Polar axes: theta zero at top, clockwise direction
INL/DNL Analysis
- adctoolbox.analyze_inl_from_sine(data, num_bits=None, full_scale=None, clip_percent=0.01, create_plot: bool = True, show_title=True, col_title=None, ax=None)[源代码]
INL/DNL analysis from sine wave excitation with optional plotting.
This function computes INL and DNL from analog or digital signal data, and optionally plots the results.
Parameters:
- dataarray_like
Input signal - either analog voltage or digital codes. - Analog: Float values in range (normalized 0-1, or full-scale voltage) - Digital: Integer codes or float representation of codes
- num_bitsint, optional
ADC number of bits. If None, infers from data range.
- full_scalefloat, optional
Full scale voltage for quantization. If provided with analog input, codes = round(data * 2^num_bits / full_scale). If None, assumes normalized input (0-1 range).
- clip_percentfloat, default=0.01
Percentage of codes to clip from edges (0.01 = 1% from each end)
- create_plotbool, default=True
Plot the INL/DNL curves (True) or just compute (False)
- show_titlebool, default=True
Show auto-generated title with min/max ranges
- col_titlestr, optional
Column title to display above DNL plot (e.g., "N = 2^10")
- axmatplotlib.axes.Axes, optional
Single axis to split into 2 rows. If None and create_plot=True, uses current axis (plt.gca()).
Returns:
- dictDictionary containing:
'inl': INL values in LSB
'dnl': DNL values in LSB
'code': Code values (x-axis)
- adctoolbox.aout.compute_inl_from_sine(data: ndarray, num_bits: int | None = None, full_scale: float | None = None, clip_percent: float = 0.01) tuple[ndarray, ndarray, ndarray][源代码]
Calculate ADC INL/DNL.
Auto-detection logic: 1. If input is Integer type -> Treated as ADC Codes. 2. If input is Float type:
Range > 2.0 -> Treated as ADC Codes (floating point representation of codes).
Range <= 2.0 -> Treated as Normalized Voltage (auto-quantized to num_bits).
- 参数:
data (array_like) -- Input signal (Codes or Voltage).
num_bits (int, optional) --
If Input is Voltage: Target quantization resolution (default 10 if None).
If Input is Codes: ADC resolution (inferred from data range if None).
full_scale (float, optional) -- Full scale voltage range for quantization. If provided with float input, used for quantization: codes = round(data * 2^num_bits / full_scale). If None, assumes normalized input (0-1 or -1 to 1).
clip_percent (float, default=0.01) -- Percentage of codes to clip from edges.
- adctoolbox.aout.plot_dnl_inl(code, dnl, inl, num_bits=None, show_title=True, col_title=None, axes=None, ax=None, color_dnl='b', color_inl='b')[源代码]
Plot DNL and INL curves in a 2-row subplot layout.
- 参数:
code (array_like) -- Code values (x-axis)
dnl (array_like) -- DNL values in LSB (y-axis)
inl (array_like) -- INL values in LSB (y-axis)
num_bits (int, optional) -- Number of bits for x-axis limits. If None, uses code range.
show_title (bool, default=True) -- Show subplot titles with DNL/INL min/max ranges
col_title (str, optional) -- Column title to display above DNL plot (e.g., "N = 2^10")
axes (tuple of matplotlib.axes.Axes, optional) -- Pre-made axes tuple (dnl_ax, inl_ax). If provided, uses these directly.
ax (matplotlib.axes.Axes, optional) -- Single axis to split into 2 rows (auto-nested GridSpec). If None and axes=None, uses current axis.
color_dnl (str, default='r') -- Color for DNL plot
color_inl (str, default='b') -- Color for INL plot
- 返回:
axes -- The axes objects [dnl_ax, inl_ax]
- 返回类型:
Static Nonlinearity Fitting
- adctoolbox.fit_static_nonlin(sig_distorted, order)[源代码]
Extract static nonlinearity coefficients from distorted sinewave.
This function extracts 2nd-order (k2) and 3rd-order (k3) static nonlinearity coefficients from a distorted single-tone signal. It CANNOT extract gain error since the sine fitting absorbs amplitude into the reference.
- 参数:
sig_distorted -- Distorted sinewave signal samples, array_like
order -- Polynomial order for fitting (positive integer, typically 2-3) order=2: Quadratic nonlinearity only (k2) order=3: Quadratic + cubic nonlinearity (k2, k3)
- 返回:
- Quadratic nonlinearity coefficient (scalar)
For ideal ADC: k2 = 0 Represents 2nd-order distortion Returns NaN if order < 2
- k3_extracted: Cubic nonlinearity coefficient (scalar)
For ideal ADC: k3 = 0 Represents 3rd-order distortion Returns NaN if order < 3
- fitted_sine: Fitted ideal sinewave input (reference signal)
Vector (N×1), same length as sig_distorted, in time order This is the ideal sine wave extracted from the distorted signal
- fitted_transfer: Fitted transfer curve for plotting, tuple (x, y)
x: 1000 smooth input points from min to max (sorted) y: polynomial-evaluated output at those points For ideal system: y=x (straight line)
- 返回类型:
k2_extracted
- Transfer Function Model:
y = x + k2*x^2 + k3*x^3 where:
x = ideal input (zero-mean sine) y = actual output (zero-mean) k2, k3 = nonlinearity coefficients
- Usage Examples:
# Extract coefficients only sig = 0.5*np.sin(2*np.pi*0.123*np.arange(1000)) + distortion k2, k3 = extract_static_nonlin(sig, 3)[:2]
# Full extraction with plotting k2, k3, fitted_sine, fitted_transfer = extract_static_nonlin(sig, 3) import matplotlib.pyplot as plt
# Plot nonlinearity curve transfer_x, transfer_y = fitted_transfer plt.plot(transfer_x, transfer_y - transfer_x, 'r-', linewidth=2) plt.xlabel('Input (V)') plt.ylabel('Nonlinearity Error (V)') plt.title(f'Static Nonlinearity: k2={k2:.4f}, k3={k3:.4f}') plt.grid(True)
备注
Gain error CANNOT be extracted from a single sinewave measurement because the sine fitting absorbs amplitude variations. Use multi-tone or DC sweep methods to extract gain separately.