.lens Guide
.lens is LensBench's lens data file. It is the equivalent of Zemax's Lens Data Editor plus System Explorer, plus the merit function, multi-configuration, tolerancing, and plot / acceptance settings, all written as text. This page walks you through writing a lens from scratch; for a statement-by-statement syntax reference, see .lens 语法参考.
One statement per line
head positional-args... key=value ... # comment- Statement names are case-insensitive, and so are parameter names (
R=andr=are the same). - Positional arguments are separated by spaces or commas.
- Numbers can carry units:
T=2000um,wave 550nm,field angle 0.5deg. Without a unit the defaults apply: length in mm, wavelength in µm, angle in degrees. - A mistake never crashes anything: every error comes with a line and column, a diagnostic code, and a "did you mean ..." hint; see 诊断码.
- Save files as UTF-8 (a leading BOM is fine). A Zemax
.zmxcannot be used as a.lensdirectly; convert it first withlb import-zmx x.zmx.
Step 1: System setup
title "Singlet"
aperture EPD 10 # entrance pupil diameter 10 mm; FNO 5 / NA 0.1 / float also work (float needs semi= on the stop surface)
field angle 0, 5 # two fields: 0° and 5°
wave F, d*, C # three wavelengths; * marks the primary wavelength; numbers such as 0.55* or 550nm* also work
ray_aim real # ray aiming: off (default, aim at the paraxial entrance pupil) / real (iteratively aim at the stop) / robust (large fields, wide angle) / real_stop (stop size set by real rays)If you leave these out: the aperture defaults to EPD 10, the field to on-axis, and the wavelength to the d line, and each of these is reported to you as an info message; ray aiming defaults to off. For wide-angle systems, large fields, or systems with strong stop aberrations, use ray_aim real; for an example see the reference design “广角” (Wide Angle) (desktop app: “主页” (Home) › “参照设计” (Reference designs)). With real / robust the stop size is set paraxially (equivalent to Zemax's Paraxial aiming); with real_stop it is set by real rays (equivalent to Zemax's Real aiming): the real marginal ray of the on-axis field exactly satisfies the aperture in object space — for an object at infinity it is parallel to the axis at height EPD/2, and for an object-space NA its angle to the axis is exactly asin(NA) — and its height at the stop is the stop radius. For systems with a large aperture and strong stop aberrations, or a wide angle, the two differ noticeably (for the “Wide Angle” reference design by 0.4 %); when comparing numbers with Zemax, pick the same one as on the Zemax side. If the marginal ray defined by the aperture cannot get through (total internal reflection, missing a surface), real_stop cannot determine the stop size and the build reports E-KERNEL; reduce the aperture or switch to real.
Object-space telecentric (common for microscope objectives, projection lenses, and machine-vision lenses): add telecentric at the end of the aperture line, and the chief ray is parallel to the axis in object space (Zemax's Telecentric Object Space). This requires a finite object distance, object_height fields (or an image-height type), and an NA or float aperture (entrance pupil diameter and image-space F/# are defined through the entrance pupil and are meaningless here); ray aiming has no effect in this case (same as Zemax). With float, the object-space aperture angle comes from the paraxial ray that leaves the object point and reaches the stop at its semi-diameter. A stop placed exactly at the rear focal plane of the front group (true object-space telecentricity, entrance pupil at infinity) builds too: lb paraxial reports the entrance pupil diameter and position as inf and the image-space F/# as “not applicable”, while the effective focal length, magnification, exit pupil, Seidel, spot diagram, MTF, etc. are computed as usual (for the image-side aperture use the working F/#, op WFNO):
aperture NA 0.133 telecentric
field object_height 0, 32, 48
surf OBJ T=110.86Afocal image space (telescopes, beam expanders, riflescopes — systems whose image-space beam is collimated): add a line afocal image (Zemax's Afocal Image Space) and aberrations are evaluated in angle — the spot diagram, ray fans, RMS spot and TRAX / TRAY / TRAR / TRAC / RSCE / RSCH, and default spot become the angle between each image-space ray and the chief ray (or centroid) direction (difference of direction cosines in the image surface's local frame), in mrad by default; unit= switches to urad / rad / arcsec / arcmin / deg (Zemax's Afocal Mode Units). OPD, wavefront map, Zernike, RWCE / RWCH and Strehl use a plane reference wave at the exit pupil, normal to the chief ray; FFT MTF frequencies are in cycles/mrad (cutoff = beam diameter / λ) and the PSF is plotted in µrad; field curvature is the beam vergence in diopters (D = 1/m, positive = converging after the image surface) and distortion compares the tangent of the image-space chief-ray angle with the angular magnification. lb paraxial reports the angular magnification AMAG (operand op AMAG) and marks effective focal length, back focal length, F/# and paraxial magnification “not applicable”. It only changes how the system is evaluated, not the rays; analyses defined in length (Huygens PSF / MTF, through-focus, longitudinal aberration, chromatic focal shift, relative illumination, encircled energy, image simulation, grid distortion) report an error in afocal mode. Operand targets can carry angle units: op TRAY Hy=1 Py=1 <= 0.1mrad; default angular (Zemax's Angular Radius) is the same as default spot in afocal mode:
afocal image unit=arcsecWhen fields carry weights or vignetting factors, write one point per line:
field angle 0
field angle 14 w=2
field angle 20 vcy=0.1Other field types are paraxial_image_height and real_image_height; a point that is not in the y direction is written as (x, y), for example field angle (0, 0), (3, 5). Wavelength weights are written w=; with weights, write one wavelength per line: wave 0.55 w=2.
Step 2: Surfaces
The surface number is the position: the first surface is OBJ (number 0), the last is IMA, and those in between are numbered in order.
surf OBJ T=inf
surf 1 stop R=51.68 T=5 glass=SCHOTT:N-BK7
surf 2 R=-51.68 T=48
surf IMAglassis the medium after this surface (as in Zemax); if omitted it is air.stopmarks the stop surface (you can also write the number asSTO).- If the object surface has no T, it defaults to
T=inf(object at infinity).
Glass
| Syntax | Meaning |
|---|---|
N-BK7 | Exact lookup in the catalogs listed in catalogs; the first hit in order wins |
SCHOTT:N-BK7 | Pin the manufacturer |
MIRROR | Reflective surface |
model(1.6, 55) | Model glass (nd, vd), dispersion by a three-term Buchdahl polynomial |
model(1.6, 55, polynomial) | Model glass with dispersion from a polynomial fit (the model used by the OpticChat corpus; defined only over 0.38–0.75 µm, an error is raised outside that range) |
ideal(1.5) | Ideal material without dispersion |
file("main/CaF2/Malitson.yml") | Point directly at a material file in the built-in material library |
The lookup order is set by the catalogs statement; the default is catalogs SCHOTT, OHARA, CDGM, HOYA, HIKARI, SUMITA. To change the order, write one line, for example catalogs SCHOTT, CDGM.
Built-in crystals and common plastics: the names below can be written directly (the same names as in Zemax's MISC / INFRARED catalogs), or pinned as BUILTIN:CAF2. Without a manufacturer, an exact lookup is made first in the manufacturer glasses of catalogs, and the built-in ones are used only if nothing is found there. The data are public-domain literature values (one fixed set per grade; the data source is written into diagnostics and evidence records), and may differ slightly from the values in Zemax's own catalogs; for bit-for-bit agreement with Zemax, load the same catalog with agf.
| Syntax | Material | Data source | Data coverage (µm) |
|---|---|---|---|
CAF2 | Calcium fluoride | Malitson 1963 | 0.23–9.7 |
BUILTIN:BAF2 | Barium fluoride (an unqualified BAF2 first hits the CDGM glass of the same name) | Malitson 1964 | 0.27–10.3 |
MGF2 | Magnesium fluoride (ordinary ray) | Dodge 1984 | 0.2–7.0 |
LIF | Lithium fluoride | Li 1976 | 0.1–11 |
SAPPHIRE | Sapphire (ordinary ray) | Malitson & Dodge 1972 | 0.2–5.0 |
ZNSE / ZNS | Zinc selenide / zinc sulfide | Connolly 1979 / Debenham 1984 | 0.54–18.2 / 0.41–13 |
GERMANIUM / SILICON | Germanium / silicon (infrared) | Burnett 2016 / Salzberg 1957 | 2–14 / 1.36–11 |
SILICA (= F_SILICA) | Fused silica | Malitson 1965 | 0.21–6.7 |
POLYCARB / PMMA / POLYSTYR | Polycarbonate / acrylic / polystyrene | Sultanova 2009 | 0.44–1.05 |
Manufacturer glasses (about 1700 grades from SCHOTT, OHARA, CDGM, HOYA, HIKARI, SUMITA and others, taken from the public compilation at refractiveindex.info) ship with the software and are not in this table; for bit-for-bit agreement with Zemax, again load the same catalog with agf. Manufacturer plastics (ZEONEX E48R, APEL APL5514ML, etc.) are not built in; load the manufacturer's AGF with agf.
When the same grade name appears at several manufacturers (for example F2 exists at SCHOTT, HIKARI, and CDGM), you are asked to write it as manufacturer:grade. If you are unsure of the grade, search: lb glass "N-SF*" --catalogs SCHOTT.
Using a manufacturer's official Zemax glass catalog (AGF): download the .AGF file from the manufacturer's site, put it next to the lens, and add a line agf "SCHOTT.AGF". The manufacturer name is taken from the file name; grades in an AGF take precedence over the built-in library and are searched before catalogs; all 13 Zemax dispersion formulas are supported. To search an AGF: lb glass "N-*" --agf SCHOTT.AGF.
Using the entire glass library of a local Zemax installation: agf can also point at a directory, for example agf "C:/Users/you/Documents/Zemax/Glasscat". Each .AGF in the directory is one manufacturer catalog (including discontinued older grades such as BK7 and SK16), searched in the order of catalogs — the same as Zemax's GCAT, so designs imported from Zemax line up most easily with this. Grades are still matched exactly, with no alias substitution. When a glass cannot be found and Zemax is installed on this machine, the diagnostic shows its Glasscat directory and the line to add (it only suggests; nothing is loaded automatically).
Aspheres
surf 1 type=evenasph R=40 k=-0.6 a4=2e-5 a6=-3e-8 T=5 glass=SCHOTT:N-BK7Coefficients are named by power: a4 is the r⁴ term and a6 is the r⁶ term. An even asphere allows only even powers, while an odd asphere (type=oddasph) allows any (up to a30). This avoids the classic mix-up over whether the first entry of a coefficient table is the r² or the r⁴ term.
Zemax's Extended Odd Asphere (XOSPHERE in zmx) is imported as type=oddasph: the coefficients are converted by the normalization radius as aᵢ = Aᵢ / normⁱ, and it is the same surface. On export, an asphere with odd terms beyond r⁸ (ODDASPHE has only 8 parameters) or even terms beyond r¹⁶ is written as XOSPHERE (normalization radius 1).
Toroidal surfaces and ideal thin lenses
surf 1 type=toroidal R=20 rx=35 k=-0.5 a4=1e-6 T=4 glass=SCHOTT:N-BK7 # toroidal surface
surf 1 type=toroidal R=20.2 T=3.8 glass=SCHOTT:N-BK7 # cylinder (omitting rx = inf)
surf 3 type=paraxial f=50 T=50 # ideal thin lens, focal length 50
surf 4 type=tilted tany=0.1 T=5 glass=SCHOTT:N-BK7 # tilted plane z = 0.1·y- Toroidal surface (Zemax Toroidal):
R,k, anda2 a4 …all describe the curve in the YZ section (even terms), andrxis the radius of revolution about an axis parallel to the y axis (the vertex radius of curvature in the XZ section; omitted, or 0 / inf, it is a cylinder with power only in the YZ section). Paraxial quantities and Seidel coefficients are computed for the YZ section. - Ideal thin lens (Zemax Paraxial): the surface itself is flat and only the focal length
fis given; for aberration-free incident light it images perfectly at any field and any conjugate, with zero third-order aberrations. The optical path is computed as in Zemax's OPD Mode:opd_mode=0(default) compensates the path with the fixed conjugate of the field;opd_mode=1integrates the actual deflection ray by ray, which is more accurate for incident light carrying aberrations but dozens of times slower (zmx PARM 2; Mode 2 / 3 are not supported and are imported as 0). It cannot have R / k / asphere coefficients and cannot be MIRROR. - Tilted plane (Zemax Tilted): z = tanx·x + tany·y; only this surface is tilted and later surfaces are unaffected (equivalent to "coordinate break + plane + reverse coordinate break"); a system with a tilted plane is built with absolute poses, just like a coordinate-break system, and does not support solve or thickness pickup.
- zmx: PARM 1 of TOROIDAL is the radius of revolution (0 = infinity), and PARM 2 onward are the coefficients of y² y⁴ …; PARM 1 of PARAXIAL is the focal length. User-defined surfaces (USERSURF, which depend on a DLL) cannot be imported.
Diffractive surface (Binary 2)
surf 1 stop type=binary2 R=24.33 T=2 glass=SCHOTT:N-BK7 norm=10 p2=-443.5 p4=258.6 # hybrid diffractive-refractive lens- A phase Φ = m·Σ pN·ρᴺ (radians) is added on an even-asphere base (
R,k,a2 a4 …), with ρ = r /norm(the normalization radius, in mm). Phase terms are named by the power of ρ:p2is the ρ² term (Zemax's A1),p4is the ρ⁴ term (A2), and so on; only even powers exist. If you write phase terms you must writenorm. mis the diffraction order; omitted = 1. Rays are deflected according to n′·sinθ′ = n·sinθ + λ/(2π)·∂Φ/∂r, so p2 < 0 converges (positive power): the paraxial power is φ = −λ·m·p2 / (π·norm²), proportional to wavelength — this is why a diffractive surface's "negative dispersion" (Abbe number about −3.45) can be used for achromatization.- Paraxial quantities (EFFL, BFL, paraxial solves) and Seidel coefficients (a diffractive surface has no field-curvature contribution) include the diffractive power; phase terms can be variables:
var p2@1 p4@1. - Diffraction efficiency is taken as 100 % (only the stated order is traced); diffractive mirrors (MIRROR) are not yet supported.
- zmx: PARM 0 of BINARY_2 is the diffraction order (older files omit it and are imported as order 1), PARM 1–8 are the base r² … r¹⁶ terms, Extra Data 1 is the number of phase terms, 2 is the normalization radius, and 3 onward are the coefficients of ρ², ρ⁴ …; variable flags on the phase terms are imported and exported.
Diffraction grating
surf 3 type=grating R=-500 T=-250 glass=MIRROR lines=1200/mm m=-1 # concave reflection grating, order −1
surf 2 type=grating T=10 lines=0.6/um m=1 # transmission grating (600 lines/mm)- On a standard surface (
R,k, can beMIRROR) the grooves run parallel to the local x axis (use a coordinate break to change the direction), and deflection happens only in the y direction: n′·M′ = n·M + m·λ·lines (M is the y direction cosine). Order 0 is plain specular reflection / straight transmission; the Littrow angle is sinθ = −m·λ·lines/2. linesmust carry a unit:1200/mmor1.2/um(Zemax takes lines per µm, a factor of 1000 different, so no unit is assumed by default).momitted = 1.- The grating deflection is a constant, not a linear paraxial term: paraxial quantities (EFFL, F-number, entrance and exit pupils, paraxial solves) and Seidel coefficients are computed for order 0 (base surface only), and the build issues an
I-GRATING-PARAXIALmessage; real-ray analyses such as spot, ray fan, and MTF use the order you wrote. To see the image position at each wavelength of a spectrometer, uselb rayor the spot diagram. - zmx: PARM 1 of DGRATING is lines per µm (not converted with the lens unit), and PARM 2 is the diffraction order.
Zernike sag surfaces
surf 2 type=zernike R=-50 k=-0.5 a4=1e-6 norm=9 z4=0.002 z6=-5e-4 z11=1e-4 T=45 # Zernike Standard sag
surf 4 type=zernike_fringe norm=4 z5=1e-3 z9=-2e-4 zdy=0.5 T=2 glass=SCHOTT:N-BK7 # Fringe numbering, Zernike part decentered- An even-asphere base (
R,k,a2 … a16) plus Σ zN·Z_N(ρ, θ): ρ = r /norm(normalization radius, mm), θ measured counter-clockwise from +x; the coefficientszNare lengths (mm by default;z4=2umworks too). Once Zernike terms are written,normis required. The surface may be aMIRROR(deformable mirrors, freeform mirrors). type=zernike(Zemax Zernike Standard Sag): the numbering and normalization are those of Zemax's Zernike Standard Coefficients — Noll numbering, RMS = 1 over the unit circle (Z4 = √3(2ρ² − 1) defocus, Z5 = √6ρ² sin 2θ and Z6 = √6ρ² cos 2θ astigmatism, Z7 / Z8 coma, Z11 = √5(6ρ⁴ − 6ρ² + 1) spherical …), the same set aslb zernikeand the ZERN operand, up toz231.type=zernike_fringe(Zemax Zernike Fringe Sag): Fringe numbering, unnormalized (amplitude 1 at ρ = 1, Z4 = 2ρ² − 1, Z9 = 6ρ⁴ − 6ρ² + 1), up toz37.zdx/zdy: decenter only the Zernike part (ρ and θ use (x − zdx, y − zdy)), not the base;extrapolate=0: outside the normalization radius (ρ > 1) only the base remains (default 1: the Zernike terms are evaluated everywhere).- Zernike terms are not paraxial: EFFL, BFL, F/#, and paraxial solves use only the base R, Seidel uses R, k, a4 (the same convention as a2 not entering the paraxial model); the build reports
I-ZERN-PARAXIAL. Spot, ray fans, wavefront, MTF and other real-ray analyses include all terms. To have the paraxial quantities reflect defocus, put the power into R. - Zernike terms can be variables:
var z4@2 z6@2 z11@2(terms not written start at 0); the baseR/k/aNas usual. - zmx: for SZERNSAG / FZERNSAG, PARM 0 is the extrapolate flag, PARM 1–8 are the base r² … r¹⁶ terms, PARM 9 / 10 the Zernike decenter x / y; Extra Data 1 is the number of terms, 2 the normalization radius, and from 3 on the coefficients of Zernike 1, 2 … (lengths, scaled with the lens units); variable flags on the coefficients are imported and exported.
solve and pickup
surf 6 R=-18.39533 T=solve(marginal_height, 0) # solve the thickness to the paraxial focus
surf 5 R=solve(fnum, 4) # solve the curvature to image-space F/4
surf 3 R=pickup(1, scale=-1) # radius is the negative of surface 1's
surf 1 T=solve(edge_thickness, 1.5, 12) # edge thickness 1.5 at radial height 12 (without a height, this surface's semi is used)
surf 4 T=solve(position, 120, 1) # 120 from the vertex of surface 1 to the vertex of surface 5
surf 2 R=solve(aplanatic) # marginal ray is aplanatic at this surface (no spherical aberration, coma, or astigmatism)
surf 7 R=solve(concentric_surface, 9) # center of curvature falls on the vertex of surface 9
surf 8 R=solve(concentric_radius, 7) # concentric with surface 7
surf 4 glass=pickup(2) # medium after the surface copied from surface 2
surf 5 a4=pickup(2, scale=-1) # r⁴ term is the negative of surface 2'sA solve is interpreted according to Zemax semantics wherever it is placed: a marginal_height on the thickness of surface j controls the marginal ray height on surface j+1; edge_thickness / position on a thickness likewise adjust the thickness of surface j and move surface j+1 and everything after it. Solves are computed at build time and the results are not written back to the text. The reference surface of position must be before this surface or this surface itself; the reference surface of the two concentric solves cannot be this surface. aplanatic applies only to refracting surfaces. A glass pickup takes only the source surface (no scale / offset) and copies the source surface's glass at parse time (in multi-configuration designs it follows the source surface's glass in each configuration); for an asphere-coefficient pickup, both the source surface and this surface must be evenasph / oddasph / binary2 / zernike / zernike_fringe. For all kinds see lb help solve.
Surface aperture and obscuration (vignetting)
semi= is only the clear semi-diameter (used for drawing and edge-thickness checks) and does not block light — just like Zemax's Semi-Diameter. To make a surface block light, write aperture=, which corresponds to Aperture in Zemax's surface properties:
surf 4 stop R=20.3 T=4.75 aperture=circular(4.5) # circular aperture: rays outside radius 4.5 are blocked
surf 5 R=79.7 T=2.95 aperture=circular(1.5, 12.5) # annulus: (Min Radius, Max Radius), same order as Zemax
surf 2 T=0 aperture=obscuration(12) # circular obscuration: blocked within the central 12 mm (Cassegrain secondary)
surf 7 T=5 aperture=rectangular(3, 2) # rectangular aperture: x half-width 3, y half-width 2
surf 3 R=-50 T=30 semi=9 aperture=float # floating aperture: blocks by semi-diameter (by semi if semi is fixed)
surf 1 stop R=50 T=5 aperture=circular(1.5, 12.5, dx=2.25, dy=-3.5) # decentered aperture (Aperture X/Y-Decenter)| Syntax | Zemax | Which rays are blocked |
|---|---|---|
circular(max) / circular(min, max) | Circular Aperture | landing radius < min or > max |
obscuration(max) / obscuration(min, max) | Circular Obscuration | landing radius within [min, max] |
rectangular(x half-width, y half-width) | Rectangular Aperture | |x| > x half-width or |y| > y half-width |
float | Floating Aperture | landing point outside the semi-diameter |
any of the above plus dx= dy= | Aperture X/Y-Decenter | aperture center shifted to (dx, dy) |
- The test is made in the surface's local coordinates (the aperture travels with the surface, also for decentered and tilted surfaces); lengths may carry units (
circular(4500um)). - Blocked rays are not counted in the spot diagram, MTF, wavefront, or footprint; in the layout plot, rays are drawn only up to the surface that blocks them, obscurations are drawn as thick black lines, and when the aperture is larger than the beam the surface is drawn out to the aperture edge.
- The footprint plot draws the aperture outline (dash-dot line) and the obscuration (gray), and "outside the aperture" is counted by aperture.
- The automatic semi-diameter is computed from the beam as if nothing were blocked (independent of apertures).
- zmx import / export: CLAP / OBSC / SQAP / FLAP / OBDC map one to one; elliptical apertures, rectangular obscurations, spider vanes, and so on are not yet supported (a warning is shown on import).
Coordinate breaks (fold, tilt, decenter)
As in Zemax, use a coordinate-break surface to change the coordinate system of the following surfaces:
surf 2 R=-50 T=30
surf 3 type=coordbreak tx=45 T=0 # coordinate system rotated 45° about x
surf 4 T=0 glass=MIRROR # mirror in the tilted coordinate system
surf 5 type=coordbreak tx=45 T=-15 # rotated another 45°; after reflection the light travels along −z, so the thickness is negative
surf IMA- Parameters:
dxdy(decenter, mm),txtytz(tilt, degrees), andorder(0 = decenter first, then tilt about the current x→y→z axes in turn; 1 = tilt z→y→x first, then decenter). - A coordinate-break surface does not trace rays itself and the medium carries over from the previous surface; it cannot have a radius, glass, or solve, and cannot be the object surface, image surface, or stop.
- Systems containing coordinate breaks do not yet support solve or thickness pickup (use optimization instead).
- With only flat fold mirrors, paraxial quantities are computed on the unfolded coaxial system; when a surface with power is decentered / tilted, paraxial quantities are unavailable (info message), while real-ray analyses such as spot, ray fan, and MTF work as usual. For a complete example see the reference design “折转镜” (Fold Mirror).
- As in Zemax, Seidel coefficients ignore coordinate breaks: decenters and tilts are treated as 0 and the system is computed as coaxial (coordinate breaks contribute nothing, a tilted plane is treated as a plane, and mirrors still fold), so a surface with power that is decentered / tilted is still computed, and the output and plots carry the note “含坐标断点:Seidel 按忽略断点后的同轴系统算(同 Zemax)” (contains coordinate breaks: Seidel is computed for the coaxial system with the breaks ignored, same as Zemax). If some coordinate system is rotated by more than 90° with no mirror folding the light back (the local z axis opposes the direction of travel), the thicknesses and curvature signs read out as coaxial no longer match the real light path, and Seidel is not given, with a note on which surface is responsible.
Step 3: Variables
var R1..R6 T6 a4@5R / T / K can be written as R3, T6, K2; other parameters are written as parameter@surface-number. A reference or range can be followed by lower and upper bounds, which are respected during optimization: var R1 in 10..100 T6 in 30..50 (R and T are lengths and may carry units; the two ends of a radius bound must have the same sign). To remove a variable, use lb fix. A cell carrying a solve/pickup can no longer be a variable; when you set a solve on a cell with lb set, the variable flag on that cell is removed automatically (same as Zemax).
The index and Abbe number of a model glass can also be variables (Zemax's Vary Index / Vary Abbe on a model glass): write the medium after the surface as glass=model(nd, vd) and the variables as nd@3, vd@3. The optimization result is written back as a glass=model(…). Without bounds, nd is limited to 1.40–2.10 and vd to 15–100 (the range of common optical glasses); for a different range write var nd@3 in 1.5..1.8.
The merit function is written in the same file too: default spot centroid rings=3 (Zemax's optimization wizard), op EFFL target=50mm (a line of the MFE), and let (intermediate quantities). For the syntax see Merit Function and Optimization, and for operands see 操作数参考(评价函数).
Multi-configuration (zoom)
config 3 # three configurations (the three columns of the Zemax MCE)
mc T5 24.353, 13.981, 5.753 # thickness of surface 5 in the three configurations (zoom spacing)
mc T10 6.156, 23.118, 38.638
mc glass@6 N-BK7, N-BK7, N-SF6
mc field@3 20, 14, 7 # y of the 3rd field
mc aperture 10, 12, 14 # value of the system aperture (type unchanged)
mc weight 1, 1, 2 # configuration weights (Zemax CWGT)- Each configuration is a copy of the same design, and
mclines give the parameters that differ from configuration 1; the values on thesurf/field/wave/aperturelines are those of configuration 1. The first value of anmcline should equal it (if not, W-MC-BASE is raised and themcvalue is used). Remove theconfigandmclines and the design returns to configuration 1. - References are written as in
var:R4T4K4; other surface parameters are writtenparameter@surface-number(glass@6semi@3a4@5tx@4…); fields usefield@2(y),field_x@2,field_w@2,field_vdy@2…, and wavelengths usewave@1(a spectral line name may be given) andwave_w@1. For all controllable parameters see .lens 语法参考. - A parameter with a solve / pickup can no longer be controlled by
mc. When an R / T / K / aN controlled bymcis flaggedvar(e.g.var T5), its value in each configuration is a separate variable (optimization of the zoom spacing); variables not controlled bymcare shared across all configurations. - Merit function:
op … config=2is evaluated only in configuration 2 (the CONF row of Zemax); lines withoutconfig=are evaluated in every configuration. The per-ray rows ofdefaultare expanded with each configuration's own fields and wavelengths. The total merit function is combined with the configuration weights (mc weight);lb meritlists every row and its value in each configuration, andlb optimizeoptimizes all configurations together, writing the result back to the surf lines and the mc lines. To change a single mc value, uselb mc-set lens T5 2 13.5. lb checkchecks each configuration in turn; problems that appear only from configuration 2 on are prefixed with “组态 k:” (“Configuration k:”); a modifying command is rejected as soon as it introduces a new error in any configuration.- Zemax interop:
lb import-zmximports the MCE (THIC, CRVT, CONN, GLSS, SDIA, PRAM, APER, YFIE, XFIE, FLWT, FVDX…, WAVE, WLWT, CWGT); if the file's current configuration is not 1, thesurflines are replaced with the values of configuration 1; anything not yet supported (IGNR, TEMP / PRES thermal analysis, non-sequential operands …) is counted in the messages.lb export-zmxwrites it back. - Per-configuration analysis and plots: all analysis commands accept
--config k(theconfigparameter in MCP); the configuration number goes into the evidence key, and the plot frame appends “组态 k/n” (“Configuration k/n”) after the lens name; the desktop status bar has a configuration selector (shown only for multi-configuration designs).lb plot lens layout --view "configs=all"stacks the layouts of all configurations vertically, with the same z scale and origin, so you can see at a glance how the zoom spacings move (it can also be written asview layout configs=all). - Acceptance specs are written per configuration:
spec efl target=70mm tol=1% config=2is checked only in configuration 2,spec ttl max=60mm config=allis checked in every configuration, and one withoutconfig=is checked in the current configuration.lb verifygives one verdict per (spec, configuration) and registers one evidence record per configuration; see “Specs and acceptance” in Plotting.
Tolerancing
tol radius 1..6 ±2fr # fringes (Zemax TFRN), converted to radius using the test wavelength and clear semi-diameter; ±0.05mm (TRAD) or ±0.1% also work
tol thick 1..5 ±0.02mm # thickness (TTHI); later surfaces move with it
tol sdecenter 1..6 ±5um # single-surface decenter x / y (TSDX / TSDY)
tol stilt 1..6 ±0.01deg # single-surface tilt (TSTX / TSTY), about the surface vertex
tol decenter 1..2 ±0.01mm # element decenter (TEDX / TEDY): surfaces 1–2 are one element
tol tilt 1..2 ±0.02deg # element tilt (TETX / TETY), about the vertex of the element's first surface
tol stilt 4 -0.01..+0.03deg # asymmetric tolerances are written lower..upper
tol index 1, 3, 5 ±0.001 # index deviation of the glass after the surface (TIND, absolute, no unit), added at all wavelengths
tol abbe 1, 3, 5 ±1% # Abbe number deviation of the glass after the surface (TABB), keeps n_d and scales the dispersion proportionally
tol conic 1..6 ±0.01 # conic constant (TCON, absolute, no unit)
tol a4 3, 5 ±2e-7 # asphere r⁴ coefficient (Zemax TPAR: that parameter of the surface; absolute, in mm, same as a4 in surf)
tol thick 2 ±0.05mm stat=uniform # specify the Monte Carlo distribution for this line at its end (Zemax STAT)
tol stat parabolic # default distribution for all lines: normal (if omitted, limits = ±2σ; sigma=3 may be added) / uniform / parabolic
tol test_wave 0.6328um # test wavelength for fringes fr, default 0.6328 µm (Zemax TWAV)
tol criterion rms_spot # criterion: rms_spot (default) / rms_wave / mtf
tol criterion mtf freq=30/mm field=all dir=avg min=0.3 # MTF criterion (see below)
comp T6 # compensator; if omitted = the last thickness before the image plane (back focal distance); comp none = no compensation- Tolerances with dimensions must carry a unit (index deviation, conic constants, and asphere coefficients do not: asphere coefficients are the same as aN in surf, in mm); index / abbe require glass after the surface; for per-surface kinds the range means individual surfaces, and for element kinds (decenter / tilt) the range is one element.
tol conicapplies to surfaces that have a conic constant (standard surfaces, aspheres, toroidal surfaces, and the base of diffractive surfaces and gratings);tol aN(a1 … a30) applies to evenasph / oddasph / toroidal / binary2 / zernike surfaces, and on even surfaces (evenasph, the base of binary2, the YZ-section polynomial of toroidal) only even terms exist. A term that did not exist before (such astol a6on a surface where only a4 is written) is added when perturbing.- Surface irregularity (Zemax TIRR / TEZI / TEXI) is not yet supported: surface-shape terms that are not rotationally symmetric (astigmatism, coma, etc.) need a kind of surface the engine does not have yet.
lb tolerance lens [--out tol.png]: sensitivity analysis — each item takes its lower and upper limit, applied on a copy of the design (decenters / tilts insert a coordinate break, and later surfaces stay put), then the compensator is re-optimized and the criterion is computed; it lists the criterion and its change for each item (sorted by impact) and a root-sum-square estimate, and--outproduces a tornado chart. The design itself is untouched; before the analysis, solves / pickups are frozen at their current values, and focus is left to the compensator.lb tolerance lens --mode montecarlo --trials 200 --seed 1 [--out mc.png]: Monte Carlo — in each trial all tolerances take random values at once (normal distribution by default, limits = ±2σ, truncated to the limits), the criterion is computed after compensation, and the mean, standard deviation, and percentiles are given (x% of trials do not exceed the value);--outproduces a histogram plus a cumulative yield curve. The same seed gives the same result.- The Monte Carlo distributions follow Zemax's STAT:
tol stat <normal|uniform|parabolic> [sigma=n]sets the default for all lines, and a single line is specified at its end withstat=uniform(orstat=normal sigma=3; writing onlysigma=3is equivalent tostat=normal sigma=3). Normal: mean at the midpoint of the limits, limits = ±nσ (n an integer from 1 to 10, default 2), truncated to the limits; uniform: uniform within the limits; parabolic: probability density ∝ (x − midpoint)², more likely the closer to the limits (the middle half of the interval holds only 1/8 of the probability). When not specified, results are bit-for-bit identical to before distributions were added (same random-number stream, same evidence id); sensitivity analysis takes only the limits and is independent of the distribution. When the distribution is not the default, the output, the plot's info block, and the orchestration notes say which distribution was used. - MTF criterion
tol criterion mtf freq=30/mm [field=all|0–1] [dir=avg|T|S] [min=0.3]: the frequency is required and carries a unit (/mm);fieldis all (default) or a relative field 0–1 (the closest defined field is taken, same asspec mtf);diris the tangential/sagittal average (default, Zemax MTFA) / tangential T / sagittal S. The basis is the diffraction FFT MTF (polychromatic, same as the default oflb mtf), and the criterion value = the field-weighted average over the selected fields, larger is better: sensitivity reports ΔMTF (negative = worse), and the estimate = nominal − root-sum-square; the Monte Carlo percentile reads as "x% of trials are not below this value", per-field statistics are listed separately, and ifmin=is given a pass rate follows (the fraction of trials in which the MTF of every selected field is not below the threshold). The compensator is first tuned coarsely by RMS wavefront and then finely by the criterion itself (average MTF). The FFT sampling is fixed (--mtf-sampling, default 64, the same sampling for every perturbation; if the nominal design is undersampled, the output says so) and goes into the evidence key. The MTF criterion is much slower than the RMS criterion (for a Cooke triplet with 30 tolerances, about 0.6 s per Monte Carlo trial). - tol / comp are not part of the model hash: changing tolerances only makes the tolerance analysis stale.
Default tolerances and inverse tolerancing
If no tolerances have been written yet, lb tolerance-default lens [--grade precision] [--dry-run] proposes a set of standard tolerances based on the structure of the design (same as Zemax's Default Tolerances), appended as tol lines:
| Kind | Placed on which surfaces | commercial | precision (default) | high |
|---|---|---|---|---|
radius | surfaces that act optically (fringes, converted to radius with the test wavelength; planes too) | ±5fr | ±3fr | ±1fr |
thick | every thickness and air gap from surface 1 to before the image plane (except the compensator) | ±0.15mm | ±0.05mm | ±0.025mm |
sdecenter | surfaces that act optically and have a shape (decentering a plane changes nothing) | ±0.025mm | ±0.01mm | ±0.005mm |
stilt | surfaces that act optically | ±3arcmin | ±1arcmin | ±0.5arcmin |
decenter | each lens element (several cemented pieces count as one) | ±0.1mm | ±0.05mm | ±0.02mm |
tilt | each lens element | ±3arcmin | ±1arcmin | ±0.5arcmin |
index | surfaces followed by a refractive material | ±0.001 | ±0.0005 | ±0.0002 |
abbe | same as above (except ideal materials and materials without a d-line index) | ±0.8% | ±0.5% | ±0.2% |
- "Surfaces that act optically" excludes coordinate breaks and dummy surfaces with the same medium on both sides (such as a stop surface written on its own); the compensator (R / T of
comp, back focal distance if omitted) gets no tolerance. - Each kind can be changed or dropped individually:
--radius 2fr,--sdecenter 10um,--stilt none; when the radius is given in mm or %, it is not placed on planes. - Only tol lines are appended (inserted after the last tol / comp line, or at the end of the file with a comment line before it if there is none), and all other lines are left untouched; kinds already covered by an existing tol line (same kind, same surface / element) are not added again. Surface irregularity (Zemax TIRR / TEZI) is not yet possible and is not added.
Once the tolerances are written, to answer "the criterion may only get worse by this much — how tight must each item be": lb tolerance-inverse lens --change 2 (each item applied alone may worsen RMS by at most 2 µm, same as Zemax's Inverse Increment) or --limit 12 (each item applied alone keeps RMS no larger than 12 µm, same as Inverse Limit; for the MTF criterion, MTF no lower than it):
- For each item (per surface / per element, x and y separately), the lower and upper limits are solved on each side: the value at which, after the compensator is re-optimized, the criterion worsens by exactly that amount; where the current tolerance does not exceed it, nothing is tightened (same as Zemax, tighten only, never loosen;
--loosen 3allows loosening up to 3 times). The criterion change agrees with the target to within 0.5 %, usually 2–4 evaluations per side. - It lists the inverse lower and upper limits of every item and the criterion change at that value (the tightest first), plus a root-sum-square estimate based on the inverse tolerances.
--writewrites back to the tol lines (look at the diff first with--dry-run): where one line covers several surfaces the tightest of them is taken, and--splitturns it into one line per surface; a±xline gets the same value on both sides; only those numbers are changed, the unit follows the original (a line written inumstays inum), with 3 significant digits, truncated toward the tighter side.- It can also be used in orchestration:
report … tolerance mode=inverse limit=12(no write-back; the alternatives are compared side by side on how many items need tightening), andtols=precisionadds a set of default tolerances on top of the design's tol lines before analysis (see Orchestration).
Step 4 (optional): view specs and acceptance specs
Plot options and acceptance targets are also written in the same file, so they can be diffed, written by AI, and reproduced across sessions:
view spot rings=8 box=120um # spot diagram: 8-ring sampling (a sampling option), 120 µm box (a display option)
view layout numbers=on fold=on # layout: label surface numbers, compress large outlying gaps
spec efl target=50mm tol=1% # acceptance: focal length 50 mm ±1%
spec mtf freq=50/mm field=0.7 dir=T min=0.3
spec distortion max=2% # absolute value by default; write signed for a signed check
pack prescription paraxial layout spot mtf verify conclusions # which items the report pack exports (lb pack)- Dimensioned values must carry a unit (
120um,50/mm,2%,13deg); leaving it out is an error, and no unit is assumed by default. - view / spec do not change the model hash: changing them does not make other analyses stale.
lb verifychecks the specs one by one;lb plotdraws the specs on the plot. See Plotting Guide for details.packstates which items the report pack exports; see Report Material Pack.
Edit with commands, not by hand
Editing the text by hand is perfectly fine, but commands have three advantages: automatic renumbering, a diff first, and undo.
lb set my.lens 3 R=-25 glass=SCHOTT:N-SF5 --dry-run
lb insert my.lens 2 R=-200 T=1 # insert after surface 2; later surface numbers, var, and pickup shift by +1 automatically
lb delete my.lens 3
lb stop my.lens 3
lb system my.lens "aperture FNO 4"
lb vary my.lens R1..R4
lb view-set my.lens spot rings=8 box=100um
lb spec-add my.lens efl target=50mm tol=1%
lb fmt my.lens --force # normalize the layout (# comments are lost)Edits change only the characters that must change: change one radius and the diff shows only that one number changing, with comments and alignment preserved.