Skip to content

Commit

Permalink
Merge pull request #46 from neuro-ml/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
vovaf709 authored Apr 24, 2024
2 parents bab650d + d9d38be commit c95488c
Show file tree
Hide file tree
Showing 17 changed files with 76 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# F401: unused imports in __init__.py-s
# I251: allow absolute imports in upper files
# B028: !r is not supported for python<3.8
ignore = W503,E203,B028
# W604: backticks in str-s are ok
ignore = W503,E203,B028,W604
per-file-ignores =
__init__.py:F401
tests/*:I251
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: fregante/setup-git-user@v1
- uses: actions/checkout@v4
- uses: fregante/setup-git-user@v2
- run: git fetch origin gh-pages --depth=1
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install
Expand Down
20 changes: 11 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.9

Expand All @@ -41,10 +41,10 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.10.0
run: python -m pip install cibuildwheel==2.17.0
- name: Install gcc for mac
if: matrix.os == 'macOS-11'
run: |
Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
env:
CIBW_ENVIRONMENT_MACOS: >
PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include"
CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-*
CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* cp310-* cp311-* cp312-*
CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<2.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi'
- uses: actions/upload-artifact@v3
with:
Expand All @@ -88,11 +88,13 @@ jobs:
needs: [ check_version ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v5
- name: Build
run: python setup.py sdist
run: |
pip install build
python -m build --sdist
- uses: actions/upload-artifact@v3
with:
path: dist/*.tar.gz
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/test_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.10.0
run: python -m pip install cibuildwheel==2.17.0
- name: Install gcc for mac
if: matrix.os == 'macOS-11'
run: |
Expand Down Expand Up @@ -52,6 +54,6 @@ jobs:
env:
CIBW_ENVIRONMENT_MACOS: >
PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include"
CIBW_BUILD: cp39-* cp36-*
CIBW_BUILD: cp39-* cp36-* cp312-*
CIBW_SKIP: "*musllinux* *manylinux_x86_64"
CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<2.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi'
13 changes: 8 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11']
python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -28,7 +28,8 @@ jobs:
if [ "$GITHUB_BASE_REF" = "master" ] && [ "$MATCH" != "" ]; then exit 1; fi
- name: Build the package
run: |
python setup.py sdist
pip install build
python -m build --sdist
- name: Install
run: |
Expand Down Expand Up @@ -73,7 +74,9 @@ jobs:
if: ${{ always() }}

- name: Upload coverage results
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
fail_ci_if_error: true
files: reports/coverage-${{ matrix.python-version }}.xml
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ y = zoom(x, 2, axis=[0, 1])
# without the need to compute the scale factor
z = zoom_to_shape(x, (4, 120, 67))
```
Works faster only for `ndim<=4, dtype=float32 or float64 (and bool-int16-32-64 if order == 0), output=None, order=0 or 1, mode='constant', grid_mode=False`
Works faster only for `ndim<=4, dtype=float32 or float64 (and bool-int16-32-64-uint8-16-32 if order == 0), output=None, order=0 or 1, mode='constant', grid_mode=False`
### Fast 1d linear interpolation

```python
Expand Down
2 changes: 1 addition & 1 deletion imops/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.8.6'
__version__ = '0.8.7'
8 changes: 7 additions & 1 deletion imops/crop.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .backend import BackendLike
from .numeric import _NUMERIC_DEFAULT_NUM_THREADS
from .pad import pad
from .utils import AxesLike, AxesParams, broadcast_axis, fill_by_indices
from .utils import AxesLike, AxesParams, assert_subdtype, broadcast_axis, fill_by_indices


def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: AxesParams = 0.5) -> np.ndarray:
Expand Down Expand Up @@ -35,6 +35,9 @@ def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio:
>>> cropped = crop_to_shape(x, [3, 4, 5]) # fail due to bigger resulting shape
"""
x = np.asarray(x)
shape = np.asarray(shape)
assert_subdtype(shape.dtype, np.integer, 'shape')

axis, shape, ratio = broadcast_axis(axis, x.ndim, shape, ratio)

old_shape, new_shape = np.array(x.shape), np.array(fill_by_indices(x.shape, shape, axis))
Expand Down Expand Up @@ -89,6 +92,9 @@ def crop_to_box(
>>> cropped = crop_to_box(x, np.array([[0], [5]]), axis=0, padding_values=0) # pad with 0-s to shape [5, 3, 4]
"""
x = np.asarray(x)
box = np.asarray(box)
assert_subdtype(box.dtype, np.integer, 'box')

start, stop = box
axis, start, stop = broadcast_axis(axis, x.ndim, start, stop)

Expand Down
4 changes: 2 additions & 2 deletions imops/morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ def wrapped(
raise ValueError('Input image and footprint number of dimensions must be the same.')

if not image.any():
warn(f'{op_name} is applied to the fully False mask (mask.any() == False).', stacklevel=3)
warn(f'{op_name} is applied to the fully False mask (mask.any() == False).', stacklevel=3) # noqa
output.fill(False)

return output

if image.all():
warn(f'{op_name} is applied to the fully True mask (mask.all() == True).', stacklevel=3)
warn(f'{op_name} is applied to the fully True mask (mask.all() == True).', stacklevel=3) # noqa
output.fill(True)

return output
Expand Down
2 changes: 2 additions & 0 deletions imops/src/_zoom.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ from libc.math cimport floor, sqrt
ctypedef cython.floating FLOAT
ctypedef fused NUM:
np.uint8_t
np.uint16_t
np.uint32_t
short
int
long long
Expand Down
5 changes: 5 additions & 0 deletions imops/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,8 @@ def check_len(*args) -> None:
lengths = list(map(len, args))
if any(length != lengths[0] for length in lengths):
raise ValueError(f'Arguments of equal length are required: {", ".join(map(str, lengths))}')


def assert_subdtype(dtype, ref_dtype, name):
if not np.issubdtype(dtype, ref_dtype):
raise ValueError(f'`{name}` must be of {ref_dtype.__name__} dtype, got {dtype}')
13 changes: 7 additions & 6 deletions imops/zoom.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def zoom(
"""
Rescale `x` according to `scale_factor` along the `axis`.
Uses a fast parallelizable implementation for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs,
Uses a fast parallelizable implementation for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0 inputs,
ndim <= 4 and order = 0 or 1.
Parameters
Expand Down Expand Up @@ -136,7 +136,7 @@ def zoom_to_shape(
"""
Rescale `x` to match `shape` along the `axis`.
Uses a fast parallelizable implementation for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs,
Uses a fast parallelizable implementation for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0 inputs,
ndim <= 4 and order = 0 or 1.
Parameters
Expand Down Expand Up @@ -198,7 +198,7 @@ def _zoom(
backend: BackendLike = None,
) -> np.ndarray:
"""
Faster parallelizable version of `scipy.ndimage.zoom` for fp32 / fp64 (and bool-int16-32-64 if order == 0) inputs.
Faster parallelizable version of `scipy.ndimage.zoom` for fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0
Works faster only for ndim <= 4. Shares interface with `scipy.ndimage.zoom`
except for
Expand Down Expand Up @@ -228,16 +228,17 @@ def _zoom(
or (
dtype not in (np.float32, np.float64)
if order == 1
else dtype not in (bool, np.float32, np.float64, np.int16, np.int32, np.int64)
else dtype
not in (bool, np.float32, np.float64, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32)
)
or ndim > 4
or output is not None
or mode != 'constant'
or grid_mode
):
warn(
'Fast zoom is only supported for ndim<=4, dtype=fp32 or fp64 (and bool-int16-32-64 if order == 0), '
"output=None, order=0 or 1, mode='constant', grid_mode=False. Falling back to scipy's implementation.",
'Fast zoom is only supported for ndim<=4, dtype=fp32-fp64 and bool-int16-32-64-uint8-16-32 if order == 0, '
"output=None, order=0 or 1 , mode='constant', grid_mode=False. Falling back to scipy's implementation.",
stacklevel=3,
)
return scipy_zoom(
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ classifiers = [
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
]

[options]
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
]

with open(root / 'requirements.txt', encoding='utf-8') as file:
Expand Down
16 changes: 15 additions & 1 deletion tests/test_crop.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,21 @@ def test_raises():
@seeded_by(SEED)
def test_crop_to_shape():
x = np.random.rand(3, 10, 10)
shape = 3, 4, 8
shape = (3, 4, 8)
assert crop_to_shape(x, shape).shape == shape
with pytest.raises(ValueError):
crop_to_shape(x, (3, 15, 10))


def test_crop_to_float_shape():
x = np.random.rand(3, 10, 10)
float_shape = (1.337, 3.1415, 2.7182)
with pytest.raises(ValueError):
crop_to_shape(x, float_shape)


def test_crop_to_float_box():
x = np.random.rand(3, 10, 10)
float_box = [[0, 1], [4, 4.5], [3.1, 9]]
with pytest.raises(ValueError):
crop_to_box(x, float_box)
3 changes: 3 additions & 0 deletions tests/test_pad.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ def test_restore_crop_invalid_box():
with pytest.raises(ValueError):
restore_crop(x, np.array([[0, 0, 0], [1, 1, 1]]), [4, 4, 4])

with pytest.raises(ValueError):
restore_crop(x, np.array([[0.5, 0.5, 0.5], [1.5, 1.5, 1.5]]), [4.5, 4.5, 4.5])


def test_pad_to_divisible():
x = np.zeros((4, 8, 12))
Expand Down
2 changes: 1 addition & 1 deletion tests/test_zoom.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def order(request):
return request.param


@pytest.fixture(params=[np.float32, np.float64, bool, np.int16, np.int32, np.int64])
@pytest.fixture(params=[np.float32, np.float64, bool, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32])
def dtype(request):
return request.param

Expand Down

0 comments on commit c95488c

Please sign in to comment.