Skip to content

Commit

Permalink
[pre-commit.ci] auto fixes from pre-commit.com hooks
Browse files Browse the repository at this point in the history
for more information, see https://pre-commit.ci
  • Loading branch information
pre-commit-ci[bot] committed Aug 29, 2024
1 parent 50d58d2 commit 328ba16
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 57 deletions.
9 changes: 3 additions & 6 deletions src/squidpy/im/_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from squidpy._docs import d, inject_docs
from squidpy._utils import Signal, SigQueue, _get_n_cores, parallelize
from squidpy.gr._utils import _save_data
from squidpy.im._container import ImageContainer
from squidpy.im import _measurements
from squidpy.im._container import ImageContainer

__all__ = ["calculate_image_features", "quantify_morphology"]

Expand All @@ -30,9 +30,7 @@
[IntegerNDArrayType, FloatNDArrayType], Union[Union[int, float, list[Union[int, float]]]]
]

RegionPropsImageCallableType = Callable[
[IntegerNDArrayType, FloatNDArrayType], dict[str, Union[int, float]]
]
RegionPropsImageCallableType = Callable[[IntegerNDArrayType, FloatNDArrayType], dict[str, Union[int, float]]]


def circularity(regionmask: IntegerNDArrayType) -> float:
Expand Down Expand Up @@ -71,10 +69,9 @@ def _get_region_props(

image_extra_methods = [
_measurements.border_occupied_factor # <--- Add additional measurements here that calculate on the entire label image
] # type: list[RegionPropsImageCallableType]
] # type: list[RegionPropsImageCallableType]
image_extra_methods = {method.__name__: method for method in image_extra_methods}


# can't use regionprops_table because it only returns int
regions = regionprops(
label_image=label_element.values,
Expand Down
54 changes: 15 additions & 39 deletions src/squidpy/im/_measurements.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from __future__ import annotations

import numpy
import numpy as np
import scipy.ndimage
import skimage.morphology

def border_occupied_factor(
mask: numpy.ndarray,
*args,
**kwargs
) -> dict[int, float]:

def border_occupied_factor(mask: numpy.ndarray, *args, **kwargs) -> dict[int, float]:
"""
Calculates the percentage of border pixels that are in a 4-connected neighborhood of another label
Takes ~1.7s/megapixels to calculate
Expand Down Expand Up @@ -41,10 +40,7 @@ def border_occupied_factor(

for adjacent_index in adjacent_indices:
try:
adjacent_pixel = mask[
coordinates[0] + adjacent_index[0],
coordinates[1] + adjacent_index[1]
]
adjacent_pixel = mask[coordinates[0] + adjacent_index[0], coordinates[1] + adjacent_index[1]]
except IndexError:
# At image border, don't count image borders
continue
Expand All @@ -69,9 +65,11 @@ def border_occupied_factor(
return result


if __name__ == '__main__':
if __name__ == "__main__":
import time

from spatialdata.datasets import blobs

# label_image = np.array([
# [0, 0, 0, 0, 0, 0, 0, 0],
# [0, 1, 1, 1, 0, 0, 0, 0],
Expand Down Expand Up @@ -234,19 +232,11 @@ def granularity(
if subsample_size < 1:
new_shape = new_shape * subsample_size
if pixels.ndim == 2:
i, j = (
numpy.mgrid[0 : new_shape[0], 0 : new_shape[1]].astype(float)
/ subsample_size
)
i, j = numpy.mgrid[0 : new_shape[0], 0 : new_shape[1]].astype(float) / subsample_size
pixels = scipy.ndimage.map_coordinates(pixels, (i, j), order=1)
mask = scipy.ndimage.map_coordinates(mask.astype(float), (i, j)) > 0.9
else:
k, i, j = (
numpy.mgrid[
0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]
].astype(float)
/ subsample_size
)
k, i, j = numpy.mgrid[0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]].astype(float) / subsample_size
pixels = scipy.ndimage.map_coordinates(pixels, (k, i, j), order=1)
mask = scipy.ndimage.map_coordinates(mask.astype(float), (k, i, j)) > 0.9
else:
Expand All @@ -258,23 +248,13 @@ def granularity(
if image_sample_size < 1:
back_shape = new_shape * image_sample_size
if pixels.ndim == 2:
i, j = (
numpy.mgrid[0 : back_shape[0], 0 : back_shape[1]].astype(float)
/ image_sample_size
)
i, j = numpy.mgrid[0 : back_shape[0], 0 : back_shape[1]].astype(float) / image_sample_size
back_pixels = scipy.ndimage.map_coordinates(pixels, (i, j), order=1)
back_mask = scipy.ndimage.map_coordinates(mask.astype(float), (i, j)) > 0.9
else:
k, i, j = (
numpy.mgrid[
0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]
].astype(float)
/ subsample_size
)
k, i, j = numpy.mgrid[0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]].astype(float) / subsample_size
back_pixels = scipy.ndimage.map_coordinates(pixels, (k, i, j), order=1)
back_mask = (
scipy.ndimage.map_coordinates(mask.astype(float), (k, i, j)) > 0.9
)
back_mask = scipy.ndimage.map_coordinates(mask.astype(float), (k, i, j)) > 0.9
else:
back_pixels = pixels
back_mask = mask
Expand Down Expand Up @@ -302,9 +282,7 @@ def granularity(
j *= float(back_shape[1] - 1) / float(new_shape[1] - 1)
back_pixels = scipy.ndimage.map_coordinates(back_pixels, (i, j), order=1)
else:
k, i, j = numpy.mgrid[
0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]
].astype(float)
k, i, j = numpy.mgrid[0 : new_shape[0], 0 : new_shape[1], 0 : new_shape[2]].astype(float)
k *= float(back_shape[0] - 1) / float(new_shape[0] - 1)
i *= float(back_shape[1] - 1) / float(new_shape[1] - 1)
j *= float(back_shape[2] - 1) / float(new_shape[2] - 1)
Expand Down Expand Up @@ -369,9 +347,7 @@ def granularity(
j *= float(new_shape[1] - 1) / float(orig_shape[1] - 1)
rec = scipy.ndimage.map_coordinates(rec, (i, j), order=1)
else:
k, i, j = numpy.mgrid[
0 : orig_shape[0], 0 : orig_shape[1], 0 : orig_shape[2]
].astype(float)
k, i, j = numpy.mgrid[0 : orig_shape[0], 0 : orig_shape[1], 0 : orig_shape[2]].astype(float)
k *= float(new_shape[0] - 1) / float(orig_shape[0] - 1)
i *= float(new_shape[1] - 1) / float(orig_shape[1] - 1)
j *= float(new_shape[2] - 1) / float(orig_shape[2] - 1)
Expand Down
27 changes: 15 additions & 12 deletions tests/image/test_morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import pandas as pd
import pytest
import skimage.measure
import spatialdata as sd
import squidpy as sq
from spatialdata import SpatialData
from spatialdata.datasets import blobs, raccoon
import spatialdata as sd

# noinspection PyProtectedMember
from squidpy.im._feature import _get_region_props

# noinspection PyProtectedMember
from squidpy.im._measurements import border_occupied_factor

Expand Down Expand Up @@ -104,16 +105,18 @@ def test_performance(self, sdata_mibitof):

class TestMeasurements:
def test_border_occupied_factor(self):
label_image = np.array([
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 2, 2, 2, 0],
[0, 1, 1, 1, 2, 2, 2, 0],
[0, 0, 3, 3, 2, 2, 2, 0],
[0, 0, 3, 3, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
])

expected = {1: 3/8, 2: 3/8, 3: 2/4}
label_image = np.array(
[
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 2, 2, 2, 0],
[0, 1, 1, 1, 2, 2, 2, 0],
[0, 0, 3, 3, 2, 2, 2, 0],
[0, 0, 3, 3, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
]
)

expected = {1: 3 / 8, 2: 3 / 8, 3: 2 / 4}
actual = border_occupied_factor(label_image)
assert actual == expected

0 comments on commit 328ba16

Please sign in to comment.