Improve mapping for images containing NaN values #383
Merged
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.
Improved mapping with
BodyXY.map_img
when using spline interpolation for images containing NaN pixels. The spline interpolator does not accept NaN values, so any NaN pixels must be replaced with finite values before performing the interpolation.Although we propagate NaN values to the map (by default at least), the replacement values can still affect the interpolated values elsewhere if the replacement values are very different to the surrounding values. Previously, we just used
np.nan_to_num
to replaced any NaNs with 0, which could introduce large artefacts when the data values were large, due to the jump between 0 and the data (see below).In the updated code, we now replace NaN (or infinite) values with the mean of surrounding non-NaN pixels (with a 3x3 footprint). All other NaN pixels (which don't have neighbouring non-NaN pixels) are replaced with the median of all the pixels in the original image. This generally minimises the delta between replaced NaN pixels, and the surrounding pixels, massively reducing (or even preventing) any artefacts around the NaN regions.
Other minor mapping changes:
propagate_nan
parameter.propagate_nan
can now be controlled from otherObservation
methods, and its value is recorded in mapped FITS headers.map_img
, where each slice will be automatically mapped and a mapped cube is returned. This saves having to manually iterate withnp.array([body.map_img(img) for img in cube])
.Closes #382
Example
This is a very extreme example of the artefacts that could be introduced around NaN regions with the old behaviour with cubic interpolation. The circles show the locations and values for the image pixels. The old behaviour had artefacts introduced along the top edge of the mapped area and the NaN pixel on the left, caused by the large jump from the filled-in 0 values and the data values. The new behaviour prevents any large jumps between the pixels, preventing any artefacts.
Pull request checklist
requirements.txt
are reflected insetup.py
and conda-forge feedstockrun_ci.sh
or check GitHub Actions)See CONTRIBUTING.md for more details.