Model notes
Ported from ADCToolbox 0.9.1. aout/: analyze_decomposition_time and analyze_decomposition_polar, which share decompose_harmonic_error, and fit_static_nonlin; siggen/nonidealities.py: apply_static_nonlinearity, apply_static_nonlinearity_hd, apply_thermal_noise, apply_quantization_noise; fundamentals/: find_coherent_frequency and fit_sine_4param; and analyze_spectrum for the third opinion. This page is the interactive companion to its examples exp_a11, exp_a12, exp_a25 and exp_a31; python/adc_harmonics.py runs ADCToolbox on the same samples and every number here matches it.
The setup. 4096 samples at 1 GS/s of a 0.45 V sine on a 0 … 1 V range, at a coherent bin low enough that harmonics 2 … 5 all stay below Nyquist. The two sliders ask for a second and a third harmonic in dBc, and apply_static_nonlinearity_hd turns each into the polynomial coefficient that puts it there: kn = 2n−1 · 10dBc/20 / An−1. Nothing else is wrong with this converter except the noise you leave it.
The decomposition fits DC, the fundamental and every harmonic at once by least squares, straight against the samples. No FFT, no window, no leakage: each harmonic comes back as a pair of coefficients, and so with a size and a phase. Its phases are relative to the fundamental's, which is why they stay still as the input frequency moves, and why a harmonic that has simply been delayed looks different from one the converter made.
What is left after every harmonic is taken out is drawn under the capture. That residual is the converter's noise and nothing else — the point of the whole exercise, since it says how much of a poor SNDR is distortion you could design out and how much is noise you cannot.
The polynomial fit works the other way round: take the fitted sine as the input the converter was given, fit a cubic from that input to the output, and read k2 and k3 off it. Gain cannot be recovered this way — the sine fit has already absorbed it — so the coefficients are normalised by the fitted linear term, and that is the curve drawn against the one you asked for.
Three opinions. The decomposition, the spectrum and the polynomial are three different ways of measuring the same bend, and on a clean capture they agree to a hundredth of a dB. Push the noise up and watch them part company: the FFT keeps its harmonic bins, the decomposition follows, and the polynomial coefficients are the first to wander.
The usual case. The two harmonics have their own phases, and the curve is neither even nor odd.
Three opinions on the same capture H2: decomposition −55.01 · spectrum −55.01 dBcH3: decomposition −65.04 · spectrum −65.04 dBcH4: decomposition −120.42 · spectrum −120.42 dBcH5: decomposition −118.97 · spectrum −118.97 dBc