Skip to content

Add optika.wavefields: physical-optics propagation through a SequentialSystem#173

Open
jacobdparker wants to merge 6 commits into
feature/zernike-sagfrom
feature/wavefields
Open

Add optika.wavefields: physical-optics propagation through a SequentialSystem#173
jacobdparker wants to merge 6 commits into
feature/zernike-sagfrom
feature/wavefields

Conversation

@jacobdparker

Copy link
Copy Markdown
Contributor

Summary

Stacked on #172 (which is stacked on #171; will retarget as they merge). The aperture-bounds fix in #171 is required for correct sampling of apertures with internal transformations (covered by a regression test here).

Adds a physical-optics path that mirrors the geometric raytrace: the complex scalar field is sampled on every surface with stratified random samples and propagated surface-by-surface with the Rayleigh-Sommerfeld (RS-I) diffraction integral, producing Huygens PSFs on the sensor.

  • optika.wavefields: WavefieldVectorArray (complex amplitude, position, surface normal, sample area; transformation dunders mirror RayVectorArray) and rayleigh_sommerfeld(), a chunked, numexpr-fused kernel whose peak memory is bounded by chunk_size x N_src x 16 B instead of the full N_src x N_dst outer product.
  • Surface.wavefield_samples / propagate_wavefield: stratified random sampling of each aperture (via na.Cartesian2dVectorStratifiedRandomSpace, which converts aliasing into broadband noise), with an optional per-surface bound to window surfaces near an intermediate focus.
  • Diffraction gratings: the ruling phase 2 pi m N(r) is applied at each sample, with the groove-counting function N(r) computed as a Gauss-Legendre line integral of the local groove density - exact for polynomial (VLS) ruling spacings and consistent with the sign convention of optika.rulings.incident_effective.
  • SequentialSystem.wavefield / psf: orchestration over the surface chain, plane- or spherical-wave initial conditions from the system object, and a sensor grid auto-centered on the geometric image centroid.

The docstring Notes document the key sampling constraint: the brute-force RS sum is only well-sampled between near-conjugate surfaces; flat masks in collimated space are better folded into the pupil than treated as propagation steps.

Validation

  • Airy pattern of an ideal paraboloid: first zero at 1.22 lambda f/D, null depth ~3e-6.
  • Chunk invariance (bitwise) and energy conservation to 0.03%.
  • Huygens vs geometric centroids agree through a 90-degree Newtonian fold and a concave VLS grating (~20 nm).
  • End-to-end on the ESIS f1 spectrograph at O V 630 A: PSF FWHM matches the no-free-parameter lambda L/D prediction of the channel pupil in both axes; image centroids match the raytrace to <0.25 um across the FOV and to <0.6 um across an 18.5 mm dispersion span (He I 584 to O V 630).

🤖 Generated with Claude Code

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.01498% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.64%. Comparing base (8455e8d) to head (60267ad).

Files with missing lines Patch % Lines
optika/systems/_sequential.py 79.80% 21 Missing ⚠️
optika/wavefields/_wavefield_vectors.py 82.02% 16 Missing ⚠️
optika/surfaces.py 82.35% 15 Missing ⚠️
optika/systems/_wavefield_test.py 99.25% 1 Missing ⚠️
optika/wavefields/_wavefield_functions.py 92.30% 1 Missing ⚠️
Additional details and impacted files
@@                   Coverage Diff                   @@
##           feature/zernike-sag     #173      +/-   ##
=======================================================
- Coverage                99.37%   98.64%   -0.74%     
=======================================================
  Files                      120      127       +7     
  Lines                     6248     6849     +601     
=======================================================
+ Hits                      6209     6756     +547     
- Misses                      39       93      +54     
Flag Coverage Δ
unittests 98.64% <91.01%> (-0.74%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jacobdparker and others added 6 commits June 15, 2026 11:47
…eld kernel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Surface.wavefield_samples generates stratified random samples of a
surface's aperture, Surface.propagate_wavefield evaluates the
Rayleigh-Sommerfeld integral between surfaces, and
SequentialSystem.wavefield/psf orchestrate the propagation from the
source through every surface to the sensor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ruling phase function is evaluated by integrating the local groove
density along the chord from the local origin to each sample point with
Gauss-Legendre quadrature, which is exact for constant ruling spacing
and accurate for smooth variable-line-spacing profiles. Validated
against the geometric raytrace of a concave grating in first order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Surfaces near an intermediate focus concentrate the wavefield in a
region much smaller than their aperture, so the sampling region must be
restricted for the field to be resolved. The new bound parameter of
SequentialSystem.wavefield (and Surface.propagate_wavefield) allows
this. Also document that brute-force Rayleigh-Sommerfeld propagation is
only well-sampled between near-conjugate surfaces, and add an
end-to-end demo computing the Huygens PSF of the ESIS flight-1 design.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Update the wavefield test to construct ZernikeSag with `base=` after the
  attribute was renamed from `sag` on the parent branch.
- Reformat the new wavefield modules with the current `black` stable release
  (parenthesized union types, collapsed short calls).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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