Skip to content

Commit a28196a

Browse files
authored
Merge pull request #501 from effigies/fix/nitransforms-25.0.1
fix: Adapt to transposed ndindex in nitransforms
2 parents cfe0d4d + d364739 commit a28196a

File tree

10 files changed

+42
-31
lines changed

10 files changed

+42
-31
lines changed

.github/workflows/build-test-publish.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,24 @@ jobs:
6565
strategy:
6666
fail-fast: false
6767
matrix:
68-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
68+
python-version: ["3.10", "3.11", "3.12", "3.13"]
6969
dependencies: ["latest", "pre"]
7070
marks: ["fast"]
7171
include:
72-
- python-version: "3.9"
72+
- python-version: "3.10"
7373
dependencies: "min"
7474
marks: "fast"
75-
- python-version: "3.9"
75+
- python-version: "3.10"
7676
dependencies: "latest"
7777
marks: "slow"
78-
- python-version: "3.12"
78+
- python-version: "3.13"
7979
dependencies: "latest"
8080
marks: "veryslow"
8181
exclude:
82-
- python-version: "3.9"
83-
dependencies: "pre"
8482
- python-version: "3.10"
8583
dependencies: "pre"
84+
- python-version: "3.11"
85+
dependencies: "pre"
8686

8787
steps:
8888
- uses: actions/checkout@v5

pyproject.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,26 @@ classifiers = [
1313
"Topic :: Scientific/Engineering :: Image Recognition",
1414
"Topic :: Scientific/Engineering :: Bio-Informatics",
1515
"License :: OSI Approved :: Apache Software License",
16-
"Programming Language :: Python :: 3.9",
1716
"Programming Language :: Python :: 3.10",
1817
"Programming Language :: Python :: 3.11",
1918
"Programming Language :: Python :: 3.12",
2019
"Programming Language :: Python :: 3.13",
2120
]
2221
license = "Apache-2.0"
23-
requires-python = ">=3.9"
22+
requires-python = ">=3.10"
2423
dependencies = [
2524
"acres >= 0.2.0",
2625
"attrs >= 20.1.0",
27-
"nibabel >= 3.0",
28-
"nipype >= 1.8.5",
26+
"nibabel >= 5.1.1",
27+
"nipype >= 1.9.0",
2928
"migas >= 0.4.0",
3029
"nireports >= 25.0.1",
3130
"niworkflows >= 1.11.0",
32-
"nitransforms >= 24.1.0",
33-
"numpy >= 1.23",
31+
"nitransforms >= 25.0.1",
32+
"numpy >= 2.0",
3433
"pybids >= 0.16.4",
35-
"scikit-image >= 0.18",
36-
"scipy >= 1.8.1",
34+
"scikit-image >= 0.23",
35+
"scipy >= 1.10",
3736
"templateflow >= 23.1",
3837
"toml >= 0.10",
3938
]
@@ -70,8 +69,8 @@ dev = [
7069
]
7170

7271
test = [
73-
"coverage[toml] >=5.2.1",
74-
"pytest >= 6",
72+
"coverage[toml] >=7",
73+
"pytest >= 8.1",
7574
"pytest-cov >= 2.11",
7675
"pytest-env",
7776
"pytest-xdist >= 2.5",
@@ -194,6 +193,7 @@ ignore = [
194193
"B019",
195194
"SIM108",
196195
"C901",
196+
"UP038",
197197
]
198198

199199
[tool.ruff.lint.flake8-quotes]

sdcflows/interfaces/epi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,15 @@ def _run_interface(self, runtime):
120120
blips,
121121
self.inputs.readout_times,
122122
self.inputs.in_data,
123+
strict=False,
123124
)
124125
)
125126

126127
(
127128
self._results['pe_dirs_fsl'],
128129
self._results['readout_times'],
129130
self._results['out_data'],
130-
) = zip(*sorted_inputs)
131+
) = zip(*sorted_inputs, strict=False)
131132

132133
# Put sign back last
133134
self._results['pe_dirs_fsl'] = [

sdcflows/interfaces/fmap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def _run_interface(self, runtime):
289289
fmap_imgs = [nb.load(fname) for fname in fmap_files]
290290

291291
# Baseline check: paired magnitude/phase maps are basically the same
292-
for mag, fmap in zip(mag_imgs, fmap_imgs):
292+
for mag, fmap in zip(mag_imgs, fmap_imgs, strict=False):
293293
msg = _check_gross_geometry(mag, fmap)
294294
if msg is not None:
295295
LOGGER.critical(msg)

sdcflows/interfaces/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,15 @@ class Flatten(SimpleInterface):
8181

8282
def _run_interface(self, runtime):
8383
self._results['out_list'] = _flatten(
84-
zip(self.inputs.in_data, self.inputs.in_meta),
84+
zip(self.inputs.in_data, self.inputs.in_meta, strict=False),
8585
max_trs=self.inputs.max_trs,
8686
out_dir=runtime.cwd,
8787
)
8888

8989
# Unzip out_data, out_meta outputs.
90-
self._results['out_data'], self._results['out_meta'] = zip(*self._results['out_list'])
90+
self._results['out_data'], self._results['out_meta'] = zip(
91+
*self._results['out_list'], strict=False
92+
)
9193
return runtime
9294

9395

@@ -449,7 +451,11 @@ def _deoblique(in_file, in_affine=None, newpath=None):
449451
if in_affine is None:
450452
orientation = nb.aff2axcodes(nii.affine)
451453
directions = (
452-
np.array([int(l1 == l2) for l1, l2 in zip(orientation, 'RAS')], dtype='float32') * 2
454+
np.array(
455+
[int(l1 == l2) for l1, l2 in zip(orientation, 'RAS', strict=False)],
456+
dtype='float32',
457+
)
458+
* 2
453459
- 1
454460
)
455461
newaff = np.eye(4)

sdcflows/tests/test_transform.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def generate_oracle(
4848
data[19:22, ...] = 0
4949
data = np.pad(data + nd.binary_erosion(data, ball(3)), 8)
5050

51-
zooms = [z if not f else -z for z, f in zip(zooms, flip)]
51+
zooms = [z if not f else -z for z, f in zip(zooms, flip, strict=False)]
5252
affine = np.diag(zooms + [1])
5353
affine[:3, 3] = -affine[:3, :3] @ ((np.array(data.shape) - 1) * 0.5)
5454

@@ -123,7 +123,9 @@ def test_displacements_field(tmpdir, testdata_dir, outdir, pe_dir, rotation, fli
123123
assert np.all((np.sqrt(((ours - theirs) ** 2).sum()) / ours.size) < 1e-1)
124124

125125
if outdir:
126-
orientation = ''.join([ax[bool(f)] for ax, f in zip(('RL', 'AP', 'SI'), flip)])
126+
orientation = ''.join(
127+
[ax[bool(f)] for ax, f in zip(('RL', 'AP', 'SI'), flip, strict=False)]
128+
)
127129

128130
SimpleBeforeAfter(
129131
after_label='Theirs (ANTs)',

sdcflows/transform.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@
4949

5050
import asyncio
5151
import os
52-
from collections.abc import Sequence
52+
from collections.abc import Callable, Sequence
5353
from functools import partial
5454
from pathlib import Path
55-
from typing import Callable
5655
from warnings import warn
5756

5857
import attr
@@ -492,7 +491,7 @@ def apply(
492491
ro_time *= n_volumes
493492

494493
pe_info = []
495-
for vol_pe_dir, vol_ro_time in zip(pe_dir, ro_time):
494+
for vol_pe_dir, vol_ro_time in zip(pe_dir, ro_time, strict=False):
496495
pe_axis = 'ijk'.index(vol_pe_dir[0])
497496
# Displacements are reversed if either is true (after ensuring positive cosines)
498497
flip = (axcodes[pe_axis] in 'LPI') ^ vol_pe_dir.endswith('-')
@@ -502,7 +501,7 @@ def apply(
502501
# Reference image's voxel coordinates (in voxel units)
503502
voxcoords = (
504503
nt.linear.Affine(reference=moving)
505-
.reference.ndindex.reshape((ndim, *data.shape[:ndim]))
504+
.reference.ndindex.T.reshape((ndim, *data.shape[:ndim]))
506505
.astype('float32')
507506
)
508507

sdcflows/utils/wrangler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ def find_estimators(
488488
targets = all_targets
489489
intent_map = [[target] for target in all_targets]
490490

491-
for target, intent in zip(targets, intent_map):
491+
for target, intent in zip(targets, intent_map, strict=False):
492492
logger.debug('Found single PE target %s', target.relpath)
493493
# The new estimator is IntendedFor the individual targets,
494494
# even if the EPI file is IntendedFor multiple

sdcflows/workflows/fit/tests/test_syn.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,10 @@ def test_mm2vox(tmp_path, fixed_ornt, moving_ornt, ijk, index):
304304

305305
vox_params = _mm2vox(str(moving_path), str(fixed_path), ijk, config)
306306
vox_values = [level[2] for level in vox_params]
307-
assert [mm_level[:2] == vox_level[:2] for mm_level, vox_level in zip(params, vox_params)]
307+
assert all(
308+
mm_level[:2] == vox_level[:2]
309+
for mm_level, vox_level in zip(params, vox_params, strict=False)
310+
)
308311
assert np.array_equal(vox_values, mm_values / [2, 3, 4][index])
309312

310313

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ requires =
33
tox>=4
44
tox-uv
55
envlist =
6-
py3{9,10,11,12,13}-latest-{fast,slow,veryslow}
7-
py39-min-fast
6+
py3{10,11,12,13}-latest-{fast,slow,veryslow}
7+
py310-min-fast
88
py3{11,12,13}-pre-{fast,slow,veryslow}
99
style
1010
spellcheck

0 commit comments

Comments
 (0)