diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 64dfa54961..f2d5472e52 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -4,7 +4,7 @@ on: pull_request: types: [opened, synchronize, reopened, ready_for_review] push: - + jobs: check: @@ -49,6 +49,8 @@ jobs: - name: Install dependencies run: | pip install tox tox-gh-actions + # Optional packages + pip install pyfftw # `test_fft` runs for pyfftw when installed - name: Test with tox run: tox --skip-missing-interpreters false -e py${{ matrix.python-version }}-${{ matrix.pyenv }} - name: Upload Coverage to CodeCov @@ -215,3 +217,32 @@ jobs: name: sphinx-docs path: docs/build retention-days: 7 + + osx_arm: + defaults: + run: + shell: bash -l {0} + needs: check + runs-on: macos-14 + # Run on every code push, but only on review ready PRs + if: ${{ github.event_name == 'push' || github.event.pull_request.draft == false }} + steps: + - uses: actions/checkout@v4 + - name: Set up Conda + uses: conda-incubator/setup-miniconda@v2.3.0 + with: + miniconda-version: "latest" + auto-update-conda: true + python-version: '3.8' + activate-environment: aspire + environment-file: environment-accelerate.yml + auto-activate-base: false + - name: Complete Install and Log Environment ${{ matrix.os }} Python ${{ matrix.python-version }} + run: | + conda info + conda list + conda install pyshtools # debug depends issues + pip install -e ".[dev]" # install aspire + pip freeze + - name: Test + run: python -m pytest -n3 --durations=50 diff --git a/environment-accelerate.yml b/environment-accelerate.yml index 1d01c51d75..38dd49813d 100644 --- a/environment-accelerate.yml +++ b/environment-accelerate.yml @@ -5,14 +5,11 @@ channels: - defaults dependencies: - - fftw - # There is a potential pyFFTW bug, pin to 0.12 - # https://github.com/pyFFTW/pyFFTW/issues/294 - - pyfftw=0.12 - pip - python=3.8 - - numpy=1.23.5 - - scipy=1.9.3 + - pyshtools + - numpy=1.24.1 + - scipy=1.10.1 - scikit-learn - scikit-image - libblas=*=*accelerate diff --git a/environment-default.yml b/environment-default.yml index f092f4c3ca..f5ff7ae893 100644 --- a/environment-default.yml +++ b/environment-default.yml @@ -5,10 +5,6 @@ channels: - defaults dependencies: - - fftw - # There is a potential pyFFTW bug, pin to 0.12 - # https://github.com/pyFFTW/pyFFTW/issues/294 - - pyfftw=0.12 - pip - python=3.8 - numpy=1.23.5 diff --git a/environment-intel.yml b/environment-intel.yml index fa3beba787..83250caeaf 100644 --- a/environment-intel.yml +++ b/environment-intel.yml @@ -5,10 +5,6 @@ channels: - defaults dependencies: - - fftw - # There is a potential pyFFTW bug, pin to 0.12 - # https://github.com/pyFFTW/pyFFTW/issues/294 - - pyfftw=0.12 - pip - python=3.8 - numpy=1.23.5 diff --git a/environment-openblas.yml b/environment-openblas.yml index bc4d61b46d..ee2f665e6e 100644 --- a/environment-openblas.yml +++ b/environment-openblas.yml @@ -5,10 +5,6 @@ channels: - defaults dependencies: - - fftw - # There is a potential pyFFTW bug, pin to 0.12 - # https://github.com/pyFFTW/pyFFTW/issues/294 - - pyfftw=0.12 - pip - python=3.8 - numpy=1.23.5 diff --git a/pyproject.toml b/pyproject.toml index 0e28ebad97..f48de5f41b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,12 +39,11 @@ dependencies = [ "joblib", "matplotlib >= 3.2.0", "mrcfile", - "numpy>=1.21.5", + "numpy>=1.21.5, <2.0.0", "packaging", "pooch>=1.7.0", "pillow", "psutil", - "pyfftw", "pymanopt", "pyshtools<=4.10.4", # 4.11.7 might have a packaging bug "PyWavelets", diff --git a/src/aspire/config_default.yaml b/src/aspire/config_default.yaml index 3d135a64f6..2a7725b1a2 100644 --- a/src/aspire/config_default.yaml +++ b/src/aspire/config_default.yaml @@ -3,7 +3,7 @@ common: # numeric module to use - one of numpy/cupy numeric: numpy # fft backend to use - one of pyfftw/scipy/cupy/mkl - fft: pyfftw + fft: scipy # Set cache directory for ASPIRE example data. # By default the cache location will be set by pooch.os_cache(), diff --git a/src/aspire/numeric/pyfftw_fft.py b/src/aspire/numeric/pyfftw_fft.py index c1b183108a..9cfdd45210 100644 --- a/src/aspire/numeric/pyfftw_fft.py +++ b/src/aspire/numeric/pyfftw_fft.py @@ -1,7 +1,11 @@ import os from threading import Lock -import pyfftw +try: + import pyfftw +except ModuleNotFoundError: + raise ModuleNotFoundError("Install `pyfftw` to use as a backend.") + import pyfftw.interfaces.scipy_fftpack as scipy_fft from aspire.numeric.base_fft import FFT diff --git a/tests/test_fft.py b/tests/test_fft.py index 45f22b1fd1..5a88929402 100644 --- a/tests/test_fft.py +++ b/tests/test_fft.py @@ -1,3 +1,4 @@ +import logging from unittest import TestCase import numpy as np @@ -5,8 +6,17 @@ from aspire import config from aspire.numeric import fft_object, numeric_object +logger = logging.getLogger(__name__) # Create test option combinations between numerical modules and FFT libs -test_backends = [("numpy", "scipy"), ("numpy", "pyfftw")] +test_backends = [("numpy", "scipy")] + +try: + import pyfftw # noqa: F401 + + test_backends.append(("numpy", "pyfftw")) +except ModuleNotFoundError: + logger.info("`pyfftw` module is not installed, skipping `pyfftw` FFT backend.") + # Create Cupy fft backend if Cupy module is enabled and lib exits. if config["common"]["numeric"].as_str() == "cupy": diff --git a/tests/test_synthetic_volume.py b/tests/test_synthetic_volume.py index 8860b3532d..ddcdcbcab5 100644 --- a/tests/test_synthetic_volume.py +++ b/tests/test_synthetic_volume.py @@ -136,4 +136,4 @@ def test_volume_symmetry(vol_fixture): corr = np.dot(rot_vol[0].flatten(), vol[0].flatten()) / np.dot( vol[0].flatten(), vol[0].flatten() ) - assert abs(corr - 1) < 1e-5 + assert abs(corr - 1) < 1.1e-5