Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: trigger building of updated binaries; deprecate python 3.8 #105

Merged
merged 5 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build-python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: [3.8, 3.9, '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Lint with flake8
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/github-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ on: workflow_dispatch
# - published

env:
CIBW_SKIP: cp27-* pp27-* pp37-* pp38-* pp39-* pp310-* cp35-* cp36-* cp37-* cp*-win32 cp*-manylinux_i686 cp*-musl* cp312-* # skip 3.12 for now until numpy releases
CIBW_SKIP: cp27-* pp27-* pp37-* pp38-* pp39-* pp310-* cp35-* cp36-* cp37-* cp38-* cp*-win32 cp*-manylinux_i686 cp*-musl*

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-latest, macos-latest]
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.8'
python-version: '3.12'

- name: Install cibuildwheel
run: |
Expand All @@ -37,7 +37,7 @@ jobs:

- name: Enable Developer Command Prompt
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1.12.0
uses: ilammy/msvc-dev-cmd@v1

- name: Build wheels
run: |
Expand All @@ -51,12 +51,12 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.8'
python-version: '3.12'

- name: Install dependencies
run: |
Expand All @@ -79,7 +79,7 @@ jobs:
id-token: write
if: github.event_name == 'workflow_dispatch'
steps:
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v4.1.7
with:
name: artifact
path: dist
Expand Down
2 changes: 2 additions & 0 deletions INSTALLATION.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
WARNING: this may contain outdated information.

Windows 10 Installation
=======================

Expand Down
50 changes: 33 additions & 17 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,44 +1,60 @@
project(
'pygrappa',
'c', 'cpp',
version: '0.26.2',
license: '',
meson_version: '>= 0.64.0',
'c', 'cpp', 'cython',
version: '0.26.3',
license: 'MIT',
meson_version: '>= 1.5.0',
default_options: [
'buildtype=debugoptimized',
'buildtype=release',
'b_ndebug=if-release',
'c_std=c99',
'cpp_std=c++14',
],
)

cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
cython = find_program('cython')
cy = meson.get_compiler('cython')
cython = find_program(cy.cmd_array()[0])
if not cy.version().version_compare('>=3.0.8')
error('SciPy requires Cython >= 3.0.8')
endif

is_windows = host_machine.system() == 'windows'

# https://mesonbuild.com/Python-module.html
py_mod = import('python')
py3 = py_mod.find_installation(pure: false)
py3 = import('python').find_installation(pure: false)
py3_dep = py3.dependency()

# NumPy include directory - needed in all submodules
incdir_numpy = run_command(py3,
[
'-c',
'import os; os.chdir(".."); import numpy; print(numpy.get_include())'
],
check: true
[
'-c',
'''import os
#os.chdir(os.path.join("..", "tools"))
import numpy as np
try:
incdir = os.path.relpath(np.get_include())
except Exception:
incdir = np.get_include()
print(incdir)
'''
],
check: true
).stdout().strip()
message(incdir_numpy)

inc_np = include_directories(incdir_numpy)
numpy_nodepr_api = '-DNPY_NO_DEPRECATED_API=NPY_1_9_API_VERSION'

cython_args = ['-3', '--fast-fail', '--output-file', '@OUTPUT@', '--include-dir', '@BUILD_ROOT@', '@INPUT@']
if cy.version().version_compare('>=3.1.0')
cython_args += ['-Xfreethreading_compatible=True']
endif
cython_cplus_args = ['--cplus'] + cython_args

cython_cli = find_program('pygrappa/utils/cythoner.py')

cython_gen_cpp = generator(cython_cli,
arguments : ['@INPUT@', '@OUTPUT@', '--cplus'],
cython_gen_cpp = generator(cython,
arguments : cython_cplus_args,
output : '@[email protected]',
depends : [])

Expand Down
2 changes: 1 addition & 1 deletion pygrappa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Bring functions up to the correct level.'''
"""Bring functions up to the correct level."""

# GRAPPA
from .mdgrappa import mdgrappa # NOQA
Expand Down
24 changes: 10 additions & 14 deletions pygrappa/cgsense.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Python implementation of iterative and CG-SENSE.'''
"""Python implementation of iterative and CG-SENSE."""

from time import time
import logging
Expand All @@ -8,25 +8,25 @@


def _fft(x0, axes=None):
'''Utility Forward FFT function.
'''
"""Utility Forward FFT function.
"""
if axes is None:
axes = np.arange(x0.ndim-1)
return np.fft.fftshift(np.fft.fftn(np.fft.ifftshift(
x0, axes=axes), axes=axes), axes=axes)


def _ifft(x0, axes=None):
'''Utility Inverse FFT function.
'''
"""Utility Inverse FFT function.
"""
if axes is None:
axes = np.arange(x0.ndim-1)
return np.fft.ifftshift(np.fft.ifftn(np.fft.fftshift(
x0, axes=axes), axes=axes), axes=axes)


def cgsense(kspace, sens, coil_axis=-1):
'''Conjugate Gradient SENSE for arbitrary Cartesian acquisitions.
def cgsense(kspace, sens, coil_axis: int = -1):
"""Conjugate Gradient SENSE for arbitrary Cartesian acquisitions.

Parameters
----------
Expand Down Expand Up @@ -65,7 +65,7 @@ def cgsense(kspace, sens, coil_axis=-1):
Resonance in Medicine: An Official Journal of the
International Society for Magnetic Resonance in Medicine
46.4 (2001): 638-651.
'''
"""
# Make sure coils are in the back
kspace = np.moveaxis(kspace, coil_axis, -1)

Expand Down Expand Up @@ -98,13 +98,13 @@ def cgsense(kspace, sens, coil_axis=-1):
# => E : (sx*sy, sx*sy)

def _AH(x0):
'''kspace -> imspace'''
"""kspace -> imspace"""
x0 = np.reshape(x0, kspace.shape)
res = np.sum(sens.conj()*_ifft(x0), axis=-1)
return np.reshape(res, (-1,))

def _A(x0):
'''imspace -> kspace'''
"""imspace -> kspace"""
res = np.reshape(x0, dims)
res = _fft(res[..., None]*sens)*mask[..., None]
return np.reshape(res, (-1,))
Expand All @@ -122,7 +122,3 @@ def E(x0):
logging.info('CG-SENSE took %g sec', (time() - t0))

return np.reshape(x, dims).astype(tipe)


if __name__ == '__main__':
pass
8 changes: 4 additions & 4 deletions pygrappa/coils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'''Coil estimation strategies.'''
"""Coil estimation strategies."""

import numpy as np
from scipy.linalg import eigh
from skimage.filters import threshold_li


def walsh(imspace, mask=None, coil_axis=-1):
'''Stochastic matched filter coil combine.
def walsh(imspace, mask=None, coil_axis: int = -1):
"""Stochastic matched filter coil combine.

Parameters
----------
Expand All @@ -31,7 +31,7 @@ def walsh(imspace, mask=None, coil_axis=-1):
imagery." Magnetic Resonance in Medicine: An Official
Journal of the International Society for Magnetic
Resonance in Medicine 43.5 (2000): 682-690.
'''
"""
imspace = np.moveaxis(imspace, coil_axis, -1)
ncoils = imspace.shape[-1]
ns = np.prod(imspace.shape[:-1])
Expand Down
3 changes: 2 additions & 1 deletion pygrappa/examples/basic_cgrappa.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'''Basic CGRAPPA example using Shepp-Logan phantom.'''
"""Basic CGRAPPA example using Shepp-Logan phantom."""

import numpy as np
import matplotlib.pyplot as plt
from phantominator import shepp_logan

from pygrappa import cgrappa


if __name__ == '__main__':

# Generate fake sensitivity maps: mps
Expand Down
3 changes: 2 additions & 1 deletion pygrappa/examples/basic_cgsense.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Basic usage of CG-SENSE implementation.'''
"""Basic usage of CG-SENSE implementation."""

import numpy as np
import matplotlib.pyplot as plt
Expand All @@ -8,6 +8,7 @@
from pygrappa import cgsense
from pygrappa.utils import gaussian_csm


if __name__ == '__main__':

N, nc = 128, 4
Expand Down
3 changes: 2 additions & 1 deletion pygrappa/examples/basic_gfactor.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'''Simple g-factor maps.'''
"""Simple g-factor maps."""

import numpy as np
import matplotlib.pyplot as plt

from pygrappa import gfactor, gfactor_single_coil_R2
from pygrappa.utils import gaussian_csm


if __name__ == '__main__':

# Make circle
Expand Down
3 changes: 2 additions & 1 deletion pygrappa/examples/basic_grappa.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'''Basic GRAPPA example using Shepp-Logan phantom.'''
"""Basic GRAPPA example using Shepp-Logan phantom."""

import numpy as np
import matplotlib.pyplot as plt
from phantominator import shepp_logan

from pygrappa import grappa


if __name__ == '__main__':

# Generate fake sensitivity maps: mps
Expand Down
8 changes: 4 additions & 4 deletions pygrappa/examples/basic_grappaop.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Basic usage of the GRAPPA operator.'''
"""Basic usage of the GRAPPA operator."""

import numpy as np
import matplotlib.pyplot as plt
Expand All @@ -8,7 +8,7 @@
except ImportError:
from skimage.measure import compare_nrmse

from pygrappa import cgrappa, grappaop
from pygrappa import mdgrappa, grappaop
from pygrappa.utils import gaussian_csm


Expand Down Expand Up @@ -51,7 +51,7 @@ def normalize(x0):
kspace4x1[3::4, ...] = 0

# Compare to regular ol' GRAPPA
grecon4x1 = cgrappa(kspace4x1, calib, kernel_size=(4, 5))
grecon4x1 = mdgrappa(kspace4x1, calib, kernel_size=(4, 5))

# Get a GRAPPA operator and do the recon
Gx, Gy = grappaop(calib)
Expand All @@ -65,7 +65,7 @@ def normalize(x0):
kspace2x2 = kspace.copy()
kspace2x2[1::2, ...] = 0
kspace2x2[:, 1::2, :] = 0
grecon2x2 = cgrappa(kspace2x2, calib, kernel_size=(4, 5))
grecon2x2 = mdgrappa(kspace2x2, calib, kernel_size=(4, 5))
recon2x2 = kspace2x2.copy()
recon2x2[1::2, ...] = recon2x2[::2, ...] @ Gx
recon2x2[:, 1::2, :] = recon2x2[:, ::2, :] @ Gy
Expand Down
4 changes: 2 additions & 2 deletions pygrappa/examples/basic_gridding.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Demonstrate how to grid non-Cartesian data.
"""Demonstrate how to grid non-Cartesian data.

Notes
-----
Expand All @@ -22,7 +22,7 @@
NFFT 3---a software library for various nonequispaced fast
Fourier transforms." ACM Transactions on Mathematical Software
(TOMS) 36.4 (2009): 19.
'''
"""

from time import time

Expand Down
3 changes: 2 additions & 1 deletion pygrappa/examples/basic_hpgrappa.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Basic hp-GRAPPA usage.'''
"""Basic hp-GRAPPA usage."""

import numpy as np
from mpl_toolkits.mplot3d import Axes3D # pylint: disable=W0611 # NOQA
Expand All @@ -8,6 +8,7 @@
from pygrappa import hpgrappa, mdgrappa
from pygrappa.utils import gaussian_csm


if __name__ == '__main__':

# The much abused Shepp-Logan phantom
Expand Down
Loading
Loading