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 classGeoLensEval- Optical performance evaluationGeoLensOptim- Optimization and constraintsGeoLensVis- 2D visualizationGeoLensIO- File I/O operationsGeoLensTolerance- 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:
- d_sensor: torch.Tensor¶
Distance from first surface to sensor 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().
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 sourcesnum_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:
- 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.
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:
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:
- 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:
Sensor Sampling¶
- GeoLens.sample_sensor(spp=64, wvln=0.587, sub_pixel=False)¶
Sample backward rays from sensor pixels for ray-tracing rendering.
Helper Methods¶
- GeoLens.sample_circle(r, z, shape=[16, 16, 512])¶
Sample points uniformly inside a circle at depth z.
- Parameters:
- Returns:
Sampled points with shape [*shape, 3]
- Return type:
- 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:
- Returns:
Sampled rays
- Return type:
Ray Tracing¶
- GeoLens.trace(ray, surf_range=None, record=False)¶
Trace rays through the lens (forward or backward determined automatically).
- GeoLens.trace2sensor(ray, record=False)¶
Trace rays to sensor plane.
- GeoLens.trace2obj(ray)¶
Trace rays to object space (backward tracing).
- GeoLens.forward_tracing(ray, surf_range, record)¶
Forward ray tracing implementation.
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:
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:
- 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:
- 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:
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:
- 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:
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:
- GeoLens.psf_geometric(points, ks=64, wvln=0.587, spp=16384, recenter=True)¶
Calculate incoherent geometric PSF using ray tracing.
- Parameters:
- Returns:
PSF tensor
- Return type:
- 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:
- 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:
- 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.
- 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:
- 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:
- Returns:
PSF patch [ks, ks]
- Return type:
- 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:
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.
- 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.
RMS Error Maps¶
- GeoLens.rms_map_rgb(num_grid=32, depth=-20000.0)¶
Calculate RGB RMS spot error map.
- Parameters:
- Returns:
RMS error map for each RGB channel
- Return type:
- GeoLens.rms_map(num_grid=32, depth=-20000.0, wvln=0.587)¶
Calculate RMS spot error map for single wavelength.
- Parameters:
- Returns:
RMS error map
- Return type:
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:
- 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).
- GeoLens.distortion_map(num_grid=16, depth=-20000.0)¶
Compute distortion map for grid_sample.
- Parameters:
- Returns:
Distortion map [num_grid, num_grid, 2]
- Return type:
- 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:
MTF Analysis¶
- GeoLens.mtf(fov, wvln=0.587)¶
Calculate Modulation Transfer Function at field of view.
- Parameters:
fov (list or torch.Tensor) – Field position [x, y] normalized in [-1, 1]
wvln (float) – Wavelength
- Returns:
MTF curve
- Return type:
- static GeoLens.psf2mtf(psf, pixel_size)¶
Convert PSF to MTF.
- Parameters:
psf (torch.Tensor) – PSF tensor
pixel_size (float) – Pixel size in mm
- Returns:
MTF curve
- Return type:
- 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.
Vignetting¶
- GeoLens.vignetting(depth=-20000.0, num_grid=64)¶
Compute vignetting map.
- Parameters:
- Returns:
Vignetting map
- Return type:
Chief Ray¶
- GeoLens.calc_chief_ray(fov, plane='sagittal')¶
Calculate chief ray for given field angle.
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.
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.
- GeoLens.get_exit_pupil(paraxial=False)¶
Get exit pupil location and radius.
- GeoLens.calc_entrance_pupil(paraxial=False)¶
Calculate entrance pupil by backward ray tracing from aperture.
Field of View¶
- GeoLens.calc_fov()¶
Compute field of view using perspective projection and ray tracing.
Focal & Sensor Planes¶
- GeoLens.calc_focal_plane(wvln=0.587)¶
Calculate focus distance in object space by backward tracing.
Helper Methods¶
- static GeoLens.compute_intersection_points_2d(origins, directions)¶
Compute intersection points of 2D lines.
- Parameters:
origins (torch.Tensor) – Line origins [N, 2]
directions (torch.Tensor) – Line directions [N, 2]
- Returns:
Intersection points [N*(N-1)/2, 2]
- Return type:
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
Shape Correction¶
Materials¶
Optimization (GeoLensOptim)¶
Constraints¶
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:
- Returns:
Total regularization loss
- Return type:
- GeoLens.loss_infocus(target=0.005)¶
Loss for focusing parallel rays.
- Parameters:
target (float) – Target RMS error in mm
- Returns:
Focus loss
- Return type:
- GeoLens.loss_surface()¶
Penalize problematic surface shapes (sag, gradient, curvature).
- Returns:
Surface shape loss
- Return type:
- GeoLens.loss_intersec()¶
Penalize surface self-intersection violations.
- Returns:
Intersection loss
- Return type:
- GeoLens.loss_gap()¶
Penalize excessive air gaps and element thickness.
- Returns:
Gap constraint loss
- Return type:
- GeoLens.loss_ray_angle()¶
Penalize large chief ray angles at sensor.
- Returns:
Ray angle loss
- Return type:
- GeoLens.loss_mat()¶
Penalize invalid material properties.
- Returns:
Material loss
- Return type:
- GeoLens.loss_rms(depth=float('inf'), grid=None, spp=None, wvlns=None, weights=None)¶
Compute RGB spot RMS loss.
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:
- 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.
- 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:
- Returns:
Adam optimizer
- Return type:
File I/O (GeoLensIO)¶
JSON Format¶
ZEMAX Format¶
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.
- GeoLens.tolerancing_monte_carlo(trials=1000, tolerance_params=None)¶
Perform Monte Carlo tolerance analysis.
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.
- GeoLens.draw_lens_2d(ax, fig, plane='meridional', label=True)¶
Draw lens surfaces in 2D.
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.
- GeoLens.sample_point_source_2D(fov=0.0, num_rays=7, wvln=0.587, plane='meridional', depth=-20000.0)¶
Sample 2D point source rays.
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.
- GeoLens.save_lens_obj(directory='./lens_mesh', num_rays=5, fov_list=None, depth=float('inf'))¶
Save lens geometry and rays as .obj files.
- GeoLens.create_mesh(num_rays=5, fov_list=None, depth=float('inf'))¶
Create all lens/bridge/sensor/aperture meshes.
- GeoLens.draw_layout_3d(filename=None, view_angle=30, show=False)¶
Alternative 3D layout visualization.
- GeoLens.create_barrier(r_extend=1.2, expand_factor=0.3, num_circle=64)¶
Create 3D barrier mesh for lens system.
Static Methods¶
See Also¶
Lens API Reference - Base Lens class documentation
Optics API Reference - Optical elements and surfaces
Sensor API Reference - Sensor and image processing
Utilities API Reference - Utility functions
References¶
Xinge Yang, Qiang Fu, and Wolfgang Heidrich, “Curriculum learning for ab initio deep learned refractive optics,” Nature Communications 2024.
Jun Dai, Liqun Chen, Xinge Yang, Yuyao Hu, Jinwei Gu, Tianfan Xue, “Tolerance-Aware Deep Optics,” arXiv:2502.04719, 2025.