Digital Output Analysis (dout)#

The dout module provides tools for analyzing digital ADC outputs and bit-weighted architectures.

Weight Calibration#

adctoolbox.calibrate_weight_sine(bits: ndarray | list[ndarray], freq: float | ndarray | None = None, force_search: bool = False, nominal_weights: ndarray | None = None, harmonic_order: int = 1, learning_rate: float = 0.5, reltol: float = 1e-12, max_iter: int = 100, verbose: int = 0) dict[源代码]#

FGCalSine — Foreground calibration using a sinewave input

This function estimates per-bit weights and a DC offset for an ADC by fitting the weighted sum of raw bit columns to a sine series at a given (or estimated) normalized frequency Fin/Fs. It optionally performs a coarse and fine frequency search to refine the input tone frequency.

Implementation uses a unified pipeline where single-dataset calibration is treated as a special case of multi-dataset calibration (N=1).

参数:
  • bits (ndarray or list of ndarrays) -- Binary data as matrix (N rows by M cols, N is data points, M is bitwidth). Each row is one sample; each column is a bit/segment. Can also be a list of arrays for multi-dataset calibration.

  • freq (float, array-like, or None, optional) -- Normalized frequency Fin/Fs. Default is None (triggers auto frequency search). Use None for automatic frequency search, a float for one frequency shared by all datasets, or an array-like value for per-dataset frequencies in multi-dataset mode.

  • force_search (bool, optional) -- Force fine frequency search even when frequency is provided. Default is False. Set to True to refine provided frequencies.

  • nominal_weights (array-like, optional) -- Nominal bit weights (only effective when rank is deficient). Default is 2^(M-1) down to 2^0.

  • harmonic_order (int, optional) -- Number of harmonic terms to exclude in calibration. Default is 1 (fundamental only, no harmonic exclusion). Higher values exclude more harmonics from the error term.

  • learning_rate (float, optional) -- Adaptive learning rate for frequency updates (0..1), default is 0.5.

  • reltol (float, optional) -- Relative error tolerance for convergence, default is 1e-12.

  • max_iter (int, optional) -- Maximum iterations for fine frequency search, default is 100.

  • verbose (int, optional) -- Print frequency search progress (1) or not (0), default is 0.

返回:

Calibration result containing weight, offset, calibrated_signal, ideal, error, and refined_frequency. Array-valued entries are returned as a single array for single-dataset input or as a list of arrays for multi-dataset input.

返回类型:

dict

adctoolbox.calibration.calibrate_weight_sine_lite(bits: ndarray, freq: float) ndarray[源代码]#

Minimal calibration at known frequency. Returns normalized weights. Expects well-conditioned binary data (N samples x M bits).

Bit And Weight Analysis#

analyze_weight_radix returns radix, wgtsca, and effres. effres is computed from the significant absolute weights as log2(sum(abs_w_sig) / min(abs_w_sig) + 1). It is a theoretical weight-list span, not a missing-code, DNL, INL, or SAR reachability proof.

adctoolbox.analyze_bit_activity(bits: ndarray, create_plot: bool = True, ax=None, title: str | None = None) ndarray[源代码]#

Analyze and plot the percentage of 1's in each bit.

Ideal SAR ADC should have 50% activity for all bits. Deviations indicate input signal DC offset or amplitude clipping.

参数:
  • bits (np.ndarray) -- Binary matrix (N x B), N=samples, B=bits (MSB to LSB)

  • create_plot (bool, default=True) -- If True, create bar chart visualization

  • ax (plt.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

返回:

Percentage of 1's for each bit (1D array of length B)

返回类型:

np.ndarray

adctoolbox.analyze_overflow(raw_code: ndarray, weight: ndarray, ofb: int | None = None, create_plot: bool = True, ax=None, title: str | None = None) tuple[ndarray, ndarray, ndarray, ndarray][源代码]#

Analyze residue distribution at each bit position for overflow detection.

Calculates normalized residue (remaining bits weighted sum) and detects overflow conditions where residue exceeds [0, 1] range.

参数:
  • raw_code (np.ndarray) -- Digital codes array, shape (N, M) where N=samples, M=bits (MSB first)

  • weight (np.ndarray) -- Weight array for each bit, shape (M,)

  • ofb (int, optional) -- Overflow bit position for overflow detection. Default is M (check at MSB, MATLAB convention: 1=LSB, M=MSB)

  • create_plot (bool, default=True) -- If True, generate residue distribution visualization

  • ax (plt.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

返回:

  • range_min: Minimum normalized residue per bit (shape M,)

  • range_max: Maximum normalized residue per bit (shape M,)

  • ovf_percent_zero: Underflow percentage per bit (shape M,)

  • ovf_percent_one: Overflow percentage per bit (shape M,)

返回类型:

tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

备注

  • A bit segment is the sub-code formed from one bit to the LSB

  • Residue is normalized by dividing by the sum of weights in the segment

  • Matches MATLAB ovfchk.m behavior exactly

adctoolbox.analyze_weight_radix(weights: ndarray, create_plot: bool = True, ax=None, title: str | None = None) dict[源代码]#

Analyze absolute bit weights, radix ratios, and weight-list resolution.

Pure binary: radix = 2.00. Sub-radix/redundancy: radix < 2.00. effres is a theoretical resolution estimate from the supplied weight dynamic range, not a missing-code/DNL proof.

参数:
  • weights (np.ndarray) -- Bit weights (1D array), nominally from MSB to LSB for radix plotting. Effective-resolution analysis uses sorted absolute magnitudes, so negative trim weights count by magnitude.

  • create_plot (bool, default=True) -- If True, create line plot with radix annotations

  • ax (plt.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

返回:

radix:

Radix between consecutive input-order weights, abs(weight[i-1]) / abs(weight[i]). The first entry is NaN.

wgtsca:

Scale factor that maps the significant absolute weights closest to integer LSB units.

effres:

Effective resolution in bits, log2(sum(abs_w_sig) / min(abs_w_sig) + 1).

返回类型:

dict

备注

The significant set abs_w_sig is formed by sorting abs(weights) in descending order, then dropping the tail after the first adjacent ratio >= 3. This excludes very small trim/noise weights from effres.

effres is useful for questions like "how many bits does this SAR weight list span?" It does not verify SAR decision reachability, code monotonicity, missing codes, DNL/INL, comparator noise, or sampling noise.

What to look for in radix values: - Radix = 2.00: Binary scaling (SAR, pure binary) - Radix < 2.00: Redundancy or sub-radix (e.g., 1.5-bit/stage → ~1.90) - Radix > 2.00: Unusual, may indicate calibration error - Consistent pattern: Expected architecture behavior - Random jumps: Calibration errors or bit mismatch

ENOB Analysis#

adctoolbox.analyze_enob_sweep(bits: ndarray, freq: float | None = None, harmonic_order: int = 1, osr: int = 1, win_type: str = 'hamming', create_plot: bool = True, ax=None, title: str | None = None, verbose: bool = False) tuple[ndarray, ndarray][源代码]#

Sweep ENOB vs number of bits used for calibration.

Incrementally adds bits (MSB to LSB) and measures ENOB after calibration to understand diminishing returns and optimal bit count.

参数:
  • bits (np.ndarray) -- Binary matrix (N samples x M bits, MSB to LSB order)

  • freq (float, optional) -- Normalized frequency (0-0.5). If None, auto-detect from data

  • harmonic_order (int, default=1) -- Harmonic order for calibrate_weight_sine

  • osr (int, default=1) -- Oversampling ratio for spectrum analysis

  • win_type (str, default='hamming') -- Window function: 'boxcar', 'hann', 'hamming'

  • create_plot (bool, default=True) -- If True, plot ENOB sweep curve

  • ax (plt.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

  • verbose (bool, default=False) -- If True, print progress messages

返回:

  • enob_sweep: ENOB for each bit count (length M)

  • n_bits_vec: Bit counts from 1 to M

返回类型:

tuple[np.ndarray, np.ndarray]

备注

What to look for in the plot: - Increasing trend: More bits improve resolution - Plateau: Additional bits don't help (noise/distortion limited) - Decrease: Extra bits add noise/calibration errors

Visualization#

adctoolbox.plot_residual_scatter(signal: ndarray, bits: ndarray, weights: ndarray | None = None, pairs: list[tuple[int, int]] | None = None, alpha: float | str = 'auto', create_plot: bool = True) dict[源代码]#

Plot partial-sum residuals of an ADC bit matrix.

For each pair (x_bit, y_bit), computes the residual after subtracting the first x_bit (or y_bit) weighted bits from the input signal, then plots y-residual vs x-residual as a scatter plot.

参数:
  • signal (np.ndarray) -- Ideal input signal to the ADC (1D, length N).

  • bits (np.ndarray) -- Raw ADC output bit matrix (N x M), MSB-first columns.

  • weights (np.ndarray, optional) -- Bit weights (length M). Default: binary [2^(M-1), ..., 1].

  • pairs (list of (int, int), optional) -- Pairs of bit indices whose residuals are plotted. Range: 0 (raw signal) to M (residual after all bits). Default: [(0, M), (1, M), ..., (M-1, M)].

  • alpha (float or 'auto', default='auto') -- Marker transparency. 'auto' scales as clamp(1000/N, 0.1, 1.0).

  • create_plot (bool, default=True) -- If True, create scatter subplots.

返回:

'pairs': list of (x_bit, y_bit) tuples used 'residuals_x': list of 1D arrays, one per pair 'residuals_y': list of 1D arrays, one per pair

返回类型:

dict