optiland.rays.ray_aiming.parameterization#
Local launch parameterization for iterative ray aiming.
The Newton/Broyden aiming core drives exactly two scalar parameters per ray.
Historically those were global launch (x, y) for infinite conjugates and
global direction (L, M) (with N held fixed) for finite ones – both
of which silently assume the beam enters along global +z. For a system
entered along any other direction one of those parameters points along the
beam (a vanishing Jacobian column), and varying L, M at fixed N
neither preserves the unit norm nor spans the transverse plane.
LaunchParameterization replaces both with two true transverse
degrees of freedom (xi, eta):
infinite conjugate: the launch point moves in the entry-frame transverse plane,
r(xi, eta) = r_seed + xi * u + eta * v, while the field direction stays fixed;finite conjugate: the object point stays fixed and the direction rotates in a per-ray orthonormal tangent basis around the seed direction,
k(xi, eta) = normalize(k_seed + xi * e1 + eta * e2)withe1, e2 perpendicular to k_seed, so every trial and line-search candidate is a unit direction by construction.
For the canonical +z entry the infinite-conjugate map reduces exactly to
the historical (x, y) offsets (u = +x, v = +y).
The bases are stored as plain Python floats. Ray aiming is an iterative
solve whose result is polished against real traces, so it never carries
gradient information (same design as pupil_map.py).
Kramer Harrison, 2026
Classes
|
A |
|
Two-parameter transverse launch model in the entry frame. |
|
Outcome of one Newton/Broyden aiming solve. |
- class BoundLaunch(param: LaunchParameterization, x, y, z, L, M, N)[source]#
A
LaunchParameterizationbound to per-ray seed states.launch(0, 0)reproduces the seeds exactly. For finite conjugates the per-ray tangent basis(e1, e2)is built perpendicular to each seed direction; the basis is refreshed by re-binding whenever the seeds change meaningfully (each solve binds once).
- class LaunchParameterization(is_infinite: bool, u: tuple[float, float, float], v: tuple[float, float, float])[source]#
Two-parameter transverse launch model in the entry frame.
- Variables:
- bind(x, y, z, L, M, N) BoundLaunch[source]#
Bind per-ray seed launch states, yielding a (xi, eta) map.
- classmethod for_optic(optic: Optic, is_infinite: bool) LaunchParameterization[source]#
Build the parameterization from the optic’s entry frame.
- class SolveReport(seed_residual: float, final_residual: float, converged: bool, iterations: int, num_rays: int, num_converged: int, fallback_used: bool = False, jacobian_refreshes: int = 0)[source]#
Outcome of one Newton/Broyden aiming solve.
A returned finite ray is not evidence of convergence; consult this report. Residuals are max-abs stop-plane errors in the stop surface’s local transverse coordinates (mm).
- Variables:
seed_residual (float) – Residual of the initial (seed) launch.
final_residual (float) – Residual of the returned launch.
converged (bool) – Whether every ray met the solver tolerance.
iterations (int) – Newton/Broyden iterations executed.
num_rays (int) – Number of rays in the solve.
num_converged (int) – Number of rays that met tolerance.
fallback_used (bool) – True when the Newton core substituted the sign-preserving paraxial diagonal for at least one ray’s Jacobian – at initialization because the central finite difference was unusable (a perturbed ray missed a surface), or during iteration because a refreshed finite-difference Jacobian remained ill-conditioned. Populated by
_solve_corefrom the actual conditioning path taken.jacobian_refreshes (int) – Number of iteration-time central-difference Jacobian refreshes triggered by an ill-conditioned (round-off level reciprocal-condition) Newton solve.