From 4de3559a1cd171440a5ef65bd36954791fba7c99 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:10:02 -0400 Subject: [PATCH 01/10] Bump to numpy2 gdist 2.9.2 supports it --- naplib/utils/surfdist.py | 6 ++--- requirements.txt | 43 ++++++++++++++++++------------ tests/preprocessing/test_filter.py | 2 +- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/naplib/utils/surfdist.py b/naplib/utils/surfdist.py index cc7e1b14..c8b03ed2 100644 --- a/naplib/utils/surfdist.py +++ b/naplib/utils/surfdist.py @@ -24,7 +24,7 @@ def load_freesurfer_label(annot_input, label_name): labels, _, names = read_annot(annot_input) names = [i.decode("utf-8") for i in names] label_value = names.index(label_name) - label_nodes = np.array(np.where(np.in1d(labels, label_value)), dtype=np.int32) + label_nodes = np.array(np.where(np.isin(labels, label_value)), dtype=np.int32) return label_nodes @@ -81,7 +81,7 @@ def triangles_keep_cortex(triangles, cortex): # for or each face/triangle keep only those that only contain nodes within the list of cortex nodes input_shape = triangles.shape triangle_is_in_cortex = np.all( - np.reshape(np.in1d(triangles.ravel(), cortex), input_shape), axis=1 + np.reshape(np.isin(triangles.ravel(), cortex), input_shape), axis=1 ) cortex_triangles_old = np.array(triangles[triangle_is_in_cortex], dtype=np.int32) @@ -100,7 +100,7 @@ def translate_src(src, cortex): """ Convert source nodes to new surface (without medial wall). """ - src_new = np.array(np.where(np.in1d(cortex, src))[0], dtype=np.int32) + src_new = np.array(np.where(np.isin(cortex, src))[0], dtype=np.int32) return src_new diff --git a/requirements.txt b/requirements.txt index 62a4a0b0..6dace379 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,29 @@ -matplotlib>=3.1.0 -numpy>=1.15.0,<2.0 # numpy>=2.0 is incompatible with gdist, a dependency of surfdist -scipy>=1.5.0 -pandas>=1.0.0 -statsmodels>=0.13.0 +# Core Scientific Stack (Updated for NumPy 2.0 ABI/API compatibility) +numpy>=2.0.0 +scipy>=1.13.0 +pandas>=2.2.2 +matplotlib>=3.9.0 +statsmodels>=0.14.2 +scikit-learn>=1.5.0 + +# Data Storage & IO +h5py>=3.11.0 hdf5storage>=0.1.1 -seaborn>=0.12.0 pyyaml -TextGrid -scikit-learn -joblib -mne -h5py -patsy +nibabel>=5.2.1 + +# Visualization +seaborn>=0.13.0 +plotly>=5.22.0 + +# Domain Specific & Specialized +gdist>=2.9.2 +mne>=1.7.1 +scikit-spatial>=7.1.0 tdt>=0.5.0 -packaging -plotly>=5.0.0 -nibabel>=5.0.0 -scikit-spatial>=5.0.0 -gdist>=2.0.0 +TextGrid + +# Utilities +joblib>=1.4.2 +patsy>=0.5.6 +packaging>=24.0 \ No newline at end of file diff --git a/tests/preprocessing/test_filter.py b/tests/preprocessing/test_filter.py index 78afd6e2..7cab81d1 100644 --- a/tests/preprocessing/test_filter.py +++ b/tests/preprocessing/test_filter.py @@ -10,7 +10,7 @@ def bandpower(x, fs, fmin, fmax): f, Pxx = scipy.signal.periodogram(x, fs=fs) ind_min = np.argmax(f > fmin) - 1 ind_max = np.argmax(f > fmax) - 1 - return np.trapz(Pxx[ind_min: ind_max], f[ind_min: ind_max]) + return np.trapezoid(Pxx[ind_min: ind_max], f[ind_min: ind_max]) @pytest.fixture(scope='module') def data(): From a0102866bfa3e706e68557d4a2bc065cf32cee90 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:12:24 -0400 Subject: [PATCH 02/10] Update to tvb-gdist --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6dace379..5235de52 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ seaborn>=0.13.0 plotly>=5.22.0 # Domain Specific & Specialized -gdist>=2.9.2 +tvb-gdist>=2.9.2 mne>=1.7.1 scikit-spatial>=7.1.0 tdt>=0.5.0 From 1f694813c471f79948f29917a97b922fb9fb160e Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:19:29 -0400 Subject: [PATCH 03/10] update hdf5storage --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5235de52..737626db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ scikit-learn>=1.5.0 # Data Storage & IO h5py>=3.11.0 -hdf5storage>=0.1.1 +hdf5storage>=0.1.9 pyyaml nibabel>=5.2.1 From 4f72ec1f99d0361aebf1dcdcc798701392d65a54 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan <42253618+vinaysraghavan@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:23:03 -0400 Subject: [PATCH 04/10] Update workflows --- .github/workflows/python-package.yml | 36 ++++++++++++++++++---------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 9f35fc65..57d5ca16 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: Python package on: @@ -11,34 +8,47 @@ on: jobs: build: - runs-on: ubuntu-latest strategy: fail-fast: false matrix: - python-version: ["3.8","3.9","3.10"] + # 3.13 is now available and worth testing for NumPy 2.0+ + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + cache: 'pip' # Automatically caches your dependencies + - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install flake8 pytest pytest-cov + + # Install requirements first if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - pip install pyyaml TextGrid - pip install --user -U mne-bids + + # Install remaining packages without --user + pip install pyyaml TextGrid mne-bids + + # Final sanity check to ensure NumPy 2.0 didn't get downgraded + python -c "import numpy; print(f'Using NumPy {numpy.__version__}')" + - name: Lint with flake8 run: | - # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest and get coverage run: | - pytest tests/ --cov=./naplib/ --cov-report=xml + # Using -v helps identify exactly which test crashes if collection fails + pytest -v tests/ --cov=./naplib/ --cov-report=xml + - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 # Updated to v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} # v4 often requires a token From 5ef2abb37af8c1c5fa7986f7ee33e20634960fe6 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:27:20 -0400 Subject: [PATCH 05/10] Update hdf5storage --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 737626db..203fb566 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ scikit-learn>=1.5.0 # Data Storage & IO h5py>=3.11.0 -hdf5storage>=0.1.9 +hdf5storage>=0.2.0 pyyaml nibabel>=5.2.1 From 1b3a0d09053cb2876fc812caa91ebdd047f19a81 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:36:56 -0400 Subject: [PATCH 06/10] hdf5storage==0.1.19 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 203fb566..99caf513 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ scikit-learn>=1.5.0 # Data Storage & IO h5py>=3.11.0 -hdf5storage>=0.2.0 +hdf5storage==0.1.19 pyyaml nibabel>=5.2.1 From fbb3ab7e7c0caa125ce1747dec834d835dff6b75 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan <42253618+vinaysraghavan@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:48:16 -0400 Subject: [PATCH 07/10] Dropping Python 3.9 --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 57d5ca16..6ededc65 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: # 3.13 is now available and worth testing for NumPy 2.0+ - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 From 15120b43935e8c95de28d07095f46721912c3f02 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:49:02 -0400 Subject: [PATCH 08/10] Fix Aligner resample --- naplib/features/aligner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/naplib/features/aligner.py b/naplib/features/aligner.py index 989b6594..7e26b9c8 100644 --- a/naplib/features/aligner.py +++ b/naplib/features/aligner.py @@ -307,7 +307,7 @@ def align_files(self, audio_dir, text_dir, names=None): if old_fs == 16000: write_wavfile(join(self.tmp_dir, wavfile_), 16000, wavdata) else: - wavdata = scipy_resample(wavdata, int(16000. / old_fs)) + wavdata = scipy_resample(wavdata, int(len(wavdata) * 16000. / old_fs)) write_wavfile(join(self.tmp_dir, wavfile_), 16000, wavdata) From b1bd56e2f7f258cc1fb470ac7a3c6f7ba6857e91 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:49:57 -0400 Subject: [PATCH 09/10] Update hdf5storage Drop support for python 3.9 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 99caf513..203fb566 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ scikit-learn>=1.5.0 # Data Storage & IO h5py>=3.11.0 -hdf5storage==0.1.19 +hdf5storage>=0.2.0 pyyaml nibabel>=5.2.1 From 4b37ac6c9b9a3e3ce98c3ae1b0d317c7eff77ef0 Mon Sep 17 00:00:00 2001 From: Vinay Raghavan Date: Mon, 6 Apr 2026 15:55:31 -0400 Subject: [PATCH 10/10] Update get cmap Updating for minimum matplotlib 3.9.0 --- naplib/utils/surfdist.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/naplib/utils/surfdist.py b/naplib/utils/surfdist.py index c8b03ed2..5114c7bc 100644 --- a/naplib/utils/surfdist.py +++ b/naplib/utils/surfdist.py @@ -4,6 +4,7 @@ """ import gdist +import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.colors import LightSource import numpy as np @@ -190,10 +191,7 @@ def surfdist_viz( # if cmap is given as string, translate to matplotlib cmap if isinstance(cmap, str): - try: - cmap = plt.cm.get_cmap(cmap) - except AttributeError: - cmap = plt.get_cmap(cmap) + cmap = mpl.colormaps[cmap] if ax is None: premade_ax = False