Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Domain Contracts in Action

Every xmris operation makes a contract about what you get back: the output domain is a pure function of the operation and the input domain — never a surprise. This page proves the two contracts executable-style; the design story lives in The Two Domains.

You callon a FID (time)on a spectrum (frequency/chemical_shift)
apodize_exp(), zero_fill()FID ✅spectrum ✅ (round trip inside)
autophase(), baseline_als()spectrum (funnel ⤵)spectrum
to_spectrum(), to_fid()explicit conversionexplicit conversion

1. A distorted, time-domain FID

('time',)

2. Domain-preserving: same physics, either side

Multiplying an FID by e−π lb te^{-\pi\,\mathrm{lb}\,t} is convolving its spectrum with a Lorentzian of width lb\mathrm{lb} Hz — one operation, two views. So apodize_exp never changes your representation:

FID path      : ('time',) -> ('time',)
spectrum path : ('frequency',) -> ('frequency',)

And the two paths are numerically the same operation — transforming the apodized FID reproduces the apodized spectrum to machine precision:

<Figure size 1050x450 with 1 Axes>

The same contract holds for zero_fill: zero-padding the FID is interpolating the spectrum onto a finer grid — so calling it on a spectrum hands back a spectrum with more points, not a FID:

Frozen({'frequency': 2048}) -> Frozen({'frequency': 4096})

3. Funnel: the canonical pipeline, one FFT

Phasing and baseline correction exist for the spectrum — their results land there. That makes the classic monotonic pipeline read naturally, with exactly one Fourier transform executing at the funnel boundary:

pipeline result: ('frequency',) | real-valued: True
<Figure size 1050x450 with 1 Axes>

4. Guardrails

One-way data fails loudly. baseline_als discards the imaginary component, so no valid FID exists behind its output — a time-domain op on it refuses rather than inventing one:

Cannot transform real-valued spectral data (dim 'frequency') into the time domain: the imaginary component is gone (e.g. discarded by `baseline_als`), so no valid FID exists behind this spectrum.

Apply time-domain operations before the step that discarded the imaginary part, or pass an explicit existing dimension to operate on.

Explicit foreign dims pass through — for domain-preserving ops. A domain-preserving op named on an axis outside its domain skips conversion entirely — naming another axis (k-space, say) leaves the data untouched. (Funnel ops have no passthrough: they always land in their home domain.)

{'kx': 8, 'ky': 8} -> {'kx': 16, 'ky': 8}