photoelastic oppolsweep → tableimport fullseye as fs; fs.ledger.photoelastic_phase_estimate(images, analyzers='camera4', min_modulation=0.01, sum_tolerance=0.05) (実装を直接呼ぶなら import photoelastic; photoelastic.photoelastic_phase_estimate(images, analyzers='camera4', min_modulation=0.01, sum_tolerance=0.05)、台帳から引くなら opsoptics.get("photoelastic_phase_estimate"))偏光像から位相差 δ と主軸 θ を閉形式で逆算 → dict。
Inverse of :func:photoelastic_polarization_images (right-circular
illumination). With S0 = ½(I0 + I90 + I45 + I135) (the mean of the two
pair sums), S1 = I0 − I90, S2 = I45 − I135:
camera4 (4 linear analysers): sin δ = √(S1² + S2²)/S0 and
δ = arcsin(·) — unique only for δ ∈ [0, π/2] (a quarter wave):
linear analysers alone cannot see the sign of cos δ.stokes6 (+ right/left circular): S3 = IR − IL and
δ = atan2(√(S1² + S2²), S3) ∈ [0, π].In both, θ = ½ atan2(−S1, S2) mod 180 deg, in (−90, 90] — the fast axis
(for a material with C > 0, σ1 lies at θ + 90°). The pair
(δ, θ) and (−δ, θ + 90°) give identical images; the estimate
returns the representative with δ ≥ 0. Where the modulation
√(S1²+S2²)/S0 (= |sin δ|) is at or below min_modulation (default
0.01, i.e. δ within ~0.01 rad of 0 or π, where 1 % intensity noise already
turns the axis by tens of degrees) the axis is undefined: axis_valid is
False and axis_deg is 0 there.
One exposure obeys I0 + I90 = I45 + I135 (and = IR + IL). Real frames
do so only to the noise and the demosaic interpolation, so the check is per
pixel and relative: sum_mismatch = |I45 + I135 − (I0 + I90)| / S0 (for
stokes6 the larger of that and |IR + IL − S0| / S0).
images : (K, H, W) array or list of K frames in the order of analyzers.
analyzers : "camera4" (0/45/90/135) or "stokes6" (+ right/left circular).
min_modulation : modulation at or below which the axis is not reported.
sum_tolerance : largest sum_mismatch a pixel may have and stay valid
(relative to S0, default 0.05). Measured basis: with 1 % independent
noise per frame the mismatch stays below it (99th percentile 2.9 %,
maximum 4.6 % over 40 000 pixels), and the bilinear interpolation of
optics.polarization_demosaic leaves ≤ 1.5 % on 95 % of a disc with
nine resolved fringes; pixels above it are aliased fringes, saturated
or moving pixels, or frames from another exposure. Must lie in [0, 1].
Returns delta_rad, axis_deg, axis_valid, valid (sum_mismatch
≤ sum_tolerance; delta_rad is still computed where it is False but is
not a measurement there, and axis_valid is False), sum_mismatch,
modulation, intensity (S0) and stokes ((4, H, W); S3 = 0 for
camera4, which is a limitation, not a measurement).
Raises ValueError: wrong number of frames, non-2-D / non-finite /
negative frames, a dark pixel (S0 = 0), sum_tolerance outside [0, 1], or
frames whose pair sums disagree by more than sum_tolerance on more than
half of the pixels (not one camera exposure, the wrong frame order, or
fringes too dense for the sensor).
optics の全 op は入力を検証してから計算する(黙って通さない):
_mm / _um / _deg / _mrad。mm と µm の取り違えは crash ではなく「もっともらしく間違った答え」なので、名前で防ぐ。大きさから単位を推測する処理は一切しない。ValueError — float('50') は成功してしまうため、未パースの設定値が長さとして通り抜ける(実測: thin_lens('50', '200') がもっともらしい 66.667 mm を返していた)。bool も True == 1 の暗黙昇格として拒否。ValueError(実数枠のみ。虚部の無言切り捨て・マスク剥がしを拒否)。NaN/Inf は全入力で ValueError。depth_of_field の過焦点距離以遠の far_mm = inf(それが過焦点距離の定義)と gaussian_beam のウエストでの wavefront_radius_mm = inf(平面波面の曲率半径)。どちらも有限の相棒(far_is_infinite / curvature_per_mm)を併せて返す。それ以外の無言 NaN/Inf は内部で検出して ValueError —「float64 が溢れた」と「答えが無限大」は別の主張なので、後者の顔で前者を返さない。optics.MAX_GRID(4096)、供給された場/PSF/開口は optics.MAX_FIELD_ELEMENTS(2^24)、ABCD 素子列は optics.MAX_SYSTEM_ELEMENTS(1024)、Zernike は MAX_ZERNIKE_TERMS(512)/ MAX_ZERNIKE_ORDER(40)/ MAX_ZERNIKE_BASIS(2^25)。小さな引数から巨大な内部確保が起きる経路(実測: n_max=40 × 4096² で 108 GB)を fail-closed で塞ぐ。| 物理的に不可能な状態も拒否: 偏光度 > 1 の Stokes ベクトル、負の透過率、負の強度、n- | m | が奇数などの不正な Zernike 添字。 |
py -3.11 examples/photoelastic_roundtrip.pytable を入力に取れる)abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd
photoelastic)brazilian_disc_stress · kirsch_plate_stress · principal_stress · retardation_from_birefringence · photoelastic_retardation · retardation_convert · cubic_photoelastic_birefringence · silicon_piezo_optic_coefficients
Provenance: photoelastic.py — OPTICS operator registry. この per-op ノートは tools/opdocs.py md が自動生成(手編集しない)。
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.