design op• Data kinds: none → table (an op determined by its arguments alone — it takes no image or data input)
• Call: import interferometry; interferometry.csi_design(wavelength_um=0.6, bandwidth_um=0.1, z_range_um=12.0, width_px=640, height_px=480, min_visibility=0.3, step_divisor=8.0) (or opsinterferometry.get("csi_design"))
The axial limits of a coherence-scanning setup, from the source spectrum.
The counterpart of :mod:visiondesign for the *vertical* axis: closed-form
answers to the questions asked before any hardware is bought — how localised
is the coherence peak, how finely must the scan step, how many planes is that,
and how much memory does the stack need.
Returned dict:
• `coherence_length_um — (4 ln2 / pi) * lambda^2 / delta_lambda`, the
FWHM of `|gamma(OPD)|` for a Gaussian source (Born & Wolf 7.5.8). This
is a property of the optical path difference. Verified in the tests
against a direct numerical Fourier transform of the Gaussian source
spectrum, at three (lambda, delta_lambda) settings, agreeing to 6
significant figures.
• `envelope_fwhm_um` — half of that: the width of the envelope along
the scan axis, because the double pass makes `OPD = 2z`. This is the
one to hand to :func:csi_signal_simulate /
:func:csi_stack_simulate, and the two are reported separately precisely
because collapsing them into one name called "coherence length" is a clean
factor-of-two error in every height the module produces. (It was one
during development, and the numerical check above is what caught it.)
• `envelope_sigma_um — envelope_fwhm_um` as a Gaussian sigma.
• `fringe_period_um — lambda/2`. The double pass halves it, and this
is the number that makes phase-shifting ambiguous above `lambda/4`.
• `max_z_step_um — lambda/4`. The Nyquist ceiling on the scan step;
:func:csi_peak_position and :func:csi_height_map refuse at or above
it. It is a rejection bound, not an operating point — the accuracy
is already gone well before the refusal. Measured on a tilted plane
(lambda 0.6 um, bandwidth 0.12 um, ceiling 0.15 um, no noise at all,
so every number below is method error):
========== =========== ===========
step [um] bias [nm] RMSE [nm]
========== =========== ===========
0.0375 0.09 0.22
0.0750 (rec) 0.09 0.26
0.1000 -0.07 0.39
0.1200 0.39 2.90
0.1400 -4.75 134.64
0.1499 -1.89 18.38
========== =========== ===========
A step of 0.14 um is accepted and returns heights that are wrong by
500x the recommended step's error, with a worst pixel at 198 nm.
Note also that the last two rows are not monotone: 0.1499 is better
than 0.1400. The error near the ceiling is an aliasing beat between the
fringe period and the step, not a smooth degradation, so "just under the
limit" cannot be made safe by nudging the step. Use
`recommended_z_step_um`; the bias only stays in the 0.1 nm range up to
about `lambda/6`.
• `recommended_z_step_um — lambda/step_divisor` (default lambda/8, the
usual 90-degree-per-plane choice), reported only if it is below the
ceiling.
• `capture_range_um` — the height interval over which the fringe contrast
stays above *min_visibility* of its peak,
`2*sigma*sqrt(2 ln(1/min_visibility))`. Outside it a surface produces
fringes too faint to locate, whatever the scan range is.
• `planes_per_envelope` — how many scan planes fall inside
`envelope_fwhm_um` at the recommended step. Below ~4 the three-point
estimators have nothing to fit.
• `n_planes / stack_elements / stack_megabytes` — the scan you are
about to run and the float64 stack it produces, plus
`stack_within_cap against :data:MAX_STACK_ELEMENTS`. This is the
number people discover after waiting for the scan.
• `phase_unambiguous_step_um — lambda/4`, the largest surface step
phase-shifting interferometry can measure without a fringe-order error.
It is here so the two families can be compared in one place: coherence
scanning has no such limit inside the scan range, and that is the
entire reason to pay for the scan.
What this deliberately does not return is a vertical *repeatability* — a
"resolution" in nanometres. That number depends on the signal-to-noise ratio
and on which of :data:ESTIMATORS you use, the estimators do not even rank
the same way with and without noise, and an attempt to verify the textbook
"two surfaces closer than the coherence length are unresolved" criterion
against this module's own forward model failed: two reflectors 0.4
coherence lengths apart still produce two envelope maxima, because the two
interferograms interfere with each other and the envelope of a sum is not the
sum of the envelopes. Rather than assert a formula that its own tests
contradict, this operator returns only quantities it can verify, and the
measured estimator table lives in the module docstring.
Raises `ValueError`: non-real / non-finite / string / bool parameters, a
non-positive wavelength / bandwidth / range, a *bandwidth_um* at or above
*wavelength_um* (a source whose spectrum reaches zero frequency is not a
quasi-monochromatic source and the coherence-length formula does not apply to
it), a *min_visibility* outside `(0, 1)`, a *step_divisor* below 4 (which
would recommend a step at or past its own Nyquist ceiling), and pixel counts
outside `[1, 65536]`.
• coherence_scanning family guide
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• The canonical algorithm (author, year) and its uses are named in the family usage guide above.
• coherence_scanning — py -3.11 examples/coherence_scanning.py
• poc_interferometry_step — py -3.11 examples/poc_interferometry_step.py
table as input)—
design)—
*Provenance: interferometry.py — INTERFEROMETRY operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.