Skip to content

Object-local frames and per-field entrance-pupil calibration (WIP)#189

Draft
roytsmart wants to merge 1 commit into
mainfrom
feature/per-field-entrance-pupil
Draft

Object-local frames and per-field entrance-pupil calibration (WIP)#189
roytsmart wants to merge 1 commit into
mainfrom
feature/per-field-entrance-pupil

Conversation

@roytsmart

Copy link
Copy Markdown
Collaborator

Reworks SequentialSystem coordinate frames (object-local; single self.transformation folded into non-object surfaces via na.transformations.compose) and adds WIP per-field entrance-pupil calibration.

Frame fixes (working): surfaces_all composition, object-local _shoot_rays/_ray_error solve with per-trial transform + broadcast seed, object-frame rayfunction_stops/pupil outputs, composed-sensor inversion in rayfunction.

WIP: per-field pupil fits (_calc_rayfunction_pupil, _pupil_min/_pupil_max, _denormalize_pupil), optika.angles 2D-cosine input, docs/stop_finding.rst.

Depends on sun-data/named-arrays#193 (na.transformations.compose).

Known-incomplete: public pupil_min/pupil_max commented out; pupil calibration traces the dense grid (should be coarse) so the full ESIS design does not yet converge; failing tests: finite-object imaging, vignetting, dxf, grazing field_max tol. FURST-style systems converge and image.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BWk1x6S9g3s8o674HJUqRQ

Rework the coordinate-frame handling of `SequentialSystem` and add
machinery to calibrate the entrance-pupil extent per field.

Frame handling:
- `surfaces_all` now composes `self.transformation` into the non-object
  surfaces (via `na.transformations.compose`), leaving the object at its
  own transformation, so the whole trace runs in the object frame and
  `self.transformation` is applied in exactly one place.
- `_shoot_rays`/`_ray_error` solve entirely in the first surface's local
  frame: the surface transformation is applied per trial inside the
  residual (so the sag `zfunc` is evaluated where it is valid) and once
  more before returning, fixing a latent bug where a translated/tilted
  launch surface had its launch `z` clobbered.
- The internal seed is broadcast to the full solution shape, so the
  "rough" seed (aimed at a powered surface, lacking the target-grid axis)
  no longer leaves the solve under-determined.
- `rayfunction_stops` and the pupil trace express their outputs in the
  object-local frame, and `rayfunction` inverts the composed sensor
  transformation.

Entrance pupil (WIP):
- Add `_calc_rayfunction_pupil` and the `_pupil_min`/`_pupil_max`
  polynomial fits to capture the field dependence of the entrance pupil,
  plus `_denormalize_pupil`/`_denormalize_field` and a `field_min`/
  `field_max` refactor that fits the field extent versus wavelength.

Supporting:
- `optika.angles` accepts a 2D vector of direction cosines, reconstructing
  the `z` component from the unit-length constraint.
- Add `docs/stop_finding.rst` documenting the stop-finding strategy.

Depends on `na.transformations.compose` (sun-data/named-arrays#193).

Still WIP: the public `pupil_min`/`pupil_max` are commented out, the
pupil calibration traces the dense grid (should be coarse), and several
tests fail (finite-object imaging, vignetting, dxf, a grazing field-max
tolerance).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWk1x6S9g3s8o674HJUqRQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant