merit_default — OPTICS lensmerit op

• Data kinds: table → table

• Call: import fullseye as fs; fs.ledger.merit_default(system=None, kind: 'str' = 'spot', fields=None, wavelengths=None, rings: 'int' = 4, reference: 'str' = 'chief', efl_target=None, efl_weight=None, field_weights=None, wavelength_weights=None, pupil_fill: 'float' = 0.98) -> 'dict' (implementation को सीधे call करना हो तो import lensmerit; lensmerit.merit_default(system=None, kind: 'str' = 'spot', fields=None, wavelengths=None, rings: 'int' = 4, reference: 'str' = 'chief', efl_target=None, efl_weight=None, field_weights=None, wavelength_weights=None, pupil_fill: 'float' = 0.98) -> 'dict', registry से लेना हो तो opsoptics.get("merit_default"))

• GPU: नहीं (केवल CPU reference implementation)

उपयोग

default merit function को operand table के रूप में बनाता है: पूरे pupil की ray पंक्तियाँ और EFL hold (table)।

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

One group row per field and wavelength: kind="spot" is TRAN (transverse ray aberrations, mm), kind="wavefront" is OPDW (OPD, waves); *reference* "chief" measures from the chief ray (for the

wavefront: the OPD as it is, relative to the chief ray) and "centroid" from the centroid of the spot (for the

wavefront: the mean OPD removed). The pupil is hexapolar with *rings* rings out to *pupil_fill*. The row weight is sqrt(field_weight x wavelength_weight) (default 1). The EFL hold is an EFFL row with target *efl_target* (default the starting EFL; False for none) and weight efl_weight / |target|; the default *efl_weight* is 10 sqrt(n_rays) for the spot and 100 sqrt(n_rays) for the wavefront. For kind="spot", reference="chief" the total equals lensopt.merit_function on the same pupil.

Returns {"operands", "fields", "wavelengths", "kind", "reference", "rings", "pupil_fill", "efl_target", "efl_weight", "n_rays"}; pass it (or its "operands" with fields= and wavelengths=) to the other ops.

Example::

m = merit_default(lens, kind="wavefront", rings=3)

merit_evaluate(lens, m)["merit"]

पूरी 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। घोषित अपवाद: bottle_fit_from_pattern का u_map न मापे जा सके पिक्सेल को NaN के रूप में लेता है (अनंत अब भी अस्वीकार)।

• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: 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 हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता। घोषित अपवाद: bottle_background_map जिन पिक्सेल की किरण अनुपयोगी है (पूर्ण आंतरिक परावर्तन आदि) उनके लिए u_mm में NaN लौटाता है, साथ में valid मास्क और गिनती भी।

• 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 करते हैं)

• optimized_lens_tolerance_sensitivity — py -3.11 examples/optimized_lens_tolerance_sensitivity.py

• poc_lens_merit_operands — py -3.11 examples/poc_lens_merit_operands.py

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

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

इसी category के (lensmerit)

merit_operands_list · merit_evaluate · merit_boundary_operands · optimize_lens_operands · merit_contributions


*Provenance: lensmerit.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*

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