diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 2c38f1dc..52c07215 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -2,10 +2,10 @@ name: Pytest on: push: - branches: ['*'] - tags: ['*'] + branches: [ '*' ] + tags: [ '*' ] pull_request: - branches: [master, 'maint/*'] + branches: [ master, 'maint/*' ] defaults: run: @@ -26,12 +26,12 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: ['ubuntu-latest'] - python-version: ['3.10', '3.11', '3.12'] - dependencies: ['latest', 'pre'] + os: [ 'ubuntu-latest' ] + python-version: [ '3.10', '3.11', '3.12', '3.13' ] + dependencies: [ 'latest', 'pre' ] include: - os: ubuntu-latest - python-version: '3.10' + python-version: '3.13' dependencies: 'min' env: diff --git a/Dockerfile b/Dockerfile index 44f23fa9..cae4e206 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,12 +26,10 @@ ARG BASE_IMAGE=ubuntu:jammy-20240405 # NiBabies wheel -FROM python:slim AS src -RUN pip install build -RUN apt-get update && \ - apt-get install -y --no-install-recommends git +FROM ghcr.io/astral-sh/uv:python3.12-alpine AS src +RUN apk add git COPY . /src -RUN python -m build /src +RUN uvx --from build pyproject-build --installer uv -w /src # Older Python to support legacy MCRIBS FROM python:3.6.15-slim as pyenv @@ -54,7 +52,7 @@ FROM downloader as afni # The download link can point to newer releases # As a safeguard, take advantage of Docker caching, and # Bump the date to current to update AFNI -RUN echo "2023.06.09" +RUN echo "2025.06.12" RUN mkdir -p /opt/afni-latest \ && curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \ | tar -xz -C /opt/afni-latest --strip-components 1 \ @@ -72,22 +70,6 @@ RUN mkdir -p /opt/afni-latest \ -name "3dAutomask" -or \ -name "3dvolreg" \) -delete -# ANTs 2.5.4 -FROM downloader as ants -RUN mkdir -p /opt && \ - curl -sSLO "https://github.com/ANTsX/ANTs/releases/download/v2.5.4/ants-2.5.4-ubuntu-22.04-X64-gcc.zip" && \ - unzip ants-2.5.4-ubuntu-22.04-X64-gcc.zip -d /opt && \ - rm ants-2.5.4-ubuntu-22.04-X64-gcc.zip - -# Connectome Workbench 1.5.0 -FROM downloader as workbench -RUN mkdir /opt/workbench && \ - curl -sSLO https://www.humanconnectome.org/storage/app/media/workbench/workbench-linux64-v1.5.0.zip && \ - unzip workbench-linux64-v1.5.0.zip -d /opt && \ - rm workbench-linux64-v1.5.0.zip && \ - rm -rf /opt/workbench/libs_linux64_software_opengl /opt/workbench/plugins_linux64 && \ - strip --remove-section=.note.ABI-tag /opt/workbench/libs_linux64/libQt5Core.so.5 - # Micromamba FROM downloader as micromamba @@ -99,7 +81,7 @@ RUN apt-get update && \ WORKDIR / # Bump the date to current to force update micromamba -RUN echo "2024.04.25" && curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba +RUN echo "2025.06.12" && curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba ENV MAMBA_ROOT_PREFIX="/opt/conda" COPY env.yml /tmp/env.yml COPY requirements.txt /tmp/requirements.txt @@ -107,7 +89,8 @@ WORKDIR /tmp RUN micromamba create -y -f /tmp/env.yml && \ micromamba clean -y -a -ENV PATH="/opt/conda/envs/nibabies/bin:$PATH" +ENV PATH="/opt/conda/envs/nibabies/bin:$PATH" \ + UV_USE_IO_URING=0 RUN npm install -g svgo@^3.2.0 bids-validator@1.14.10 && \ rm -r ~/.npm @@ -180,23 +163,12 @@ RUN apt-get update -qq \ && ldconfig COPY --from=afni /opt/afni-latest /opt/afni-latest -COPY --from=ants /opt/ants-2.5.4 /opt/ants -COPY --from=workbench /opt/workbench /opt/workbench # AFNI config ENV PATH="/opt/afni-latest:$PATH" \ AFNI_IMSAVE_WARNINGS="NO" \ AFNI_PLUGINPATH="/opt/afni-latest" -# ANTs config -ENV ANTSPATH="/opt/ants" \ - PATH="/opt/ants/bin:$PATH" \ - LD_LIBRARY_PATH="/opt/ants/lib:$LD_LIBRARY_PATH" - -# Workbench config -ENV PATH="/opt/workbench/bin_linux64:$PATH" \ - LD_LIBRARY_PATH="/opt/workbench/lib_linux64:$LD_LIBRARY_PATH" - # Install FreeSurfer (with Infant Module) COPY --from=nipreps/freesurfer@sha256:3b895fc732a7080374a15c4f976510f39c0c48dc76c030ab27316febd5e419ee /opt/freesurfer /opt/freesurfer ENV FREESURFER_HOME="/opt/freesurfer" @@ -278,8 +250,8 @@ ARG BUILD_DATE ARG VCS_REF ARG VERSION LABEL org.label-schema.build-date=$BUILD_DATE \ - org.label-schema.name="NiBabies" \ - org.label-schema.description="NiBabies - NeuroImaging tools for babies" \ + org.label-schema.name="fMRIPrep Lifespan" \ + org.label-schema.description="fMRIPrep Lifespan - fMRI processing tool from birth and on" \ org.label-schema.url="https://github.com/nipreps/nibabies" \ org.label-schema.vcs-ref=$VCS_REF \ org.label-schema.vcs-url="https://github.com/nipreps/nibabies" \ diff --git a/env.yml b/env.yml index 349b6750..f92db278 100644 --- a/env.yml +++ b/env.yml @@ -1,44 +1,46 @@ name: nibabies channels: - - https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ - - conda-forge -# Update this ~yearly; last updated April 2023 +- https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ +- conda-forge +# Update this ~yearly; last updated June 12 2025 dependencies: - - python =3.11 - # Needed for svgo and bids-validator; consider moving to deno - - nodejs=20 - # Intel Math Kernel Library for numpy - - mkl=2023.2.0 - - mkl-service=2.4.0 - # git-annex for templateflow users with DataLad superdatasets - - git-annex=*=alldep* - # Base scientific python stack; required by FSL, so pinned here - - numpy=1.26 - - scipy=1.11 - - matplotlib=3.8 - - pandas=2.2 - - h5py=3.10 - # Dependencies compiled against numpy, best to stick with conda - - nitime=0.10 - - scikit-image=0.22 - - scikit-learn=1.4 - # Utilities - - graphviz=9.0 - - pandoc=3.1 - # Workflow dependencies: ANTs - - ants=2.5 - # Workflow dependencies: Convert3d - - convert3d=1.4 - # Workflow dependencies: FSL (versions pinned in 6.0.7.7) - - fsl-bet2=2111.4 - - fsl-flirt=2111.2 - - fsl-fast4=2111.3 - - fsl-fugue=2201.4 - - fsl-mcflirt=2111.0 - - fsl-miscmaths=2203.2 - - fsl-topup=2203.2 - - pip - - pip: - - -r requirements.txt +- python=3.13 +# Needed for svgo and bids-validator; consider moving to deno +- nodejs=20 +# Intel Math Kernel Library for numpy +- mkl=2024.2.2 +- mkl-service=2.4.2 +# git-annex for templateflow users with DataLad superdatasets +- git-annex=*=alldep* +# Base scientific python stack; required by FSL, so pinned here +- numpy=2.3 +- scipy=1.15 +- matplotlib=3.10 +- pandas=2.3 +- h5py=3.14 +# Dependencies compiled against numpy, best to stick with conda +- nitime=0.11 +- scikit-image=0.25 +- scikit-learn=1.7 +# Utilities +- graphviz=12.2 +- pandoc=3.7 +# Workflow dependencies: ANTs +- ants=2.6 +# Workflow dependencies: Connectome Workbench +- connectome-workbench-cli=2.0 +# Workflow dependencies: Convert3d +- convert3d=1.4 +# Workflow dependencies: FSL (versions pinned in 6.0.7.17.20250415.fe1c582e) +- fsl-bet2=2111.8 +- fsl-flirt=2111.4 +- fsl-fast4=2111.3 +- fsl-fugue=2201.5 +- fsl-mcflirt=2111.0 +- fsl-miscmaths=2412.4 +- fsl-topup=2203.5 +- pip +- pip: + - -r requirements.txt variables: FSLOUTPUTTYPE: NIFTI_GZ diff --git a/requirements.txt b/requirements.txt index 898987da..6f60ca49 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ # -# This file is autogenerated by pip-compile with Python 3.11 +# This file is autogenerated by pip-compile with Python 3.13 # by the following command: # # pip-compile --extra=container --output-file=requirements.txt --strip-extras pyproject.toml # -acres==0.3.0 +acres==0.5.0 # via # bidsschematools # nibabies (pyproject.toml) @@ -22,17 +22,15 @@ attrs==25.3.0 # via # niworkflows # sdcflows -backports-tarfile==1.2.0 - # via jaraco-context bids-validator==1.14.7.post0 # via pybids -bidsschematools==1.0.8 +bidsschematools==1.0.10 # via bids-validator bokeh==3.6.3 # via tedana -boto3==1.38.18 +boto3==1.38.35 # via datalad -botocore==1.38.18 +botocore==1.38.35 # via # boto3 # s3transfer @@ -46,7 +44,7 @@ ci-info==0.3.0 # via # etelemetry # migas -click==8.2.0 +click==8.2.1 # via # bidsschematools # nipype @@ -57,7 +55,7 @@ contourpy==1.3.2 # matplotlib cycler==0.12.1 # via matplotlib -datalad==1.1.6 +datalad==1.2.0 # via # datalad-next # datalad-osf @@ -76,15 +74,15 @@ fasteners==0.19 # via datalad filelock==3.18.0 # via nipype -fonttools==4.58.0 +fonttools==4.58.2 # via matplotlib formulaic==1.1.1 # via pybids frozendict==2.4.6 # via pybids -fsspec==2025.3.2 +fsspec==2025.5.1 # via universal-pathlib -h5py==3.13.0 +h5py==3.14.0 # via nitransforms humanize==4.12.3 # via @@ -94,18 +92,12 @@ idna==3.10 # via requests imageio==2.37.0 # via scikit-image -importlib-metadata==8.7.0 - # via keyring -importlib-resources==6.5.2 - # via nibabel -indexed-gzip==1.9.4 +indexed-gzip==1.9.5 # via smriprep interface-meta==1.3.0 # via formulaic iso8601==2.1.0 # via datalad -isodate==0.6.1 - # via rdflib jaraco-classes==3.4.0 # via # keyring @@ -124,7 +116,7 @@ jmespath==1.0.1 # via # boto3 # botocore -joblib==1.5.0 +joblib==1.5.1 # via # nilearn # robustica @@ -151,7 +143,6 @@ lxml==5.4.0 # via # nilearn # nireports - # prov # svgutils mapca==0.0.5 # via tedana @@ -176,7 +167,7 @@ more-itertools==10.7.0 # jaraco-functools msgpack==1.1.0 # via datalad -networkx==3.4.2 +networkx==3.5 # via # nipype # prov @@ -207,18 +198,18 @@ nipype==1.10.0 # niworkflows # sdcflows # smriprep -nireports==25.0.1 +nireports==25.2.0 # via # nibabies (pyproject.toml) # sdcflows nitime==0.11 # via nibabies (pyproject.toml) -nitransforms==24.1.1 +nitransforms==24.1.2 # via # nibabies (pyproject.toml) # niworkflows # sdcflows -niworkflows==1.13.3 +niworkflows==1.13.4 # via # nibabies (pyproject.toml) # sdcflows @@ -297,7 +288,7 @@ platformdirs==4.3.8 # pooch pooch==1.8.2 # via nibabies (pyproject.toml) -prov==2.0.1 +prov==2.0.2 # via nipype psutil==7.0.0 # via nibabies (pyproject.toml) @@ -316,7 +307,9 @@ pybtex==0.24.0 pybtex-apa-style==1.3 # via tedana pydot==4.0.0 - # via nipype + # via + # nipype + # prov pyparsing==3.2.3 # via # matplotlib @@ -329,7 +322,7 @@ python-dateutil==2.9.0.post0 # nipype # pandas # prov -python-gitlab==5.6.0 +python-gitlab==6.0.0 # via datalad pytz==2025.2 # via pandas @@ -341,11 +334,9 @@ pyyaml==6.0.2 # niworkflows # pybtex # smriprep -rdflib==6.3.2 - # via - # nipype - # prov -requests==2.32.3 +rdflib==7.1.4 + # via nipype +requests==2.32.4 # via # datalad # etelemetry @@ -360,7 +351,7 @@ requests-toolbelt==1.0.0 # via python-gitlab robustica==0.1.4 # via tedana -s3transfer==0.12.0 +s3transfer==0.13.0 # via boto3 scikit-image==0.25.2 # via @@ -387,19 +378,19 @@ scipy==1.15.2 # scikit-learn # sdcflows # tedana -sdcflows==2.13.0 +sdcflows==2.13.1 # via nibabies (pyproject.toml) seaborn==0.13.2 # via # nireports # niworkflows + # tedana simpleitk==2.5.0 # via nibabies (pyproject.toml) simplejson==3.20.1 # via nipype six==1.17.0 # via - # isodate # osfclient # pybtex # python-dateutil @@ -409,7 +400,7 @@ sqlalchemy==2.0.41 # via pybids svgutils==0.3.4 # via niworkflows -tedana==25.0.0 +tedana==25.0.1 # via nibabies (pyproject.toml) templateflow==24.2.2 # via @@ -422,13 +413,13 @@ threadpoolctl==3.6.0 # via # scikit-learn # tedana -tifffile==2025.5.10 +tifffile==2025.6.11 # via scikit-image toml==0.10.2 # via # nibabies (pyproject.toml) # sdcflows -tornado==6.5 +tornado==6.5.1 # via bokeh tqdm==4.67.1 # via @@ -441,10 +432,9 @@ traits==7.0.2 # via nipype transforms3d==0.4.2 # via niworkflows -typing-extensions==4.13.2 +typing-extensions==4.14.0 # via # formulaic - # nibabel # sqlalchemy tzdata==2025.2 # via pandas @@ -458,5 +448,3 @@ wrapt==1.17.2 # via formulaic xyzservices==2025.4.0 # via bokeh -zipp==3.21.0 - # via importlib-metadata diff --git a/tox.ini b/tox.ini index 7b9fb682..eb48d56d 100644 --- a/tox.ini +++ b/tox.ini @@ -2,9 +2,8 @@ requires = tox>=4 envlist = - py3{10,11,12}-latest - py310-min - py3{10,11,12}-pre + py3{10,11,12,13}-{latest,pre} + py313-min skip_missing_interpreters = true # Configuration that allows us to split tests across GitHub runners effectively @@ -13,6 +12,7 @@ python = 3.10: py310 3.11: py311 3.12: py312 + 3.13: py313 [gh-actions:env] DEPENDS = @@ -38,21 +38,18 @@ pass_env = CLICOLOR CLICOLOR_FORCE PYTHON_GIL +deps = + py313: traits @ git+https://github.com/enthought/traits.git@10954eb extras = test setenv = pre: PIP_EXTRA_INDEX_URL=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple -deps = - min: nibabel == 4.0.1 - min: nipype == 1.8.5 - min: nitransforms == 21.0.0 - min: numpy == 1.22 - min: psutil == 5.4 - min: pybids == 0.15.2 - min: tedana == 23.0.2 - min: templateflow == 24.1.0 + pre: UV_INDEX=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + pre: UV_INDEX_STRATEGY=unsafe-best-match +uv_resolution = + min: lowest-direct commands_pre = - python scripts/fetch_templates.py + py3{10,11,12,13}: python scripts/fetch_templates.py commands = pytest --cov-report term-missing --durations=20 --durations-min=1.0 {posargs:-n auto} diff --git a/wrapper/src/nibabies_wrapper/__main__.py b/wrapper/src/nibabies_wrapper/__main__.py index 46d5a578..6b459581 100755 --- a/wrapper/src/nibabies_wrapper/__main__.py +++ b/wrapper/src/nibabies_wrapper/__main__.py @@ -29,7 +29,7 @@ MISSING = """ Image '{}' is missing Would you like to download? [Y/n] """ -PKG_PATH = '/opt/conda/envs/nibabies/lib/python3.11/site-packages' +PKG_PATH = '/opt/conda/envs/nibabies/lib/python3.13/site-packages' TF_TEMPLATES = ( 'MNI152Lin', 'MNI152NLin2009cAsym',