Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mapping interpolation with k>1 when NaN values are present #382

Closed
ortk95 opened this issue Jul 10, 2024 · 3 comments
Closed

Improve mapping interpolation with k>1 when NaN values are present #382

ortk95 opened this issue Jul 10, 2024 · 3 comments
Labels
backend Related to the backend (coordinate conversion, SPICE etc.) polish Minor changes to improve quality

Comments

@ortk95
Copy link
Owner

ortk95 commented Jul 10, 2024

Currently, we use RectBivariateSpline, so have to replace NaN pixels with some value before interpolating (currently just set to 0). Even though we later mask any projected NaN pixels (with _should_propagate_nan_to_map), this can produce edge effects near NaN pixels when using e.g. cubic splines.

It would make more sense therefore to either:

  • Replace NaNs with a more appropriate constant value before interpolating - e.g. the median value of the image rather than 0. This would be the easiest to implement, and have negligible performance impact.
  • Replace NaNs with locally derived value before interpolating - e.g. do nanmean of 3x3 footprint around each pixel. This would cost more performance, but provide better results for variable data.
  • Use a different interpolation method that doesn't require a regular grid - probably using bisplrep or griddata.
@ortk95 ortk95 added polish Minor changes to improve quality backend Related to the backend (coordinate conversion, SPICE etc.) labels Jul 10, 2024
@ortk95
Copy link
Owner Author

ortk95 commented Jul 10, 2024

Could do locally derived value fixing with something along the lines of

def clean(img: np.ndarray) -> np.ndarray:
    nans = np.isnan(img)
    cleaned = img.copy()
    cleaned[nans] = np.nanmedian(img)
    to_fix = nans & ~scipy.ndimage.uniform_filter(nans, size=3)
    for i, j in np.argwhere(to_fix):
        cleaned[i, j] = np.nanmean(img[max(i - 1, 0) : i + 2, max(j - 1, 0) : j + 2])
    return cleaned

@ortk95
Copy link
Owner Author

ortk95 commented Jul 16, 2024

griddata clearly performs best at keeping original variation with no influence from NaNs, so think we should use that as the default method. Can keep RectBivariateSpline as an option for e.g. if smoothing is wanted.

image
image
image
image
image

ortk95 added a commit that referenced this issue Jul 17, 2024
Non-finite values are replaced with the average of neighbouring pixels before mapping, rather than 0. This should reduce artefacts when using spline interpolation.

#382
@ortk95
Copy link
Owner Author

ortk95 commented Jul 18, 2024

From futher testing, griddata doesn't seem as great:

  • It can become prohibitively slow for larger (~1000px) datasets, as it needs to construct a triangulation.
  • The results can be unstable and dependent on the system (see failing tests only on GitHub's macOS workers). It seems like this is probably again due to the triangulation, which doesn't necessarily have a unique solution, and can therefore be affected by floating point errors.

I think this probably therefore rules out griddata, as e.g. we don't want unstable mapping results to be interpreted as changes in the target etc.

Scipy's RegularGridInterpolator seems to perform really nicely (and quickly) when paired with our custom _replace_nans_with_interpolated_values, so this is probably the way to go.

image

image

ortk95 added a commit that referenced this issue Jul 18, 2024
`scipy.interpolate.griddata` was very slow, and could produce unstable results, so it seems much more sensible to stick with `RectBivariateSpline` with the newer more sophisticated NaN replacement.

#382 (comment)
@ortk95 ortk95 closed this as completed Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Related to the backend (coordinate conversion, SPICE etc.) polish Minor changes to improve quality
Projects
None yet
Development

No branches or pull requests

1 participant