Repository navigation
Add a point-spread function to IdealInstrument, and a tutorial with a different PSF in each channel - #36
Merged
Conversation
… different PSF in each channel. `IdealInstrument` and `OptikaInstrument` gain `psf`, the fraction of the light landing in a pixel which reaches each pixel around it, and `axis_psf_xy`, its axes along `axis_sensor_xy`. Other axes of the PSF are broadcast by name, so it may differ per channel or wavelength or vary across the sensor. `AbstractLinearInstrument._convolve_psf()` folds it into `weights` with `na.regridding.convolve_weights()`, so `image()` blurs by it, and `backproject()`, the transpose built from the same weights, accounts for it; MART models it with no other change. The tutorial images the Gaussian scene with a different elliptical PSF in each channel and compares MART with the PSFs modeled, stopped where the mean chi squared first reaches one, against MART ignoring them. Requires named-arrays 2.13.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqceVSp8s2msxj1Dr9MrGU
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #36 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 24 24
Lines 892 918 +26
=========================================
+ Hits 892 918 +26
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
… the observed images only by the PSF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqceVSp8s2msxj1Dr9MrGU
…ribe the PSF without reference to charge diffusion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqceVSp8s2msxj1Dr9MrGU
…mpute its own PSF from its optika system. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqceVSp8s2msxj1Dr9MrGU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a point-spread function to
IdealInstrument, and a tutorial which inverts a scene blurred by a different PSF in each channel.psfIdealInstrumentgains two fields:psf: None | na.AbstractScalar = None: the fraction of the light landing in a pixel which reaches each of the pixels around it.axis_psf_xy = ("psf_x", "psf_y"): the axes ofpsfwhich run alongaxis_sensor_xy.Any other axis of the PSF is broadcast by name:
axis_channeloraxis_wavelengthgive a PSF per channel or per wavelength;axis_sensor_xygives one that varies across the sensor.IdealInstrument.weightsfolds the PSF into the weights withna.regridding.convolve_weights()(named-arrays 2.13.0).weights_transposeis built fromweights, soimage()blurs by the PSF andbackproject(), the transpose, accounts for it, with no other changes. MART uses only those two methods, so it models the PSF automatically.OptikaInstrumentdoesn't take a PSF: it will compute its own from its optika system.Requires
named-arrays>=2.13.0.Tutorial: "Invert a Scene Blurred by a Different PSF in Each Channel"
docs/tutorials/psf-mart.ipynbuses the Gaussian scene and the instrument from the MART tutorial, and gives each of the four channels its own elongated elliptical Gaussian PSF, with a different length, width and orientation. It then:Across noise seeds, modeling the PSFs recovers all three moments better. A typical run:
Tests
IdealInstrumentwith a PSF: every abstract instrument test now also runs on anIdealInstrumentwith apsf, including flux conservation through the image → backproject → image round trip.test_psf: checks that the per-wavelength image with an asymmetric PSF that differs by channel equals the image without one, convolved channel by channel withscipy.ndimage.convolve. It fails if the PSF is not applied.🤖 Generated with Claude Code
https://claude.ai/code/session_01GqceVSp8s2msxj1Dr9MrGU