GeoLens API Reference

Note

This API reference is still under development. Some details may contain mistakes or be incomplete.

GeoLens is a differentiable geometric lens simulator that uses ray tracing for modeling refractive and diffractive optical systems. It inherits from multiple mixin classes that provide specialized functionality.

Class Hierarchy

The GeoLens class inherits from:

  • Lens - Base lens class

  • GeoLensEval - Optical performance evaluation

  • GeoLensOptim - Optimization and constraints

  • GeoLensVis - 2D visualization

  • GeoLensIO - File I/O operations

  • GeoLensTolerance - Tolerance analysis

Main Class

class GeoLens(filename=None, device=None, dtype=torch.float32)

Geometric lens system using differentiable ray tracing.

Parameters:
  • filename (str or None) – Path to lens file (.json, .zmx, .seq). If None, creates empty lens

  • device (str or None) – Computing device (‘cuda’ or ‘cpu’). If None, auto-selects

  • dtype (torch.dtype) – Data type for computations

Note

Sensor size and resolution are read from the lens file. If not provided, defaults of 8mm x 8mm and 2000x2000 pixels will be used.

Key Attributes:

surfaces: list

List of optical surfaces (Aperture, Spheric, Aspheric, etc.)

materials: list

List of optical materials between surfaces

foclen: float

Effective focal length in mm

fnum: float

F-number (focal length / entrance pupil diameter)

rfov: float

Half-diagonal field of view in radians

d_sensor: torch.Tensor

Distance from first surface to sensor in mm

aper_idx: int

Index of aperture stop surface

entr_pupilz: float

Entrance pupil z-position in mm

entr_pupilr: float

Entrance pupil radius in mm

exit_pupilz: float

Exit pupil z-position in mm

exit_pupilr: float

Exit pupil radius in mm

Initialization & Configuration

GeoLens.read_lens(filename)

Load lens from file (.json or .zmx format).

Parameters:

filename (str) – Path to lens file

Note

The .seq format is not yet supported.

GeoLens.post_computation()

Compute focal length, pupil, and field of view after loading or modifying lens. Automatically called after read_lens().

GeoLens.__call__(ray)

Trace rays through the lens system.

Parameters:

ray (Ray) – Input rays

Returns:

Output rays after tracing through lens

Return type:

Ray

Ray Sampling

Grid Sampling

GeoLens.sample_grid_rays(depth=float('inf'), num_grid=(11, 11), num_rays=16384, wvln=0.587, uniform_fov=True, sample_more_off_axis=False, scale_pupil=1.0)

Sample grid rays from object space for PSF map or spot diagram analysis.

Parameters:
  • depth (float) – Object depth. float("inf") for parallel rays, finite for point sources

  • num_grid (tuple or int) – Grid size (cols, rows)

  • num_rays (int) – Rays per grid point

  • wvln (float) – Wavelength in micrometers

  • uniform_fov (bool) – If True, sample uniform FoV angles; otherwise sample uniform object grid

  • sample_more_off_axis (bool) – If True, sample more rays at off-axis fields

  • scale_pupil (float) – Scale factor for pupil radius

Returns:

Ray object with shape [num_grid[1], num_grid[0], num_rays, 3]

Return type:

Ray

GeoLens.sample_radial_rays(num_field=5, depth=float('inf'), num_rays=16384, wvln=0.587)

Sample radial (meridional, y-direction) rays at different field angles.

Parameters:
  • num_field (int) – Number of field angles

  • depth (float) – Object depth

  • num_rays (int) – Rays per field

  • wvln (float) – Wavelength in micrometers

Returns:

Ray object with shape [num_field, num_rays, 3]

Return type:

Ray

Point Source Sampling

GeoLens.sample_from_points(points=[[0.0, 0.0, -10000.0]], num_rays=16384, wvln=0.587, scale_pupil=1.0)

Sample rays from point sources at absolute 3D coordinates.

Parameters:
  • points (list or torch.Tensor) – Point source positions in shape [3], [N, 3], or [Nx, Ny, 3]

  • num_rays (int) – Rays per point

  • wvln (float) – Wavelength in micrometers

  • scale_pupil (float) – Scale factor for pupil radius

Returns:

Sampled rays with shape [*points.shape[:-1], num_rays, 3]

Return type:

Ray

Parallel & Angular Sampling

GeoLens.sample_parallel(fov_x=[0.0], fov_y=[0.0], num_rays=1024, wvln=0.587, entrance_pupil=True, depth=-1.0, scale_pupil=1.0)

Sample parallel rays at given field angles.

Parameters:
  • fov_x (float or list) – Field angle(s) in x direction in degrees

  • fov_y (float or list) – Field angle(s) in y direction in degrees

  • num_rays (int) – Rays per field point

  • wvln (float) – Wavelength in micrometers

  • entrance_pupil (bool) – If True, sample on entrance pupil; else on first surface

  • depth (float) – Propagation depth in z

  • scale_pupil (float) – Scale factor for pupil radius

Returns:

Ray object with shape [len(fov_y), len(fov_x), num_rays, 3]

Return type:

Ray

GeoLens.sample_point_source(fov_x=[0.0], fov_y=[0.0], depth=-20000.0, num_rays=16384, wvln=0.587, entrance_pupil=True, scale_pupil=1.0)

Sample point source rays at given field angles and depth.

Parameters:
  • fov_x (float or list) – Field angle(s) in x direction in degrees

  • fov_y (float or list) – Field angle(s) in y direction in degrees

  • depth (float) – Object depth in mm

  • num_rays (int) – Rays per field point

  • wvln (float) – Wavelength in micrometers

  • entrance_pupil (bool) – If True, use entrance pupil

  • scale_pupil (float) – Scale factor for pupil radius

Returns:

Ray object with shape [len(fov_y), len(fov_x), num_rays, 3]

Return type:

Ray

Sensor Sampling

GeoLens.sample_sensor(spp=64, wvln=0.587, sub_pixel=False)

Sample backward rays from sensor pixels for ray-tracing rendering.

Parameters:
  • spp (int) – Samples per pixel

  • wvln (float) – Wavelength in micrometers

  • sub_pixel (bool) – If True, enable sub-pixel sampling

Returns:

Ray object with shape [H, W, spp, 3]

Return type:

Ray

Helper Methods

GeoLens.sample_circle(r, z, shape=[16, 16, 512])

Sample points uniformly inside a circle at depth z.

Parameters:
  • r (float) – Circle radius

  • z (float) – Z-coordinate

  • shape (list) – Output shape

Returns:

Sampled points with shape [*shape, 3]

Return type:

torch.Tensor

GeoLens.sample_ring_arm_rays(num_ring=8, num_arm=8, spp=2048, depth=-20000.0, wvln=0.587, scale_pupil=1.0, sample_more_off_axis=True)

Sample rays using ring-arm pattern for optimization (from GeoLensOptim).

Parameters:
  • num_ring (int) – Number of concentric rings

  • num_arm (int) – Number of radial arms

  • spp (int) – Samples per pixel

  • depth (float) – Object depth

  • wvln (float) – Wavelength in micrometers

  • scale_pupil (float) – Pupil scale factor

  • sample_more_off_axis (bool) – Sample more off-axis rays

Returns:

Sampled rays

Return type:

Ray

Ray Tracing

GeoLens.trace(ray, surf_range=None, record=False)

Trace rays through the lens (forward or backward determined automatically).

Parameters:
  • ray (Ray) – Input rays

  • surf_range (range or None) – Surface index range to trace through. If None, traces all surfaces

  • record (bool) – If True, record intersection points at each surface

Returns:

Output rays and optional intersection records

Return type:

tuple(Ray, list or None)

GeoLens.trace2sensor(ray, record=False)

Trace rays to sensor plane.

Parameters:
  • ray (Ray) – Input rays

  • record (bool) – If True, record intersection points

Returns:

Rays at sensor plane (and optional records if record=True)

Return type:

Ray or tuple(Ray, list)

GeoLens.trace2obj(ray)

Trace rays to object space (backward tracing).

Parameters:

ray (Ray) – Input rays from sensor

Returns:

Output rays in object space

Return type:

Ray

GeoLens.forward_tracing(ray, surf_range, record)

Forward ray tracing implementation.

Parameters:
  • ray (Ray) – Input rays

  • surf_range (range) – Surface range

  • record (bool) – Record intersections

Returns:

Output rays and records

Return type:

tuple(Ray, list or None)

GeoLens.backward_tracing(ray, surf_range, record)

Backward ray tracing implementation.

Parameters:
  • ray (Ray) – Input rays

  • surf_range (range) – Surface range

  • record (bool) – Record intersections

Returns:

Output rays and records

Return type:

tuple(Ray, list or None)

Image Rendering

Main Rendering

GeoLens.render(img_obj, depth=-20000.0, method='ray_tracing', **kwargs)

Differentiable image simulation through the lens.

Parameters:
  • img_obj (torch.Tensor of shape [B, C, H, W]) – Input image tensor

  • depth (float) – Object depth in mm

  • method (str) – Rendering method - “ray_tracing”, “psf_map”, or “psf_patch”

  • kwargs – Additional method-specific arguments: - For “psf_map”: psf_grid=(10,10), psf_ks=64 - For “psf_patch”: patch_center=(0.0,0.0), psf_ks=64 - For “ray_tracing”: spp=64

Returns:

Rendered image tensor [B, C, H, W]

Return type:

torch.Tensor

Ray Tracing Rendering

GeoLens.render_raytracing(img, depth=-20000.0, spp=64, vignetting=False)

Render RGB image using ray tracing.

Parameters:
  • img (torch.Tensor) – RGB image tensor [N, 3, H, W]

  • depth (float) – Object depth

  • spp (int) – Samples per pixel

  • vignetting (bool) – Consider vignetting effect

Returns:

Rendered image [N, 3, H, W]

Return type:

torch.Tensor

GeoLens.render_raytracing_mono(img, wvln, depth=-20000.0, spp=64, vignetting=False)

Render monochrome image using ray tracing.

Parameters:
  • img (torch.Tensor) – Monochrome image [N, H, W] or [N, 1, H, W]

  • wvln (float) – Wavelength in micrometers

  • depth (float) – Object depth

  • spp (int) – Samples per pixel

  • vignetting (bool) – Consider vignetting effect

Returns:

Rendered image

Return type:

torch.Tensor

GeoLens.render_compute_image(img, depth, scale, ray, vignetting=False)

Core rendering computation using bilinear interpolation.

Parameters:
  • img (torch.Tensor) – Image tensor [N, C, H, W] or [N, H, W]

  • depth (float) – Object depth

  • scale (float) – Scale factor

  • ray (Ray) – Traced rays [H, W, spp, 3]

  • vignetting (bool) – Consider vignetting

Returns:

Rendered image

Return type:

torch.Tensor

Post-Processing

GeoLens.unwarp(img, depth=-20000.0, num_grid=128, crop=True, flip=True)

Unwarp rendered images to correct distortion.

Parameters:
  • img (torch.Tensor) – Rendered image [N, C, H, W]

  • depth (float) – Object depth

  • num_grid (int) – Distortion grid resolution

  • crop (bool) – Crop the unwarped image

  • flip (bool) – Flip vertically

Returns:

Unwarped image [N, C, H, W]

Return type:

torch.Tensor

GeoLens.analysis_rendering(img_org, save_name=None, depth=-20000.0, spp=64, unwarp=False, noise=0.0, method='ray_tracing', show=False)

Render image and compute PSNR/SSIM for analysis.

Parameters:
  • img_org (numpy.ndarray or torch.Tensor) – Original image [H, W, 3]

  • save_name (str or None) – Save filename prefix

  • depth (float) – Object depth

  • spp (int) – Samples per pixel

  • unwarp (bool) – Apply distortion correction

  • noise (float) – Gaussian noise level

  • method (str) – Rendering method

  • show (bool) – Display result

Returns:

Rendered image

Return type:

torch.Tensor

PSF Calculation

GeoLens.psf(points, ks=64, wvln=0.587, spp=None, recenter=True, model='geometric')

Calculate Point Spread Function (PSF) using different models.

Parameters:
  • points (torch.Tensor or list) – Point source positions in shape [3], [N, 3], or [Nx, Ny, 3]

  • ks (int) – PSF kernel size

  • wvln (float) – Wavelength in micrometers

  • spp (int or None) – Samples per pixel (defaults to spp_psf for geometric, spp_coherent for coherent/huygens)

  • recenter (bool) – Recenter PSF using chief ray

  • model (str) – PSF model - “geometric”, “coherent”, or “huygens”

Returns:

PSF tensor [ks, ks] or [N, ks, ks]

Return type:

torch.Tensor

GeoLens.psf_geometric(points, ks=64, wvln=0.587, spp=16384, recenter=True)

Calculate incoherent geometric PSF using ray tracing.

Parameters:
  • points (torch.Tensor or list) – Point positions [N, 3]

  • ks (int) – PSF kernel size

  • wvln (float) – Wavelength in micrometers

  • spp (int) – Samples per pixel

  • recenter (bool) – Recenter PSF using chief ray

Returns:

PSF tensor

Return type:

torch.Tensor

GeoLens.psf_coherent(points, ks=64, wvln=0.587, spp=16777216, recenter=True)

Calculate coherent PSF by propagating pupil field to sensor (Ray-Wave model). Alias for psf_pupil_prop.

GeoLens.psf_pupil_prop(points, ks=64, wvln=0.587, spp=16777216, recenter=True)

Calculate coherent PSF by propagating pupil field to sensor using ASM.

Parameters:
  • points – Point source positions

  • ks – Kernel size

  • wvln – Wavelength

  • spp – Sample rays (typically 16777216, ~16.8M, 2^24)

  • recenter – Recenter PSF

Returns:

PSF patch

Return type:

torch.Tensor

GeoLens.psf_huygens(points, ks=64, wvln=0.587, spp=16777216, recenter=True)

Calculate Huygens PSF by treating every exit-pupil ray as a secondary spherical wave source.

Parameters:
  • points – Point source position

  • ks – Kernel size

  • wvln – Wavelength

  • spp – Sample rays

  • recenter – Recenter PSF

Returns:

Huygens PSF patch

Return type:

torch.Tensor

GeoLens.psf_map(depth=-20000.0, grid=(7, 7), ks=64, spp=16384, wvln=0.587, recenter=True)

Calculate PSF map at different field positions.

Parameters:
  • depth (float) – Object depth

  • grid (tuple or int) – Grid size (grid_w, grid_h)

  • ks (int) – Kernel size

  • spp (int) – Samples per pixel

  • wvln (float) – Wavelength

  • recenter (bool) – Recenter PSFs

Returns:

PSF map [grid_h, grid_w, 1, ks, ks]

Return type:

torch.Tensor

GeoLens.psf_center(points_obj, method='chief_ray')

Calculate PSF center position on sensor.

Parameters:
  • points_obj (torch.Tensor) – Un-normalized point source positions in object plane […, 3]

  • method (str) – Calculation method - “chief_ray” or “pinhole”. Defaults to “chief_ray”.

Returns:

PSF centers […, 2]

Return type:

torch.Tensor

GeoLens.psf_coherent(points, ks=64, wvln=0.587, spp=16777216, recenter=True)

Calculate coherent PSF using ray-wave model. Alias for psf_pupil_prop.

Parameters:
  • points (torch.Tensor or list) – Point source position [3] or [1, 3]

  • ks (int) – Kernel size

  • wvln (float) – Wavelength

  • spp (int) – Sample rays (>= 16777216, ~16.8M, 2^24 recommended)

  • recenter (bool) – Recenter PSF using chief ray

Returns:

PSF patch [ks, ks]

Return type:

torch.Tensor

GeoLens.pupil_field(points, wvln=0.587, spp=16777216, recenter=True)

Calculate complex wavefront at exit pupil using coherent ray tracing. Only single-point input is supported.

Parameters:
  • points (torch.Tensor or list) – Point source position [3] or [1, 3]

  • wvln (float) – Wavelength in micrometers

  • spp (int) – Samples (>= 16777216, ~16.8M, 2^24 required)

  • recenter (bool) – Recenter PSF using chief ray

Returns:

Tuple of (wavefront field, PSF center)

Return type:

tuple(torch.Tensor, list)

Optical Analysis (GeoLensEval)

Spot Diagrams

GeoLens.draw_spot_radial(save_name='./lens_spot_radial.png', num_fov=5, depth=float('inf'), num_rays=16384, wvln_list=[0.656, 0.587, 0.486], show=False)

Draw spot diagrams along meridional direction.

Parameters:
  • save_name (str) – Save filename

  • num_fov (int) – Number of field of view angles

  • depth (float) – Object depth

  • num_rays (int) – Number of rays to sample

  • wvln_list (list) – List of wavelengths to render (RGB)

  • show (bool) – Display plot

GeoLens.draw_spot_map(save_name='./lens_spot_map.png', num_grid=5, depth=-20000.0, num_rays=16384, wvln_list=[0.656, 0.587, 0.486], show=False)

Draw spot diagram grid.

Parameters:
  • save_name (str) – Save filename

  • num_grid (int) – Grid size

  • depth (float) – Object depth

  • num_rays (int) – Number of rays to sample

  • wvln_list (list) – List of wavelengths to render (RGB)

  • show (bool) – Display plot

GeoLens.analysis_spot(num_field=3, depth=float('inf'))

Compute RMS spot size and geometric radius.

Parameters:
  • num_field (int) – Number of fields to analyze

  • depth (float) – Object depth

Returns:

Dictionary with RMS and radius for each field

Return type:

dict

RMS Error Maps

GeoLens.rms_map_rgb(num_grid=32, depth=-20000.0)

Calculate RGB RMS spot error map.

Parameters:
  • num_grid (int) – Grid resolution

  • depth (float) – Object depth

Returns:

RMS error map for each RGB channel

Return type:

torch.Tensor

GeoLens.rms_map(num_grid=32, depth=-20000.0, wvln=0.587)

Calculate RMS spot error map for single wavelength.

Parameters:
  • num_grid (int) – Grid resolution

  • depth (float) – Object depth

  • wvln (float) – Wavelength

Returns:

RMS error map

Return type:

torch.Tensor

Distortion

GeoLens.calc_distortion_2D(rfov, wvln=0.587, plane='meridional', ray_aiming=True)

Calculate distortion at a specific field angle.

Parameters:
  • rfov (float or torch.Tensor) – View angle in degrees

  • wvln (float) – Wavelength in micrometers

  • plane (str) – ‘meridional’ or ‘sagittal’

  • ray_aiming (bool) – Whether the chief ray passes through the center of the stop

Returns:

Distortion at the specific field angle

Return type:

float or numpy.ndarray

GeoLens.draw_distortion_radial(rfov, save_name=None, num_points=21, wvln=0.587, plane='meridional', ray_aiming=True, show=False)

Draw distortion curve vs field angle (Zemax-style).

Parameters:
  • rfov (float) – Maximum view angle in degrees

  • save_name (str or None) – Save filename

  • num_points (int) – Number of field samples

  • wvln (float) – Wavelength in micrometers

  • plane (str) – ‘meridional’ or ‘sagittal’

  • ray_aiming (bool) – Whether to use ray aiming

  • show (bool) – Display plot

GeoLens.distortion_map(num_grid=16, depth=-20000.0)

Compute distortion map for grid_sample.

Parameters:
  • num_grid (int) – Grid resolution

  • depth (float) – Object depth

Returns:

Distortion map [num_grid, num_grid, 2]

Return type:

torch.Tensor

GeoLens.distortion_center(points)

Calculate the distortion center for given normalized points.

Parameters:

points (torch.Tensor) – Normalized point source positions […, 3]. x, y in [-1, 1], z (depth) in [-Inf, 0]

Returns:

Normalized distortion center positions […, 2]. x, y in [-1, 1]

Return type:

torch.Tensor

GeoLens.draw_distortion(filename=None, num_grid=16, depth=-20000.0)

Visualize distortion map.

Parameters:
  • filename (str or None) – Save filename

  • num_grid (int) – Grid resolution

  • depth (float) – Object depth

MTF Analysis

GeoLens.mtf(fov, wvln=0.587)

Calculate Modulation Transfer Function at field of view.

Parameters:
Returns:

MTF curve

Return type:

torch.Tensor

static GeoLens.psf2mtf(psf, pixel_size)

Convert PSF to MTF.

Parameters:
Returns:

MTF curve

Return type:

torch.Tensor

GeoLens.draw_mtf(save_name='./lens_mtf.png', relative_fov_list=[0.0, 0.7, 1.0], depth_list=[-20000.0], psf_ks=128, show=False)

Draw MTF curves for multiple depths, FOVs and RGB wavelengths.

Parameters:
  • save_name (str) – Save filename

  • relative_fov_list (list) – List of relative field of view values (0.0 to 1.0)

  • depth_list (list) – List of object depths in mm

  • psf_ks (int) – Kernel size for PSF calculation

  • show (bool) – Display plot

Vignetting

GeoLens.vignetting(depth=-20000.0, num_grid=64)

Compute vignetting map.

Parameters:
  • depth (float) – Object depth

  • num_grid (int) – Grid resolution

Returns:

Vignetting map

Return type:

torch.Tensor

GeoLens.draw_vignetting(filename=None, depth=-20000.0, resolution=512)

Visualize vignetting effect.

Parameters:
  • filename (str or None) – Save filename

  • depth (float) – Object depth

  • resolution (int) – Output resolution

Chief Ray

GeoLens.calc_chief_ray(fov, plane='sagittal')

Calculate chief ray for given field angle.

Parameters:
  • fov (float) – Field of view in degrees

  • plane (str) – “sagittal” or “meridional”

Returns:

Chief ray

Return type:

Ray

GeoLens.calc_chief_ray_infinite(fov, plane='sagittal')

Calculate chief ray for infinite object distance.

Parameters:
  • fov (float) – Field of view in degrees

  • plane (str) – “sagittal” or “meridional”

Returns:

Chief ray

Return type:

Ray

Comprehensive Analysis

GeoLens.analysis(save_name='./lens', depth=float('inf'), render=False, render_unwarp=False, lens_title=None, show=False)

Comprehensive lens analysis including layout, spot, MTF, and optional rendering.

Parameters:
  • save_name (str) – Filename prefix for outputs

  • depth (float) – Object depth

  • render (bool) – Render test image

  • render_unwarp (bool) – Apply distortion correction

  • lens_title (str or None) – Title for plots

  • show (bool) – Display plots

Geometric Calculations

Focal Length & Pupils

GeoLens.calc_foclen()

Compute effective focal length by tracing paraxial chief ray.

GeoLens.calc_pupil()

Compute entrance and exit pupil positions and radii.

GeoLens.get_entrance_pupil(paraxial=False)

Get entrance pupil location and radius.

Parameters:

paraxial (bool) – Use paraxial approximation

Returns:

(z_position, radius)

Return type:

tuple(float, float)

GeoLens.get_exit_pupil(paraxial=False)

Get exit pupil location and radius.

Parameters:

paraxial (bool) – Use paraxial approximation

Returns:

(z_position, radius)

Return type:

tuple(float, float)

GeoLens.calc_entrance_pupil(paraxial=False)

Calculate entrance pupil by backward ray tracing from aperture.

Parameters:

paraxial (bool) – Use paraxial mode for stability

Returns:

(z_position, radius)

Return type:

tuple(float, float)

GeoLens.calc_exit_pupil(paraxial=False)

Calculate exit pupil by forward ray tracing from aperture.

Parameters:

paraxial (bool) – Use paraxial mode for stability

Returns:

(z_position, radius)

Return type:

tuple(float, float)

Field of View

GeoLens.calc_fov()

Compute field of view using perspective projection and ray tracing.

GeoLens.set_fov(rfov)

Set target half-diagonal field of view.

Parameters:

rfov (float) – Half diagonal FOV in radians

Focal & Sensor Planes

GeoLens.calc_focal_plane(wvln=0.587)

Calculate focus distance in object space by backward tracing.

Parameters:

wvln (float) – Wavelength

Returns:

Focal plane z-position

Return type:

float

GeoLens.calc_sensor_plane(depth=float('inf'))

Calculate in-focus sensor position for given object depth.

Parameters:

depth (float) – Object depth

Returns:

Sensor z-position

Return type:

torch.Tensor

GeoLens.calc_scale(depth)

Calculate magnification scale (obj_height / img_height).

Parameters:

depth (float) – Object depth

Returns:

Scale factor

Return type:

float

Helper Methods

static GeoLens.compute_intersection_points_2d(origins, directions)

Compute intersection points of 2D lines.

Parameters:
Returns:

Intersection points [N*(N-1)/2, 2]

Return type:

torch.Tensor

GeoLens.find_diff_surf()

Get list of differentiable/optimizable surface indices.

Returns:

Range of optimizable surface indices

Return type:

range

Lens Operations

Focusing & Aperture

GeoLens.refocus(foc_dist=float('inf'))

Refocus lens by adjusting sensor position.

Parameters:

foc_dist (float) – Target focal distance in object space

GeoLens.set_fnum(fnum)

Set F-number by adjusting aperture radius using binary search.

Parameters:

fnum (float) – Target F-number

GeoLens.set_target_fov_fnum(rfov, fnum)

Set both FoV and F-number design targets.

Parameters:
  • rfov (float) – Half diagonal FOV in radians

  • fnum (float) – F-number

Shape Correction

GeoLens.prune_surf(expand_factor=None)

Prune surface radii to allow valid rays with expansion margin.

Parameters:

expand_factor (float or None) – Expansion factor (auto-selected if None)

GeoLens.correct_shape(expand_factor=None)

Correct wrong lens shape during design.

Parameters:

expand_factor (float or None) – Expansion factor for pruning

Returns:

True if shape was changed

Return type:

bool

Materials

GeoLens.match_materials(mat_table='CDGM')

Match all materials to closest in catalog.

Parameters:

mat_table (str) – Material catalog name

Optimization (GeoLensOptim)

Constraints

GeoLens.init_constraints(constraint_params=None)

Initialize lens design constraints (edge thickness, etc.).

Parameters:

constraint_params (dict or None) – Custom constraint parameters

Loss Functions

GeoLens.loss_reg(w_focus=10.0, w_ray_angle=2.0, w_intersec=1.0, w_gap=0.1, w_surf=1.0)

Empirical regularization loss for lens design.

Parameters:
  • w_focus (float) – Weight for in-focus loss

  • w_ray_angle (float) – Weight for chief ray angle

  • w_intersec (float) – Weight for surface intersection

  • w_gap (float) – Weight for air gap constraints

  • w_surf (float) – Weight for surface shape

Returns:

Total regularization loss

Return type:

torch.Tensor

GeoLens.loss_infocus(target=0.005)

Loss for focusing parallel rays.

Parameters:

target (float) – Target RMS error in mm

Returns:

Focus loss

Return type:

torch.Tensor

GeoLens.loss_surface()

Penalize problematic surface shapes (sag, gradient, curvature).

Returns:

Surface shape loss

Return type:

torch.Tensor

GeoLens.loss_intersec()

Penalize surface self-intersection violations.

Returns:

Intersection loss

Return type:

torch.Tensor

GeoLens.loss_gap()

Penalize excessive air gaps and element thickness.

Returns:

Gap constraint loss

Return type:

torch.Tensor

GeoLens.loss_ray_angle()

Penalize large chief ray angles at sensor.

Returns:

Ray angle loss

Return type:

torch.Tensor

GeoLens.loss_mat()

Penalize invalid material properties.

Returns:

Material loss

Return type:

torch.Tensor

GeoLens.loss_rms(depth=float('inf'), grid=None, spp=None, wvlns=None, weights=None)

Compute RGB spot RMS loss.

Parameters:
  • depth (float) – Object depth

  • grid (tuple or None) – Field grid size

  • spp (int or None) – Samples per pixel

  • wvlns (list or None) – Wavelengths list

  • weights (list or None) – Field weights [center, 0.7, edge]

Returns:

RMS loss

Return type:

torch.Tensor

Optimization

GeoLens.optimize(iterations=1000, lrs=[1e-4, 1e-4, 1e-2, 1e-4], loss_type='rms', test_per_iter=100, decay=0.01, save_dir='./results', start_epoch=0)

Optimize lens design to minimize RMS errors.

Parameters:
  • iterations (int) – Number of optimization iterations

  • lrs (list) – Learning rates [d, c, k, a] for surface parameters

  • loss_type (str) – Loss type - ‘rms’, ‘infocus’, etc.

  • test_per_iter (int) – Test every N iterations

  • decay (float) – Learning rate decay for higher-order terms

  • save_dir (str) – Directory for saving results

  • start_epoch (int) – Starting epoch number

Returns:

Loss history

Return type:

list

GeoLens.get_optimizer_params(lrs=[1e-4, 1e-4, 1e-2, 1e-4], decay=0.01, optim_mat=False, optim_surf_range=None)

Get optimizer parameter groups.

Parameters:
  • lrs (list) – Learning rates for [d, c, k, a]

  • decay (float) – Decay for higher-order terms

  • optim_mat (bool) – Optimize materials

  • optim_surf_range (list or None) – Surface indices to optimize

Returns:

Parameter list for optimizer

Return type:

list

GeoLens.get_optimizer(lrs=[1e-4, 1e-4, 1e-1, 1e-4], decay=0.01, optim_surf_range=None, optim_mat=False)

Get Adam optimizer for lens parameters.

Parameters:
  • lrs (list) – Learning rates

  • decay (float) – Decay factor

  • optim_surf_range (list or None) – Surfaces to optimize

  • optim_mat (bool) – Optimize materials

Returns:

Adam optimizer

Return type:

torch.optim.Adam

File I/O (GeoLensIO)

JSON Format

GeoLens.read_lens_json(filename='./test.json')

Load lens from JSON file.

Parameters:

filename (str) – Path to .json file

GeoLens.write_lens_json(filename='./test.json')

Save lens to JSON file.

Parameters:

filename (str) – Output path

ZEMAX Format

GeoLens.read_lens_zmx(filename='./test.zmx')

Load lens from ZEMAX .zmx file.

Parameters:

filename (str) – Path to .zmx file

GeoLens.write_lens_zmx(filename='./test.zmx')

Save lens to ZEMAX .zmx format.

Parameters:

filename (str) – Output path

Tolerance Analysis (GeoLensTolerance)

Setup

GeoLens.init_tolerance(tolerance_params=None)

Initialize tolerance parameters for manufacturing analysis.

Parameters:

tolerance_params (dict or None) – Custom tolerance settings

GeoLens.sample_tolerance()

Apply random manufacturing errors to all surfaces and refocus.

GeoLens.zero_tolerance()

Clear all manufacturing errors and restore nominal design.

Analysis Methods

GeoLens.tolerancing_sensitivity(tolerance_params=None)

Compute tolerance sensitivity using first-order gradients.

Parameters:

tolerance_params (dict or None) – Tolerance settings

Returns:

Sensitivity results dictionary

Return type:

dict

GeoLens.tolerancing_monte_carlo(trials=1000, tolerance_params=None)

Perform Monte Carlo tolerance analysis.

Parameters:
  • trials (int) – Number of random trials

  • tolerance_params (dict or None) – Tolerance settings

Returns:

Statistical tolerance results

Return type:

dict

GeoLens.tolerancing_wavefront(tolerance_params=None)

Wavefront-based tolerance analysis.

Parameters:

tolerance_params (dict or None) – Tolerance settings

Returns:

Wavefront tolerance results

Return type:

dict

Visualization (GeoLensVis)

2D Layout

GeoLens.draw_layout(filename, depth=float('inf'), zmx_format=True, multi_plot=False, lens_title=None, show=False)

Draw 2D lens layout with ray paths.

Parameters:
  • filename (str) – Save filename (required)

  • depth (float) – Object depth

  • zmx_format (bool) – Whether to use Zemax-style format

  • multi_plot (bool) – Whether to create multiple plots (one per wavelength)

  • lens_title (str or None) – Plot title

  • show (bool) – Display plot

GeoLens.draw_lens_2d(ax, fig, plane='meridional', label=True)

Draw lens surfaces in 2D.

Parameters:
  • ax (matplotlib.axes.Axes) – Matplotlib axis

  • fig (matplotlib.figure.Figure) – Matplotlib figure

  • plane (str) – “meridional” or “sagittal”

  • label (bool) – Show surface labels

GeoLens.draw_ray_2d(ray_o_record, ax, fig, color='b')

Draw ray paths on 2D plot.

Parameters:
  • ray_o_record (list) – Ray intersection records

  • ax (matplotlib.axes.Axes) – Matplotlib axis

  • fig (matplotlib.figure.Figure) – Matplotlib figure

  • color (str) – Ray color

2D Ray Sampling

GeoLens.sample_parallel_2D(fov=0.0, num_rays=7, wvln=0.587, plane='meridional', entrance_pupil=True, depth=0.0)

Sample 2D parallel rays for layout visualization.

Parameters:
  • fov (float) – Field angle in degrees

  • num_rays (int) – Number of rays

  • wvln (float) – Wavelength

  • plane (str) – “meridional” or “sagittal”

  • entrance_pupil (bool) – Use entrance pupil

  • depth (float) – Sampling depth

Returns:

2D ray object

Return type:

Ray

GeoLens.sample_point_source_2D(fov=0.0, num_rays=7, wvln=0.587, plane='meridional', depth=-20000.0)

Sample 2D point source rays.

Parameters:
  • fov (float) – Field angle in degrees

  • num_rays (int) – Number of rays

  • wvln (float) – Wavelength

  • plane (str) – “meridional” or “sagittal”

  • depth (float) – Object depth

Returns:

2D ray object

Return type:

Ray

3D Visualization (GeoLensVis3D)

GeoLens.draw_lens_3d(filename=None, num_rays=5, view_angle=30, fov_list=None, depth=float('inf'), show=False)

Draw 3D lens layout with rays using PyVista.

Parameters:
  • filename (str or None) – Save filename (.png)

  • num_rays (int) – Rays per field

  • view_angle (float) – Camera view angle

  • fov_list (list or None) – List of field angles to visualize

  • depth (float) – Object depth

  • show (bool) – Display interactive window

GeoLens.save_lens_obj(directory='./lens_mesh', num_rays=5, fov_list=None, depth=float('inf'))

Save lens geometry and rays as .obj files.

Parameters:
  • directory (str) – Output directory

  • num_rays (int) – Rays per field

  • fov_list (list or None) – Field angles to export

  • depth (float) – Object depth

GeoLens.create_mesh(num_rays=5, fov_list=None, depth=float('inf'))

Create all lens/bridge/sensor/aperture meshes.

Parameters:
  • num_rays (int) – Rays per field

  • fov_list (list or None) – Field angles

  • depth (float) – Object depth

Returns:

Dictionary with all mesh components

Return type:

dict

GeoLens.draw_layout_3d(filename=None, view_angle=30, show=False)

Alternative 3D layout visualization.

Parameters:
  • filename (str or None) – Save filename

  • view_angle (float) – View angle

  • show (bool) – Display plot

GeoLens.create_barrier(r_extend=1.2, expand_factor=0.3, num_circle=64)

Create 3D barrier mesh for lens system.

Parameters:
  • r_extend (float) – Radial extension factor

  • expand_factor (float) – Expansion factor

  • num_circle (int) – Circle resolution

Returns:

Barrier mesh vertices and faces

Return type:

tuple

Static Methods

static GeoLens.draw_mesh(plotter, mesh, color, opacity=1.0)

Draw a mesh to PyVista plotter.

Parameters:
  • plotter (pyvista.Plotter) – PyVista plotter

  • mesh (CrossPoly) – Mesh object

  • color (list) – RGB color [r, g, b]

  • opacity (float) – Mesh opacity

See Also

References

  1. Xinge Yang, Qiang Fu, and Wolfgang Heidrich, “Curriculum learning for ab initio deep learned refractive optics,” Nature Communications 2024.

  2. Jun Dai, Liqun Chen, Xinge Yang, Yuyao Hu, Jinwei Gu, Tianfan Xue, “Tolerance-Aware Deep Optics,” arXiv:2502.04719, 2025.