polarization op• Data kinds: signal → matrix
• Call: import fullseye as fs; fs.ledger.mueller_from_intensities(intensities, psg, psa, rank_tol=1e-09) (implementation को सीधे call करना हो तो import optics; optics.mueller_from_intensities(intensities, psg, psa, rank_tol=1e-09), registry से लेना हो तो opsoptics.get("mueller_from_intensities"))
ज्ञात generator / analyser states से मापी गई intensities से Mueller matrix वापस निकालता है (polarimetric least squares)।
> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।
Model: the detector behind a polarisation-state analyser sees I_i = (A_i @ M @ G_i)[0, 0] = a_i^T M g_i where g_i = G_i[:, 0] is the Stokes vector the generator emits from unpolarised light and a_i = A_i[0, :] is the analyser's first row. That is linear in the 16 entries of M: I_i = w_i . vec(M) with w_i = outer(a_i, g_i).ravel(). Stacking the N measurements gives W (N x 16), solved by least squares.
*intensities* is (N,) (one detector) or (N, ...) (an image per
state: the same system solved per pixel, so the result is (4, 4, ...)). *psg* and *psa* are sequences of N Mueller matrices (4x4) — build them with mueller_element and matrix products.
Fail-closed on an under-determined design: if W has rank < 16 the design cannot see every entry (the classic case — linear polarisers only, no retarder — leaves the S3 row and column unobservable, rank 9) and the function raises with the rank instead of returning a pseudo-inverse answer that would look plausible and be wrong in the unobserved entries.
Ground truth in the tests: a known M (retarder then polariser), 36 generator/analyser pairs with quarter-wave plates, intensities computed by the forward model → M recovered to 1e-10; the same with polarisers only → rank 9, refused.
Raises ValueError: shapes disagree, fewer than 16 measurements, non-finite input, or rank < 16.
Provenance: the observation matrix outer(a, g) is the standard formulation (Chipman, "Polarimetry", *Handbook of Optics* ch. 15); the pinv variant is what Polanalyser's calcMueller does. Re-implemented with an explicit rank check.
optics के सभी ops गणना से पहले input की जाँच करते हैं (कुछ भी चुपचाप पास नहीं होता):
• Unit argument के नाम में ही लिखी होती है — _mm / _um / _deg / _mrad। mm और µm की गड़बड़ी crash नहीं करती, बल्कि "सही दिखने वाला पर गलत उत्तर" देती है, इसलिए नाम से इसे रोका जाता है। मान के आकार से unit का अनुमान बिल्कुल नहीं लगाया जाता।
• String से ValueError — float('50') सफल हो जाता है, इसलिए बिना parse किया config value length के रूप में निकल जाता (मापा गया: thin_lens('50', '200') सही दिखने वाला 66.667 mm लौटा रहा था)। bool को भी True == 1 वाले implicit promotion के रूप में अस्वीकार किया जाता है।
• complex / masked array से ValueError (केवल real-valued slots; imaginary part को चुपचाप छोड़ना या mask हटाना अस्वीकार)। हर input पर NaN/Inf से ValueError।
• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: focal length 0, radius of curvature 0, refractive index <= 0, पूरी तरह opaque aperture (सब 0, इसलिए normalisation 0/0), ऐसा PSF जिसका योग <= 0 हो, S0 = 0 वाला Stokes vector, और front focal point पर रखा object (image अनंत पर)।
• केवल 2 ops non-finite value लौटाते हैं, और वह भी contract के रूप में लिखा हुआ: depth_of_field hyperfocal distance से आगे far_mm = inf (hyperfocal distance की परिभाषा यही है) और gaussian_beam waist पर wavefront_radius_mm = inf (plane wavefront की radius of curvature)। दोनों साथ में एक finite साथी (far_is_infinite / curvature_per_mm) भी लौटाते हैं। इसके अलावा कोई भी चुपचाप आया NaN/Inf अंदर ही पकड़ा जाता है और ValueError देता है — "float64 overflow हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता।
• Size की सीमा: generate होने वाले grid के लिए optics.MAX_GRID (4096), दिए गए field/PSF/aperture के लिए optics.MAX_FIELD_ELEMENTS (2^24), ABCD element chain के लिए optics.MAX_SYSTEM_ELEMENTS (1024), Zernike के लिए MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25)। छोटे argument से बहुत बड़ा internal allocation होने वाले रास्तों (मापा गया: n_max=40 × 4096² पर 108 GB) को fail-closed ढंग से बंद किया गया है।
• भौतिक रूप से असंभव states भी अस्वीकार: degree of polarisation > 1 वाला Stokes vector, ऋणात्मक transmittance, ऋणात्मक intensity, और n-|m| odd जैसे अमान्य Zernike indices।
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• polarization_camera_pipeline — py -3.11 examples/polarization_camera_pipeline.py
matrix को input के रूप में लेते हैं)abcd_trace · mueller_apply · mueller_checks
polarization)jones_element · jones_apply · stokes_from_jones · mueller_element · mueller_apply · stokes_analyze · polarization_demosaic · polarization_demosaic_color
*Provenance: optics.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.