Skip to content

Add optika.systems.LinearSystem, a linear forward-model approximation to SequentialSystem#152

Open
roytsmart wants to merge 8 commits into
mainfrom
feature/interpolated-system
Open

Add optika.systems.LinearSystem, a linear forward-model approximation to SequentialSystem#152
roytsmart wants to merge 8 commits into
mainfrom
feature/interpolated-system

Conversation

@roytsmart

@roytsmart roytsmart commented Apr 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds optika.systems.LinearSystem (and its abstract base AbstractLinearSystem), a fast linear forward model that approximates a SequentialSystem.

Instead of raytracing every scene, a LinearSystem is characterized once by a set of precomputed models:

  • a distortion model mapping object-plane coordinates onto the detector,
  • an area_effective (effective area) model,
  • optional vignetting and field_stop models,
  • and a sensor.

image() maps a scene's energy spectral radiance to detector electrons by conservatively regridding it through the distortion model, weighting each cell by the effective area, vignetting, and field stop, then applying the sensor's exposure model. The expensive conservative-regridding operator is built once in weights() and reused by image_from_weights(), so many scenes can be imaged through the same optics cheaply.

Supporting changes

  • Shaped on the calibration models. AbstractDistortionModel, AbstractVignettingModel, and AbstractEffectiveAreaModel now inherit the Shaped mixin, with shape implemented on the concrete models (SimpleDistortionModel, PolynomialDistortionModel, PolynomialVignettingModel, InterpolatedEffectiveAreaModel). Each returns the model's batch shape (excluding the wavelength/field domain axes), which is what lets LinearSystem.shape report the system's parametrization.
  • Moved Plottable/DxfWritable from AbstractSystem to AbstractSequentialSystem. A LinearSystem has no geometry to plot or export to CAD, so the common AbstractSystem base no longer forces those mixins; the geometric SequentialSystem keeps them.

Tests

_linear_test.py adds TestLinearSystem with two fixtures (a minimal system, and one with vignetting and a field stop), driving image() end-to-end with noise on and off, plus the model interface. The distortion/vignetting/effective-area test bases gained shape coverage.

Docs

LinearSystem has a runnable .. jupyter-execute:: example that assembles the component models and images a USAF-1951 target, mirroring the SequentialSystem example. AbstractLinearSystem documents the full model, and a Features bullet was added to the landing page.

Follow-ups (known limitations)

  • A scene with only a single wavelength cell currently fails in image(): the size-1 wavelength axis is dropped and the regridding cannot align the weights.
  • LinearSystem.image expects energy spectral radiance, whereas SequentialSystem.image takes photon radiance; the two image() methods disagree on units.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CtdKmedevWkDab6BWupXqQ

@codecov

codecov Bot commented Apr 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.55%. Comparing base (bf75a1f) to head (6381076).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #152      +/-   ##
==========================================
+ Coverage   99.54%   99.55%   +0.01%     
==========================================
  Files         116      118       +2     
  Lines        6374     6553     +179     
==========================================
+ Hits         6345     6524     +179     
  Misses         29       29              
Flag Coverage Δ
unittests 99.55% <100.00%> (+0.01%) ⬆️

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.

@roytsmart
roytsmart force-pushed the feature/interpolated-system branch from 4b5ad3a to c625f4b Compare July 6, 2026 16:36
@roytsmart
roytsmart force-pushed the feature/interpolated-system branch from 23ec8b0 to 33b7cd0 Compare July 21, 2026 22:16
Rewrite the `AbstractLinearSystem` docstring to describe the full linear
forward model (distortion, effective area, and optional vignetting/field
stop) instead of the stale "define a distortion/vignetting method" text, and
add a `LinearSystem` class docstring with a `jupyter-execute` example that
assembles the component models and images a USAF-1951 target, mirroring the
`SequentialSystem` example.

Also document the `shape` property, clarify that `image()` expects energy
spectral radiance, and add a Features bullet for the linear forward model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CtdKmedevWkDab6BWupXqQ
@roytsmart roytsmart changed the title Added optika.systems.InterpolatedSystem as an approximation to SequentialSystem. Add optika.systems.LinearSystem, a linear forward-model approximation to SequentialSystem Jul 21, 2026
roytsmart and others added 3 commits July 21, 2026 20:22
Fit the system's distortion, vignetting, and effective area models and
assemble them (with the sensor) into a `LinearSystem`. The `pupil` argument is
interpreted as cell vertices: the effective area fit uses the vertices to
compute pupil cell areas, while the distortion and vignetting fits trace at the
corresponding cell centers. The field stop is not modeled, so `field_stop` is
left `None`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CtdKmedevWkDab6BWupXqQ
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