Repository navigation
Weight wfs_input_opd_rms_m by the pupil and remove piston (2.0.0) - #12
Merged
Merged
Conversation
wfs_input_opd_rms_m now follows aocore CONVENTIONS 4.1: the RMS of the input OPD in metres weighted by the intensity of the pupil the optics use, on the input grid, with the intensity-weighted mean removed. An analytic pupil is evaluated on input.shape with the configured supersampling; a custom mask is area-averaged from the engine's pupil grid. The 1.x quantity, the unweighted whole-grid RMS with piston kept, is still recorded as wfs_input_opd_rms_unweighted_m. Both are reduced on the device and cross in the existing single batched transfer. Release 2.0.0: this changes the meaning of an existing metadata key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Require aocore>=0.1.3,<0.2. block_sum delegates every factor to aocore.block_sum, which measured at least as fast as the local factor-two shortcut on the Shack-Hartmann spot stacks on CPU and GPU. Pixel-centre coordinates are built on the selected device through ArrayBackend.centered_coordinates. The input-RMS tests check the unweighted key against aocore.rms_unweighted; the per-frame reduction stays local because the aocore metrics return host floats. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
Breaking (2.0.0).
wfs_input_opd_rms_mnow follows aocore CONVENTIONS.md 4.1: the RMS of the input OPD in metres, weighted by pupil intensity, with piston removed. In 1.x it was the quadratic mean over the whole input grid: every pixel counted equally, including pixels outside the pupil, and piston was kept.input.shapewith the same telescope model andnumerics.pupil_supersamplingthe engine uses on its own grid. This is the mapWavefrontSensor.pupil_illumination()returns, computed in float64. Both grids spaninput.grid_extent_m.configured_pupil, now exposed on both engines), so its intensity is area-averaged onto the input grid by the newsampling.area_rebin. That function uses exact cell overlaps for any shape ratio and returns the mask unchanged when the shapes match.wfs_input_opd_rms_unweighted_m.backend.scalarsbatch, so there is no new host round trip.docs/concepts.mddefines both keys,docs/stability.mdhas a "Migrating to 2.0" note, the CHANGELOG has a Breaking section, and AGENTS.md records the contract.closed_loop_injection.pyandshowcase.pynow plot the metadata value instead of a whole-gridnp.std.__about__.py,CITATION.cffand the CHANGELOG (dated 2026-10-07).Consumers. I grepped the whole aosim stack (shmpipeline-ao, pyRTC, solvephase, aocore, pyturb) for
wfs_input_opd_rms. Nothing outside makewfs reads the key.aocore 0.1.3 adoption (second commit). The dependency is now
aocore>=0.1.3,<0.2.block_sum.sampling.block_sumdrops the local factor-two shortcut and delegates toaocore.block_sum. I timed both at the real Shack-Hartmann call sites (medians, CPU / P620):(400,16,16)f32(3600,12,12)f64(64,16,16)f32Shack-Hartmann images now differ from 1.2.0 by addition-order rounding: at most about 1e-7 relative in float32 and 2e-16 in float64. Pyramid images are bit-identical.
Coordinates. Pixel-centre coordinates are built on the device with
aocore.centered_coordinates(dtype=, backend=), throughArrayBackend.centered_coordinates. The values are identical.rms_unweighted.aocore.rms_unweightedis now the reference for the unweighted key in the tests. It is not used per frame because it returns a host float, which would add a synchronization.Tests
New
tests/test_input_rms.py, run on both sensors:pupil_rmspassesaocore.conformance.check_rms.s R sqrt(1+e^2)/2to 0.2 %, and matchesaocore.rmson the sensor's pupil to 1e-12.expose_integratedreports the RMS of the mean OPD.area_rebinkeeps uniform maps uniform, conserves the area integral, and is a block mean for integer factors.The new GPU test (
-m gpu) checks CPU/GPU agreement to 1e-12 for both keys, both sensors, analytic and custom pupils, and both single and integrated exposures.Local runs (conda
3_13, Quadro P620):main(argmin of an empty sequence).pytest -m gpu: 21 passed.mkdocs build --strictandpython -m buildpass.Cost: the extra reductions add about 0.1 ms of CuPy dispatch per frame on the P620. That is within the run-to-run noise of a 2.5 ms warm SH expose on a GPU shared with other processes.
🤖 Generated with Claude Code