optiland.rays.ray_aiming.robust#
Robust Ray Aiming Module
This module implements a chief-ray calibrated robust ray aiming algorithm.
For each field, a cheap chief-ray solve plus four cardinal edge probes
((+-1, 0), (0, +-1) on the stop) are fit to a 2x2 affine launch
model (see pupil_map.py). That model seeds every requested pupil point,
which is then driven to its exact target by the same Newton/Broyden polish
used by IterativeRayAimer. Calibration is warm-started from the
previous fit (or the nearest already-solved field) rather than a paraxial
guess extrapolated across the whole field range, which is what allows this
to converge cold at extreme field angles without the recursive homotopy
subdivision the previous implementation relied on.
See optiland/jupyter/SPEC_ray_aiming_20260703.md for the full design.
Kramer Harrison, 2026
Classes
|
Per-field outcome of one robust aiming call. |
|
Chief-ray calibrated robust ray aiming algorithm. |
|
Aggregate outcome of one |
- class RobustFieldReport(Hx: float, Hy: float, wavelength: float, final_polish: SolveReport, chief_seed_strategy: str, used_cached_map: bool, edge_probe_fallbacks: int, calibration_used: bool, fallback_used: bool)[source]#
Per-field outcome of one robust aiming call.
- Variables:
Hy (Hx,) – Normalized field coordinates of the group.
wavelength (float) – Wavelength of the group in micrometers.
final_polish (optiland.rays.ray_aiming.parameterization.SolveReport) –
SolveReportof the group’s final Newton polish (or of the failed chief solve when calibration itself failed).chief_seed_strategy (str) – How the chief anchor was obtained –
"initial_guess"(caller-supplied guess solved directly),"cached_map"(fresh cached map reused, no calibration),"warm_map"(chief solved from a stale/nearest cached map),"direct_paraxial"(chief solved from the fresh paraxial seed),"marching"(field-marching fallback),"scan"(transverse scan fallback) or"failed".used_cached_map (bool) – Whether a fresh cached pupil map was reused without recalibration.
edge_probe_fallbacks (int) – Number of cardinal edge probes that failed to converge and fell back to the chief launch in the affine fit.
calibration_used (bool) – Whether a fresh chief-plus-probes calibration ran for this field.
fallback_used (bool) – Whether any substitute strategy was used for this field: a failed caller-supplied guess, chief marching or scan, edge-probe fallbacks, or a Jacobian conditioning fallback inside the final polish.
- final_polish: SolveReport#
- class RobustRayAimer(optic: Optic, max_iter: int = 20, tol: float = 1e-08, scale_fields: bool = True, **kwargs: Any)[source]#
Chief-ray calibrated robust ray aiming algorithm.
Designed to handle challenging optical systems (wide-angle, fisheye) where a cold paraxial seed for the iterative solver is too far from the real solution to converge directly. Per field, a chief-ray calibration (§4.2 of the spec) produces a cheap affine seed model; every requested ray is then polished to exactness (§4.3) via the reused
IterativeRayAimerNewton/Broyden core. Individual ray failures (vignetting, TIR) are reported as NaN rather than aborting the batch.- Variables:
optic (Optic) – The optical system instance.
max_iter (int) – Maximum number of iterations for the internal solver.
tol (float) – Numerical tolerance for convergence.
scale_fields (bool) – Retained for constructor-signature stability; the calibration-based algorithm does not use homotopy field-scaling, so this is a no-op.
- aim_rays(fields: tuple, wavelengths: Any, pupil_coords: tuple, initial_guess: tuple | None = None) tuple[source]#
Calculate ray starting coordinates using chief-ray calibration.
- Parameters:
fields (tuple) – Field coordinates
(Hx, Hy).wavelengths (Any) – Wavelengths in microns.
pupil_coords (tuple) – Normalized pupil coordinates
(Px, Py).initial_guess (tuple | None, optional) – Optional starting guess. If provided, the method first attempts to solve directly using the iterative solver with this guess; only on failure does it fall back to the full calibrated solve below.
- Returns:
Solved ray parameters
(x, y, z, L, M, N).- Return type:
- Raises:
ValueError – If every ray for a field fails to converge (a misconfiguration, not ordinary partial vignetting).
- last_report: RobustSolveReport | None#
Aggregate report of the most recent
aim_rays()call. Set before raising on a total field failure, so the failure can be inspected.
- class RobustSolveReport(field_reports: tuple, num_rays: int, num_converged: int, converged: bool, seed_residual: float, final_residual: float, final_polish_iterations: int, fallback_used: bool)[source]#
Aggregate outcome of one
RobustRayAimer.aim_rays()call.Robust aiming may return NaN for individual vignetted/unreachable rays;
convergedis therefore defined asnum_converged == num_raysand the exact counts are retained.- Variables:
field_reports (tuple) – One
RobustFieldReportper processed field group, in processing order.num_rays (int) – Total number of requested rays.
num_converged (int) – Number of rays that met the solver tolerance.
converged (bool) –
num_converged == num_rays.seed_residual (float) – Worst (max) seed residual across the field polishes.
final_residual (float) – Worst (max) final residual across the field polishes.
final_polish_iterations (int) – Largest Newton iteration count among the field polishes.
fallback_used (bool) – Whether any field used a substitute strategy (see
RobustFieldReport.fallback_used).