fullseye

csi_peak_position — INTERFEROMETRY locate op

使い方

Surface height from one z-scan: the position of the coherence envelope peak.

This is the operator the whole module is for. Unlike a phase, an envelope has no period, so there is no fringe order to get wrong and no unwrapping to do — the height is simply where the fringe contrast is greatest, and it is correct for a surface step of any size that stays inside the scan.

mode picks the estimator. Measured on the reference scan (0.60 um wavelength, 2.83 um envelope FWHM, 0.05 um step, surface centred, four sub-step offsets), and then again with 1 % additive noise over 200 trials:

There is no single best estimator here and this module does not pretend otherwise: "gaussian" is 30x better than "parabolic" on clean data and indistinguishable from it on noisy data, where "centroid" beats both by 6.4x — and "centroid" is the only one of the four whose bias grows with how far the surface sits from the middle of the scan.

signal: 1-D scan intensities. z_step_um: spacing of the scan planes. Must be below the wavelength_um/4 Nyquist ceiling — see :func:csi_design. z_start_um: height of plane 0. wavelength_um: mean wavelength, used only for the Nyquist check. mode: one of :data:ESTIMATORS. remove_bias: passed to :func:csi_envelope. min_visibility: refuse a scan whose envelope prominence (max - median)/max is below this. A real interferogram scores 0.958; the chain fuzzer’s generic signal (a sinusoid plus 10 % noise, no coherence envelope at all) scores 0.241 and is refused; a constant scores 0.000. The argmax of a flat envelope is a plane noise chose, not a surface. max_edge_envelope: refuse a scan whose envelope has not decayed by the ends, max(env[0], env[-1]) / max(env) > this. See :func:_edge_level for the measured table this default of 0.05 comes from, and for the silent failure it exists to catch — a surface at 0.500 um read as 0.119 um, from an envelope peaking on an interior plane so that no first-or-last-plane check fires. Pass 1.0 to disable the check and accept that reading. carrier_tolerance: refuse a scan whose fringe carrier is more than this factor away from the 2/wavelength_um the stated wavelength implies. This is the unit guard, and it is the only thing standing between a nanometre/micrometre swap and a wrong answer: wavelength_um is otherwise used only for the Nyquist ceiling, so writing 600 instead of 0.6 silently disables that ceiling while changing nothing in the returned height (measured: the same 6.025 um either way). The default factor of 2 is deliberately loose — the measured ratio on real scans is 0.996 and stays there under 10 % noise, a truncated envelope and a 0.3 um envelope — because it exists to catch a factor of 1000, not to re-derive the wavelength. Scans shorter than 16 planes skip it (the FFT cannot resolve the carrier: the ratio is 0.667 at 9 planes). Pass 0 to disable.

Returns the height as a float, in the same units as z_start_um / z_step_um.

Raises ValueError: everything :func:csi_envelope raises, plus an unknown mode, a non-positive z_step_um / wavelength_um, a z_step_um at or past the Nyquist ceiling, an envelope prominence below min_visibility, an envelope edge level above max_edge_envelope, and an envelope peaking on the first or last plane (the surface is at or beyond the end of the scan). Those last three are the same trap in three shapes: each would otherwise return a height that is finite, plausible, and wrong.

Honest scope of the boundary check: it is a backstop, not the workhorse. The analytic-signal magnitude of a finite record is suppressed at its own endpoints, so a surface at z = 0.0 — or at -3.0 um, entirely outside the scan — comes back with its envelope maximum on plane 1, one plane inside the boundary, and the first-or-last-plane test does not fire. It fires for a genuinely monotone input (a ramp, an impulse on the first sample) and for a dead pixel. Everything else is caught by max_edge_envelope, and the tests pin both halves of that statement.

詳しい使い方ガイド

参考(サンプルデータ・文献)

実行できる例(この op を実際に呼ぶ検証済みサンプル)

型が繋がる次の op(measurement を入力に取れる)

同カテゴリ(locate)


Provenance: interferometry.py — INTERFEROMETRY operator registry. この per-op ノートは tools/opdocs.py md が自動生成(手編集しない)。

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.