Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

vyges-meas — closed measurement kernels

Part of the Vyges Loom suite. Install once with vyges install loom, then run vyges loom meas. It’s also a standalone vyges-meas binary on your PATH (the integration contract for flow authors).

vyges-meas answers: what does this capture actually measure? Two families of scalars — coherent single-tone SNR, SINAD, THD, SFDR from a captured time series, and gain, bandwidth, unity-gain frequency, phase margin from an AC sweep.

Why the definition is the product

SNR names a ratio, not a measurement. Whether the fundamental is excluded from noise, how many harmonics are counted, whether DC is in the band, where the band ends, what happens to a harmonic that aliases back below Nyquist — every one of those changes the number, and two honest tools can differ by several dB while both being “right”. A converter datasheet is comparable to a simulation only if both state the same choices.

So each kernel fixes one method, documents every choice, and refuses inputs it cannot measure that way. A refusal is a result: it says the number would have been meaningless.

Run it

vyges install loom                                                    # one-time

# spectral — one scalar per call, each independently checked
vyges loom meas spectral capture.samples --fundamental-bin 37 \
      --metric thd --harmonics 2,3,4,5

# AC transfer
vyges loom meas transfer opamp.ac --metric phase-margin --target 45

SERIES is one sample per line in capture order. SWEEP is hz gain_db phase_deg per line, strictly increasing. Both accept # comments. Add --json for machine output; -o FILE writes a report while the JSON still goes to stdout, so asking for the file never costs you the parsed result.

The spectral method

choicethis kernel
record lengthpower of two, 8 to 65,536 samples
samplingcoherent — the fundamental lands exactly on a DFT bin, and you say which
windownone. A rectangular window is exact for a coherent capture and wrong otherwise, so a non-coherent capture is refused, not smeared
DCthe mean is removed and the DC bin is excluded from every partition
harmonicsfolded into the first Nyquist zone — an aliased harmonic’s power is really in the record
integration widthzero bins: each component is exactly one bin, never a skirt
collisionsa harmonic landing on DC, the fundamental, or another harmonic is refused — counting one bin twice would double-count its power
clippinga clipped record is refused: it describes the acquisition, not the device
SNR   = 10 log10(p_f / p_n)      noise only, declared harmonics excluded
SINAD = 10 log10(p_f / p_r)      everything that is not the fundamental
THD   = 10 log10(p_h / p_f)      harmonics against the fundamental (negative dB)
SFDR  = 10 log10(p_f / p_s)      distance to the worst single spur

The AC method

Values between swept points are interpolated in (log10 f, dB) and (log10 f, degrees) — the space these are plotted in, so a coarse sweep does not read low. Nothing is extrapolated: a crossing outside the swept range is reported as absent, because a sweep that stopped too early is a fixable mistake and a guessed number is not.

Bandwidth is referenced to the peak gain, not the first point. A response that peaks before rolling off has its −3 dB corner relative to that peak, and referencing the first point would be wrong for exactly the circuits where the number matters most.

The verdict

With --target, the result carries a pass/fail: SNR, SINAD, SFDR and the AC metrics want at least the target; THD wants at most it. Without a target there is no claim to make, so met is null and the result envelope reports unknown rather than a pass nobody asked for.

A refused input also resolves to unknown — the engine ran, and the evidence does not support a conclusion.

How much a result claims

A number and a standard’s name printed near each other read as a conformance claim whether or not one was meant. So every result carries a machine-readable statement of exactly how much it claims:

levelmeans
vyges-definitionthe method is ours, complete and versioned. No external standard is claimed.
candidatethe application lies inside a named standard’s published scope, but no clause-level review has been done
revieweda crosswalk records the exact edition, clauses, choices, deviations, reviewer and artifact
conformantan independently reviewed profile and a conformance suite

--application decides which scope a result may name. It defaults to generic, because the tool cannot infer from a list of numbers what device produced them and guessing would manufacture a standards claim out of nothing:

--applicationreachesagainst
generic (default)vyges-definition
adccandidateIEEE 1241-2023
daccandidateIEEE 1658-2023
recordercandidateIEEE 1057-2017
"alignment": {
  "level": "candidate",
  "edition": "IEEE 1241-2023",
  "application": "adc",
  "statement": "candidate (IEEE 1241-2023) — … NO clause-level review has been performed, so this is not a conformance claim"
}

The ladder is enforced, not merely documented. reviewed and conformant can only be built from a crosswalk, and a crosswalk cannot exist without every field of the evidence it stands for — edition, clauses, choices, deviations, reviewer, artifact. A claim stronger than the evidence has no constructor. Nothing here is reviewed or conformant, and nothing becomes so by editing a label.

The published scopes of those editions are the limit of what is asserted; the normative clauses needed for a conformance claim are not public, so candidate is the honest ceiling today.

IEEE 519 is not authority here. It governs harmonic control in electric power systems at a point of common coupling — a different quantity, measured elsewhere, for a different purpose. A THD figure from this engine must never be cited as 519-anything. Common enough on datasheets that the exclusion is recorded in code.