Skip to content

Move ensure_spacing into skimage2#8067

Merged
lagru merged 8 commits intoscikit-image:mainfrom
lagru:sk2-ensure-spacing
Mar 13, 2026
Merged

Move ensure_spacing into skimage2#8067
lagru merged 8 commits intoscikit-image:mainfrom
lagru:sk2-ensure-spacing

Conversation

@lagru
Copy link
Copy Markdown
Member

@lagru lagru commented Feb 26, 2026

Description

When pitching this, I actually thought that ensure_spacing was a public function. Turns out it is not. That made porting it easy.

It's not used anywhere else besides peak_local_max. So _shared didn't seem like a good fit and I just moved it into the same module as peak_local_max.

Checklist

Release note

For maintainers and optionally contributors, please refer to the instructions on how to document this PR for the release notes.

...

@lagru lagru added 🔧 type: Maintenance Refactoring and maintenance of internals 🥾 Path to skimage2 A step towards the new "API 2.0" labels Feb 26, 2026
@coderabbitai coderabbitai bot removed the 🔧 type: Maintenance Refactoring and maintenance of internals label Feb 26, 2026
coderabbitai[bot]

This comment was marked as outdated.

@lagru lagru added the 🔧 type: Maintenance Refactoring and maintenance of internals label Feb 26, 2026
@scikit-image scikit-image deleted a comment from coderabbitai bot Feb 26, 2026
@coderabbitai coderabbitai bot removed the 🔧 type: Maintenance Refactoring and maintenance of internals label Feb 26, 2026
coderabbitai[bot]

This comment was marked as outdated.

@scikit-image scikit-image deleted a comment from coderabbitai bot Feb 26, 2026
@coderabbitai coderabbitai bot added the 🔧 type: Maintenance Refactoring and maintenance of internals label Feb 26, 2026
@coderabbitai

This comment was marked as outdated.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/skimage2/feature/_peaks.py (1)

117-119: Consider handling 1D coordinate input explicitly.

When coords is a 1D array (single point like [1, 2, 3]), np.atleast_2d converts it to shape (1, 3) which is correct. However, the initial assignment output = coords on line 117 means if len(coords) == 0 returns the original input type (could be a list []), but non-empty inputs return an ndarray. This inconsistency is minor but could surprise callers.

♻️ Optional: ensure consistent return type
-    output = coords
-    if len(coords):
+    if len(coords) == 0:
+        return np.zeros((0, 1), dtype=float)
+    else:
         coords = np.atleast_2d(coords)
tests/skimage2/feature/test_peaks.py (4)

19-35: Consider using a fixed random seed for reproducibility.

The test uses np.random.randn without setting a seed, which makes test results non-deterministic. If a test fails, it may be difficult to reproduce. Consider using np.random.default_rng(seed) for reproducible tests.

♻️ Proposed fix
 `@pytest.mark.parametrize`("p", [1, 2, np.inf])
 `@pytest.mark.parametrize`("size", [30, 50, None])
 def test_ensure_spacing_trivial(p, size):
+    rng = np.random.default_rng(42)
     # --- Empty input
     assert _ensure_spacing([], p_norm=p) == []

     # --- A unique point
-    coord = np.random.randn(1, 2)
+    coord = rng.standard_normal((1, 2))
     assert np.array_equal(coord, _ensure_spacing(coord, p_norm=p, min_split_size=size))

     # --- Verified spacing
-    coord = np.random.randn(100, 2)
+    coord = rng.standard_normal((100, 2))

48-60: Consider setting a random seed for reproducibility.

Same concern as test_ensure_spacing_trivial - using np.random.randn without a seed makes the test non-deterministic.

Also, minor grammar nit: Line 53 comment says "between the point" but should be "between the points" (plural).

♻️ Proposed fix
 `@pytest.mark.parametrize`("p", [1, 2, np.inf])
 `@pytest.mark.parametrize`("size", [50, 100, None])
 def test_ensure_spacing_batch_processing(p, size):
-    coord = np.random.randn(100, 2)
+    rng = np.random.default_rng(123)
+    coord = rng.standard_normal((100, 2))

-    # --- Consider the average distance between the point as spacing
+    # --- Consider the average distance between the points as spacing
     spacing = np.median(pdist(coord, metric=minkowski, p=p))

63-81: Timing-based test may still be flaky on resource-constrained CI.

While the relaxed assertion (dur1 < 1.33 * dur2) helps, timing-based tests remain inherently sensitive to system load. Consider either:

  1. Using pytest.mark.slow to optionally skip in CI
  2. Increasing the tolerance further if flakiness persists
  3. Using a fixed seed for np.random.randint for reproducibility
♻️ Optional: add slow marker and fixed seed
+@pytest.mark.slow
 def test_ensure_spacing_max_batch_size():
     """Small batches are slow, large batches -> large allocations -> also slow.

     https://github.com/scikit-image/scikit-image/pull/6035#discussion_r751518691
     """
-    coords = np.random.randint(low=0, high=1848, size=(40000, 2))
+    rng = np.random.default_rng(0)
+    coords = rng.integers(low=0, high=1848, size=(40000, 2))

84-93: Same recommendations: fixed seed and grammar fix.

Consider using a fixed random seed for reproducibility, and update the comment on line 89 to "between the points" (plural).

♻️ Proposed fix
 `@pytest.mark.parametrize`("p", [1, 2, np.inf])
 `@pytest.mark.parametrize`("size", [30, 50, None])
 def test_ensure_spacing_p_norm(p, size):
-    coord = np.random.randn(100, 2)
+    rng = np.random.default_rng(456)
+    coord = rng.standard_normal((100, 2))

-    # --- Consider the average distance between the point as spacing
+    # --- Consider the average distance between the points as spacing
     spacing = np.median(pdist(coord, metric=minkowski, p=p))

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea7afcb and 0952cdd.

📒 Files selected for processing (5)
  • src/skimage/_shared/coord.py
  • src/skimage/_shared/meson.build
  • src/skimage2/feature/_peaks.py
  • tests/skimage/_shared/test_coord.py
  • tests/skimage2/feature/test_peaks.py
💤 Files with no reviewable changes (3)
  • tests/skimage/_shared/test_coord.py
  • src/skimage/_shared/meson.build
  • src/skimage/_shared/coord.py

@coderabbitai coderabbitai bot removed the 🔧 type: Maintenance Refactoring and maintenance of internals label Feb 27, 2026
coderabbitai[bot]

This comment was marked as outdated.

@lagru lagru moved this to Doing in Work pitches Mar 12, 2026
@lagru lagru self-assigned this Mar 12, 2026
@lagru lagru moved this from Doing to Needs review in Work pitches Mar 12, 2026
@lagru lagru moved this from Review to Doing in Work pitches Mar 13, 2026
@lagru lagru merged commit 79ab331 into scikit-image:main Mar 13, 2026
24 checks passed
@github-project-automation github-project-automation bot moved this from Doing to Done in Work pitches Mar 13, 2026
@lagru lagru deleted the sk2-ensure-spacing branch March 13, 2026 17:22
@stefanv stefanv added this to the 0.27 milestone Mar 13, 2026
matthew-brett added a commit that referenced this pull request Apr 10, 2026
* origin/main: (27 commits)
  Move `_shared` to `_skimage2` (#8102)
  Port `pad_footprint` & `mirror_footprint` to `skimage2` (#8094)
  Add rescaling API to skimage2 (#8075)
  Move `skimage2` implementation into `_skimage2` (#8093)
  Undo (double) mirroring in `ski2.morphology.dilation` (#8060)
  Grammar (#8091)
  Move `ensure_spacing` into `skimage2` (#8067)
  Ensure that `skimage2` does not eagerly import `skimage` (#8087)
  Use lazy-loader 0.5 (#8080)
  MAINT: make ellipse fitting forward compatible  (#8054)
  Avoid deprecated assign to ndarray.shape (#8020)
  Avoid circular import in `feature/corner.py` (#8077)
  Turn off coderabbit auto-labeling & label checks (#8070)
  Fix GIL being re-enabled by C++ extensions (#8059)
  Fix conventions following docstub and misc. (#8055)
  Port grayscale morphology operators to skimage2 (#8046)
  Add revised `peak_local_max` to `skimage2` (#8039)
  Allow read-only arrays as input to remap (#7535)
  Add `prescale`  parameter to "blob functions" (#7858)
  Try to make coderabbit respect exisiting type labels (#8042)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🥾 Path to skimage2 A step towards the new "API 2.0"

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants