mtf_diffraction — OPTICS imaging op

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

• Call: import fullseye as fs; fs.ledger.mtf_diffraction(f_number=5.6, wavelength_um=0.55, samples=64) (implementation को सीधे call करना हो तो import optics; optics.mtf_diffraction(f_number=5.6, wavelength_um=0.55, samples=64), registry से लेना हो तो opsoptics.get("mtf_diffraction"))

उपयोग

circular pupil का diffraction-limited MTF (closed form)।

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

MTF(x) = (2/pi)*(arccos(x) - x*sqrt(1 - x^2)) with x = nu/nu_c the frequency normalised to the cutoff nu_c = 1/(lambda*N). This is the

ceiling: no aberration-free lens at this f-number can do better, and a

measured psf_to_mtf curve above it means the measurement is wrong.

Returns a (samples, 2) float64 pairs array: column 0 the spatial frequency in cycles per millimetre from 0 to the cutoff, column 1 the MTF in [0, 1].

Ground truth it reproduces exactly (machine precision): MTF(0) = 1, MTF(nu_c) = 0, and at half the cutoff the textbook 0.391 ((2/pi)*(pi/3 - sqrt(3)/4) = 0.3910022...). The cutoff itself at lambda = 0.55 um, N = 5.6 is 324.7 cycles/mm — which is why stopping a machine-vision lens past f/8 stops buying depth of field and starts buying blur (compare depth_of_field).

Raises ValueError: non-positive or non-finite *f_number* / *wavelength_um*; *samples* outside [2, MAX_GRID].

Incoherent illumination, circular unobstructed pupil, no aberration, no defocus, and no detector: the pixel aperture and the sensor's own MTF multiply on top of this and are not included.

पूरी 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

पृष्ठभूमि guides (इस op के पीछे की physics और conventions)

• measurement_uncertainty — Measurement uncertainty और calibration — 'हम माप रहे हैं' कहने के लिए क्या चाहिए

• mv_cameras — Industrial camera निर्माता (sensor mapping, line scan / TDI)

• virtual_machine_vision — Virtual machine vision — parameters की सूची और एक object model

संदर्भ (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

• poc_veiling_glare — py -3.11 examples/poc_veiling_glare.py

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

mtf50

इसी category के (imaging)

psf_to_mtf · wavefront_stats · edge_spread · sfr_from_edge · mtf50 · veiling_glare_index


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