fullseye

stokes_analyze — OPTICS polarization op

使い方

Read a Stokes vector: degree of polarisation, azimuth, ellipticity.

Returns a dict: intensity S0 · dop degree of polarisation sqrt(S1^2+S2^2+S3^2)/S0 · dolp linear part sqrt(S1^2+S2^2)/S0 · docp circular part |S3|/S0 · azimuth_deg orientation of the polarisation ellipse 0.5*atan2(S2, S1) mapped into [0, 180) · ellipticity_deg 0.5*asin(S3/|S|) in [-45, +45] · handedness one of "right" / "left" / "linear". azimuth_deg is measured from +x (along a row) toward +y (down the rows) — clockwise on a displayed image; "right" means S3 > 0, which on a displayed image (y down) is a counter-clockwise field rotation as seen by the camera (see :func:stokes_from_jones). The ellipticity is that of the polarised part (S3 over sqrt(S1^2+S2^2+S3^2)); pypolar divides by S0 instead, which for partially polarised light mixes the unpolarised part into the ellipse — the two agree only for fully polarised light (measured 2026-09-18).

azimuth_deg and ellipticity_deg are None when they are undefined — azimuth when the linear part is zero (circular or unpolarised light has no orientation), ellipticity when the polarised part is zero (unpolarised light has no ellipse). Returning 0.0 there would be a fabricated angle; None says the truth and forces the caller to handle it.

“Zero” is relative: <= 1e-12 * S0 (2026-10-24). Mueller products leave rounding dust: mueller_element("half_wave", 22.5) applied to [1, 1, 0, 0] gives S3 = 8.7e-17, which an exact S3 == 0 test reported as "right"-handed, and a quarter-wave plate at 45 on the same beam leaves a linear part of 8.7e-17 that came back as an azimuth of 22.5. The same floor decides handedness ("linear" when |S3| <= 1e-12 * S0), azimuth_deg and ellipticity_deg; it is relative to S0 so that it means the same at every intensity scale. dop / dolp / docp are returned as computed (the dust is an honest number there, as in :func:specularity.polarization_stokes_map).

Ground truth it reproduces exactly: [1,1,0,0] -> dop 1, azimuth 0, ellipticity 0, linear; [1,-1,0,0] -> azimuth 90; [1,0,1,0] -> azimuth 45; [1,0,0,1] -> docp 1, ellipticity +45, right-handed; [1,0,0,0] -> dop 0 with both angles None; [2,1,0,0] -> dop 0.5 (a partially polarised beam, which is exactly the case Jones algebra cannot express).

Raises ValueError: stokes is not a 1-D 4-vector, is complex / masked / non-finite, is unphysical (S0 < 0 or degree of polarisation above 1 — which is how you find out a Mueller matrix was not physical), or has S0 == 0 (no light at all: every ratio would be 0/0, and “the polarisation of darkness” is not a question with an answer).

ファミリ共通の入力契約(fail-closed)

optics の全 op は入力を検証してから計算する(黙って通さない):

詳しい使い方ガイド

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

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

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

abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd

同カテゴリ(polarization)

jones_element · jones_apply · stokes_from_jones · mueller_element · mueller_partial_polarizer · mueller_apply · polarization_demosaic · polarization_demosaic_color


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

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