ADCToolbox Algorithm Overview

Last Updated: 2025-12-03

Introduction

This document describes the working principles and architectural design of the MATLAB algorithms in ADCToolbox. The toolbox has been streamlined for efficiency, maintainability, and consistent output formatting.


Toolset Architecture

Design Principles

  1. Separation of Concerns: Tool execution and panel generation are separate functions

  2. Data-Driven Execution: Tool lists defined as data structures to eliminate repetitive code

  3. Auto-Detection: Panel functions automatically locate plot files using naming conventions

  4. Consistent Formatting: All tools use standardized figure properties and output

File Organization

matlab/src/
├── toolset_aout.m          # 9 analog analysis tools
├── toolset_aout_panel.m    # Combine AOUT plots into 3×3 panel
├── toolset_dout.m          # 6 digital analysis tools
├── toolset_dout_panel.m    # Combine DOUT plots into 3×2 panel
└── [individual tool functions]

toolset_aout: Analog Output Analysis

Files:

  • MATLAB: matlab/src/toolset_aout.m

  • Python: python/src/adctoolbox/toolset_aout.py

Purpose

Executes 9 diagnostic tools on calibrated ADC analog output data (sine wave). Covers time-domain, frequency-domain, and statistical error analysis.

Algorithm Workflow

1. Parse inputs (aout_data, outputDir, optional parameters)
2. Create output directory if needed
3. Pre-compute common parameters:
   - freqCal = findfreq(aout_data)          % Auto-detect input frequency
   - FullScale = max(aout_data) - min(aout_data)
   - err_data = aout_data - sinfit(aout_data)  % Error signal
4. For each tool i = 1:9:
   - Create figure (800×600, visible/hidden)
   - Execute tool function with pre-computed params
   - Format (title, font size 14)
   - Save PNG: <prefix>_<i>_<toolname>.png
   - Close figure
   - Print progress message
5. Return cell array of 9 file paths

Tool Execution Pattern

Each tool follows a standardized pattern:

fprintf('[%d/9] toolname');
figure('Position', [100, 100, 800, 600], 'Visible', opts.Visible);
tool_function(params...);
title('Tool Name');
set(gca, 'FontSize', 14);
plot_files{i} = fullfile(outputDir, sprintf('%s_%d_toolname.png', opts.Prefix, i));
saveas(gcf, plot_files{i});
close(gcf);
fprintf(' -> %s\n', plot_files{i});

Tools Executed

#

Tool

Key Parameters

1

tomdec

freqCal, 10 harmonics, 1 OSR

2

plotspec

label=1, harmonic=5, OSR=1, window=@hann

3

plotphase

harmonic=10, mode='FFT'

4

errsin (code)

bin=20, fin=freqCal, xaxis='value'

5

errsin (phase)

bin=99, fin=freqCal, xaxis='phase'

6

errpdf

Resolution, FullScale

7

errac

MaxLag=200, Normalize=true

8

plotspec (error)

label=0

9

errevspec

Fs=1

Key Features

  • Pre-computation: Expensive calculations (frequency detection, sine fit) done once and reused

  • Memory Management: Figures closed immediately after save to prevent memory buildup

  • Fail-Fast: Execution stops on first error (use try-catch for fail-safe execution)

  • Standardized Output: All plots have consistent size and formatting


toolset_dout: Digital Output Analysis

Files:

  • MATLAB: matlab/src/toolset_dout.m

  • Python: python/src/adctoolbox/toolset_dout.py

Purpose

Executes 6 diagnostic tools on ADC digital bit outputs (for SAR ADCs and bit-weighted architectures). Performs calibration, weight analysis, and performance evaluation.

Algorithm Workflow

1. Parse inputs (bits, outputDir, optional parameters)
2. Create output directory if needed
3. Extract resolution: nBits = size(bits, 2)
4. Calibrate bit weights:
   [w_cal, ~, ~, ~, ~, f_cal] = wcalsine(bits, 'freq', 0, 'order', Order, 'verbose', 0)
5. Pre-compute digital codes:
   - digitalCodes = bits * (2.^(nBits-1:-1:0))'  % Nominal binary weights
   - digitalCodes_cal = bits * w_cal'             % Calibrated weights
6. Define tool execution table (struct array with 6 entries)
7. For each tool i = 1:6:
   - Create figure (variable size, visible/hidden)
   - Execute tool function handle from struct
   - Format (title, font size 14)
   - Save PNG with exportgraphics (150 DPI)
   - Close figure
   - Print progress message
8. Return cell array of 6 file paths

Data-Driven Tool Execution

Unlike the old repetitive approach, tools are defined as a struct array:

tools = {
    struct('idx', 1, 'name', 'Spectrum (Nominal)', 'suffix', '1_spectrum_nominal', ...
        'pos', [100, 100, 800, 600], ...
        'fn', @() plotspec(digitalCodes, 'label', 1, 'harmonic', 5, 'OSR', 1, 'window', @hann));
    struct('idx', 2, 'name', 'Spectrum (Calibrated)', 'suffix', '2_spectrum_calibrated', ...
        'pos', [100, 100, 800, 600], ...
        'fn', @() plotspec(digitalCodes_cal, 'label', 1, 'harmonic', 5, 'OSR', 1, 'window', @hann));
    % ... 4 more tools
};

for i = 1:6
    fprintf('[%d/6] %s', i, tools{i}.name);
    figure('Position', tools{i}.pos, 'Visible', p.Results.Visible);
    tools{i}.fn();  % Execute function handle
    title(tools{i}.name);
    set(gca, 'FontSize', 14);
    plot_files{i} = fullfile(outputDir, sprintf('%s_%s.png', p.Results.Prefix, tools{i}.suffix));
    exportgraphics(gcf, plot_files{i}, 'Resolution', 150);
    close(gcf);
    fprintf(' -> %s\n', plot_files{i});
end

Benefits of Data-Driven Approach:

  • Code Reduction: 109 lines → 66 lines (40% reduction)

  • Consistency: Single point of control for formatting

  • Maintainability: Easy to add/remove/modify tools

  • Readability: Tool properties clearly visible in struct definition

Tools Executed

#

Tool

Purpose

Figure Size

1

plotspec (nominal)

Spectrum before calibration

800×600

2

plotspec (calibrated)

Spectrum after wcalsine calibration

800×600

3

bitact

Bit toggle rate analysis

1000×750

4

ovfchk

Overflow/redundancy check

1000×600

5

weightScaling

Radix visualization

800×600

6

bitsweep

ENoB vs number of bits

800×600


Panel Functions

toolset_aout_panel

File: matlab/src/toolset_aout_panel.m

Combines 9 individual AOUT plots into a 3×3 panel figure.

Algorithm

1. Parse inputs (outputDir, optional Prefix, PlotFiles, Visible)
2. If PlotFiles not provided:
   - Auto-construct file paths: <outputDir>/<prefix>_<i>_<name>.png
3. Validate 9 files expected
4. Create 3×3 tiled layout figure (1800×1000)
5. For each plot i = 1:9:
   - nexttile
   - If file exists: imread, imshow, title
   - Else: display "Missing" text in red
6. Add super title "AOUT Toolset Overview"
7. Export panel: PANEL_<PREFIX>.png (300 DPI)
8. Close figure
9. Return status struct (.success, .panel_path, .errors)

File Naming Convention

Auto-detected files:

<prefix>_1_tomdec.png
<prefix>_2_plotspec.png
<prefix>_3_plotphase.png
<prefix>_4_errsin_code.png
<prefix>_5_errsin_phase.png
<prefix>_6_errPDF.png
<prefix>_7_errAutoCorrelation.png
<prefix>_8_errSpectrum.png
<prefix>_9_errEnvelopeSpectrum.png

toolset_dout_panel

File: matlab/src/toolset_dout_panel.m

Combines 6 individual DOUT plots into a 3×2 panel figure.

Algorithm

Same as toolset_aout_panel but with 6 plots in 3×2 layout (1200×1000).

File Naming Convention

Auto-detected files:

<prefix>_1_spectrum_nominal.png
<prefix>_2_spectrum_calibrated.png
<prefix>_3_bitActivity.png
<prefix>_4_overflowChk.png
<prefix>_5_weightScaling.png
<prefix>_6_ENoB_sweep.png

Key Features

  1. Auto-Detection: Uses prefix to find files - no need to manually specify paths

  2. Flexible: Can override with explicit PlotFiles parameter

  3. Robust: Handles missing files gracefully (shows placeholder)

  4. Reusable: Can re-generate panels without re-running tools


Common Utility Functions

findfreq

File: matlab/src/findfreq.m

Auto-detects sine wave frequency from time-domain signal using FFT.

Algorithm:

  1. Compute FFT of input signal

  2. Find peak in magnitude spectrum

  3. Convert bin index to normalized frequency

  4. Return frequency (0 to 0.5, normalized to sampling rate)

sinfit

File: matlab/src/sinfit.m

Fits a 4-parameter sine wave to data: A*sin(2πft + φ) + DC

Algorithm:

  1. Use findfreq to detect frequency

  2. Set up nonlinear least squares problem

  3. Optimize amplitude, frequency, phase, DC offset

  4. Return fitted sine wave


Naming Conventions

File Naming

Individual tool outputs:

<prefix>_<index>_<toolname>.png

Examples:

  • aout_1_tomdec.png

  • dout_3_bitActivity.png

Panel outputs:

PANEL_<PREFIX>.png

Examples:

  • PANEL_AOUT.png

  • PANEL_DOUT.png

Variable Naming

  • plot_files — Cell array of PNG file paths

  • outputDir — Directory for output files

  • freqCal — Calibrated/detected frequency

  • w_cal — Calibrated bit weights

  • digitalCodes — Digital output codes (nominal weights)

  • digitalCodes_cal — Digital output codes (calibrated weights)


Performance Optimizations

Memory Management

  • Figures closed immediately after save

  • Use 'Visible', false for batch processing (faster)

  • Pre-allocate cell arrays for file paths

Computation Efficiency

  • Pre-computation: Expensive operations (frequency detection, sine fit, calibration) done once

  • Data-driven loops: Eliminates repetitive code

  • Minimal disk I/O: Each plot saved once

Code Efficiency

Before (repetitive):

% Tool 1
fprintf('[1/6] Tool1...');
f = figure('Visible', figVis, 'Position', [100, 100, 800, 600]);
tool1_function(params);
save_and_close(f, outputDir, opts.Prefix, '1_tool1', 'Tool 1');

% Tool 2
fprintf('[2/6] Tool2...');
f = figure('Visible', figVis, 'Position', [100, 100, 800, 600]);
tool2_function(params);
save_and_close(f, outputDir, opts.Prefix, '2_tool2', 'Tool 2');

% ... repeated 4 more times

After (data-driven):

tools = {struct('name', 'Tool1', 'suffix', '1_tool1', 'pos', [100,100,800,600], 'fn', @() tool1_function(params)); ...};

for i = 1:6
    fprintf('[%d/6] %s', i, tools{i}.name);
    figure('Position', tools{i}.pos, 'Visible', figVis);
    tools{i}.fn();
    % ... standardized save
end

Result: 109 lines → 66 lines (40% reduction)


Usage Patterns

Pattern 1: Generate plots and panel together

% AOUT
plot_files = toolset_aout(aout_data, 'output/test1');
panel_status = toolset_aout_panel('output/test1', 'Prefix', 'aout');

% DOUT
plot_files = toolset_dout(bits, 'output/test1');
panel_status = toolset_dout_panel('output/test1', 'Prefix', 'dout');

Pattern 2: Batch generate plots, then gather panels

% Generate all plots first
for i = 1:N
    toolset_aout(data{i}, sprintf('output/run%d', i), 'Prefix', sprintf('run%d', i));
end

% Then generate all panels
for i = 1:N
    toolset_aout_panel(sprintf('output/run%d', i), 'Prefix', sprintf('run%d', i));
end

Pattern 3: Re-generate panels only (plots already exist)

% No need to re-run toolset - just regenerate panels
toolset_aout_panel('output/test1', 'Prefix', 'aout');
toolset_dout_panel('output/test2', 'Prefix', 'dout');

Error Handling

Current Behavior

Both toolsets use fail-fast error handling:

  • Execution stops on first error

  • MATLAB displays error message

  • Partial results may be saved

Implementing Fail-Safe Execution

To continue execution after errors, wrap tools in try-catch:

for i = 1:length(tools)
    try
        % ... tool execution
        success(i) = true;
    catch ME
        fprintf(' ✗ %s\n', ME.message);
        errors{end+1} = sprintf('Tool %d: %s', i, ME.message);
        success(i) = false;
    end
end

Future Enhancements

Planned Features

  1. Python panel functions: Implement toolset_aout_panel and toolset_dout_panel in Python

  2. Parallel execution: Run independent tools in parallel using parfor

  3. Progress callbacks: Optional callback function for progress updates

  4. Custom tool selection: Allow users to specify which tools to run

  5. Fail-safe mode: Option to continue execution after errors

Architectural Improvements

  1. Tool registry: Central registry of all available tools

  2. Plugin system: Easy addition of custom tools

  3. Configuration files: YAML/JSON config for tool parameters

  4. Result caching: Cache expensive computations for reuse


References

  • IEEE Std 1241-2010: Standard for ADC Test Methods

  • IEEE Std 1057-2017: Standard for Digitizing Waveform Recorders

  • MATLAB documentation: Function handles, struct arrays, exportgraphics


Version History

Version

Date

Changes

2.0

2025-12-03

Streamlined toolsets with data-driven execution, separated panel functions

1.0

2025-01-28

Initial implementation