diff --git a/.maint/update_requirements.py b/.maint/update_requirements.py deleted file mode 100755 index 3a10c1508a..0000000000 --- a/.maint/update_requirements.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 -from copy import copy -from pathlib import Path -from packaging.requirements import Requirement, SpecifierSet - -try: - from tomllib import loads # Python +3.11 -except ImportError: - from pip._vendor.tomli import loads - -repo_root = Path(__file__).parent.parent -pyproject = repo_root / "pyproject.toml" -reqs = repo_root / "requirements.txt" -min_reqs = repo_root / "min-requirements.txt" - -requirements = [ - Requirement(req) - for req in loads(pyproject.read_text())["project"]["dependencies"] -] - -script_name = Path(__file__).relative_to(repo_root) - - -def to_min(req): - if req.specifier: - req = copy(req) - try: - min_spec = [spec for spec in req.specifier if spec.operator in (">=", "~=")][0] - except IndexError: - return req - min_spec._spec = ("==",) + min_spec._spec[1:] - req.specifier = SpecifierSet(str(min_spec)) - return req - - -lines = [f"# Auto-generated by {script_name}", ""] - -# Write requirements -lines[1:-1] = [str(req) for req in requirements] -reqs.write_text("\n".join(lines)) - -# Write minimum requirements -lines[1:-1] = [str(to_min(req)) for req in requirements] -min_reqs.write_text("\n".join(lines)) diff --git a/CHANGES.rst b/CHANGES.rst index a58e21c3f0..7136988928 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,19 @@ +2.12.0 (March 21, 2025) +======================= +Feature release in the 2.12.x series. + +This release migrates from the deprecated ``niworkflows.reporting`` +module to the ``nireports`` package. + +* FIX: AttributeError for _ApplyCoeffsFieldInputSpec (#481) +* ENH: Allow running SyN SDC without using prior (#480) +* ENH: Allow estimated and fallback TotalReadoutTime (#477) +* RF: Transition from niworkflows reporting interfaces (#473) +* DOC: Fix broken link [skip ci] (#482) +* MNT: Add `defaults` to `conda` channels in `build-test-publish` GHA (#474) +* MNT: Update `niworkflows` version to 1.11.0 (#478) + + 2.11.0 (December 18, 2024) ========================== Feature release in the 2.11.x series. diff --git a/env.yml b/env.yml index 28b9e9be11..c59a736884 100644 --- a/env.yml +++ b/env.yml @@ -2,24 +2,28 @@ name: sdcflows channels: - https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ - conda-forge -# Update this ~yearly; last updated April 2023 +# Update this ~yearly; last updated Mar 2025 dependencies: - - python=3.10 + - python=3.12 # Intel Math Kernel Library for numpy - - mkl=2022.1 - - mkl-service=2.4 + - mkl=2024.2.2 + - mkl-service=2.4.2 # Base scientific python stack; required by FSL, so pinned here - numpy=1.26 - - scipy=1.11 - - matplotlib=3.8 - - pandas=2.1 - - h5py=3.8 + - scipy=1.15 + - matplotlib=3.9 + - pandas=2.2 + - h5py=3.13 # Dependencies compiled against numpy, best to stick with conda - - scikit-image=0.22 + - scikit-image=0.25 # Utilities - - graphviz=6.0 + - graphviz=11.0 # Workflow dependencies: ANTs - - ants=2.4.4 - # Workflow dependencies: FSL (versions pinned in 6.0.6.2) - - fsl-fugue=2201.2 - - fsl-topup=2203.1 + - ants=2.5 + # 5.4.1 and 5.4.2 cause segfaults with ants + # Try to remove this ASAP + # https://github.com/conda-forge/ants-feedstock/issues/19 + - libitk=5.4.0 + # Workflow dependencies: FSL (versions pinned in 6.0.7.13) + - fsl-fugue=2201.5 + - fsl-topup=2203.5 diff --git a/min-requirements.txt b/min-requirements.txt deleted file mode 100644 index 626bac5b5a..0000000000 --- a/min-requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Auto-generated by .maint/update_requirements.py -acres==0.2.0 -attrs==20.1.0 -nibabel==3.0 -nipype==1.8.5 -migas==0.4.0 -nireports==24.1.0 -niworkflows==1.11.0 -nitransforms==24.1.0 -numpy==1.22 -pybids==0.16.4 -scikit-image==0.18 -scipy==1.8.1 -templateflow==23.1 -toml==0.10 diff --git a/pyproject.toml b/pyproject.toml index a083e0bb87..84dd1ef9bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,10 +27,10 @@ dependencies = [ "nibabel >= 3.0", "nipype >= 1.8.5", "migas >= 0.4.0", - "nireports >= 24.1.0", + "nireports >= 25.0.1", "niworkflows >= 1.11.0", "nitransforms >= 24.1.0", - "numpy >= 1.22", + "numpy >= 1.23", "pybids >= 0.16.4", "scikit-image >= 0.18", "scipy >= 1.8.1", diff --git a/requirements.txt b/requirements.txt index 6dade0b7a8..a5ccf82ab1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,281 @@ -# Auto-generated by .maint/update_requirements.py -acres>=0.2.0 -attrs>=20.1.0 -nibabel>=3.0 -nipype>=1.8.5 -migas>=0.4.0 -nireports>=24.1.0 -niworkflows>=1.11.0 -nitransforms>=24.1.0 -numpy>=1.22 -pybids>=0.16.4 -scikit-image>=0.18 -scipy>=1.8.1 -templateflow>=23.1 -toml>=0.10 +# This file was autogenerated by uv via the following command: +# uv pip compile --strip-extras pyproject.toml -o requirements.txt -p 3.12 -c- +acres==0.3.0 + # via + # sdcflows (pyproject.toml) + # nipype + # nireports + # niworkflows +attrs==25.3.0 + # via + # sdcflows (pyproject.toml) + # jsonschema + # niworkflows + # referencing +bids-validator==1.14.7.post0 + # via pybids +bidsschematools==1.0.4 + # via bids-validator +certifi==2025.1.31 + # via requests +charset-normalizer==3.4.1 + # via requests +ci-info==0.3.0 + # via + # etelemetry + # migas +click==8.1.8 + # via + # bidsschematools + # nipype + # pybids +contourpy==1.3.1 + # via matplotlib +cycler==0.12.1 + # via matplotlib +docopt==0.6.2 + # via num2words +etelemetry==0.3.1 + # via nipype +filelock==3.18.0 + # via nipype +fonttools==4.56.0 + # via matplotlib +formulaic==1.1.1 + # via pybids +frozendict==2.4.6 + # via pybids +fsspec==2025.3.0 + # via universal-pathlib +greenlet==3.1.1 + # via sqlalchemy +h5py==3.13.0 + # via nitransforms +idna==3.10 + # via requests +imageio==2.37.0 + # via scikit-image +interface-meta==1.3.0 + # via formulaic +isodate==0.6.1 + # via rdflib +jinja2==3.1.6 + # via niworkflows +joblib==1.4.2 + # via + # nilearn + # scikit-learn +jsonschema==4.23.0 + # via bidsschematools +jsonschema-specifications==2024.10.1 + # via jsonschema +kiwisolver==1.4.8 + # via matplotlib +lazy-loader==0.4 + # via scikit-image +looseversion==1.3.0 + # via + # nipype + # niworkflows +lxml==5.3.1 + # via + # nilearn + # nireports + # prov + # svgutils +markupsafe==3.0.2 + # via jinja2 +matplotlib==3.9.4 + # via + # nireports + # niworkflows + # seaborn +migas==0.4.0 + # via sdcflows (pyproject.toml) +networkx==3.4.2 + # via + # nipype + # prov + # scikit-image +nibabel==5.3.2 + # via + # sdcflows (pyproject.toml) + # nilearn + # nipype + # nireports + # nitransforms + # niworkflows + # pybids +nilearn==0.11.1 + # via + # nireports + # niworkflows +nipype==1.10.0 + # via + # sdcflows (pyproject.toml) + # nireports + # niworkflows +nireports==25.0.1 + # via sdcflows (pyproject.toml) +nitransforms==24.1.1 + # via + # sdcflows (pyproject.toml) + # niworkflows +niworkflows==1.13.0 + # via sdcflows (pyproject.toml) +num2words==0.5.14 + # via pybids +numpy==1.26.4 + # via + # sdcflows (pyproject.toml) + # contourpy + # formulaic + # h5py + # imageio + # matplotlib + # nibabel + # nilearn + # nipype + # nireports + # nitransforms + # niworkflows + # pandas + # pybids + # scikit-image + # scikit-learn + # scipy + # seaborn + # tifffile + # transforms3d +packaging==24.2 + # via + # etelemetry + # lazy-loader + # matplotlib + # nibabel + # nilearn + # nipype + # niworkflows + # scikit-image +pandas==2.2.3 + # via + # formulaic + # nilearn + # nireports + # niworkflows + # pybids + # seaborn +pillow==11.1.0 + # via + # imageio + # matplotlib + # scikit-image +prov==2.0.1 + # via nipype +puremagic==1.28 + # via nipype +pybids==0.19.0 + # via + # sdcflows (pyproject.toml) + # nireports + # niworkflows + # templateflow +pydot==3.0.4 + # via nipype +pyparsing==3.2.1 + # via + # matplotlib + # pydot + # rdflib +python-dateutil==2.9.0.post0 + # via + # matplotlib + # nipype + # pandas + # prov +pytz==2025.1 + # via pandas +pyyaml==6.0.2 + # via + # bidsschematools + # nireports + # niworkflows +rdflib==6.3.2 + # via + # nipype + # prov +referencing==0.36.2 + # via + # jsonschema + # jsonschema-specifications +requests==2.32.3 + # via + # etelemetry + # nilearn + # templateflow +rpds-py==0.23.1 + # via + # jsonschema + # referencing +scikit-image==0.25.2 + # via + # sdcflows (pyproject.toml) + # niworkflows +scikit-learn==1.6.1 + # via nilearn +scipy==1.15.2 + # via + # sdcflows (pyproject.toml) + # formulaic + # nilearn + # nipype + # nitransforms + # niworkflows + # pybids + # scikit-image + # scikit-learn +seaborn==0.13.2 + # via + # nireports + # niworkflows +simplejson==3.20.1 + # via nipype +six==1.17.0 + # via + # isodate + # python-dateutil +sqlalchemy==2.0.39 + # via pybids +svgutils==0.3.4 + # via niworkflows +templateflow==24.2.2 + # via + # sdcflows (pyproject.toml) + # nireports + # niworkflows +threadpoolctl==3.6.0 + # via scikit-learn +tifffile==2025.3.13 + # via scikit-image +toml==0.10.2 + # via sdcflows (pyproject.toml) +tqdm==4.67.1 + # via templateflow +traits==7.0.2 + # via nipype +transforms3d==0.4.2 + # via niworkflows +typing-extensions==4.12.2 + # via + # formulaic + # nibabel + # referencing + # sqlalchemy +tzdata==2025.1 + # via pandas +universal-pathlib==0.2.6 + # via pybids +urllib3==2.3.0 + # via requests +wrapt==1.17.2 + # via formulaic diff --git a/sdcflows/utils/epimanip.py b/sdcflows/utils/epimanip.py index 449c94b5db..c8f08e45b9 100644 --- a/sdcflows/utils/epimanip.py +++ b/sdcflows/utils/epimanip.py @@ -313,7 +313,7 @@ def epi_mask(in_file, out_file=None): maxnorm = np.percentile(closed[closed > 0], 90) closed = np.clip(closed, a_min=0.0, a_max=maxnorm) # Calculate index of center of masses - cm = tuple(np.round(ndimage.measurements.center_of_mass(closed)).astype(int)) + cm = tuple(np.round(ndimage.center_of_mass(closed)).astype(int)) # Erode the picture of the brain by a lot eroded = ndimage.grey_erosion(closed, structure=ball(5)) # Calculate the residual diff --git a/sdcflows/viz/utils.py b/sdcflows/viz/utils.py index b5225a627e..0790d04d50 100644 --- a/sdcflows/viz/utils.py +++ b/sdcflows/viz/utils.py @@ -46,7 +46,7 @@ def plot_registration( from lxml import etree import matplotlib.pyplot as plt from nilearn.plotting import plot_anat - from svgutils.transform import SVGFigure + from nireports._vendored.svgutils.transform import SVGFigure from nireports.reportlets.utils import robust_set_limits, extract_svg, SVGNS plot_params = plot_params or {}