Skip to content

Refactor IDW interpolation: simplify logic and clarify API#877

Open
ecomodeller wants to merge 7 commits into
mainfrom
refactor/simplify-idw-interpolation
Open

Refactor IDW interpolation: simplify logic and clarify API#877
ecomodeller wants to merge 7 commits into
mainfrom
refactor/simplify-idw-interpolation

Conversation

@ecomodeller
Copy link
Copy Markdown
Member

@ecomodeller ecomodeller commented Dec 10, 2025

Summary

  • Simplified IDW interpolation function by removing unnecessary conditional logic
  • Clarified public vs private API boundaries
  • Updated documentation and notebooks to use self-contained examples instead of private functions

Why this matters

Documentation that imports private functions teaches users to depend on implementation details. When users copy examples from docs, those imports become de facto public API—making internal refactoring a breaking change. This undermines the purpose of private/public separation and makes version upgrades break user code.

Changes

Code simplification

  • Renamed get_idw_interpolant_get_idw_interpolant (make private)
  • Removed 1D/2D conversion logic (function now requires 2D input)
  • Cleaner normalization using keepdims=True
  • Added documentation explaining assumptions (distances must be sorted)

Testing

  • Removed direct unit test of private function
  • Behavior still validated through integration tests:
    • test_interp2d_same_points verifies exact match handling
    • Other tests verify full interpolation pipeline

Documentation

  • Updated scatter interpolation example with copy-pasteable simple_idw() function
  • Removed this section from Jupyter notebook with same approach
  • Removed reliance on private mikeio functions
  • Makes it clear users should implement their own solution for this use case

- Make get_idw_interpolant private (_get_idw_interpolant)
- Remove unnecessary 1D/2D conditional logic
- Require 2D input (callers use np.atleast_2d if needed)
- Add proper documentation with assumptions (sorted distances)
- Remove direct unit test (covered by integration tests)
- Update scatter interpolation examples with copy-pasteable implementation
- Remove reliance on private functions in documentation and notebooks

This follows Sandi Metz principles:
- Reduce conditional complexity
- Test public interfaces, not implementation details
- Clear public vs private API separation
Use np.zeros_like and np.ones_like instead of np.zeros/np.ones to preserve
input dtype (float32) throughout interpolation. DFS files use float32 to save
memory, and the previous implementation was converting to float64, doubling
memory usage during Dataset.interp_like operations.

Changes:
- _interpolation.py: np.zeros(distances.shape) → np.zeros_like(distances)
- _FM_geometry.py: np.ones(dists.shape) → np.ones_like(dists)
- Add tests to verify float32 dtype preservation
Copy link
Copy Markdown
Contributor

@ryan-kipawa ryan-kipawa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the overall principles of this PR. However, I suspect this is very common functionality, and since it's been in the documentation for so long, it could be argued it's already part of the public API despite having a leading underscore. How do you see that?

We could consider

  1. Support such functionality in the public API
  2. If we remove it, keep _get_idw_interpolate with a deprecation warning that it will be removed and is not part of the public API

@ecomodeller
Copy link
Copy Markdown
Member Author

I was made aware of yet another use case for interpolating scatter data onto a mesh to create a dfsu.
MIKE 21/3 FM has support for Depth correction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants