design op• 数据种类:无 → table(仅由参数决定的算子 —— 不接受图像或数据输入)
• 调用: import fullseye as fs; fs.ledger.lens_system(surfaces=None, stop=None, object_mm=inf, wavelength_um=0.58756, index_object=1.0, image_mm=None, field=None, aim='paraxial', vignetting=None, image_R=inf, image_k=0.0, afocal=False)(要直接调用实现,import raytrace; raytrace.lens_system(surfaces=None, stop=None, object_mm=inf, wavelength_um=0.58756, index_object=1.0, image_mm=None, field=None, aim='paraxial', vignetting=None, image_R=inf, image_k=0.0, afocal=False);从台账取用则 opsoptics.get("lens_system"))
• GPU:无(仅 CPU 参考实现)
构建经过校验的逐面处方(其他所有算子消费的那个 table)。
> 以下的详细说明为原文 —— 摘要与标题已翻译。
*surfaces* is a list; each entry is a dict {"R", "t", "n", "k", "ap", "mirror", "decenter", "tilt", "asph"} or a tuple (R, t, n[, k[, ap]]):
• R radius (mm, inf for flat), t thickness to the next surface (mm, the last one is the distance to the image plane when *image_mm* is not given — use None to place the image at the paraxial focus), n medium after the surface (index, (nd, vd) or glass), k conic (default 0), ap semi-aperture in mm (default None = unlimited), mirror bool, decenter (dx, dy) mm, tilt (ax, ay) degrees about x and y, asph even aspheric coefficients (A4, A6, A8, …) in mm⁻³, mm⁻⁵, … (default none = pure conic), f the focal length (mm, negative = diverging) of an ideal paraxial lens.
• An ideal lens surface ({"f": 50.0, "t": …}) has zero thickness, no shape and no glass (R is flat and n is the medium it sits in; both may be left out). It turns every ray by the thin-lens law exactly, tan θ' = tan θ − h/f per transverse axis (h = the ray height), so a collimated beam crosses the axis at f and a point object images at the Gaussian conjugate with m = −s'/s. Its optical path is the stigmatic one (f − √(h² + f²) for a collimated input, which is the quadratic phase −h²/(2f) at small h; a first surface with a finite object uses that object and its Gaussian image instead), so spot, OPD and PSF analyses of an aberration-free lens read zero aberration. It adds no Seidel terms and no dispersion, takes no mirror / conic / asph, and the non-coaxial raytrace3d does not read it.
• *stop*: index of the aperture-stop surface (default: the first surface). The stop's ap is the stop radius. If omitted, the smallest non-null aperture on any surface is used; an error is raised only if none exists.
• *object_mm*: distance from the first vertex to the object (inf for a collimated object); *index_object*: index of object space.
• *field*: default field for the analysis ops — degrees (infinite object) or object height in mm (finite object). Default 0 (on axis).
• *aim*: how the pupil rays are launched. "paraxial" (the default, and what every earlier version did) aims them at the paraxial entrance pupil, with only the chief ray moved onto the stop centre; in a system with pupil aberration the marginal rays then land outside the stop and are clipped (the stock Cooke triplet loses 48 of 217 rays on axis). "stop" is real-ray aiming: every pupil ray is iterated (Newton, tolerance 1e-11 of the stop radius, ValueError if it does not converge) so that it crosses the stop surface at the requested point, which is what lens-design software reports. See with_aiming.
• *vignetting*: per-field pupil vignetting factors as design software stores them, a list of {"field", "vdx", "vdy", "vcx", "vcy", "van"} (field in the same unit as *field*; missing keys are 0). Definition: the format's user guide (topic "Vignetting Factors") and knowledge-base article KA-01393. The normalised pupil p is first scaled and shifted, p' = (VDX, VDY) + diag(1 - VCX, 1 - VCY) p, and the result is then rotated by van degrees (counter-clockwise, x' = x cos - y sin): q = R(van) p' — the decentre rotates too. It is applied before the rays are aimed (at the stop with aim="stop", at the paraxial entrance pupil otherwise). A field between two records is interpolated linearly, one outside the listed range takes the nearest record. set_vignetting computes them from the apertures.
• a2 the r^2 term of the sag (mm^-1; the even asphere's PARM 1) and odd the general power series (B1, B2, ..., B8) added to the sag, z += B1 r + B2 r^2 + ... (an *odd asphere*; the coefficient of r^i is in mm^(1-i)). Both are left out of the surface dict when zero, so a prescription without them is bit-identical to before.
• solve a declarative rule that sets this surface's curvature or the thickness after it from the rest of the prescription (marginal / chief ray height or angle, paraxial image, F/#, concentric, aplanatic, pickup); lenssolve.lens_solve_set builds one, lenssolve.lens_apply_solves resolves them (lens_system resolves them once at construction, so the R / t it returns already hold the solved values). A surface with a thickness solve may leave t out.
• *image_R*, *image_k*: radius (mm, inf flat) and conic constant of the image surface; rays are intersected with it and spot / OPD are measured on it (the paraxial image is unchanged). Positive R: centre to the right.
• *afocal*: the image space is collimated (an afocal system: telescope, beam expander). It needs an object at infinity; paraxial_trace then reports angular_magnification and the exit pupil instead of a focal length (efl = bfl = inf), ray_bundle / spot_stats / ray_fan report the exit angle in arcminutes (relative to the chief ray) in place of the image-plane position, and opd_samples references a plane wave. A system flagged afocal whose collimated beam does not leave collimated is refused (ValueError).
Default (no *surfaces*): a plano-convex BK7 singlet, f ≈ 100 mm, f/4, stop at the first surface — a sensible starting point for the examples and for the no-argument registry call.
Returns a plain dict (JSON-friendly) — pass it to the other functions.
optics 的每个算子都先校验输入再计算(不让任何东西无声通过):
• 单位写进参数名 —— _mm / _um / _deg / _mrad。把 mm 和 µm 弄混不会崩溃,而是给出「看着合理却是错的答案」,所以用命名来防。这里绝不从数值大小去猜单位。
• 字符串一律 ValueError —— float('50') 会成功,于是未解析的配置值会被当成长度混进来(实测:thin_lens('50', '200') 曾返回看着合理的 66.667 mm)。bool 也按 True == 1 的隐式提升拒绝。
• complex / masked array 一律 ValueError(仅接受实数槽位;拒绝无声丢弃虚部或剥掉掩码)。所有输入中的 NaN/Inf 一律 ValueError。但已声明的缺测除外:bottle_fit_from_pattern 的 u_map 以 NaN 接收未能测得的像素(∞ 仍被拒绝)。
• 逐项点名拒绝除零及其近亲:焦距 0、曲率半径 0、折射率 <= 0、全不透明光阑(全为 0,归一化变成 0/0)、总和 <= 0 的 PSF、S0 = 0 的 Stokes 矢量、物体位于前焦点(像在无穷远)。
• 只有两个算子会返回非有限值,而且都写进了契约:depth_of_field 在超焦距以外返回 far_mm = inf(这正是超焦距的定义),gaussian_beam 在束腰处返回 wavefront_radius_mm = inf(平面波前的曲率半径)。两者都同时返回一个有限的搭档(far_is_infinite / curvature_per_mm)。除此之外的无声 NaN/Inf 都在内部检出并 ValueError ——「float64 溢出了」和「答案是无穷大」是两种不同的主张,不能拿后者的脸去交付前者。但已声明的缺测除外:bottle_background_map 对光线不可用的像素(全反射等)在 u_mm 中返回 NaN,并同时返回 valid 掩码和数量。
• 尺寸上限:生成网格受 optics.MAX_GRID(4096)限制,传入的场/PSF/光阑受 optics.MAX_FIELD_ELEMENTS(2^24),ABCD 元件序列受 optics.MAX_SYSTEM_ELEMENTS(1024),Zernike 受 MAX_ZERNIKE_TERMS(512)/ MAX_ZERNIKE_ORDER(40)/ MAX_ZERNIKE_BASIS(2^25)。以 fail-closed 堵住「小参数引发巨大内部分配」的路径(实测:n_max=40 × 4096² 需要 108 GB)。
• 物理上不可能的状态同样拒绝:偏振度 > 1 的 Stokes 矢量、负透过率、负强度、n-|m| 为奇数等非法 Zernike 指标。
• 示例数据目录(下载 URL / 许可证) —— 2-D 用 skimage.data(BSD/公有领域)加合成图,3-D 给出真实数据源(Stanford/PDS 等)的下载 URL。
• 算子来历与参考文献 —— 该算子族所依据的研究/方法出处。
• 算法的正典(作者、年份)与用途见上面的族使用指南。
• anim3d_lens_aberrations — py -3.11 examples/anim3d_lens_aberrations.py
• lens_calibration_loop_demo — py -3.11 examples/lens_calibration_loop_demo.py
• lens_defect_dataset_demo — py -3.11 examples/lens_defect_dataset_demo.py
• lens_design_demo — py -3.11 examples/lens_design_demo.py
• lens_optimize_demo — py -3.11 examples/lens_optimize_demo.py
• optical_design_metrics — py -3.11 examples/optical_design_metrics.py
• plenoptic_capture_pipeline — py -3.11 examples/plenoptic_capture_pipeline.py
• poc_chromatic_confocal — py -3.11 examples/poc_chromatic_confocal.py
• poc_lens_file_roundtrip — py -3.11 examples/poc_lens_file_roundtrip.py
• poc_lens_global_search — py -3.11 examples/poc_lens_global_search.py
• poc_lens_merit_operands — py -3.11 examples/poc_lens_merit_operands.py
• poc_lens_solves_afocal — py -3.11 examples/poc_lens_solves_afocal.py
• poc_lens_tolerancing — py -3.11 examples/poc_lens_tolerancing.py
• poc_material_optical_library — py -3.11 examples/poc_material_optical_library.py
• poc_noncoaxial_optics — py -3.11 examples/poc_noncoaxial_optics.py
• poc_optics_drawings — py -3.11 examples/poc_optics_drawings.py
• poc_photograph_through_prescription — py -3.11 examples/poc_photograph_through_prescription.py
• poc_plenoptic_camera — py -3.11 examples/poc_plenoptic_camera.py
• poc_tdi_linescan — py -3.11 examples/poc_tdi_linescan.py
• poc_telecentric_metrology — py -3.11 examples/poc_telecentric_metrology.py
• poc_zoom_configurations — py -3.11 examples/poc_zoom_configurations.py
table 作为输入)abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd
design)thick_lens · glass · example_system · glass_catalog · sellmeier · paraxial_trace · seidel_coefficients · spot_stats
*Provenance: raytrace.py — OPTICS 算子登记表。本条目由 tools/opdocs.py md 自动生成(请勿手工编辑)。*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.