Optics Core
Shared building blocks used by every lens model: base classes, optical surfaces, light/wave representations, and image-simulation utilities.
Base Classes
Base class for all optical objects. Provides device transfer, dtype conversion, and cloning by introspecting instance tensors.
deeplens.DeepObj
Base class for all differentiable optical objects in DeepLens.
Provides device management, dtype conversion, and deep-copy support via
automatic introspection over instance tensors and nested DeepObj
sub-objects. All lens, surface, material, ray, and wave objects inherit
from this class.
Attributes:
| Name | Type | Description |
|---|---|---|
dtype |
dtype
|
Floating-point dtype of all owned tensors. |
device |
str or device
|
Compute device, set by |
Initialize the base object and record its floating-point dtype.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype
|
dtype
|
Floating-point dtype for owned
tensors. Defaults to |
None
|
Source code in deeplens-src/deeplens/base.py
__str__
Return a multi-line string listing the object's attributes.
Scalars and tensors are printed as key: value; lists and tuples are
expanded element-wise; dicts and sets are skipped.
Returns:
| Name | Type | Description |
|---|---|---|
text |
str
|
Human-readable summary of the object's attributes. |
Source code in deeplens-src/deeplens/base.py
__call__
Forward the input to the subclass forward method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inp
|
Any
|
Input passed through to |
required |
Returns:
| Name | Type | Description |
|---|---|---|
output |
Any
|
Result of |
clone
Return a deep copy of this object.
Returns:
| Name | Type | Description |
|---|---|---|
obj |
DeepObj
|
A new, independent deep copy of |
to
Move all tensors and nested objects to a device.
Recursively walks over every instance attribute and moves tensors,
nn.Parameter data, nn.Module sub-objects, nested DeepObj objects,
and tensors/DeepObj items inside lists and tuples to the target device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device
|
str or device
|
Target device, e.g. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
self |
DeepObj
|
The updated object (for chaining). |
Examples:
Source code in deeplens-src/deeplens/base.py
astype
Convert all floating-point tensors to a target dtype.
Recursively converts owned floating-point and complex tensors,
nn.Parameter data, modules, nested DeepObj objects, and values inside
lists, tuples, and dictionaries. Conversion is local to this object; it
never changes PyTorch's process-wide default dtype.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype
|
dtype or None
|
Target floating-point dtype, one of
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
self |
DeepObj
|
The updated object (for chaining). |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If dtype is not one of the three supported floating-point dtypes. |
Examples:
Source code in deeplens-src/deeplens/base.py
Optical material model (refractive index and dispersion) used by refractive surfaces.
deeplens.Material
Bases: DeepObj
Optical material defined by its wavelength-dependent refractive index.
Materials are looked up by name in the bundled CDGM, SCHOTT, or MISC AGF
catalogs, in a custom JSON catalog, in the bundled refractiveindex.info
catalog (optical glasses from SCHOTT/OHARA/HOYA/HIKARI/SUMITA/CDGM/LZOS/
Crystran plus common substrate crystals), or specified inline as "n/V"
(Cauchy approximation from Abbe number V). Names defined by more than one
source resolve in that order, so refractiveindex.info only fills gaps and
never overrides an existing name.
Supported dispersion models: "sellmeier", "cauchy", "schott",
"interp" (lookup table), "rii" (refractiveindex.info dispersion
formulas), and "optimizable" (Cauchy with learnable n, V).
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Lowercase material name. |
device |
str
|
Compute device for dispersion tensors. |
dispersion |
str
|
Dispersion model in use ( |
n |
float or Tensor
|
Refractive index at the d-line (587.6 nm).
Becomes a learnable tensor after |
V |
float or Tensor
|
Abbe number. Also learnable in
|
Initialize an optical material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or None
|
Material name (case-insensitive). Accepted forms:
Defaults to None (treated as |
None
|
device
|
str
|
Compute device. Defaults to |
'cpu'
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If name is not found in any catalog. |
Examples:
Source code in deeplens-src/deeplens/material/materials.py
get_name
Return the material name, or an inline "n/V" string if optimizable.
Returns:
| Name | Type | Description |
|---|---|---|
name |
str
|
The catalog name, or a |
Source code in deeplens-src/deeplens/material/materials.py
load_dispersion
Resolve the material name into a dispersion model and its parameters.
Sets self.dispersion and the corresponding coefficients (Sellmeier
k*/l*, Schott a*, Cauchy A/B, or interpolation tables), along
with self.n (d-line index) and self.V (Abbe number). Looks up the
name in the AGF catalogs, the inline "n/V" form, the custom JSON
tables, then the bundled refractiveindex.info catalog (RII_data) as a
final fallback, so names from earlier sources keep precedence.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If the material name is not found in any catalog. |
ValueError
|
If a custom |
Source code in deeplens-src/deeplens/material/materials.py
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
load_interp_table
Set up a tabulated-index ("interp") material from a data table.
Stores the reference wavelength/index arrays (and cached tensors), then
samples self.n (d-line) and self.V (Abbe number) from the table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mat_data
|
dict
|
Mapping with keys |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the wavelength and index tables differ in length. |
Source code in deeplens-src/deeplens/material/materials.py
set_material_param_agf
Set dispersion model and coefficients from an AGF catalog entry.
Reads the calculate_mode flag to pick the Schott (mode 1) or Sellmeier
(mode 2) model, fills the corresponding coefficients, and sets self.n
and self.V from the catalog's nd/vd fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
material_data
|
dict
|
Parsed AGF catalog (name to parameter dict). |
required |
material_name
|
str
|
Lowercase material name to look up. |
required |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If the entry's |
Source code in deeplens-src/deeplens/material/materials.py
set_sellmeier_param
Manually set the six Sellmeier coefficients for a custom material.
Switches the dispersion model to "sellmeier" so subsequent ior calls
use the newly set parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
tuple or list or None
|
The six coefficients
|
None
|
Source code in deeplens-src/deeplens/material/materials.py
refractive_index
Compute the refractive index at a given wavelength.
Thin wrapper over ior that accepts a Python float and returns a float,
otherwise passes a tensor through unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wvln
|
float or Tensor
|
Wavelength in micrometres [µm]. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
n |
float or Tensor
|
Refractive index. A float when |
Source code in deeplens-src/deeplens/material/materials.py
ior
Compute the refractive index from the active dispersion model.
Dispatches on self.dispersion: Sellmeier, Schott, Cauchy, linear
interpolation of a lookup table, the refractiveindex.info dispersion
formulas ("rii"), or an optimizable Cauchy form with learnable (n, V).
The Cauchy branch evaluates \(n = A + B/\lambda^2\) with \(\lambda\) in
nanometres; all other branches take \(\lambda\) in micrometres directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wvln
|
Tensor
|
Wavelength in micrometres [µm]. Must lie in (0.1, 10). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
n |
Tensor
|
Refractive index, same shape as |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
Source code in deeplens-src/deeplens/material/materials.py
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | |
nV_to_AB
staticmethod
Convert (n, V) to Cauchy coefficients (A, B).
Solves the two-term Cauchy model \(n(\lambda) = A + B/\lambda^2\) for A
and B given the d-line index and Abbe number, using the F/d/C lines
(486.1 / 587.6 / 656.3 nm). B is in nm², matching the Cauchy branch of
ior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
float
|
Refractive index at the d-line. |
required |
V
|
float
|
Abbe number. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
float
|
Cauchy constant term. |
B |
float
|
Cauchy dispersion term, in nm². |
Source code in deeplens-src/deeplens/material/materials.py
match_material
Snap this material to the closest real glass in a catalog.
Finds the catalog entry minimising the normalised (n, V) distance (n scaled by 0.4, V by 40), renames this material to it, and reloads its dispersion. No-op for air.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mat_table
|
str or dict or None
|
Catalog to match against.
|
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
Source code in deeplens-src/deeplens/material/materials.py
get_optimizer_params
Make (n, V) learnable and return optimizer parameter groups.
Converts self.n and self.V to gradient-tracking tensors and switches
the dispersion model to "optimizable". Optimizing the refractive index
matters more than the Abbe number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates |
[0.0001, 0.01]
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
Two optimizer parameter-group dicts, one for n and one for V, each with its own learning rate. |
Source code in deeplens-src/deeplens/material/materials.py
Surfaces
Axial spacing
Current surface constructors use d_next, the axial distance to the next
surface. A few upstream-generated argument descriptions still say d;
follow the rendered function signature. Use lens.surf_d(i) for global z.
Geometric Surfaces
Base class for all geometric optical surfaces. Implements surface intersection (Newton's method with one differentiable step) and differentiable vector Snell's law refraction.
deeplens.geometric_surface.Surface
Surface(
r,
d_next,
mat2,
pos_xy=[0.0, 0.0],
vec_local=[0.0, 0.0, 1.0],
is_square=False,
device="cpu",
)
Bases: DeepObj
Base class for all geometric optical surfaces.
Surfaces use sequential geometry: each surface owns only d_next, the
axial thickness [mm] from its vertex to the next vertex (or from the last
surface to the sensor). Absolute vertex positions are derived by
GeoLens.surf_d; they are not stored on individual surfaces. A surface
also has an aperture radius r [mm] and separates two optical media.
Subclasses override _sag and _dfdxy to define their shape.
Ray-surface interaction is handled in three stages by ray_reaction:
- Coordinate transform: the ray is brought into the local surface frame.
- Intersection: solved via Newton's method (
newtons_method), using a non-differentiable iteration loop followed by a single differentiable Newton step to enable gradient flow. - Refraction / reflection: vector Snell's law (
refract) or specular reflection (reflect).
Attributes:
| Name | Type | Description |
|---|---|---|
d_next |
Tensor
|
Thickness to the next vertex [mm], scalar tensor. |
r |
float
|
Aperture radius [mm]. For a square aperture this is the circumscribed-circle radius (half-diagonal). |
mat2 |
Material
|
Optical material on the transmission side. |
pos_x |
Tensor
|
Lateral x offset of the vertex [mm], scalar tensor. |
pos_y |
Tensor
|
Lateral y offset of the vertex [mm], scalar tensor. |
vec_local |
Tensor
|
Local surface normal direction, shape [3]. |
is_square |
bool
|
If True the aperture is square; otherwise circular. |
w |
float
|
Square aperture side length [mm] (only set when |
h |
float
|
Square aperture side length [mm] (only set when |
Initialize a generic optical surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius [mm]. For a square aperture this is the
circumscribed-circle radius (half-diagonal), so the side length
is |
required |
d_next
|
float
|
Axial thickness to the next vertex [mm]. |
required |
mat2
|
str or Material
|
Material on the transmission side (e.g. "N-BK7", "air"). |
required |
pos_xy
|
list[float]
|
Lateral offset [x, y][mm]. Defaults to [0.0, 0.0]. |
[0.0, 0.0]
|
vec_local
|
list[float]
|
Local surface normal direction; normalized internally. Defaults to [0.0, 0.0, 1.0] (on-axis). |
[0.0, 0.0, 1.0]
|
is_square
|
bool
|
Use a square aperture instead of a circular one. Defaults to False. |
False
|
device
|
str
|
Compute device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
init_from_dict
classmethod
Initialize a surface from a serialized dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters, typically produced by
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
surface |
Surface
|
The reconstructed surface instance. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Always, on the base class; subclasses override. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
paraxial_power
Return the paraxial (first-order) optical power of this surface [1/mm].
Only the vertex geometry contributes: conic constants, aspheric terms and freeform departures vanish in the paraxial limit, matching the first-order convention used by Zemax and CODE V. Surfaces with a base curvature or an explicit focal length override this; flat and freeform surfaces contribute pure transfer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n1
|
Tensor
|
Refractive index of the incident medium. |
required |
n2
|
Tensor
|
Refractive index of the transmission medium. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
power |
Tensor
|
Surface power [1/mm], scalar. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
ray_reaction
Compute the output ray after intersection and refraction/reflection.
The input ray is expressed in this surface's reference frame (its
vertex is at z=0). This method applies only the surface-local lateral
offset/orientation, intersection and refraction/reflection. GeoLens
applies the axial d_next frame step between surface interactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Incident ray bundle. |
required |
n1
|
float
|
Refractive index of the incident medium. |
required |
n2
|
float
|
Refractive index of the transmission medium. |
required |
refraction
|
bool
|
If True refract the ray; if False reflect it. Defaults to True. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Updated ray bundle after the surface interaction. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
intersect
Solve ray-surface intersection in the local coordinate system.
Moves each valid ray origin to the surface and, for coherent rays,
accumulates optical path length n * t into ray.opl.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray bundle in local coordinates. |
required |
n
|
float
|
Refractive index of the medium the ray travels through to reach the surface. Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Ray with updated origins, validity mask, and (for coherent rays) optical path length. |
Raises:
| Type | Description |
|---|---|
Exception
|
If a coherent ray has float32 dtype and an intersection distance above 100 mm, which can cause OPL precision problems. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
newton_initial_t
Return the initial ray parameter for Newton intersection solving.
The generic approximation intersects the ray with the local vertex
plane at z = 0. Surfaces with a closer analytic base shape can
override this hook without duplicating the Newton iteration itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray bundle in local surface coordinates. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
t |
Tensor
|
Initial intersection parameter [mm], shape [...] matching the ray batch. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
newtons_method
Solve the ray-surface intersection by Newton's method (local frame).
Runs newton_maxiter - 1 non-differentiable iterations followed by one
differentiable Newton step, so gradients flow only through the final
step. The solved \(t\) satisfies sag(x, y) - z = 0 along the ray.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray bundle in local coordinates. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
t |
Tensor
|
Intersection parameter (distance along the ray) [mm], shape [...] matching the ray batch. |
valid |
Tensor
|
Boolean mask of converged, in-range intersections, shape [...]. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
bend_penalty
Accumulate a soft per-surface bend penalty onto the ray.
The penalty rises smoothly once the bend angle between old_d and the
refracted ray.d exceeds bend_angle_max (degrees, default 30) and
stays at zero for milder refractions. It is added into ray.bend_penalty.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Ray after refraction ( |
required |
old_d
|
Tensor
|
Pre-refraction ray directions, shape [..., 3],
same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Ray with |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
refract
Refract a ray with vector Snell's law in local coordinates.
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
to_local_coord
Transform a ray from the surface reference frame to local coordinates.
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
to_global_coord
Transform a ray from local coordinates to the surface reference frame.
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
reflect
Reflect the ray specularly off the surface (local coordinate system).
The surface normal points from the surface toward the side the light comes from. The reflected direction is renormalized.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Incident ray bundle. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Reflected ray with updated direction. |
Reference
[1] https://registry.khronos.org/OpenGL-Refpages/gl4/html/reflect.xhtml [2] https://en.wikipedia.org/wiki/Snell%27s_law, "Vector form" section.
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
normal_vec
Compute the unit surface normal at the ray intersection point (local frame).
The normal points from the surface toward the side the light comes from (it is flipped to oppose forward-propagating rays).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray bundle whose origins |
required |
Returns:
| Name | Type | Description |
|---|---|---|
n_vec |
Tensor
|
Unit surface normal vectors, shape [..., 3]. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
sag
Calculate the surface sag \(z = f(x, y)\) [mm] with validity masking.
The valid mask zeroes out-of-range coordinates before calling _sag,
avoiding NaN for spherical/aspheric surfaces where \(r = \sqrt{x^2 + y^2}\)
is undefined in back-propagation at \(x = y = 0\) (since \(dr/dx = x/r\)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
valid
|
Tensor or None
|
Boolean mask of valid points,
same shape as |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
z |
Tensor
|
Surface sag [mm], same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
dfdxyz
Compute the gradient of the implicit surface function.
The surface is defined implicitly as \(f(x, y, z) = \mathrm{sag}(x, y) - z = 0\). This gradient is used in Newton's method and normal-vector computation. The analytical implementation here only works for explicit surfaces \(z = \mathrm{sag}(x, y)\); for implicit surfaces one could instead use numerical finite differences or autograd.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
valid
|
Tensor or None
|
Boolean mask of valid points,
same shape as |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dfdx |
Tensor
|
Partial derivative \(\partial f/\partial x\) [1], same shape as |
dfdy |
Tensor
|
Partial derivative \(\partial f/\partial y\) [1], same shape as |
dfdz |
Tensor
|
Partial derivative \(\partial f/\partial z = -1\), same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
d2fdxyz2
Compute second-order partial derivatives of the implicit surface function.
The surface function is \(f(x, y, z) = \mathrm{sag}(x, y) - z = 0\), so all second derivatives involving \(z\) vanish. Currently used only for surface constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
valid
|
Tensor or None
|
Boolean mask of valid points,
same shape as |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
d2f_dx2 |
Tensor
|
\(\partial^2 f/\partial x^2\), same shape as |
d2f_dxdy |
Tensor
|
\(\partial^2 f/\partial x\partial y\), same shape as |
d2f_dy2 |
Tensor
|
\(\partial^2 f/\partial y^2\), same shape as |
d2f_dxdz |
Tensor
|
\(\partial^2 f/\partial x\partial z = 0\), same shape as |
d2f_dydz |
Tensor
|
\(\partial^2 f/\partial y\partial z = 0\), same shape as |
d2f_dz2 |
Tensor
|
\(\partial^2 f/\partial z^2 = 0\), same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
is_valid
Return a mask of points within both the data range and aperture boundary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
valid |
Tensor
|
Boolean mask, same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
is_within_boundary
Return a mask of points inside the aperture boundary.
For a square aperture the limits are the half-side lengths w/2, h/2;
otherwise the circular radius r is used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
valid |
Tensor
|
Boolean mask, same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
is_within_data_range
Return a mask of points inside the sag function's data region.
The base surface has an unbounded data region, so all points are valid; subclasses (e.g. spheric) override this to exclude regions where the sag is undefined.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm], any shape. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
valid |
Tensor
|
Boolean mask, same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
max_height
Return the maximum valid radial height of the surface [mm].
Returns:
| Name | Type | Description |
|---|---|---|
max_height |
float
|
Maximum valid height [mm] (10e3 for the base surface). |
surface_with_offset
Compute the z coordinate sag(x, y) + d.
The surface does not own an absolute axial position, so callers that
need global geometry pass the vertex position from GeoLens.surf_d.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor or float
|
Local x coordinate [mm]. |
required |
y
|
Tensor or float
|
Local y coordinate [mm], same shape as |
required |
valid_check
|
bool
|
If True apply |
True
|
d
|
float or Tensor
|
Vertex position to add [mm]. Defaults to 0 (the surface reference frame). |
0.0
|
Returns:
| Name | Type | Description |
|---|---|---|
z |
Tensor
|
Global z coordinate [mm], same shape as |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
surface_sag
Compute the local surface sag at (x, y) as a Python float.
This function is currently not used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor or float
|
Local x coordinate [mm]. |
required |
y
|
Tensor or float
|
Local y coordinate [mm]. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
sag |
float
|
Surface sag [mm] at (x, y). |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
get_optimizer_params
Build the per-parameter optimizer parameter groups (subclass-specific).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list[float]
|
Learning rates for the surface's differentiable parameters. Defaults to [1e-4]. |
[0.0001]
|
optim_mat
|
bool
|
Whether to also optimize the material refractive index/dispersion. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list[dict]
|
Adam parameter groups (param tensors and |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Always, on the base class; subclasses override. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
get_optimizer
Build an Adam optimizer over the surface's differentiable parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list[float]
|
Learning rates passed to
|
[0.0001]
|
optim_mat
|
bool
|
Whether to optimize the material. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
optimizer |
Adam
|
Adam optimizer for the surface. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
update_r
Update the aperture radius, clamped to max_height.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Requested aperture radius [mm]. |
required |
draw_r
Return the effective drawing radius [mm], clamped to max_height.
Returns:
| Name | Type | Description |
|---|---|---|
r_eff |
float
|
Effective drawing radius [mm]. |
draw_widget
Draw the surface profile as a 2D line on a Matplotlib axis.
Plots the meridional (y-z) cross section sampled across the aperture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes
|
Axis to draw on. |
required |
color
|
str
|
Line color. Defaults to "black". |
'black'
|
linestyle
|
str
|
Matplotlib line style. Defaults to "solid". |
'solid'
|
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
create_mesh
Create a triangulated mesh of the surface for 3D visualization.
Populates self.vertices, self.faces, self.rim, and self.mesh_color.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_rings
|
int
|
Number of concentric rings for radial sampling. Defaults to 32. |
32
|
n_arms
|
int
|
Number of angular divisions. Defaults to 128. |
128
|
color
|
list[float]
|
RGB mesh color in [0, 1]. Defaults to [0.06, 0.3, 0.6]. |
[0.06, 0.3, 0.6]
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Surface
|
The surface with mesh data (for chaining). |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
get_polydata
Build a PyVista PolyData object from the cached vertices and faces.
Requires create_mesh to have been called first. The PolyData is used to
draw the surface and export it as an .obj file.
Returns:
| Name | Type | Description |
|---|---|---|
polydata |
PolyData
|
Mesh as a PyVista PolyData object. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
surf_dict
Serialize the surface's common parameters to a dict.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters (type, |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
zmx_str
Return the Zemax (.zmx) text block describing this surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_idx
|
int
|
Index of this surface in the Zemax surface list. |
required |
d_next
|
float
|
Axial distance [mm] to the next surface (thickness). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
zmx_str |
str
|
Zemax-formatted surface definition string. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Always, on the base class; subclasses override. |
Source code in deeplens-src/deeplens/geometric_surface/base_surface.py
Spherical surface defined by curvature c = 1/R.
deeplens.geometric_surface.Spheric
Spheric(
c,
r,
d_next,
mat2,
pos_xy=[0.0, 0.0],
vec_local=[0.0, 0.0, 1.0],
is_square=False,
device="cpu",
)
Bases: Surface
Spherical refractive surface parameterized by curvature.
A sphere of radius \(R = 1/c\) whose vertex sits at the optical axis. The sag (surface height along \(z\)) is:
Attributes:
| Name | Type | Description |
|---|---|---|
c |
Tensor
|
Surface curvature \(1/R\) [1/mm], scalar tensor.
Gradients are enabled by |
Initialize a spherical surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
c
|
float
|
Surface curvature \(1/R\) [1/mm]. Use 0 for a flat surface (treated as a plane). |
required |
r
|
float
|
Aperture radius [mm]. |
required |
d
|
float
|
Axial vertex position [mm]. |
required |
mat2
|
str or Material
|
Material on the transmission side. |
required |
pos_xy
|
list[float]
|
Lateral offset |
[0.0, 0.0]
|
vec_local
|
list[float]
|
Local surface normal direction.
Defaults to |
[0.0, 0.0, 1.0]
|
is_square
|
bool
|
Use a square aperture instead of a circular one. Defaults to False. |
False
|
device
|
str
|
Compute device. Defaults to |
'cpu'
|
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
init_from_dict
classmethod
Construct a Spheric surface from a parameter dictionary.
Accepts either a radius of curvature roc [mm] (converted to curvature
c, with roc == 0 mapped to c = 0) or a curvature c [1/mm]
directly. The aperture radius r [mm], vertex position d [mm], and
transmission material mat2 are read from the dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Must contain |
required |
Returns:
| Name | Type | Description |
|---|---|---|
surface |
Spheric
|
The constructed spherical surface. |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
paraxial_power
Return the paraxial optical power of this surface [1/mm].
Only the vertex curvature contributes; higher-order geometry does not affect first-order properties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n1
|
Tensor
|
Refractive index of the incident medium. |
required |
n2
|
Tensor
|
Refractive index of the transmission medium. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
power |
Tensor
|
Surface power |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
intersect
Solve the ray-surface intersection analytically in local coordinates.
Substitutes the ray \(p(t) = o + t\,d\) into the sphere
\(x^2 + y^2 + (z - R)^2 = R^2\) (with \(R = 1/c\)) and solves the resulting
quadratic for \(t\), picking the root whose intersection lies closest to
the surface vertex at \(z = 0\). A flat surface ($|c| < $ EPSILON) is
handled as a plane. Rays falling outside the aperture or with no real
root are flagged invalid. Updates ray.o, ray.is_valid, and, for
coherent rays, ray.opl (adding \(n\,t\)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray, modified in place. |
required |
n
|
float
|
Refractive index of the incident medium, used for the optical path length update. Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
The same ray with updated position, validity, and opl. |
Raises:
| Type | Description |
|---|---|
Exception
|
If a coherent ray travels more than 100 mm under float32, where OPL accumulation loses precision. |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | |
is_within_data_range
Check whether points lie within the sag-defined region.
Points are valid only where \(x^2 + y^2 < 1/c^2\), i.e. inside the radius where the sphere's sag is real-valued.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Local x coordinate [mm]. |
required |
y
|
Tensor
|
Local y coordinate [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
valid |
Tensor
|
Boolean mask, same shape as |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
max_height
Return the maximum valid radial height of the surface.
Equal to \(|R| = 1/|c|\) minus a small 0.001 mm margin to stay inside the region where the sag is well-defined.
Returns:
| Name | Type | Description |
|---|---|---|
max_height |
float
|
Maximum radial height [mm]. |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
get_optimizer_params
Enable gradients on c and d and build optimizer parameter groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list[float]
|
Learning rates |
[0.0001, 0.0001]
|
optim_mat
|
bool
|
Also optimize the transmission material parameters (skipped when the material is air). Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list[dict]
|
Optimizer parameter groups, each with |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
surf_dict
Serialize the surface to a parameter dictionary.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters with keys |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
zmx_str
Format the surface as a Zemax STANDARD surface block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_idx
|
int
|
Surface index in the Zemax file. |
required |
d_next
|
Tensor
|
Axial distance to the next surface [mm], scalar tensor. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
zmx_str |
str
|
Multi-line Zemax surface description. |
Source code in deeplens-src/deeplens/geometric_surface/spheric.py
Even-asphere surface: spherical base with polynomial corrections.
deeplens.geometric_surface.Aspheric
Aspheric(
r,
d_next,
c,
k,
ai,
mat2,
ai2=None,
pos_xy=[0.0, 0.0],
vec_local=[0.0, 0.0, 1.0],
is_square=False,
device="cpu",
)
Bases: Surface
Even-order aspheric surface.
The sag function is:
The polynomial starts at the 4th-order term (a4) because the 2nd-order
term competes with the base curvature c.
All coefficients c, k, and ai are differentiable torch
tensors so they can be optimised with gradient descent.
Attributes:
| Name | Type | Description |
|---|---|---|
c |
Tensor
|
Base curvature [1/mm]. |
k |
Tensor
|
Conic constant. |
ai2 |
Tensor or None
|
2nd-order aspheric coefficient (legacy). |
ai |
Tensor
|
Even-order aspheric coefficients
|
Initialize an aspheric surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius [mm]. |
required |
d
|
float
|
Axial vertex position [mm]. |
required |
c
|
float
|
Base curvature |
required |
k
|
float
|
Conic constant ( |
required |
ai
|
list[float] or None
|
Even-order aspheric coefficients
starting from the 4th-order term: |
required |
mat2
|
str or Material
|
Material on the transmission side. |
required |
ai2
|
float or None
|
2nd-order aspheric coefficient from legacy data. Included in sag but not optimised. Defaults to None. |
None
|
pos_xy
|
list[float]
|
Lateral offset |
[0.0, 0.0]
|
vec_local
|
list[float]
|
Local normal direction.
Defaults to |
[0.0, 0.0, 1.0]
|
is_square
|
bool
|
Square aperture flag. Defaults to False. |
False
|
device
|
str
|
Compute device. Defaults to |
'cpu'
|
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
init_from_dict
classmethod
Create an aspheric surface from a serialized dict.
The base curvature is read from roc (radius of curvature [mm],
converted to c = 1/roc) when present, otherwise from c [1/mm].
For legacy data where use_ai2 is True (or absent), the first
element of ai is interpreted as the 2nd-order coefficient a2
and the rest as [a4, a6, a8, ...].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Serialized surface with keys |
required |
Returns:
| Name | Type | Description |
|---|---|---|
surface |
Aspheric
|
The reconstructed aspheric surface. |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
paraxial_power
Return the paraxial optical power of this surface [1/mm].
Only the vertex curvature contributes, so the conic constant and the 4th- and higher-order coefficients do not affect first-order properties. The legacy \(a_2\rho^2\) term is the exception: near the vertex the sag is \((c/2 + a_2)\rho^2\), so it shifts the vertex curvature to \(c + 2 a_2\) and must be included.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n1
|
Tensor
|
Refractive index of the incident medium. |
required |
n2
|
Tensor
|
Refractive index of the transmission medium. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
power |
Tensor
|
Surface power |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
is_within_data_range
Return a mask of points where the conic sag is real-valued.
A point is valid when \((1+k)c^2\rho^2 < 1\), i.e. inside the conic's
real boundary. Fully tensorized (no Python branch on the tensor value
of k) so the function is safe to trace through torch.compile.
When \(k \le -1\) the conic has no real boundary, so every point is
treated as valid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
x coordinate(s) [mm], any shape. |
required |
y
|
Tensor
|
y coordinate(s) [mm], broadcastable with |
required |
Returns:
| Name | Type | Description |
|---|---|---|
valid |
Tensor
|
Boolean mask, same shape as the broadcast
of |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
max_height
Return the maximum valid radial height of the surface.
For an oblate/ellipsoidal conic (\(k > -1\)) the sag is real only up to \(\rho_{max} = \sqrt{1/((k+1)c^2)}\); a small margin (0.001 mm) is subtracted. For \(k \le -1\) there is no boundary and a large value (10000 mm) is returned.
Returns:
| Name | Type | Description |
|---|---|---|
max_height |
float
|
Maximum valid radial height [mm]. |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
newton_initial_t
Seed Newton's method with the base-sphere intersection.
The base sphere is defined by the asphere curvature c with
conic constant and polynomial coefficients set to zero. Its vertex is
at the local origin and its center is at (0, 0, 1/c). Of the two
analytic intersections, this method selects the point closest to the
vertex, matching the sag branch represented by _sag.
A repeated root is handled explicitly. A flat base, a ray that misses
the sphere, or a non-finite analytic result falls back safely to the
vertex-plane approximation supplied by Surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray bundle in local surface coordinates. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
t |
Tensor
|
Initial intersection parameter [mm], shape [...] matching the ray batch. |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
get_optimizer_params
Get optimizer parameters for different parameters.
The learning rate for each aspheric coefficient \(a_{2n}\) is scaled by \(1 / \max(r, 1)^{2n}\) so that the effective sag perturbation per Adam step is approximately constant (~lr_base mm) regardless of surface semi-diameter. Without this normalisation, gradients scale as \(O(r^{2n})\) and can reach \(10^5\) for camera-sized surfaces, causing NaN within a few dozen iterations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list[float]
|
Learning rates for |
[0.0001, 0.0001, 0.01, 0.0001]
|
optim_mat
|
bool
|
Whether to also optimize the material parameters. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list[dict]
|
Parameter groups (each a dict with |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
surf_dict
Serialize the surface to a dict.
The aspheric coefficients are written into the ai list as
[a4, a6, a8, ...]; when the legacy ai2 coefficient is present it
is prepended so ai[0] = a2 and use_ai2 is set True.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Serialized surface (keys |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
zmx_str
Return the Zemax (.zmx) text block for this surface.
Emits an EVENASPH surface. PARM 1 holds the legacy 2nd-order
coefficient a2, and PARM 2 onward hold a4, a6, a8, ..., padded
with zeros up to PARM 8 (a16).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_idx
|
int
|
Surface index in the Zemax file. |
required |
d_next
|
Tensor
|
Axial distance [mm] to the next surface. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
zmx_str |
str
|
Multi-line Zemax surface description. |
Source code in deeplens-src/deeplens/geometric_surface/aspheric.py
deeplens.geometric_surface.Aperture
Bases: Plane
Aperture stop surface.
A flat circular (or square) opening that blocks rays falling outside its
clear aperture. Inherits the planar intersection logic from Plane and
always sits in air (no refraction).
Attributes:
| Name | Type | Description |
|---|---|---|
r |
float
|
Aperture radius (clear half-diameter) in [mm]. |
d_next |
Tensor
|
Thickness to the next vertex in [mm]. |
is_square |
bool
|
If True, the aperture is square instead of circular. |
tolerancing |
bool
|
Whether tolerancing perturbations are enabled. |
Initialize an aperture surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius (clear half-diameter) in [mm]. |
required |
d_next
|
float
|
Thickness to the next vertex in [mm]. |
required |
pos_xy
|
list
|
Lateral (x, y) offset of the surface in [mm]. Defaults to [0.0, 0.0]. |
[0.0, 0.0]
|
vec_local
|
list
|
Local surface normal (z-axis) direction. Defaults to [0.0, 0.0, 1.0]. |
[0.0, 0.0, 1.0]
|
is_square
|
bool
|
If True, use a square aperture. Defaults to False. |
False
|
device
|
str
|
Torch device for surface tensors. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
init_from_dict
classmethod
Construct an Aperture from a surface dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Requires "r" and "d_next"; optional keys "is_square", "pos_xy", "vec_local", and "device". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
aperture |
Aperture
|
The constructed aperture surface. |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
ray_reaction
Trace a ray through the aperture.
Transforms the ray into local coordinates, intersects it with the
aperture plane (rays outside the clear aperture are marked invalid),
then transforms back to global coordinates. The aperture does not
refract, so n1, n2, and refraction are ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Input ray batch in global coordinates. |
required |
n1
|
float
|
Refractive index before the surface (unused). Defaults to 1.0. |
1.0
|
n2
|
float
|
Refractive index after the surface (unused). Defaults to 1.0. |
1.0
|
refraction
|
bool
|
Ignored for an aperture. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Ray after intersection, in global coordinates, with |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
draw_widget
Draw the aperture as wedge marks on a 2D cross-section plot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes
|
Axes to draw on (z-x cross-section). |
required |
color
|
str
|
Line color. Defaults to "orange". |
'orange'
|
linestyle
|
str
|
Matplotlib line style. Defaults to "solid". |
'solid'
|
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
draw_widget3D
Draw the aperture as an edge circle in a 3D plot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes3D
|
3D axes to draw on. |
required |
color
|
str
|
Line color. Defaults to "black". |
'black'
|
Returns:
| Name | Type | Description |
|---|---|---|
line |
list
|
The Line3D objects returned by |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
create_mesh
Create a triangulated surface mesh for the aperture.
Builds vertices, faces, and rim, then stores them on the surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_rings
|
int
|
Number of concentric rings for sampling. Defaults to 32. |
32
|
n_arms
|
int
|
Number of angular divisions. Defaults to 128. |
128
|
color
|
list
|
RGB color of the mesh. Defaults to [0.0, 0.0, 0.0]. |
[0.0, 0.0, 0.0]
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Aperture
|
The aperture with |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
get_optimizer_params
Enable gradients on the axial position and build optimizer param groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates; |
[0.0001]
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List with one optimizer param group dict for |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
surf_dict
Serialize the aperture parameters to a dictionary.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters with keys "type", "r", "d_next", "mat2", and "is_square". Radius and position are in [mm]. |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
zmx_str
Format the aperture as a Zemax (.zmx) STOP surface block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_idx
|
int
|
Surface index in the Zemax file. |
required |
d_next
|
Tensor
|
Distance to the next surface in [mm]. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
zmx_str |
str
|
Zemax surface definition string for this aperture. |
Source code in deeplens-src/deeplens/geometric_surface/aperture.py
Phase Surfaces
Phase surfaces model flat diffractive optical elements (DOEs) and metasurfaces
via a wavelength-scaled phase profile. All classes inherit from Phase and
implement phi() (phase map) and dphi_dxy() (phase gradient) for the
generalized Snell's law deflection in diffract().
Note:
Phase.diffract()treats the phase profile as wavelength-independent. Only the λ scaling in the generalized Snell's law and the OPL accumulation vary with wavelength. For a physical DOE whose phase profile changes with wavelength via the height–index relation(n(λ)−1)·h, useDiffractiveSurfaceinstead.
deeplens.phase_surface.Phase
Phase(
r,
d_next,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: DeepObj
Base phase profile for diffractive surfaces (metasurface or DOE).
Represents a flat (zero-sag) substrate carrying a phase pattern \(\phi(x, y)\),
using sequential geometry. It owns only d_next, the thickness to the next
vertex; the containing GeoLens derives its absolute position. Provides the
common ray-tracing machinery (intersection, refraction, generalized-Snell
diffraction, local/global transforms); the phase profile \(\phi\) and its
gradient are defined by subclasses.
Attributes:
| Name | Type | Description |
|---|---|---|
vec_global |
Tensor
|
Global axis direction \([0, 0, 1]\), shape [3]. |
d_next |
Tensor
|
Thickness to the next vertex in [mm], scalar. |
pos_x |
Tensor
|
Surface x-offset in [mm], scalar. |
pos_y |
Tensor
|
Surface y-offset in [mm], scalar. |
vec_local |
Tensor
|
Unit surface normal in global coordinates, shape [3]. |
mat2 |
Material
|
Material on the exit side of the surface. |
r |
float
|
Surface radius / half-aperture in [mm]. |
is_square |
bool
|
If True the aperture is a square of side \(r\sqrt{2}\); otherwise a circle of radius \(r\). |
w |
float
|
Square aperture width \(r\sqrt{2}\) in [mm]. |
h |
float
|
Square aperture height \(r\sqrt{2}\) in [mm]. |
diffraction_order |
int
|
Diffraction order \(m\) used in the generalized Snell's law. Defaults to 1. |
norm_radii |
float
|
Radius in [mm] used to normalize coordinates for the
phase polynomial. Defaults to |
device |
str or device
|
Device holding the tensor state. |
Reference
[1] https://support.zemax.com/hc/en-us/articles/1500005489061-How-diffractive-surfaces-are-modeled-in-OpticStudio [2] https://optics.ansys.com/hc/en-us/articles/360042097313-Small-Scale-Metalens-Field-Propagation [3] https://optics.ansys.com/hc/en-us/articles/18254409091987-Large-Scale-Metalens-Ray-Propagation
Initialize a flat phase substrate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Surface radius / half-aperture in [mm]. |
required |
d_next
|
float
|
Axial thickness to the next vertex in [mm]. |
required |
norm_radii
|
float or None
|
Radius in [mm] used to normalize
coordinates for the phase polynomial. Defaults to None, which uses |
None
|
mat2
|
str
|
Material on the exit side of the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral (x, y) offset of the surface center in [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Surface normal direction (not necessarily normalized) in global coordinates. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True the aperture is a square of side \(r\sqrt{2}\); otherwise a circle of radius \(r\). Defaults to True. |
True
|
device
|
str
|
Device for the tensor state. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
phi
Reference phase map at design wavelength. Must be implemented by subclasses.
dphi_dxy
Calculate phase derivatives. Must be implemented by subclasses.
ray_reaction
Trace a ray through the phase surface.
Transforms the ray to local coordinates, intersects it with the plane, applies refraction then diffraction, and transforms back to global coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Incident ray in global coordinates. |
required |
n1
|
float
|
Refractive index of the medium before the surface. |
required |
n2
|
float
|
Refractive index of the medium after the surface. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Updated ray in global coordinates. |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
intersect
Solve ray-plane intersection in local coordinates and update the ray.
Advances each ray to the \(z = 0\) plane, marks rays falling outside the aperture as invalid, and (for coherent rays) accumulates optical path length. Rays nearly parallel to the plane are guarded against division by a near-zero z-direction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Ray in local coordinates. |
required |
n
|
float
|
Refractive index of the medium the ray travels through, used for OPL accumulation. Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Ray advanced to the surface plane with updated |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
diffract
Apply phase-surface diffraction to a ray.
Two effects are applied:
- The phase \(\phi\) (in radians) adds to the optical path length as \(\phi \cdot \lambda / (2\pi)\), where \(\lambda\) is converted from [µm] to [mm] internally.
- The phase gradient bends the ray via the generalized Snell's law \(n_2 \sin\theta_2 = n_1 \sin\theta_1 + m\,\lambda / (2\pi)\,\partial\phi/\partial x\). Since standard refraction is already applied, the remaining deflection added to the unit direction is \(\Delta l = m\,\lambda / (2\pi n_2)\,\partial\phi/\partial x\). The deflection sign is flipped for backward-propagating rays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Ray with position, direction, and wavelength in [µm]. |
required |
n2
|
float
|
Refractive index of the medium after the surface; the deflection scales as \(1/n_2\). Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
Ray with updated direction |
Note
Material dispersion is not modelled here. The phase profile \(\phi(x, y)\)
is treated as wavelength-independent; only the \(\lambda\) scaling in the
generalized Snell's law and the OPL accumulation vary with wavelength.
For a physical DOE whose phase profile itself changes with wavelength
(via \((n(\lambda) - 1)\,h\)), use DiffractiveSurface instead.
Reference
[1] https://support.zemax.com/hc/en-us/articles/1500005489061-How-diffractive-surfaces-are-modeled-in-OpticStudio [2] Light propagation with phase discontinuities: generalized laws of reflection and refraction. Science 2011.
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
refract
Refract a ray with vector Snell's law in local coordinates.
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
to_local_coord
Transform a ray from the surface reference frame to local coordinates.
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
to_global_coord
Transform a ray from local coordinates to the surface reference frame.
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
normal_vec
Calculate the surface normal vector at intersection points.
The normal points from the surface toward the side the light comes from (i.e. it is flipped to oppose the ray's z-direction).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Ray providing the propagation direction. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
normal_vec |
Tensor
|
Unit normal vectors, same shape as |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
get_optimizer_params
Generate optimizer parameters. Must be implemented by subclasses.
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
get_optimizer
Build an Adam optimizer over the surface's learnable parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list or float
|
Learning rate(s) for the parameter groups. A single float is wrapped into a one-element list. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
optimizer |
Adam
|
Adam optimizer over the parameters
returned by |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
update_r
Update surface radius / half-aperture and the square aperture extents.
A flat phase surface has no geometric height constraint, and because the
polynomial is normalized by a fixed norm_radii, phase coefficients do
not need rescaling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
New surface radius / half-aperture in [mm]. |
required |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
phase2height_map
Convert the phase map to a physical height map for DOE fabrication.
Derived from the phase-height relation of a transmissive DOE in air, \(\phi = (2\pi/\lambda)(n - 1)h\), giving \(h = \phi\lambda / (2\pi(n - 1))\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
design_wvln
|
float
|
Design wavelength in [µm]. |
required |
refractive_idx
|
float
|
Refractive index of the DOE material
at |
1.5
|
res
|
int
|
Pixel resolution of the returned square height map. Defaults to 512. |
512
|
Returns:
| Name | Type | Description |
|---|---|---|
height_map |
Tensor
|
Height map of shape [res, res] in the same
units as |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
draw_r
surface_with_offset
Return the caller-provided vertex position for layout drawing.
The phase surface is flat and does not own an absolute position.
Returns:
| Name | Type | Description |
|---|---|---|
d |
Tensor
|
Axial plane position in [mm], scalar. |
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
draw_phase_map
Draw the phase map (clipped to \([0, 2\pi]\)) and save it to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_name
|
str
|
Output image path. Defaults to "./DOE_phase_map.png". |
'./DOE_phase_map.png'
|
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
draw_widget
Draw the DOE as a sawtooth (blazed) profile on a 2D layout axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes
|
Axis to draw on. |
required |
color
|
str
|
Accepted for API consistency but ignored; the profile is always drawn in orange. Defaults to "black". |
'black'
|
linestyle
|
str
|
Matplotlib line style for the profile. Defaults to "-". |
'-'
|
Source code in deeplens-src/deeplens/phase_surface/base_phase.py
save_ckpt
Save DOE parameters. Must be implemented by subclasses.
load_ckpt
Load DOE parameters. Must be implemented by subclasses.
surf_dict
Return surface parameters. Must be implemented by subclasses.
deeplens.phase_surface.Binary2Phase
Binary2Phase(
r,
d_next,
order2=0.0,
order4=0.0,
order6=0.0,
order8=0.0,
order10=0.0,
order12=0.0,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Zemax BINARY_2 phase profile on a flat substrate.
Parameterizes the diffractive phase as an even radial polynomial in the normalized radius \(\rho = r / r_\text{norm}\):
where the coefficients order2..order12 are stored in radians [rad].
The phase is evaluated with Horner's method and wrapped to \([0, 2\pi)\).
Attributes:
| Name | Type | Description |
|---|---|---|
order2 |
Tensor
|
Coefficient of \(\rho^2\), scalar [rad]. |
order4 |
Tensor
|
Coefficient of \(\rho^4\), scalar [rad]. |
order6 |
Tensor
|
Coefficient of \(\rho^6\), scalar [rad]. |
order8 |
Tensor
|
Coefficient of \(\rho^8\), scalar [rad]. |
order10 |
Tensor
|
Coefficient of \(\rho^{10}\), scalar [rad]. |
order12 |
Tensor
|
Coefficient of \(\rho^{12}\), scalar [rad]. |
param_model |
str
|
Parameterization tag, always "binary2". |
norm_radii |
float
|
Normalization radius \(r_\text{norm}\) [mm]. |
Initialize a Binary2 phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius (half-diameter) [mm]. |
required |
d
|
float
|
Axial position of the surface in global coordinates [mm]. |
required |
order2
|
float
|
Coefficient of \(\rho^2\) [rad]. Defaults to 0.0. |
0.0
|
order4
|
float
|
Coefficient of \(\rho^4\) [rad]. Defaults to 0.0. |
0.0
|
order6
|
float
|
Coefficient of \(\rho^6\) [rad]. Defaults to 0.0. |
0.0
|
order8
|
float
|
Coefficient of \(\rho^8\) [rad]. Defaults to 0.0. |
0.0
|
order10
|
float
|
Coefficient of \(\rho^{10}\) [rad]. Defaults to 0.0. |
0.0
|
order12
|
float
|
Coefficient of \(\rho^{12}\) [rad]. Defaults to 0.0. |
0.0
|
norm_radii
|
float or None
|
Normalization radius for the polynomial [mm].
Defaults to None, in which case |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral (x, y) offset of the surface center [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True, use a square aperture; otherwise circular. Defaults to True. |
True
|
device
|
str
|
Torch device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/binary2.py
init_from_dict
classmethod
Construct a Binary2 phase surface from a parameter dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Requires keys "r" and "d_next"; optionally "order2".."order12", "norm_radii", "mat2", and "is_square". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
obj |
Binary2Phase
|
The constructed phase surface. |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
phi
Compute the reference phase at the design wavelength.
Evaluates the even radial polynomial in normalized radius via Horner's
method and wraps the result to \([0, 2\pi)\) with torch.remainder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase values [rad] wrapped to \([0, 2\pi)\), same shape as |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
dphi_dxy
Compute the lateral phase gradient at the given points.
Differentiates the (unwrapped) phase polynomial and applies the chain rule through the normalized radius.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Partial derivative \(\partial\phi/\partial x\) [rad/mm], same shape as |
dphidy |
Tensor
|
Partial derivative \(\partial\phi/\partial y\) [rad/mm], same shape as |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
get_optimizer_params
Build optimizer parameter groups for the phase surface.
Enables gradients on d_next and the six polynomial coefficients,
grouping d_next with the first learning rate and all
coefficients with the second.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates |
[0.0001, 0.01]
|
optim_mat
|
bool
|
Must be False; materials are not optimized for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List of parameter-group dicts for a torch optimizer. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
save_ckpt
Save the Binary2 phase coefficients to disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output checkpoint path. Defaults to "./binary2_doe.pth". |
'./binary2_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/binary2.py
load_ckpt
Load Binary2 phase coefficients from disk onto the surface device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path to load. Defaults to "./binary2_doe.pth". |
'./binary2_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/binary2.py
zmx_str
Return the Zemax BINARY_2 surface block as a string.
PARM 1-8 are set to zero (flat substrate, no aspheric sag) so that Zemax interprets the XDAT entries purely as phase polynomial coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_idx
|
int
|
Surface index used in the SURF header. |
required |
d_next
|
Tensor
|
Distance to the next surface [mm], scalar tensor (read via |
required |
Returns:
| Name | Type | Description |
|---|---|---|
zmx_str |
str
|
Multi-line Zemax surface description. |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
surf_dict
Return a serializable dictionary of the surface parameters.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters including type, radius |
Source code in deeplens-src/deeplens/phase_surface/binary2.py
deeplens.phase_surface.FresnelPhase
FresnelPhase(
r,
d_next,
f0=100.0,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Ideal Fresnel-lens phase profile on a plane substrate.
Implements the quadratic phase of a thin lens, \(\phi = -\pi (x^2 + y^2) / (\lambda_0 f_0)\),
wrapped to \([0, 2\pi)\), where the design wavelength is fixed at \(\lambda_0 = 0.55\,\mu m\).
The single optimizable parameter is the focal length f0 [mm].
Attributes:
| Name | Type | Description |
|---|---|---|
f0 |
Tensor
|
Scalar tensor, focal length at the design wavelength (550 nm) [mm]. |
param_model |
str
|
Parameterization identifier, always "fresnel". |
Initialize a Fresnel-lens phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius (half-diameter) of the surface [mm]. |
required |
d
|
float
|
Axial position of the surface along the optical axis [mm]. |
required |
f0
|
float
|
Focal length at the design wavelength (550 nm) [mm]. Defaults to 100.0. |
100.0
|
norm_radii
|
float or None
|
Normalization radius for the phase profile [mm].
Defaults to None, in which case |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral (x, y) position of the surface center [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction in the global frame. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True the aperture is a square of full
width \(r\sqrt{2}\); otherwise it is a circle of radius |
True
|
device
|
str
|
Torch device for tensors. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
init_from_dict
classmethod
Initialize a FresnelPhase from a dictionary of parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
param_dict
|
dict
|
Surface parameters. Recognized keys are "r", "d_next", "f0",
"norm_radii", "mat2", "pos_xy", "vec_local", "is_square", and "device",
matching the |
required |
Returns:
| Name | Type | Description |
|---|---|---|
surf |
FresnelPhase
|
The constructed Fresnel phase surface. |
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
phi
Compute the wrapped Fresnel-lens phase at the design wavelength.
Evaluates the ideal thin-lens quadratic phase \(\phi = -\pi (x^2 + y^2) / (\lambda_0 f_0)\) with \(\lambda_0 = 0.55\,\mu m\) (0.55e-3 mm), wrapped to \([0, 2\pi)\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates on the surface [mm], any broadcastable shape. |
required |
y
|
Tensor
|
Y coordinates on the surface [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase in radians, wrapped to \([0, 2\pi)\), same shape as |
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
dphi_dxy
Compute the phase gradient (dphi/dx, dphi/dy) of the unwrapped phase.
Differentiates the unwrapped quadratic phase, giving \(\partial\phi/\partial x = -2\pi x / (\lambda_0 f_0)\) and likewise for \(y\), with \(\lambda_0 = 0.55\,\mu m\) (0.55e-3 mm).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates on the surface [mm], any broadcastable shape. |
required |
y
|
Tensor
|
Y coordinates on the surface [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase derivative along x [rad/mm], same shape as |
dphidy |
Tensor
|
Phase derivative along y [rad/mm], same shape as |
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
get_optimizer_params
Build optimizer parameter groups for the focal length.
Enables gradients on f0 and returns a single parameter group using lrs[0]
as its learning rate. Material parameters are not optimized for a phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates; only |
[0.0001]
|
optim_mat
|
bool
|
Must be False; material optimization is unsupported. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
A list with one parameter group dict {"params": [f0], "lr": lrs[0]}. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
save_ckpt
Save Fresnel DOE parameters (param_model and f0) to a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output checkpoint path. Defaults to "./fresnel_doe.pth". |
'./fresnel_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
load_ckpt
Load Fresnel DOE parameters (param_model and f0) from a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path to load. Defaults to "./fresnel_doe.pth". |
'./fresnel_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
surf_dict
Return a serializable dict of surface parameters.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters including "type", "r", "is_square",
"param_model", "f0", "norm_radii", "d", "mat2", plus informational
"(mat2_n)"/"(mat2_V)", suitable for
reconstruction via |
Source code in deeplens-src/deeplens/phase_surface/fresnel.py
deeplens.phase_surface.ZernikePhase
ZernikePhase(
r,
d_next,
zernike_order=37,
zernike_coeff=None,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=False,
device="cpu",
)
Bases: Phase
Diffractive phase surface parameterized by Zernike polynomials.
Implements a flat (plane-substrate) diffractive surface whose phase profile
is the weighted sum of the first 37 standard (normalized) Zernike
polynomials evaluated over a circular pupil. Inherits ray-tracing,
refraction, and diffraction from Phase.
Attributes:
| Name | Type | Description |
|---|---|---|
param_model |
str
|
Parameterization tag, always "zernike". |
zernike_order |
int
|
Number of Zernike terms (up to 37). |
z_coeff |
Tensor
|
Zernike coefficients, shape [zernike_order]. |
norm_radii |
float
|
Radius [mm] used to normalize pupil coordinates. |
Reference
[1] https://support.zemax.com/hc/en-us/articles/1500005489061-How-diffractive-surfaces-are-modeled-in-OpticStudio [2] https://optics.ansys.com/hc/en-us/articles/360042097313-Small-Scale-Metalens-Field-Propagation [3] https://optics.ansys.com/hc/en-us/articles/18254409091987-Large-Scale-Metalens-Ray-Propagation
Initialize a Zernike phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius of the surface [mm]. |
required |
d
|
float
|
Axial position (distance to next surface) [mm]. |
required |
zernike_order
|
int
|
Number of Zernike terms. Defaults to 37. |
37
|
zernike_coeff
|
list or Tensor or None
|
Initial Zernike
coefficients of length |
None
|
norm_radii
|
float or None
|
Radius [mm] used to normalize pupil
coordinates. Defaults to None, meaning |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral (x, y) position of the surface center [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction in global coordinates. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
Whether the aperture is square. Defaults to False. |
False
|
device
|
str
|
Computation device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/zernike.py
init_from_dict
classmethod
Construct a Zernike phase surface from a serialized dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Requires keys "r" and "d_next"; optionally reads "mat2", "norm_radii", "zernike_order", and "z_coeff" (the Zernike coefficient list/tensor). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
obj |
ZernikePhase
|
The reconstructed phase surface. |
Source code in deeplens-src/deeplens/phase_surface/zernike.py
phi
Compute the reference phase map from the Zernike polynomials.
Overrides Phase.phi. Coordinates are normalized by norm_radii before
evaluation, and the result is wrapped into \([0, 2\pi)\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Lateral x coordinates [mm], any shape. |
required |
y
|
Tensor
|
Lateral y coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase in radians, wrapped to \([0, 2\pi)\), same shape as |
Source code in deeplens-src/deeplens/phase_surface/zernike.py
dphi_dxy
Compute the phase gradient (dphi/dx, dphi/dy) at given points.
Overrides Phase.dphi_dxy. Coordinates are normalized by norm_radii
before evaluation; the returned derivatives are with respect to the
physical x, y in [mm].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Lateral x coordinates [mm], any shape. |
required |
y
|
Tensor
|
Lateral y coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase derivative dphi/dx [1/mm], same shape as |
dphidy |
Tensor
|
Phase derivative dphi/dy [1/mm], same shape as |
Source code in deeplens-src/deeplens/phase_surface/zernike.py
get_optimizer_params
Build optimizer parameter groups for the Zernike coefficients.
Enables gradients on z_coeff and assigns it the first learning rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates; |
[0.0001]
|
optim_mat
|
bool
|
Must be False; material optimization is unsupported for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List with one parameter-group dict for the optimizer. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/zernike.py
save_ckpt
Save the Zernike coefficients and order to a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output path. Defaults to "./zernike_doe.pth". |
'./zernike_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/zernike.py
load_ckpt
Load Zernike coefficients and order from a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path. Defaults to "./zernike_doe.pth". |
'./zernike_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/zernike.py
surf_dict
Serialize the surface parameters to a JSON-friendly dictionary.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters including type, radius |
Source code in deeplens-src/deeplens/phase_surface/zernike.py
deeplens.phase_surface.PolyPhase
PolyPhase(
r,
d_next,
order2=0.0,
order3=0.0,
order4=0.0,
order5=0.0,
order6=0.0,
order7=0.0,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Polynomial phase profile on a plane substrate.
Models a diffractive (DOE/metasurface) phase pattern as a 1D radial
polynomial with even terms in the normalized radius plus odd terms in the
normalized \(x\)/\(y\) coordinates. Coordinates are normalized by norm_radii
before evaluation. The reference phase is
where \(r_n = \sqrt{x_n^2 + y_n^2}\) and \(x_n, y_n\) are the normalized coordinates. Phase is in radians and wrapped to \([0, 2\pi)\).
Attributes:
| Name | Type | Description |
|---|---|---|
order2 |
Tensor
|
Coefficient \(a_2\) of the \(r_n^2\) term (scalar tensor). |
order3 |
Tensor
|
Coefficient \(a_3\) of the \((x_n^3 + y_n^3)\) term (scalar tensor). |
order4 |
Tensor
|
Coefficient \(a_4\) of the \(r_n^4\) term (scalar tensor). |
order5 |
Tensor
|
Coefficient \(a_5\) of the \((x_n^5 + y_n^5)\) term (scalar tensor). |
order6 |
Tensor
|
Coefficient \(a_6\) of the \(r_n^6\) term (scalar tensor). |
order7 |
Tensor
|
Coefficient \(a_7\) of the \((x_n^7 + y_n^7)\) term (scalar tensor). |
param_model |
str
|
Parameterization identifier, always "poly1d". |
Initialize a polynomial phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius of the substrate [mm]. |
required |
d
|
float
|
Axial position of the surface along the optical axis [mm]. |
required |
order2
|
float
|
Coefficient of the \(r_n^2\) term. Defaults to 0.0. |
0.0
|
order3
|
float
|
Coefficient of the \((x_n^3 + y_n^3)\) term. Defaults to 0.0. |
0.0
|
order4
|
float
|
Coefficient of the \(r_n^4\) term. Defaults to 0.0. |
0.0
|
order5
|
float
|
Coefficient of the \((x_n^5 + y_n^5)\) term. Defaults to 0.0. |
0.0
|
order6
|
float
|
Coefficient of the \(r_n^6\) term. Defaults to 0.0. |
0.0
|
order7
|
float
|
Coefficient of the \((x_n^7 + y_n^7)\) term. Defaults to 0.0. |
0.0
|
norm_radii
|
float or None
|
Normalization radius [mm] for the
coordinates. Defaults to the aperture radius |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral \((x, y)\) offset of the surface [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local direction vector (surface normal) in global coordinates; normalized internally. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True, the aperture is square; otherwise circular. Defaults to True. |
True
|
device
|
str
|
Torch device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/poly.py
phi
Evaluate the reference phase map at design wavelength.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
\(x\) coordinates [mm], any shape. |
required |
y
|
Tensor
|
\(y\) coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase in radians wrapped to \([0, 2\pi)\), same shape as |
Source code in deeplens-src/deeplens/phase_surface/poly.py
dphi_dxy
Compute the spatial phase gradient at the given points.
Returns the partial derivatives of the unwrapped phase polynomial, in units of radians per millimetre [rad/mm].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
\(x\) coordinates [mm], any shape. |
required |
y
|
Tensor
|
\(y\) coordinates [mm], same shape as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
\(\partial\phi/\partial x\) [rad/mm], same shape as |
dphidy |
Tensor
|
\(\partial\phi/\partial y\) [rad/mm], same shape as |
Source code in deeplens-src/deeplens/phase_surface/poly.py
get_optimizer_params
Build per-parameter optimizer groups for the polynomial coefficients.
Marks the six polynomial coefficients (order2 through order7) as
requiring gradients and assigns each its own learning rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Six learning rates applied to |
[0.0001, 0.001, 0.0001, 1e-05, 1e-06, 1e-07]
|
optim_mat
|
bool
|
Must be False; material parameters are not optimized for a phase surface. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List of parameter-group dicts, one per coefficient, each with keys "params" and "lr". |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/poly.py
save_ckpt
Save the Poly1D DOE parameters to a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output checkpoint path. Defaults to "./poly1d_doe.pth". |
'./poly1d_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/poly.py
load_ckpt
Load the Poly1D DOE parameters from a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path to load. Defaults to "./poly1d_doe.pth". |
'./poly1d_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/poly.py
surf_dict
Return a serializable dict of the surface parameters.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters, including the surface type,
aperture radius |
Source code in deeplens-src/deeplens/phase_surface/poly.py
deeplens.phase_surface.CubicPhase
CubicPhase(
r,
d_next,
coeff_x3=0.0,
coeff_y3=0.0,
coeff_x2y=0.0,
coeff_xy2=0.0,
coeff_x3y=0.0,
coeff_xy3=0.0,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Cubic phase profile on a plane substrate.
Diffractive surface whose phase is a cubic 2D polynomial in normalized
coordinates \((x/r_n,\, y/r_n)\), where \(r_n\) is norm_radii. Used to model
cubic-phase (wavefront-coding) plates that extend depth of field.
Attributes:
| Name | Type | Description |
|---|---|---|
coeff_x3 |
Tensor
|
Scalar coefficient of \(x^3\) [rad]. |
coeff_y3 |
Tensor
|
Scalar coefficient of \(y^3\) [rad]. |
coeff_x2y |
Tensor
|
Scalar coefficient of \(x^2 y\) [rad]. |
coeff_xy2 |
Tensor
|
Scalar coefficient of \(x y^2\) [rad]. |
coeff_x3y |
Tensor
|
Scalar coefficient of \(x^3 y\) [rad]. |
coeff_xy3 |
Tensor
|
Scalar coefficient of \(x y^3\) [rad]. |
norm_radii |
float
|
Normalization radius [mm] used to scale \((x, y)\). |
param_model |
str
|
Parameterization name, always "cubic". |
Initialize a cubic phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Surface aperture radius [mm]. |
required |
d
|
float
|
Axial position of the surface in the global frame [mm]. |
required |
coeff_x3
|
float
|
Coefficient of \(x^3\) [rad]. Defaults to 0.0. |
0.0
|
coeff_y3
|
float
|
Coefficient of \(y^3\) [rad]. Defaults to 0.0. |
0.0
|
coeff_x2y
|
float
|
Coefficient of \(x^2 y\) [rad]. Defaults to 0.0. |
0.0
|
coeff_xy2
|
float
|
Coefficient of \(x y^2\) [rad]. Defaults to 0.0. |
0.0
|
coeff_x3y
|
float
|
Coefficient of \(x^3 y\) [rad]. Defaults to 0.0. |
0.0
|
coeff_xy3
|
float
|
Coefficient of \(x y^3\) [rad]. Defaults to 0.0. |
0.0
|
norm_radii
|
float or None
|
Normalization radius [mm] for the
polynomial coordinates. Defaults to None, in which case the base
class sets it to |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral \((x, y)\) offset of the surface center [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True, use a square aperture; otherwise circular. Defaults to True. |
True
|
device
|
str
|
Torch device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/cubic.py
phi
Compute the reference phase map at the design wavelength.
Evaluates the cubic polynomial in normalized coordinates
\((x_n, y_n) = (x/r_n,\, y/r_n)\) and wraps the result into \([0, 2\pi)\)
via torch.remainder:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], broadcastable with |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Wrapped phase [rad] in \([0, 2\pi)\), same shape
as the broadcast of |
Source code in deeplens-src/deeplens/phase_surface/cubic.py
dphi_dxy
Compute the spatial phase derivatives at given points.
Returns the analytic gradient of the unwrapped cubic polynomial (not the
wrapped phi). Derivatives are taken w.r.t. normalized coordinates and
converted to physical coordinates by dividing by norm_radii.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], broadcastable with |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase derivative \(\partial\phi/\partial x\)
[rad/mm], same shape as the broadcast of |
dphidy |
Tensor
|
Phase derivative \(\partial\phi/\partial y\)
[rad/mm], same shape as the broadcast of |
Source code in deeplens-src/deeplens/phase_surface/cubic.py
get_optimizer_params
Build optimizer parameter groups for the cubic coefficients.
Enables gradients on the six polynomial coefficients and assigns each a
per-group learning rate, in the order
[coeff_x3, coeff_y3, coeff_x2y, coeff_xy2, coeff_x3y, coeff_xy3].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Six learning rates, one per coefficient. Defaults to [1e-4, 1e-4, 1e-4, 1e-4, 1e-5, 1e-5]. |
[0.0001, 0.0001, 0.0001, 0.0001, 1e-05, 1e-05]
|
optim_mat
|
bool
|
Must be False; material parameters are not optimized for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List of six optimizer parameter-group dicts, each with "params" and "lr" keys. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/cubic.py
save_ckpt
Save the cubic DOE parameters to a checkpoint file.
Saves param_model and the six cubic coefficients (detached, on CPU).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output checkpoint path. Defaults to "./cubic_doe.pth". |
'./cubic_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/cubic.py
load_ckpt
Load the cubic DOE parameters from a checkpoint file.
Restores param_model and the six cubic coefficients onto self.device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path to load. Defaults to "./cubic_doe.pth". |
'./cubic_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/cubic.py
surf_dict
Return a serializable dict of the surface parameters.
Coefficients, norm_radii, and d are rounded to 4 decimals. Used for
exporting the surface to a lens file.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters including type, |
Source code in deeplens-src/deeplens/phase_surface/cubic.py
deeplens.phase_surface.GratingPhase
GratingPhase(
r,
d_next,
theta=0.0,
alpha=0.0,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Linear (blazed) grating phase on a plane substrate.
The phase profile is a linear ramp along a direction set by theta:
where \(R\) is norm_radii, \(\alpha\) (alpha) is the ramp magnitude, and
\(\theta\) (theta) is the grating-vector angle measured from the x-axis [rad].
The returned phase is wrapped to \([0, 2\pi)\). Inherits ray tracing,
diffraction, and coordinate transforms from Phase.
Attributes:
| Name | Type | Description |
|---|---|---|
theta |
Tensor
|
Scalar grating-vector angle from the x-axis [rad]. |
alpha |
Tensor
|
Scalar phase-ramp magnitude [rad] over |
param_model |
str
|
Parameterization tag, "grating". |
Initialize a linear grating phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Surface aperture radius [mm]. |
required |
d
|
float
|
Axial position of the surface in global coordinates [mm]. |
required |
theta
|
float
|
Grating-vector angle from the x-axis [rad]. Defaults to 0.0. |
0.0
|
alpha
|
float
|
Phase-ramp magnitude [rad] across |
0.0
|
norm_radii
|
float or None
|
Normalization radius [mm] for the phase
profile. Defaults to None, which uses |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Lateral (x, y) surface offset [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True, use a square aperture; otherwise circular. Defaults to True. |
True
|
device
|
str
|
Torch device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/grating.py
init_from_dict
classmethod
Initialize a GratingPhase from a parameter dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
param_dict
|
dict
|
Parameter dictionary. Recognized keys match the
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
grating |
GratingPhase
|
The constructed grating phase surface. |
Source code in deeplens-src/deeplens/phase_surface/grating.py
phi
Compute the grating phase at given points, wrapped to \([0, 2\pi)\).
Evaluates \(\phi = \alpha\,(x/R \sin\theta + y/R \cos\theta)\) where
\(R\) is norm_radii, then wraps the result into \([0, 2\pi)\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Lateral x-coordinates [mm], any shape. |
required |
y
|
Tensor
|
Lateral y-coordinates [mm], broadcastable with |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase values [rad] in \([0, 2\pi)\), same shape as the
broadcast of |
Source code in deeplens-src/deeplens/phase_surface/grating.py
dphi_dxy
Compute the phase gradient (dphi/dx, dphi/dy) at given points.
For this linear grating the gradient is spatially constant:
\(\partial\phi/\partial x = \alpha\sin\theta / R\) and
\(\partial\phi/\partial y = \alpha\cos\theta / R\), with \(R\) = norm_radii.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Lateral x-coordinates [mm]; only its shape is used. |
required |
y
|
Tensor
|
Lateral y-coordinates [mm]; only its shape is used. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase x-derivative [rad/mm], broadcast to the shape of |
dphidy |
Tensor
|
Phase y-derivative [rad/mm], broadcast to the shape of |
Source code in deeplens-src/deeplens/phase_surface/grating.py
get_optimizer_params
Build Adam parameter groups for the grating phase parameters.
Enables gradients on theta and alpha and returns one parameter group
each, using lrs[0] for theta and lrs[1] for alpha.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates |
[0.0001, 0.001]
|
optim_mat
|
bool
|
Must be False; material parameters are not optimized for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List of two parameter-group dicts for |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/phase_surface/grating.py
save_ckpt
Save grating parameters (param_model, theta, alpha) to a checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output checkpoint path. Defaults to "./grating_doe.pth". |
'./grating_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/grating.py
load_ckpt
Load grating parameters (param_model, theta, alpha) from a checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path to load. Defaults to "./grating_doe.pth". |
'./grating_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/grating.py
surf_dict
Return a serializable dict of the grating surface parameters.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters including "type", "r", "is_square", "param_model", "theta", "alpha", "norm_radii", "d", "mat2", plus informational "(mat2_n)"/"(mat2_V)". Numeric "theta", "alpha", "norm_radii", and "d" are rounded to 4 decimals. |
Source code in deeplens-src/deeplens/phase_surface/grating.py
deeplens.phase_surface.NURBSPhase
NURBSPhase(
r,
d_next,
control_points_u=8,
control_points_v=8,
degree_u=3,
degree_v=3,
control_points=None,
weights=None,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Diffractive phase surface parameterized by a NURBS surface.
The phase profile is the z-component of a NURBS (Non-Uniform Rational B-Spline) surface defined by a 2D grid of control points and clamped knot vectors in the u and v directions. The surface is evaluated with B-spline basis functions via the Cox-de Boor recursion. The (x, y) ray coordinates are normalized to the NURBS parameter domain [0, 1]; the returned phase is in radians and wrapped to [0, 2π).
Attributes:
| Name | Type | Description |
|---|---|---|
control_points |
Tensor
|
Control point coordinates (x, y, z) of shape (control_points_u, control_points_v, 3); z is the phase [rad]. |
weights |
Tensor
|
Rational B-spline weights of shape (control_points_u, control_points_v). |
knots_u |
Tensor
|
Clamped knot vector in u of shape (control_points_u + degree_u + 1,). |
knots_v |
Tensor
|
Clamped knot vector in v of shape (control_points_v + degree_v + 1,). |
control_points_u |
int
|
Number of control points in u. |
control_points_v |
int
|
Number of control points in v. |
degree_u |
int
|
B-spline degree in u. |
degree_v |
int
|
B-spline degree in v. |
param_model |
str
|
Parameterization tag, "nurbs". |
Reference
[1] The NURBS Book by Piegl and Tiller. [2] https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline
Initialize a NURBS phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius of the surface [mm]. |
required |
d
|
float
|
Axial distance to the next surface [mm]. |
required |
control_points_u
|
int
|
Number of control points in u. Defaults to 8. |
8
|
control_points_v
|
int
|
Number of control points in v. Defaults to 8. |
8
|
degree_u
|
int
|
B-spline degree in u. Defaults to 3. |
3
|
degree_v
|
int
|
B-spline degree in v. Defaults to 3. |
3
|
control_points
|
Tensor or None
|
Control point coordinates of shape (control_points_u, control_points_v, 3) holding (x, y, z) where z is the phase [rad]. If None, x, y are placed on an even grid in [-1, 1] and z is initialized with small random values (std 1e-3 [rad]). Defaults to None. |
None
|
weights
|
Tensor or None
|
Rational B-spline weights of shape (control_points_u, control_points_v). If None, all weights are 1. Defaults to None. |
None
|
norm_radii
|
float or None
|
Radius [mm] used to normalize (x, y) into the parameter domain. If None, defaults to r. Defaults to None. |
None
|
mat2
|
str
|
Material after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
Surface (x, y) position [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction. Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
Whether the aperture is square. Defaults to True. |
True
|
device
|
str
|
Computation device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
init_from_dict
classmethod
Initialize a NURBS phase surface from a parameter dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Requires "r" and "d"; optional keys include "mat2", "norm_radii", "control_points_u", "control_points_v", "degree_u", "degree_v", "control_points", and "weights". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
obj |
NURBSPhase
|
The constructed NURBS phase surface. |
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
phi
Compute the reference phase map at the design wavelength.
Coordinates are normalized by norm_radii and mapped to the NURBS
parameter domain [0, 1]. Points outside the unit circle (normalized
radius greater than 1) are set to 0, and the result is wrapped to [0, 2π).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
x coordinates [mm]. |
required |
y
|
Tensor
|
y coordinates [mm], same shape as x. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Phase [rad] in [0, 2π), same shape as x. |
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
dphi_dxy
Compute phase derivatives (dphi/dx, dphi/dy) by central differences.
Uses a finite-difference step of 1e-6 [mm] on phi. Points outside the
unit circle (normalized radius greater than 1) are set to 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
x coordinates [mm]. |
required |
y
|
Tensor
|
y coordinates [mm], same shape as x. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase derivative along x [rad/mm], same shape as x. |
dphidy |
Tensor
|
Phase derivative along y [rad/mm], same shape as x. |
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
get_optimizer_params
Build optimizer parameter groups for the NURBS control points.
Control points are always optimized at lrs[0]. If a second learning
rate is given, the weights are also optimized at lrs[1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates [control_points_lr, weights_lr]. Defaults to [1e-4, 1e-2]. |
[0.0001, 0.01]
|
optim_mat
|
bool
|
Must be False; material parameters are not optimized for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
List of parameter-group dicts for |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If optim_mat is True. |
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
save_ckpt
Save NURBS DOE parameters to a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output path. Defaults to "./nurbs_doe.pth". |
'./nurbs_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
load_ckpt
Load NURBS DOE parameters from a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path. Defaults to "./nurbs_doe.pth". |
'./nurbs_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
surf_dict
Return surface parameters as a serializable dictionary.
Returns:
| Name | Type | Description |
|---|---|---|
surf_dict |
dict
|
Surface parameters (control points, weights, knot vectors, degrees, radii, distance, and material) suitable for JSON export. |
Source code in deeplens-src/deeplens/phase_surface/nurbs.py
deeplens.phase_surface.VortexPhase
VortexPhase(
r,
d_next,
charge=1,
f0=None,
norm_radii=None,
mat2="air",
pos_xy=(0.0, 0.0),
vec_local=(0.0, 0.0, 1.0),
is_square=True,
device="cpu",
)
Bases: Phase
Vortex phase surface combining a spiral phase and an optional Fresnel lens.
The phase profile is
where the first term imparts orbital angular momentum (topological charge charge)
and the second term is a Fresnel focusing phase. f0 directly sets the phase
curvature [mm²]; no design wavelength is assumed, so chromatic behaviour emerges
naturally from the ray wavelength during diffraction. Setting f0=None disables
the Fresnel term, leaving a pure vortex.
Attributes:
| Name | Type | Description |
|---|---|---|
charge |
int
|
Topological charge of the spiral phase term. |
f0 |
Tensor or None
|
Scalar Fresnel phase-curvature parameter [mm²], or None if the Fresnel term is disabled. |
param_model |
str
|
Parameterization tag, always "vortex". |
Reference
Yu et al., "Light Propagation with Phase Discontinuities," Science 2011.
Initialize a vortex phase surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
Aperture radius [mm]. |
required |
d
|
float
|
Axial position [mm]. |
required |
charge
|
int
|
Topological charge of the spiral term. Positive for a left-handed helix, negative for right-handed. Defaults to 1. |
1
|
f0
|
float or None
|
Fresnel phase-curvature parameter [mm²], setting the quadratic term \(-\pi r^2 / f_0\). No design wavelength is assumed, so the implied focal length is \(f_0 / \lambda\) and varies with the ray wavelength \(\lambda\). None disables the Fresnel term. Defaults to None. |
None
|
norm_radii
|
float or None
|
Normalization radius [mm] for phase-map
display. Defaults to None, which falls back to |
None
|
mat2
|
str
|
Material name after the surface. Defaults to "air". |
'air'
|
pos_xy
|
tuple
|
(x, y) position offset in the global frame [mm]. Defaults to (0.0, 0.0). |
(0.0, 0.0)
|
vec_local
|
tuple
|
Local surface normal direction (x, y, z). Defaults to (0.0, 0.0, 1.0). |
(0.0, 0.0, 1.0)
|
is_square
|
bool
|
If True use a square aperture, else circular. Defaults to True. |
True
|
device
|
str
|
Torch device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/phase_surface/vortex.py
init_from_dict
classmethod
Initialize a VortexPhase from a parameter dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surf_dict
|
dict
|
Surface parameters. Recognized keys: "r", "d" (required), and optionally "charge", "f0", "norm_radii", "mat2", "pos_xy", "vec_local", "is_square", "device". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
surf |
VortexPhase
|
The constructed vortex phase surface. |
Source code in deeplens-src/deeplens/phase_surface/vortex.py
phi
Compute the phase map, wrapped to [0, 2π) [rad].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], same shape as x. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
phi |
Tensor
|
Wrapped phase [rad], same shape as x. |
Source code in deeplens-src/deeplens/phase_surface/vortex.py
dphi_dxy
Compute the analytical (unwrapped) phase gradient for generalized Snell's law.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
X coordinates [mm], any shape. |
required |
y
|
Tensor
|
Y coordinates [mm], same shape as x. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dphidx |
Tensor
|
Phase derivative along x [rad/mm], same shape as x. |
dphidy |
Tensor
|
Phase derivative along y [rad/mm], same shape as x. |
Source code in deeplens-src/deeplens/phase_surface/vortex.py
get_optimizer_params
Return optimizer parameter groups.
Only f0 is differentiable; the topological charge charge is discrete and
therefore never optimized. When f0 is None the returned list is empty.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lrs
|
list
|
Learning rates; only |
[0.0001]
|
optim_mat
|
bool
|
Must be False; material parameters are not optimized for phase surfaces. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
params |
list
|
Optimizer parameter groups, one dict per optimized tensor. |
Source code in deeplens-src/deeplens/phase_surface/vortex.py
save_ckpt
Save VortexPhase parameters to a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_path
|
str
|
Output path. Defaults to "./vortex_doe.pth". |
'./vortex_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/vortex.py
load_ckpt
Load VortexPhase parameters from a checkpoint file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
load_path
|
str
|
Checkpoint path. Defaults to "./vortex_doe.pth". |
'./vortex_doe.pth'
|
Source code in deeplens-src/deeplens/phase_surface/vortex.py
surf_dict
Return surface parameters as a serializable dictionary.
The "f0" key is included only when the Fresnel term is enabled.
Returns:
| Name | Type | Description |
|---|---|---|
d |
dict
|
Surface parameters (type, geometry, charge, f0, material, etc.). |
Source code in deeplens-src/deeplens/phase_surface/vortex.py
Light
Geometric ray representation carrying origin, direction, wavelength, validity mask, energy, and optical path length (OPL).
deeplens.Ray
Bases: DeepObj
Batched ray bundle for optical simulation.
Stores ray origins, directions, wavelength, validity mask, energy, bend
penalty, and optical path length. Per-ray tensors share a batch shape,
conventionally (..., num_rays), with trailing feature axes where noted
below. Wavelength is a scalar. With no remaining batch axes, a single ray
has origin and direction shapes (3,).
Attributes:
| Name | Type | Description |
|---|---|---|
o |
Tensor
|
Ray origins, shape |
d |
Tensor
|
Unit ray directions, shape |
wvln |
Tensor
|
Wavelength scalar [µm]. |
shape |
Size
|
Batch shape |
is_valid |
Tensor
|
Binary validity mask, shape |
en |
Tensor
|
Energy weight, shape |
stop_dist |
Tensor
|
Per-ray distance from the physical
aperture-stop centre in units of the stop radius, shape
|
bend_penalty |
Tensor
|
Accumulated per-surface bend penalty, shape |
opl |
Tensor
|
Optical path length, shape |
is_coherent |
bool
|
Whether optical path length tracking is enabled. |
device |
str | device
|
Compute device holding the ray tensors. |
Initialize a ray object.
The direction d is normalized to unit length on construction. Auxiliary
tensors (is_valid, en, bend_penalty, opl, stop_dist) are
allocated over the batch shape using the origin's dtype and device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
o
|
Tensor
|
Ray origin, shape |
required |
d
|
Tensor
|
Ray direction, shape |
required |
wvln
|
float
|
Ray wavelength [µm], must satisfy 0.1 < wvln < 10.0.
Required and passed explicitly (the Lens carries |
required |
is_coherent
|
bool
|
Enable optical path length tracking for coherent tracing. Defaults to False. |
False
|
device
|
str | device
|
Compute device. Defaults to "cpu". |
'cpu'
|
Source code in deeplens-src/deeplens/light/ray.py
prop_to
Propagate the ray to a given depth plane in place.
Moves each valid ray origin along its direction toward the depth plane
at axial coordinate \(z\). The denominator for nearly parallel rays is
clamped to magnitude EPSILON, preserving its sign; their displacement
is approximate. Invalid rays retain their origins and optical paths.
In coherent mode, float64 rays are required and the optical path length
is incremented by \(n \cdot t\), where \(t\) is the signed propagation
distance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
z
|
float | Tensor
|
Target axial coordinate [mm], scalar or broadcastable to the ray batch shape. |
required |
n
|
float | Tensor
|
Refractive index, scalar or broadcastable to the ray batch shape. Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Ray
|
The updated ray (for chaining). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If coherent propagation is requested for non-float64 rays. |
Source code in deeplens-src/deeplens/light/ray.py
centroid
Compute a geometric or chief-ray reference position for each field.
In chief-ray mode, selection precedes the final validity check. If the selected ray was clipped after the stop, or no finite stop distance was recorded, that field falls back to its geometric centroid. The sample selection is discrete; gradients through ray positions are preserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
str
|
|
'geometric'
|
Returns:
| Name | Type | Description |
|---|---|---|
centroid |
Tensor
|
Centroid position, shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deeplens-src/deeplens/light/ray.py
rms_error
Compute the mean RMS spot radius over valid rays.
For each field, the RMS radius is computed from the in-plane (x, y)
deviation of valid ray origins about center_ref, then averaged across
fields. A shifted square root keeps zero-radius gradients finite.
Fields with no valid rays contribute inf.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center_ref
|
Tensor
|
Reference center, shape |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
rms_error |
Tensor
|
Scalar mean RMS spot radius [mm]. |
Source code in deeplens-src/deeplens/light/ray.py
flip_xy
Negate the x and y components of ray origins and directions in place.
Used when computing the point spread function and wavefront distribution.
Returns:
| Name | Type | Description |
|---|---|---|
self |
Ray
|
The updated ray (for chaining). |
Source code in deeplens-src/deeplens/light/ray.py
clone
Copy ray tensors and tracing state, optionally to another device.
Tensor storage is independent; autograd connections are preserved. This copies the defined ray state rather than arbitrary attributes added by callers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device
|
str | device | None
|
Target device for the clone. If None, the source device is used. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
ray |
Ray
|
A new ray with cloned tensors on the target device. |
Source code in deeplens-src/deeplens/light/ray.py
squeeze
Squeeze the leading batch dimension of all ray tensors in place.
Only the leading batch axis is supported: it is the one axis shared by
every ray tensor regardless of its trailing feature axis, so trailing
feature axes and the scalar wavelength are preserved. shape is
updated. Squeezing a non-singleton axis is a no-op.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
int
|
Batch dimension to squeeze. Only 0 is supported. Defaults to 0. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Ray
|
The updated ray (for chaining). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deeplens-src/deeplens/light/ray.py
unsqueeze
Insert a leading size-1 batch dimension into all ray tensors in place.
Only the leading batch axis is supported: it is the one axis shared by
every ray tensor regardless of its trailing feature axis, so trailing
feature axes and the scalar wavelength are preserved. shape is
updated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
int
|
Position at which to insert the batch dimension. Only 0 is supported. Defaults to 0. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Ray
|
The updated ray (for chaining). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deeplens-src/deeplens/light/ray.py
Complex electromagnetic field with Angular Spectrum Method (ASM), Fresnel, and
Fraunhofer propagation via torch.fft.
deeplens.ComplexWave
Bases: DeepObj
Complex scalar wave field for diffraction simulation.
Represents a monochromatic, coherent complex amplitude on a uniform
rectangular grid. Propagation methods (band-limited ASM, Fresnel) are
implemented as member functions and use torch.fft for efficiency.
Attributes:
| Name | Type | Description |
|---|---|---|
u |
Tensor
|
Complex amplitude, shape [1, 1, H, W]. |
wvln |
float
|
Wavelength [µm]. |
k |
float
|
Wave number \(2\pi / (\lambda \times 10^{-3})\) [mm⁻¹]. |
phy_size |
tuple
|
Physical aperture size (W, H) [mm]. |
ps |
float
|
Pixel pitch [mm] (square pixels). |
res |
tuple
|
Grid resolution (H, W) in pixels. |
x |
Tensor
|
x coordinate grid, shape [H, W][mm]. |
y |
Tensor
|
y coordinate grid, shape [H, W][mm]. |
z |
Tensor
|
Axial position grid, shape [H, W][mm]. |
plain_asm_dist_max |
float
|
Nyquist limit of plain ASM [mm] (reference only). |
fresnel_dist_min |
float
|
Distance above which single-FFT Fresnel is well-sampled [mm]. |
Initialize a complex wave field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
Tensor or None
|
Initial complex amplitude. Accepted shapes: [H, W], [1, H, W], or [1, 1, H, W]. If None, a zero field is created with the given res. Defaults to None. |
None
|
wvln
|
float
|
Wavelength [µm]. Defaults to 0.55. |
0.55
|
z
|
float
|
Initial axial position [mm]. Defaults to 0.0. |
0.0
|
phy_size
|
tuple
|
Physical aperture (W, H) [mm]. Defaults to (4.0, 4.0). |
(4.0, 4.0)
|
res
|
tuple
|
Grid resolution (H, W) [pixels]. Only used when u is None. Defaults to (2000, 2000). |
(2000, 2000)
|
Raises:
| Type | Description |
|---|---|
AssertionError
|
If the pixel pitch is not square or the wavelength is outside the range (0.1, 10) µm. |
Source code in deeplens-src/deeplens/light/wave.py
point_wave
classmethod
point_wave(
point=(0.0, 0.0, -1000.0),
wvln=0.55,
z=0.0,
phy_size=(4.0, 4.0),
res=(2000, 2000),
valid_r=None,
)
Create a spherical wave field on the x0y plane from a point source.
The phase is \(\pm k r\) where \(r\) is the distance from the source to each grid point; the sign is positive for a diverging wave (source behind the plane, \(z_{src} < z\)) and negative otherwise. The amplitude is normalized to \(r_{min} / r\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point
|
tuple
|
Point source position (x, y, z) in object space [mm]. Defaults to (0.0, 0.0, -1000.0). |
(0.0, 0.0, -1000.0)
|
wvln
|
float
|
Wavelength [µm]. Defaults to 0.55. |
0.55
|
z
|
float
|
Field z position [mm]. Defaults to 0.0. |
0.0
|
phy_size
|
tuple
|
Physical size (W, H) of the x0y plane [mm]. Defaults to (4.0, 4.0). |
(4.0, 4.0)
|
res
|
tuple
|
Grid resolution (H, W) [pixels]. Defaults to (2000, 2000). |
(2000, 2000)
|
valid_r
|
float or None
|
If set, zero the field outside a circle of this radius [mm], e.g. a lens aperture. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
field |
ComplexWave
|
Complex field on the x0y plane. |
Source code in deeplens-src/deeplens/light/wave.py
plane_wave
classmethod
plane_wave(
wvln=0.55,
z=0.0,
phy_size=(4.0, 4.0),
res=(2000, 2000),
theta_x=0.0,
theta_y=0.0,
valid_r=None,
)
Create a planar wave field on the x0y plane.
With theta_x = theta_y = 0 the result is a uniform unit-amplitude plane wave travelling along +z. Non-zero angles produce a tilted (obliquely incident / off-axis) plane wave whose wavevector makes the given angles with the optical axis; this adds the linear phase ramp \(\exp(i k (x \sin\theta_x + y \sin\theta_y))\) while the amplitude stays uniform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wvln
|
float
|
Wavelength [µm]. Defaults to 0.55. |
0.55
|
z
|
float
|
Field z position [mm]. Defaults to 0.0. |
0.0
|
phy_size
|
tuple
|
Physical size (W, H) of the field [mm]. Defaults to (4.0, 4.0). |
(4.0, 4.0)
|
res
|
tuple
|
Grid resolution (H, W) [pixels]. Defaults to (2000, 2000). |
(2000, 2000)
|
theta_x
|
float
|
Tilt angle of the wavevector in the x-z plane [rad]. Defaults to 0.0. |
0.0
|
theta_y
|
float
|
Tilt angle of the wavevector in the y-z plane [rad]. Defaults to 0.0. |
0.0
|
valid_r
|
float or None
|
If set, zero the field outside a circle of this radius [mm]. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
field |
ComplexWave
|
Complex field. |
Source code in deeplens-src/deeplens/light/wave.py
image_wave
classmethod
Initialize a complex wave field from an image.
The image is interpreted as intensity in range [0, 1]; the field amplitude is its square root and the phase is zero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Input image, shape [H, W] or [B, C, H, W], data range [0, 1], dtype float32. |
required |
wvln
|
float
|
Wavelength [µm]. Defaults to 0.55. |
0.55
|
z
|
float
|
Field z position [mm]. Defaults to 0.0. |
0.0
|
phy_size
|
tuple
|
Physical size (W, H) of the field [mm]. Defaults to (4.0, 4.0). |
(4.0, 4.0)
|
Returns:
| Name | Type | Description |
|---|---|---|
field |
ComplexWave
|
Complex field. |
Source code in deeplens-src/deeplens/light/wave.py
prop
Propagate the field forward by prop_dist and update self.
Selects the diffraction method from the propagation distance: a
near-zero distance is a no-op; sub-wavelength distances raise (not
implemented); distances up to fresnel_dist_min use band-limited ASM;
larger distances use single-FFT Fresnel diffraction. The axial grid z
is advanced by prop_dist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prop_dist
|
float
|
Propagation distance [mm]. |
required |
n
|
float
|
Refractive index of the medium. Defaults to 1.0. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
ComplexWave
|
The propagated wave field (for chaining). |
Raises:
| Type | Description |
|---|---|
Exception
|
If the propagation distance is in the sub-wavelength range (full-wave methods such as FDTD are not implemented). |
Reference
[1] Modeling and propagation of near-field diffraction patterns: A more complete approach. Table 1. [2] https://github.com/kaanaksit/odak/blob/master/odak/wave/classical.py [3] https://spie.org/samples/PM103.pdf [4] "Non-approximated Rayleigh Sommerfeld diffraction integral: advantages and disadvantages in the propagation of complex wave fields"
Source code in deeplens-src/deeplens/light/wave.py
prop_to
Propagate the field to the absolute plane z and update self.
Computes the relative distance from the current axial position and
delegates to prop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
z
|
float
|
Destination plane z coordinate [mm]. |
required |
n
|
float
|
Refractive index of the medium. Defaults to 1. |
1
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
ComplexWave
|
The propagated wave field (for chaining). |
Source code in deeplens-src/deeplens/light/wave.py
gen_xy_grid
Generate the x and y coordinate grids, shape [H, W].
x runs along the width (res[1] columns, extent phy_size[0]) and y along
the height (res[0] rows, extent phy_size[1]), consistent with
point_wave / plane_wave. With indexing="xy" the outputs have shape
(len(y_1d), len(x_1d)) = (H, W).
Returns:
| Name | Type | Description |
|---|---|---|
x |
Tensor
|
x coordinate grid, shape [H, W][mm]. |
y |
Tensor
|
y coordinate grid, shape [H, W][mm]. |
Source code in deeplens-src/deeplens/light/wave.py
gen_freq_grid
Generate the spatial-frequency grids, shape [H, W].
Returns:
| Name | Type | Description |
|---|---|---|
fx |
Tensor
|
x-frequency grid, shape [H, W][mm⁻¹]. |
fy |
Tensor
|
y-frequency grid, shape [H, W][mm⁻¹]. |
Source code in deeplens-src/deeplens/light/wave.py
load
Load a wave field from file (only .npz is supported).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
str
|
Path to the file to load. |
required |
Raises:
| Type | Description |
|---|---|
Exception
|
If the file format is not supported. |
Source code in deeplens-src/deeplens/light/wave.py
load_npz
Load the complex wave field and grids from a .npz file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
str
|
Path to the |
required |
Source code in deeplens-src/deeplens/light/wave.py
save
Save the complex wave field to file (only .npz is supported).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
str
|
Output path. Defaults to "./wavefield.npz". |
'./wavefield.npz'
|
Raises:
| Type | Description |
|---|---|
Exception
|
If the file format is not supported. |
Source code in deeplens-src/deeplens/light/wave.py
save_npz
Save the field to a .npz file plus intensity/amplitude/phase PNGs.
Writes u, x, y, wvln, and phy_size to the .npz archive, and
additionally saves normalized intensity, amplitude, and phase images
next to it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
str
|
Output |
'./wavefield.npz'
|
Source code in deeplens-src/deeplens/light/wave.py
save_image
Render the field to an image (alias of show).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_name
|
str or None
|
Output image path; if None, plot with matplotlib instead. Defaults to None. |
None
|
data
|
str
|
Quantity to visualize, one of "irr", "amp", "phi"/"phase", "real", "imag". Defaults to "irr". |
'irr'
|
Source code in deeplens-src/deeplens/light/wave.py
show
Render the field as an image, either saved to disk or plotted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
save_name
|
str or None
|
Output image path; if None, the field is shown with matplotlib. Defaults to None. |
None
|
data
|
str
|
Quantity to visualize: "irr" (intensity), "amp" (amplitude), "phi"/"phase", "real", or "imag". Defaults to "irr". |
'irr'
|
Raises:
| Type | Description |
|---|---|
Exception
|
If |
Source code in deeplens-src/deeplens/light/wave.py
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | |
pad
Zero-pad the field and expand its physical size accordingly.
Pads Hpad pixels on the top and bottom and Wpad pixels on the left
and right, then updates res, phy_size, and the coordinate grids so
the pixel pitch stays constant. Modifies self in place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Hpad
|
int
|
Number of pixels to pad on the top and bottom. |
required |
Wpad
|
int
|
Number of pixels to pad on the left and right. |
required |
Source code in deeplens-src/deeplens/light/wave.py
flip
Flip the field and its grids horizontally and vertically.
Returns:
| Name | Type | Description |
|---|---|---|
self |
ComplexWave
|
The flipped wave field (for chaining). |
Source code in deeplens-src/deeplens/light/wave.py
Image Simulation
PSF Rendering
Functions for rendering images with point spread functions.
deeplens.imgsim.psf.conv_psf
Render an image batch with one spatially invariant PSF.
Applies a per-channel, size-preserving ("same") 2-D convolution using
reflect padding so that the output keeps the input spatial dimensions. The
"conv" and "fft" backends apply the identical reflect-padded
convolution and agree to FFT round-off; they differ only in compute cost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Input image batch, shape |
required |
psf
|
Tensor
|
Shared PSF kernel with shape |
required |
method
|
str
|
Convolution backend. |
'conv'
|
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Rendered image, shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
Source code in deeplens-src/deeplens/imgsim/psf.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
deeplens.imgsim.psf.conv_psf_map
Render an image batch with a spatially varying PSF map.
Divides the image into grid_h × grid_w non-overlapping patches and
convolves each patch with its corresponding PSF kernel. The full image is
padded before patch extraction to avoid artificial seams from independent
per-patch padding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Input image batch, shape |
required |
psf_map
|
Tensor
|
PSF map, shape |
required |
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Rendered image, shape |
Source code in deeplens-src/deeplens/imgsim/psf.py
deeplens.imgsim.psf.conv_psf_depth_interp
conv_psf_depth_interp(
img, depth, psf_kernels, psf_depths, interp_mode="depth", padding_mode="reflect"
)
Depth-interpolated PSF convolution for a spatially-uniform but depth-varying blur.
Pre-convolves the image with PSFs at each reference depth, then blends the
results using per-pixel linear interpolation weights derived from depth.
This approximates defocus blur for a single field position across a depth
range without computing a separate PSF per pixel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Image batch, shape |
required |
depth
|
Tensor
|
Depth map, shape |
required |
psf_kernels
|
Tensor
|
PSF stack at reference depths, shape
|
required |
psf_depths
|
Tensor
|
Depth of each PSF layer, shape
|
required |
interp_mode
|
str
|
Interpolation space. |
'depth'
|
padding_mode
|
str or None
|
Padding mode passed to
|
'reflect'
|
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Blurred image, shape |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
Source code in deeplens-src/deeplens/imgsim/psf.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | |
deeplens.imgsim.psf.conv_psf_map_depth_interp
Render with a spatially varying, depth-interpolated PSF map.
The image is divided into PSF-map grid cells. For each cell, the image patch is convolved with all reference-depth PSFs for that cell, then the convolved results are blended per pixel using interpolation weights from the depth map.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Image batch, shape |
required |
depth
|
Tensor
|
Depth map, shape |
required |
psf_map
|
Tensor
|
PSF map, shape
|
required |
psf_depths
|
Tensor
|
Reference depths, shape |
required |
interp_mode
|
str
|
|
'depth'
|
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Rendered image, shape |
Source code in deeplens-src/deeplens/imgsim/psf.py
deeplens.imgsim.psf.conv_psf_occlusion
Occlusion-aware bokeh rendering using back-to-front layered compositing.
Discretizes the scene into depth layers and composites them from back (far) to front (near). Each layer is blurred independently with its depth-specific PSF, and composited using the over-operator. This prevents color bleeding at depth discontinuities.
Reference
[1] "Dr.Bokeh: DiffeRentiable Occlusion-aware Bokeh Rendering", CVPR 2024.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Input image, shape |
required |
depth
|
Tensor
|
Depth map, shape |
required |
psf_kernels
|
Tensor
|
PSF at each depth layer, shape
|
required |
psf_depths
|
Tensor
|
Depth value for each layer, shape
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Rendered image, shape |
Source code in deeplens-src/deeplens/imgsim/psf.py
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | |
deeplens.imgsim.psf.splat_psf_per_pixel
Render an image batch by splatting each pixel through its own PSF.
Uses a different PSF kernel for each source pixel and accumulates the
scattered contributions with F.fold. When chunk_size is set, source
pixels are processed tile by tile to reduce peak memory while preserving
PSF contributions that cross tile boundaries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
img
|
Tensor
|
Image batch to be blurred, shape |
required |
psf
|
Tensor
|
Per-pixel local PSFs, shape |
required |
chunk_size
|
int or None
|
Source tile size for
memory-efficient rendering. If |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
img_render |
Tensor
|
Rendered image, shape |
Source code in deeplens-src/deeplens/imgsim/psf.py
deeplens.imgsim.psf.interp_psf_map
Resample a PSF map to a different spatial grid size.
Supports either a packed map [C, grid_old*ks, grid_old*ks] or an
unpacked map [grid_old, grid_old, C, ks, ks]. Each kernel sample
location is bilinearly interpolated across the PSF grid, and the result is
returned in packed-map layout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psf_map
|
Tensor
|
Packed or unpacked PSF map. |
required |
grid_old
|
int
|
Input grid size. Ignored for unpacked input, where the
grid size is read from |
required |
grid_new
|
int
|
Output grid size. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
psf_map_interp |
Tensor
|
Interpolated packed PSF map, shape
|
Source code in deeplens-src/deeplens/imgsim/psf.py
deeplens.imgsim.psf.rotate_psf
Rotate a batch of RGB PSF kernels counter-clockwise.
Rotation is performed around the center of each square PSF kernel using
F.grid_sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psf
|
Tensor
|
PSF batch, shape |
required |
theta
|
Tensor
|
Rotation angles in radians, shape |
required |
Returns:
| Name | Type | Description |
|---|---|---|
rotated_psf |
Tensor
|
Rotated PSFs, shape |
Source code in deeplens-src/deeplens/imgsim/psf.py
Monte Carlo Integrals
Utilities for ray-bundle accumulation and ray-traced image sampling.
deeplens.imgsim.monte_carlo.forward_integral
Differentiable Monte-Carlo integral over a ray bundle onto a pixel grid.
Bins ray hit positions into a ks x ks grid centred on pointc (or the
valid-ray centroid when pointc is None). In coherent mode the complex
amplitude sqrt(|dz|) * exp(i * phase) is accumulated; in incoherent mode
unit intensity is accumulated. All N field points scatter into their own
output slices in batched index_put_(accumulate=True) calls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Traced ray bundle with origin |
required |
ps
|
float
|
Pixel size [mm]. |
required |
ks
|
int
|
Output grid size in pixels (square). |
required |
pointc
|
Tensor or None
|
Reference centre [mm] for each field point, shape [N, 2]. If None, the valid-ray centroid is used. Defaults to None. |
None
|
interpolate
|
bool
|
If True, each ray splits its contribution across the four surrounding pixels via bilinear weights. If False, each ray is hard-binned into the floor pixel (faster, no gradient w.r.t. in-pixel position). Defaults to True. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
grid |
Tensor
|
Accumulated field, shape [N, ks, ks] (or [ks, ks]
for a single input point). Dtype is complex when |
Source code in deeplens-src/deeplens/imgsim/monte_carlo.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
deeplens.imgsim.monte_carlo.backward_integral
Backward Monte-Carlo integration for ray-tracing-based rendering.
Sample an input image at each ray's hit position and average over the samples-per-pixel (spp) axis to render the output. The input image is always replicate-padded by one pixel on each side so that rays landing within half a pixel of the edge can still be bilinearly sampled without silently truncating.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ray
|
Ray
|
Ray object. Shape of |
required |
img_obj
|
Tensor
|
Source image, shape [B, C, H, W]. Spatial size H, W is read from this tensor. |
required |
ps
|
float
|
Pixel size [mm]. |
required |
interpolate
|
bool
|
If True, bilinearly sample the four surrounding pixels; if False, nearest-pixel sampling. Defaults to True. |
True
|
energy_correction
|
Tensor or None
|
Per-ray weight
tensor of shape [h, w, spp, 1] (e.g. |
None
|
vignetting
|
bool
|
If True, divide by a fixed denominator
( |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
output |
Tensor
|
Rendered image, shape [B, C, h, w]. |
Raises:
| Type | Description |
|---|---|
Exception
|
If |
Source code in deeplens-src/deeplens/imgsim/monte_carlo.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
deeplens.imgsim.monte_carlo.assign_points_to_pixels
Scatter point samples onto a ks x ks pixel grid.
Bins each point's value (intensity or complex amplitude) into the grid
spanned by x_range x y_range using index_put_(accumulate=True).
Supports both incoherent and coherent ray tracing. Handles a single point
source only, constrained by the advanced-indexing scatter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
Tensor
|
Sample positions [mm], shape [spp, 2] as (x, y). |
required |
mask
|
Tensor
|
Validity mask, shape [spp]. |
required |
ks
|
int
|
Output grid size in pixels (square). |
required |
x_range
|
tuple
|
Grid extent (x_min, x_max) [mm]. |
required |
y_range
|
tuple
|
Grid extent (y_min, y_max) [mm]. |
required |
value
|
Tensor
|
Per-point value to accumulate (intensity or complex amplitude), shape [spp]. |
required |
interpolate
|
bool
|
If True, split each point across the four surrounding pixels via bilinear weights; if False, hard-bin into the floor pixel. Defaults to True. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
grid |
Tensor
|
Accumulated intensity or complex amplitude, shape
[ks, ks]. Dtype matches |
Source code in deeplens-src/deeplens/imgsim/monte_carlo.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |