Optical Elements¶
DeepLens provides a comprehensive library of optical elements for building custom lens systems.
Geometric Surfaces¶
Spheric Surface¶
Standard spherical surface, the most common optical element.
from deeplens.optics import Spheric
surface = Spheric(
r=50.0, # Radius of curvature [mm]
d=5.0, # Thickness to next surface [mm]
is_square=False, # Circular aperture
device='cuda'
)
Parameters:
r: Radius of curvature (positive for convex, negative for concave)d: Thickness/distance to next surfaceis_square: Aperture shape (True for square, False for circular)
Mathematical Form:
Aspheric Surface¶
Even-order aspheric surface for aberration correction.
from deeplens.optics import Aspheric
surface = Aspheric(
r=50.0, # Base radius
d=5.0, # Thickness
k=0.0, # Conic constant
ai=[0, 0, 1e-5, 0, -1e-7], # Aspheric coefficients
is_square=False,
device='cuda'
)
Mathematical Form:
where \(c = 1/r\) is the curvature, \(k\) is the conic constant, \(\\rho^2 = x^2 + y^2\).
Conic Constant Values:
k = 0: Spherek = -1: Parabolak < -1: Hyperbola-1 < k < 0: Ellipsek > 0: Oblate ellipsoid
Aspheric Normalized¶
Normalized aspheric representation (alternative formulation).
from deeplens.optics import AsphericNorm
surface = AsphericNorm(
r=50.0,
d=5.0,
k=0.0,
ai=[0, 0, 1e-5, 0, -1e-7],
norm_radius=25.0, # Normalization radius
is_square=False,
device='cuda'
)
Plane Surface¶
Flat surface (infinite radius of curvature).
from deeplens.optics import Plane
surface = Plane(
d=10.0, # Air gap or glass thickness
device='cuda'
)
Aperture Stop¶
Aperture stop defining the entrance pupil.
from deeplens.optics import Aperture
surface = Aperture(
r=5.0, # Semi-diameter [mm]
d=0.0, # Typically zero thickness
is_square=False,
device='cuda'
)
The aperture stop controls:
F-number of the system
Vignetting effects
Depth of field
Thin Lens¶
Paraxial thin lens approximation.
from deeplens.optics import ThinLens
surface = ThinLens(
foclen=50.0, # Focal length [mm]
d=10.0, # Distance to next surface
r=10.0, # Semi-diameter
device='cuda'
)
Useful for:
Quick prototyping
Paraxial analysis
First-order optical design
Cubic Phase Surface¶
Cubic phase plate for extended depth of field.
from deeplens.optics import Cubic
surface = Cubic(
r=float('inf'), # Typically flat base
d=1.0,
alpha=10.0, # Cubic phase coefficient
device='cuda'
)
Phase Function:
Phase Surface¶
General phase surface for computational optics.
from deeplens.optics import Phase
surface = Phase(
phase_map=torch.rand(512, 512), # Custom phase pattern
d=0.0,
device='cuda'
)
Diffractive Surfaces¶
Fresnel Zone Plate¶
Diffractive lens based on Fresnel zones.
from deeplens.optics.diffractive_surface import Fresnel
surface = Fresnel(
foclen=50.0, # Focal length [mm]
d=0.001, # DOE thickness [mm]
zone_num=100, # Number of zones
wavelength=0.550, # Design wavelength [micrometers]
device='cuda'
)
Binary Diffractive Surface (Binary 2-level)¶
Simple binary phase surface.
from deeplens.optics.diffractive_surface import Binary2
surface = Binary2(
phase_pattern=torch.rand(512, 512) > 0.5, # Binary pattern
d=0.001,
wavelength=0.550,
device='cuda'
)
Pixelated Metasurface¶
High-resolution pixelated diffractive element.
from deeplens.optics.diffractive_surface import Pixel2D
surface = Pixel2D(
height_map=torch.rand(1024, 1024) * 0.5, # Height in micrometers
pixel_size=0.5, # Pixel size in micrometers
d=0.001,
n_material=1.5, # Refractive index
wavelength=0.550,
device='cuda'
)
Zernike Phase Surface¶
Phase surface defined by Zernike polynomials.
from deeplens.optics.diffractive_surface import Zernike
surface = Zernike(
coefficients=[0, 0, 1, 0.5, 0, 0], # Zernike coefficients
d=0.001,
aperture_radius=10.0,
wavelength=0.550,
device='cuda'
)
Common Zernike Terms:
Index 0-2: Piston, tilt
Index 3: Defocus
Index 4-5: Astigmatism
Index 6-8: Coma, trefoil
Index 9: Spherical aberration
Materials¶
Material Database¶
DeepLens includes extensive material libraries:
from deeplens.optics import Material
# Standard optical glass
glass = Material('N-BK7')
# Get refractive index at wavelength
n = glass.n(wavelength=550) # nm
# Dispersion curve
import matplotlib.pyplot as plt
wavelengths = torch.linspace(400, 700, 100)
indices = [glass.n(w) for w in wavelengths]
plt.plot(wavelengths, indices)
plt.xlabel('Wavelength [nm]')
plt.ylabel('Refractive Index')
plt.show()
Available Catalogs¶
SCHOTT: Standard optical glasses (e.g., N-BK7, N-SF11)
CDGM: Chinese optical glasses
PLASTIC: Optical plastics (e.g., PMMA, PC)
MISC: Special materials
Common Materials¶
Name |
Type |
Refractive Index (550nm) |
Application |
|---|---|---|---|
N-BK7 |
Crown glass |
1.519 |
General purpose |
N-SF11 |
Flint glass |
1.785 |
Chromatic correction |
PMMA |
Plastic |
1.492 |
Low cost optics |
Fused Silica |
Glass |
1.460 |
UV/IR applications |
Custom Materials¶
Define custom materials:
from deeplens.optics import Material
# Sellmeier equation coefficients
material = Material(
name='CustomGlass',
catalog='CUSTOM',
sellmeier_coef=[
1.03961212,
0.231792344,
1.01046945,
0.00600069867,
0.0200179144,
103.560653
]
)
Sellmeier Equation:
Ray Object¶
The Ray class represents light rays for ray tracing.
Creating Rays¶
from deeplens.optics import Ray
# Manual ray creation
ray = Ray(
o=torch.tensor([[0, 0, 0]]), # Origins [mm]
d=torch.tensor([[0, 0, 1]]), # Directions (unit vectors)
wavelength=0.550, # Wavelength [micrometers]
device='cuda'
)
Ray Properties¶
# Ray origins
print(ray.o.shape) # [N, 3]
# Ray directions
print(ray.d.shape) # [N, 3]
# Ray status (1 = active, 0 = blocked)
print(ray.ra)
# Wavelength
print(ray.wavelength)
# Optical path length
print(ray.opl)
Ray Tracing Through Surfaces¶
# Trace ray through a surface
ray_out = surface.ray_reaction(
ray=ray,
n1=1.0, # Refractive index before
n2=1.5, # Refractive index after
wavelength=0.550
)
Wave Propagation¶
Angular Spectrum Method¶
For wave optics propagation:
from deeplens.optics import AngularSpectrumMethod
asm = AngularSpectrumMethod(device='cuda')
# Input field [H, W, 2] (complex field: real, imag)
field_in = torch.randn(512, 512, 2).cuda()
# Propagate
field_out = asm.forward(
field=field_in,
distance=10.0, # Propagation distance [mm]
wavelength=0.550, # Wavelength [micrometers]
pixel_size=0.01 # Pixel size [mm]
)
Fresnel Propagation¶
from deeplens.optics import fresnel_propagation
field_out = fresnel_propagation(
field=field_in,
distance=10.0,
wavelength=0.550,
pixel_size=0.01
)
Loss Functions for Optimization¶
DeepLens provides specialized loss functions for lens optimization:
Spot Loss¶
RMS spot size loss:
from deeplens.optics import SpotLoss
loss_fn = SpotLoss()
loss = loss_fn(ray_out) # Smaller is better
RMS Wavefront Error¶
from deeplens.optics import RMSLoss
loss_fn = RMSLoss()
loss = loss_fn(ray_out)
MTF Loss¶
Modulation Transfer Function based loss:
from deeplens.optics import MTFLoss
loss_fn = MTFLoss(frequency=50) # lp/mm
loss = loss_fn(psf)
Constraints¶
Physical constraints for lens optimization:
# Lens system constraints
lens.init_constraints(
min_thickness=0.5, # Minimum edge thickness [mm]
max_thickness=20.0, # Maximum center thickness [mm]
min_radius=10.0, # Minimum radius of curvature [mm]
max_radius=1000.0 # Maximum radius of curvature [mm]
)
# Get constraint loss
constraint_loss = lens.loss_constraint()
Utilities¶
Ray Sampling¶
from deeplens.optics import sample_rays
# Sample rays from a point source
rays = sample_rays(
source='point',
origin=[0, 0, -1000],
pupil_radius=10.0,
num_rays=1000,
wavelength=0.550,
device='cuda'
)
Coordinate Transformations¶
from deeplens.optics.utils import cart2pol, pol2cart
# Cartesian to polar
r, theta = cart2pol(x, y)
# Polar to Cartesian
x, y = pol2cart(r, theta)
Best Practices¶
Surface Design¶
Start Simple: Begin with spherical surfaces, add aspherics only when needed
Aperture Placement: Place aperture stop strategically for aberration control
Material Selection: Use crown-flint pairs for achromatic designs
Thickness Constraints: Ensure physically realizable thicknesses
Optimization¶
Initialize Well: Start from a reasonable design (e.g., from literature)
Gradual Complexity: Optimize spherical surfaces first, then add aspherics
Multi-Wavelength: Always optimize for multiple wavelengths
Constraints: Use physical constraints to ensure manufacturability
Performance¶
GPU Memory: Monitor GPU memory usage, reduce ray count if needed
Batch Processing: Process multiple field points simultaneously
Precision: Use float32 for speed, float64 for critical calculations
Caching: Cache PSFs for repeated rendering tasks
Next Steps¶
Learn about Sensors and ISP for complete imaging simulation
See Automated Lens Design for optimization workflows
Explore Optics API Reference for detailed API reference