jones_element — OPTICS polarization op

• Data kinds: कोई नहीं → cimage (केवल arguments से तय होने वाला op — यह कोई image या data input नहीं लेता)

• Call: import fullseye as fs; fs.ledger.jones_element(kind='polarizer', angle_deg=0.0, retardance_deg=90.0) (implementation को सीधे call करना हो तो import optics; optics.jones_element(kind='polarizer', angle_deg=0.0, retardance_deg=90.0), registry से लेना हो तो opsoptics.get("jones_element"))

उपयोग

एक polarisation element के लिए 2x2 complex Jones matrix।

> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।

*kind* is one of JONES_KINDS:

"polarizer" ideal linear polariser, transmission axis at *angle_deg* from x · "retarder" linear retarder, fast axis at *angle_deg*, retardance *retardance_deg* · "quarter_wave" / "half_wave" retarders with the retardance fixed at 90 / 180 degrees (*retardance_deg* is then ignored — stated here so a caller who passes one is not left wondering) · "rotator" optical rotator turning the polarisation by *angle_deg*.

The retarder is written symmetrically, diag(exp(-i*d/2), exp(+i*d/2)) before rotation, so it introduces no common phase — the fast axis leads. (Cross-checked 2026-09-18: Jones phase and handedness conventions differ per library — pypolar carries two and this matches neither away from 0 degrees — so the comparison is made in the Mueller domain: every kind, pushed through stokes_from_jones, equals pypolar's Mueller element to 1e-15. The rotator turns the state by +angle, so pypolar op_rotation / polanalyser rotator — coordinate rotations — equal ours at -angle. See tests/test_polarization_external_diff.py.) Elements are built as R(+a) @ J0 @ R(-a).

Returns a (2, 2) complex128 matrix acting on a Jones vector [Ex, Ey]; compose a train with J_total = J_last @ ... @ J_first and apply it with jones_apply.

Ground truth it reproduces exactly (machine precision): two crossed ideal polarisers multiply to the zero matrix; a polariser is idempotent (P @ P == P); a half-wave plate is an involution up to a global phase (H @ H == -I in this symmetric convention); a quarter-wave plate at 45 degrees turns horizontal linear light into circular (|S3| == 1); the Malus law cos^2(theta) falls out of two polarisers at relative angle theta.

Raises ValueError: an unknown *kind* (the message lists the valid ones); non-finite *angle_deg* or *retardance_deg*.

Ideal, lossless, normal-incidence elements. A real polariser has a finite extinction ratio and a real waveplate is chromatic; neither is modelled, and neither is silently approximated. Jones algebra can only carry fully polarised light — for partial polarisation use mueller_element.

पूरी family का input contract (fail-closed)

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।

उपयोग की विस्तृत guide

• optics_imaging family guide

संदर्भ (sample data, साहित्य)

• 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 में दिए गए हैं।

चलाए जा सकने वाले उदाहरण (verified samples जो सच में यह op call करते हैं)

• optics_imaging — py -3.11 examples/optics_imaging.py

वे अगले ops जिनसे type जुड़ता है (cimage को input के रूप में लेते हैं)

angular_spectrum_propagate · four_f_filter · jones_apply

इसी category के (polarization)

jones_apply · stokes_from_jones · mueller_element · mueller_apply · stokes_analyze · polarization_demosaic · polarization_demosaic_color · mueller_from_intensities


*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.