Check that linearizing a system conserves flux - #208
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #208 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 121 121
Lines 7303 7317 +14
=========================================
+ Hits 7303 7317 +14
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:
|
Nothing tied `SequentialSystem` and the `LinearSystem` it produces together. `test_linearize` asserts the types of the three fitted models, `_linear_test.py` builds its systems from hand-written fixtures rather than from a real one, and `test_image` only asserts that each system puts a nonzero number of electrons on its sensor. The distortion, vignetting, and effective-area models were each checked alone, and never against each other. Trace a flat field through a system and through its linearization, and compare the total electrons. The system needs a field stop which is not the sensor. The normalized field grid is the bounding box of the field of view, so a field stop shaped like the sensor fills it and leaves nothing vignetted: on the system the other tests use, 99% of the grid is illuminated and the vignetting model has no work to do. A round field stop leaves the corners dark, 57% illuminated here, which is the shape a system like ESIS actually has. The two agree to about 1.4%, and are stable to 0.24% over repeated builds of the linear system, so the tolerance is 15%. Averaging the effective area over a different set of field positions than the vignetting model is normalized over puts the ratio at 0.56, which fails. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
870dbcf to
00ca26a
Compare
Correction to the "not addressed here" note aboveThe claim that the pupil quadrature "does not settle" is wrong, and the sequence quoted for it (1.294 at 4×4 through 1.449 at 80×80) is the midpoint rule, which is not what Measured properly, 40 draws per grid, effective area at field centre: That is the What is actually wrong is
|
Retraction of the correction aboveThe previous comment's claim that I built the comparison from pupil=na.Cartesian2dVectorLinearSpace(
...
centers=True,
)so the samples land at ±0.909 … 0 — strictly interior. The boundary-sampling mechanism I described, where a third of the samples sit where nothing gets through, never happens. I constructed the defect and then measured it. Unvignetted fraction at field centre, against a converged value of ~0.281: The left column is what the code does: within 3% at n=11, bouncing either side of the answer as midpoint quadrature does. The right column, creeping up from below at ~1/n, is the grid I invented. Re-measured properly, taking the pupil grid straight from So the effect is rms 1.9%, not 14.8%, and the raw bias runs high rather than low. That is a modest quadrature error of the kind you would expect from a midpoint rule at this resolution, not a radiometric defect. What survives:
Apologies for the noise. The error was measuring a reconstruction of the input instead of the input itself. |
Depends on #207, and must merge after it (the test fails without that fix).
This targets
mainrather than #207's branch on purpose, so that deleting that branch on merge cannot close this PR. Until #207 lands, the diff below shows both changes; once it does, this branch is rebased and the diff narrows to the test alone.Why
Nothing tied
SequentialSystemand theLinearSystemit produces together:test_linearizeasserts the types of the three fitted models and nothing about their values_linear_test.pybuilds its systems from hand-written_distortion()/_vignetting()/_area_effective()fixtures, never from a real systemtest_imageasserts each system puts a nonzero number of electrons on its sensorSo the distortion, vignetting, and effective-area models were each checked alone and never against each other, which is how #207's bug survived: it is entirely a disagreement between two of them.
The test
Trace a flat field through a system and through its linearization; compare total electrons.
The interesting part is that the system has to be chosen carefully. The normalized field grid is the bounding box of the field of view, so a field stop shaped like the sensor fills that box and leaves nothing vignetted. On the system the other tests use, 99% of the grid is illuminated, the vignetting model has no work to do, and the test would pass with or without #207. A round field stop leaves the corners dark, which is the shape ESIS actually has:
With that, on a scene covering the inner half of the field of view:
Tolerance
rtol=0.15. The two discretize differently andarea_effectivetraces at randomly placed pupil cell centers, so exact agreement isn't available. Measured spread over six rebuilds of the linear system:Verified to fail with #207's change reverted. Runs in 0.75 s. Five consecutive runs pass.
Found while writing this, not addressed here
The polynomial fits are unusable above degree 2 and fail silently. Fitted illumination over the scene, on an 11×11 field grid with 3 wavelengths:
Almost certainly rank deficiency: a degree-3 fit needs at least 4 samples along the wavelength axis and the grid has 3. It produces no error and no warning, just ±10¹⁴ and negative illumination. Worth its own issue, and a reason this test pins
degree=2._grid_inputin this module spans [0, 1], one quadrant of the normalized field, rather than [-1, 1]. Fitting there and evaluating over the full field of view gave 0.58 of the true flux. Presumably deliberate for the other tests, but it makes anything built onlinearizemisleading.🤖 Generated with Claude Code