Skip to content

Commit

Permalink
Merge pull request #59 from neuro-ml/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
vovaf709 authored Aug 4, 2024
2 parents d15ec60 + 8c43e58 commit b305c36
Show file tree
Hide file tree
Showing 31 changed files with 348 additions and 111 deletions.
12 changes: 7 additions & 5 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
[flake8]
# W503: line break before binary operator is actually considered best-practice
# E203: spaces around complex variables in slices are pep-right
# F401: unused imports in __init__.py-s
# F401: unused imports in __init__.py-s and compat.py
# I251: allow absolute imports in upper files
# B028: !r is not supported for python<3.8
# W604: backticks in str-s are ok
ignore = W503,E203,B028,W604
# S101: asserts are ok for now
# S102: exec in build scripts is ok
ignore = W503,E203,B028,W604,S101
per-file-ignores =
__init__.py:F401
tests/*:I251
benchmarks/*:I251
setup.py,_build_utils.py:S102
__init__.py,compat.py:F401
tests/*,benchmarks/*:I251
max-line-length = 120
banned-modules =
imops.* = Use relative imports
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
needs: [ check_version ]
strategy:
matrix:
os: [ ubuntu-22.04, windows-2019, macOS-11 ]
os: [ ubuntu-22.04, windows-2019, macOS-12 ]

name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand All @@ -48,7 +48,7 @@ jobs:
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.17.0
- name: Install gcc for mac
if: matrix.os == 'macOS-11'
if: matrix.os == 'macOS-12'
run: |
brew install llvm libomp
echo $PATH
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
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: 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'
CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<3.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi'
- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
build_wheels:
strategy:
matrix:
os: [ubuntu-22.04, windows-2019, macOS-11 ]
os: [ubuntu-22.04, windows-2019, macOS-12 ]

name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand All @@ -22,7 +22,7 @@ jobs:
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.17.0
- name: Install gcc for mac
if: matrix.os == 'macOS-11'
if: matrix.os == 'macOS-12'
run: |
brew install llvm libomp
echo $PATH
Expand Down Expand Up @@ -56,4 +56,4 @@ jobs:
PATH="/usr/local/opt/llvm/bin:$PATH" LDFLAGS="-L/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include"
CIBW_BUILD: cp39-* 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'
CIBW_BEFORE_BUILD_LINUX: 'if [ $(python -c "import sys; print(sys.version_info[1])") -ge 9 ]; then python -m pip install "numpy<3.0.0" --config-settings=setup-args="-Dallow-noblas=true"; fi'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__pycache__/
.pytest_cache/
build/
imops/src/*.cpp
imops/src/*.c
imops/src/*.so
imops/src/_fast*.pyx
Expand Down
13 changes: 12 additions & 1 deletion _build_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,16 @@ def get_ext_modules():
extra_compile_args=args + cpp_args,
extra_link_args=args + cpp_args,
language='c++',
)
),
Extension(
f'{name}.src._utils',
[f'{name}/src/_utils.pyx'],
language='c++',
include_dirs=[LazyImport('numpy')],
extra_compile_args=args + cpp_args,
extra_link_args=args + cpp_args,
define_macros=[('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION')],
),
]
for module in modules:
libraries = []
Expand All @@ -93,6 +102,7 @@ def get_ext_modules():
if not on_windows:
libraries.append('m')

# TODO: mb throw `ffast-math` away?
# FIXME: import of `ffast-math` compiled modules changes global FPU state, so now `fast=True` will just
# fallback to standard `-O2` compiled versions until https://github.com/neuro-ml/imops/issues/37 is resolved
# for prefix, additional_args in zip(['', 'fast_'], [[], ['-ffast-math']])
Expand All @@ -101,6 +111,7 @@ def get_ext_modules():
Extension(
f'{name}.src._{prefix}{module}',
[f'{name}/src/_{prefix}{module}.pyx'],
language='c',
include_dirs=include_dirs,
library_dirs=library_dirs,
libraries=libraries,
Expand Down
6 changes: 3 additions & 3 deletions asv.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
"project": "imops",
"project_url": "https://github.com/neuro-ml/imops",
"repo": ".",
"branches": ["master", "dev"],
"branches": ["dev"],
"dvcs": "git",
"environment_type": "conda",
"show_commit_url": "https://github.com/neuro-ml/imops/commit",
"pythons": ["3.10"],
"pythons": ["3.12.3"],
"conda_channels": ["defaults", "conda-forge"],
"matrix": {
"req": {
"numpy": [],
"Cython": ["0.29.36"],
"Cython": ["3.0.10"],
"scipy": [],
"scikit-image": [],
"numba": [],
Expand Down
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ pip install imops[numba] # additionally install Numba backend
::: imops.radon.radon

::: imops.radon.inverse_radon

::: imops.utils.isin
2 changes: 1 addition & 1 deletion imops/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.8.8'
__version__ = '0.9.0'
14 changes: 14 additions & 0 deletions imops/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
try:
from numpy.lib.array_utils import normalize_axis_tuple
except ModuleNotFoundError:
from numpy.core.numeric import normalize_axis_tuple

try:
from numpy.exceptions import VisibleDeprecationWarning
except ModuleNotFoundError:
from numpy import VisibleDeprecationWarning

try:
from scipy.ndimage._morphology import _ni_support
except ImportError:
from scipy.ndimage.morphology import _ni_support
5 changes: 3 additions & 2 deletions imops/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
}


# TODO: Make it work and test on immutable arrays as soon as `cc3d` package is fixed
def label(
label_image: np.ndarray,
background: int = None,
Expand Down Expand Up @@ -213,8 +214,8 @@ def center_of_mass(

src_center_of_mass = _fast_labeled_center_of_mass if backend.fast else _labeled_center_of_mass

if array.dtype != 'float64':
array = array.astype(float)
if array.dtype not in ('float32', 'float64'):
array = array.astype(np.float32)

n_dummy = 3 - ndim
if n_dummy:
Expand Down
8 changes: 1 addition & 7 deletions imops/morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@
from edt import edt
from scipy.ndimage import distance_transform_edt as scipy_distance_transform_edt, generate_binary_structure
from scipy.ndimage._nd_image import euclidean_feature_transform


try:
from scipy.ndimage._morphology import _ni_support
except ImportError:
from scipy.ndimage.morphology import _ni_support

from skimage.morphology import (
binary_closing as scipy_binary_closing,
binary_dilation as scipy_binary_dilation,
Expand All @@ -21,6 +14,7 @@

from .backend import BackendLike, Cython, Scipy, resolve_backend
from .box import add_margin, box_to_shape, mask_to_box, shape_to_box
from .compat import _ni_support
from .crop import crop_to_box
from .pad import restore_crop
from .src._fast_morphology import (
Expand Down
3 changes: 2 additions & 1 deletion imops/radon.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from scipy.fftpack import fft, ifft

from .backend import BackendLike, resolve_backend
from .compat import normalize_axis_tuple
from .numeric import copy
from .src._backprojection import backprojection3d
from .src._fast_backprojection import backprojection3d as fast_backprojection3d
Expand Down Expand Up @@ -208,7 +209,7 @@ def normalize_axes(x: np.ndarray, axes):
raise ValueError('For arrays of higher dimensionality the `axis` arguments is required')
axes = [0, 1]

axes = np.core.numeric.normalize_axis_tuple(axes, x.ndim, 'axes')
axes = normalize_axis_tuple(axes, x.ndim, 'axes')
x = np.moveaxis(x, axes, (-2, -1))
extra = x.shape[:-2]
x = x.reshape(-1, *x.shape[-2:])
Expand Down
12 changes: 6 additions & 6 deletions imops/src/_backprojection.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ctypedef np.uint8_t uint8

@cython.boundscheck(False)
@cython.wraparound(False)
cdef inline FLOAT interpolate(FLOAT x, FLOAT* ys, FLOAT radius, FLOAT right_limit) nogil:
cdef inline FLOAT interpolate(FLOAT x, const FLOAT* ys, FLOAT radius, FLOAT right_limit) noexcept nogil:
cdef Py_ssize_t idx
cdef FLOAT val, value

Expand All @@ -40,8 +40,8 @@ cdef inline FLOAT interpolate(FLOAT x, FLOAT* ys, FLOAT radius, FLOAT right_limi

@cython.boundscheck(False)
@cython.wraparound(False)
cdef FLOAT accumulate(FLOAT x, FLOAT y, FLOAT* sinuses, FLOAT* cosinuses, FLOAT* ys,
Py_ssize_t size, Py_ssize_t image_size, FLOAT radius, FLOAT right_limit) nogil:
cdef FLOAT accumulate(FLOAT x, FLOAT y, const FLOAT* sinuses, const FLOAT* cosinuses, const FLOAT* ys,
Py_ssize_t size, Py_ssize_t image_size, FLOAT radius, FLOAT right_limit) noexcept nogil:
cdef FLOAT accumulator = 0
cdef Py_ssize_t k

Expand All @@ -52,9 +52,9 @@ cdef FLOAT accumulate(FLOAT x, FLOAT y, FLOAT* sinuses, FLOAT* cosinuses, FLOAT*

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef FLOAT[:, :, :] backprojection3d(FLOAT[:, :, :] sinogram, FLOAT[:] theta, FLOAT[:] xs,
uint8[:, :] inside_circle, FLOAT fill_value, int image_size, int output_size,
Py_ssize_t num_threads):
cpdef FLOAT[:, :, :] backprojection3d(const FLOAT[:, :, :] sinogram, const FLOAT[:] theta, const FLOAT[:] xs,
const uint8[:, :] inside_circle, FLOAT fill_value, int image_size,
int output_size, Py_ssize_t num_threads):
cdef FLOAT[:, :, :] result = np.zeros_like(sinogram, shape=(len(sinogram), output_size, output_size))
cdef Py_ssize_t slc, i, j, n_angles = len(theta), n_slices = len(sinogram)
cdef FLOAT min_val = image_size // 2, right_lim = image_size - 1
Expand Down
26 changes: 15 additions & 11 deletions imops/src/_measure.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

import numpy as np

cimport cython
cimport numpy as np

from cython.parallel import prange


ctypedef cython.floating FLOAT

ctypedef fused LABEL:
signed char
short
Expand All @@ -23,7 +26,7 @@ ctypedef fused LABEL:
unsigned long long


cdef inline Py_ssize_t _find(LABEL num, LABEL[:] nums) nogil:
cdef inline Py_ssize_t _find(LABEL num, const LABEL[:] nums) noexcept nogil:
cdef Py_ssize_t i

for i in range(len(nums)):
Expand All @@ -33,15 +36,16 @@ cdef inline Py_ssize_t _find(LABEL num, LABEL[:] nums) nogil:
return -1


def _labeled_center_of_mass(double[:, :, :] nums, LABEL[:, :, :] labels, LABEL[:] index) -> np.ndarray:
cdef double[:, :, ::1] contiguous_nums = np.ascontiguousarray(nums)
cdef LABEL[:, :, ::1] contiguous_labels = np.ascontiguousarray(labels)
cdef LABEL[:] contiguous_index = np.ascontiguousarray(index)
def _labeled_center_of_mass(const FLOAT[:, :, :] nums, const LABEL[:, :, :] labels,
const LABEL[:] index) -> np.ndarray:
cdef const FLOAT[:, :, ::1] contiguous_nums = np.ascontiguousarray(nums)
cdef const LABEL[:, :, ::1] contiguous_labels = np.ascontiguousarray(labels)
cdef const LABEL[:] contiguous_index = np.ascontiguousarray(index)

cdef Py_ssize_t index_len = len(index)

cdef double[:, ::1] output = np.zeros((index_len, 3))
cdef double[:] normalizers = np.zeros(index_len)
cdef FLOAT[:, ::1] output = np.zeros_like(nums, shape=(index_len, 3))
cdef FLOAT[:] normalizers = np.zeros_like(nums, shape=(index_len,))

cdef Py_ssize_t rows = nums.shape[0], cols = nums.shape[1], dims = nums.shape[2]
cdef Py_ssize_t i, j, k, pos
Expand All @@ -66,11 +70,11 @@ def _labeled_center_of_mass(double[:, :, :] nums, LABEL[:, :, :] labels, LABEL[:
return np.asarray(output)


def _center_of_mass(double[:, :, :] nums, Py_ssize_t num_threads) -> np.ndarray:
cdef double[:, :, ::1] contiguous_nums = np.ascontiguousarray(nums)
def _center_of_mass(const FLOAT[:, :, :] nums, Py_ssize_t num_threads) -> np.ndarray:
cdef const FLOAT[:, :, ::1] contiguous_nums = np.ascontiguousarray(nums)

cdef double output_x = 0, output_y = 0, output_z = 0
cdef double normalizer = 0
cdef FLOAT output_x = 0, output_y = 0, output_z = 0
cdef FLOAT normalizer = 0

cdef Py_ssize_t rows = nums.shape[0], cols = nums.shape[1], dims = nums.shape[2]
cdef Py_ssize_t i, j, k
Expand Down
Loading

0 comments on commit b305c36

Please sign in to comment.