Skip to content

Commit b8b6b0a

Browse files
Merge pull request #223 from naplab/update_numpy2
Bump to NumPy 2.x
2 parents 1fa9392 + 4b37ac6 commit b8b6b0a

5 files changed

Lines changed: 57 additions & 40 deletions

File tree

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
41
name: Python package
52

63
on:
@@ -11,34 +8,47 @@ on:
118

129
jobs:
1310
build:
14-
1511
runs-on: ubuntu-latest
1612
strategy:
1713
fail-fast: false
1814
matrix:
19-
python-version: ["3.8","3.9","3.10"]
15+
# 3.13 is now available and worth testing for NumPy 2.0+
16+
python-version: ["3.10", "3.11", "3.12", "3.13"]
2017

2118
steps:
22-
- uses: actions/checkout@v3
19+
- uses: actions/checkout@v4
20+
2321
- name: Set up Python ${{ matrix.python-version }}
24-
uses: actions/setup-python@v3
22+
uses: actions/setup-python@v5
2523
with:
2624
python-version: ${{ matrix.python-version }}
25+
cache: 'pip' # Automatically caches your dependencies
26+
2727
- name: Install dependencies
2828
run: |
2929
python -m pip install --upgrade pip
3030
python -m pip install flake8 pytest pytest-cov
31+
32+
# Install requirements first
3133
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
32-
pip install pyyaml TextGrid
33-
pip install --user -U mne-bids
34+
35+
# Install remaining packages without --user
36+
pip install pyyaml TextGrid mne-bids
37+
38+
# Final sanity check to ensure NumPy 2.0 didn't get downgraded
39+
python -c "import numpy; print(f'Using NumPy {numpy.__version__}')"
40+
3441
- name: Lint with flake8
3542
run: |
36-
# stop the build if there are Python syntax errors or undefined names
3743
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
38-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
3944
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
45+
4046
- name: Test with pytest and get coverage
4147
run: |
42-
pytest tests/ --cov=./naplib/ --cov-report=xml
48+
# Using -v helps identify exactly which test crashes if collection fails
49+
pytest -v tests/ --cov=./naplib/ --cov-report=xml
50+
4351
- name: Upload coverage reports to Codecov
44-
uses: codecov/codecov-action@v3
52+
uses: codecov/codecov-action@v4 # Updated to v4
53+
with:
54+
token: ${{ secrets.CODECOV_TOKEN }} # v4 often requires a token

naplib/features/aligner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def align_files(self, audio_dir, text_dir, names=None):
307307
if old_fs == 16000:
308308
write_wavfile(join(self.tmp_dir, wavfile_), 16000, wavdata)
309309
else:
310-
wavdata = scipy_resample(wavdata, int(16000. / old_fs))
310+
wavdata = scipy_resample(wavdata, int(len(wavdata) * 16000. / old_fs))
311311
write_wavfile(join(self.tmp_dir, wavfile_), 16000, wavdata)
312312

313313

naplib/utils/surfdist.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""
55

66
import gdist
7+
import matplotlib as mpl
78
import matplotlib.pyplot as plt
89
from matplotlib.colors import LightSource
910
import numpy as np
@@ -24,7 +25,7 @@ def load_freesurfer_label(annot_input, label_name):
2425
labels, _, names = read_annot(annot_input)
2526
names = [i.decode("utf-8") for i in names]
2627
label_value = names.index(label_name)
27-
label_nodes = np.array(np.where(np.in1d(labels, label_value)), dtype=np.int32)
28+
label_nodes = np.array(np.where(np.isin(labels, label_value)), dtype=np.int32)
2829

2930
return label_nodes
3031

@@ -81,7 +82,7 @@ def triangles_keep_cortex(triangles, cortex):
8182
# for or each face/triangle keep only those that only contain nodes within the list of cortex nodes
8283
input_shape = triangles.shape
8384
triangle_is_in_cortex = np.all(
84-
np.reshape(np.in1d(triangles.ravel(), cortex), input_shape), axis=1
85+
np.reshape(np.isin(triangles.ravel(), cortex), input_shape), axis=1
8586
)
8687

8788
cortex_triangles_old = np.array(triangles[triangle_is_in_cortex], dtype=np.int32)
@@ -100,7 +101,7 @@ def translate_src(src, cortex):
100101
"""
101102
Convert source nodes to new surface (without medial wall).
102103
"""
103-
src_new = np.array(np.where(np.in1d(cortex, src))[0], dtype=np.int32)
104+
src_new = np.array(np.where(np.isin(cortex, src))[0], dtype=np.int32)
104105

105106
return src_new
106107

@@ -190,10 +191,7 @@ def surfdist_viz(
190191

191192
# if cmap is given as string, translate to matplotlib cmap
192193
if isinstance(cmap, str):
193-
try:
194-
cmap = plt.cm.get_cmap(cmap)
195-
except AttributeError:
196-
cmap = plt.get_cmap(cmap)
194+
cmap = mpl.colormaps[cmap]
197195

198196
if ax is None:
199197
premade_ax = False

requirements.txt

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
matplotlib>=3.1.0
2-
numpy>=1.15.0,<2.0 # numpy>=2.0 is incompatible with gdist, a dependency of surfdist
3-
scipy>=1.5.0
4-
pandas>=1.0.0
5-
statsmodels>=0.13.0
6-
hdf5storage>=0.1.1
7-
seaborn>=0.12.0
1+
# Core Scientific Stack (Updated for NumPy 2.0 ABI/API compatibility)
2+
numpy>=2.0.0
3+
scipy>=1.13.0
4+
pandas>=2.2.2
5+
matplotlib>=3.9.0
6+
statsmodels>=0.14.2
7+
scikit-learn>=1.5.0
8+
9+
# Data Storage & IO
10+
h5py>=3.11.0
11+
hdf5storage>=0.2.0
812
pyyaml
9-
TextGrid
10-
scikit-learn
11-
joblib
12-
mne
13-
h5py
14-
patsy
13+
nibabel>=5.2.1
14+
15+
# Visualization
16+
seaborn>=0.13.0
17+
plotly>=5.22.0
18+
19+
# Domain Specific & Specialized
20+
tvb-gdist>=2.9.2
21+
mne>=1.7.1
22+
scikit-spatial>=7.1.0
1523
tdt>=0.5.0
16-
packaging
17-
plotly>=5.0.0
18-
nibabel>=5.0.0
19-
scikit-spatial>=5.0.0
20-
gdist>=2.0.0
24+
TextGrid
25+
26+
# Utilities
27+
joblib>=1.4.2
28+
patsy>=0.5.6
29+
packaging>=24.0

tests/preprocessing/test_filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def bandpower(x, fs, fmin, fmax):
1010
f, Pxx = scipy.signal.periodogram(x, fs=fs)
1111
ind_min = np.argmax(f > fmin) - 1
1212
ind_max = np.argmax(f > fmax) - 1
13-
return np.trapz(Pxx[ind_min: ind_max], f[ind_min: ind_max])
13+
return np.trapezoid(Pxx[ind_min: ind_max], f[ind_min: ind_max])
1414

1515
@pytest.fixture(scope='module')
1616
def data():

0 commit comments

Comments
 (0)