diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..12ae213 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,50 @@ +# Git files +.git +.gitignore +.gitattributes + +# Documentation +*.md +!README.md +UPDATING_FREESURFER.md +MODERNIZATION_PLAN.md + +# Docker files (except those needed for build) +docker-compose*.yml +MultiStage_Dockerfile + +# Validation and test data +validation/ +Fariba_full_pipeline/TVB1/ + +# Python cache +**/__pycache__ +**/*.pyc +**/*.pyo +**/*.pyd +.Python +*.so +*.egg +*.egg-info +dist/ +build/ + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Temporary files +*.tmp +*.log +.cache/ + +# Jupyter notebook checkpoints +.ipynb_checkpoints/ + +# Only include specific notebooks needed in the image +validation/workspace/*.ipynb +!README.ipynb diff --git a/.github/workflows/check-image.yml b/.github/workflows/check-image.yml index 8f4bb78..1b6a4ed 100644 --- a/.github/workflows/check-image.yml +++ b/.github/workflows/check-image.yml @@ -13,11 +13,11 @@ jobs: - name: Checkout repo content uses: actions/checkout@v3 - name: ooil version - uses: docker://itisfoundation/ci-service-integration-library:v2.0.10 + uses: docker://itisfoundation/ci-service-integration-library:v2.1.27 with: args: ooil --version - name: Assemble docker compose spec - uses: docker://itisfoundation/ci-service-integration-library:v2.0.10 + uses: docker://itisfoundation/ci-service-integration-library:v2.1.27 with: args: ooil compose - name: create new dir @@ -44,8 +44,8 @@ jobs: - name: check disk space before image build run: df -h - name: Build all images if multiple - uses: docker://itisfoundation/ci-service-integration-library:v2.0.10 + uses: docker://itisfoundation/ci-service-integration-library:v2.1.27 with: - args: docker compose build --quiet + args: docker compose build --progress=plain - name: print docker image info - run: docker images + run: docker images \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 2f4f6c8..7f5fb48 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ -## Refactor as normal (ie no multistage) dockerfile -## also have a smaller base image +## Multi-stage build: use FreeSurfer official Docker image to avoid slow server downloads +FROM freesurfer/freesurfer:7.4.1@sha256:10b6468cbd9fcd2db3708f4651d59ad75d4da849a2c5d8bb6dba217f08b8c46b as freesurfer-source + +## Main build stage FROM itisfoundation/jupyter-math:2.0.9 as main LABEL maintainer="ordonez" USER root @@ -17,7 +19,10 @@ RUN apt-get -qq update \ libqt5opengl5-dev \ libqt5svg5-dev \ libtiff5-dev \ - qt5-default \ + qtbase5-dev \ + qtchooser \ + qt5-qmake \ + qtbase5-dev-tools \ zlib1g-dev \ && rm -rf /var/lib/apt/lists/* @@ -40,19 +45,22 @@ ENV ANTSPATH="$HOME/ants/bin" \ PATH="$HOME/mrtrix3/bin:$HOME/ants/bin:$HOME/art/bin:$PATH" ############################################################ -## Freesurfer +## Freesurfer v7.4.1 (copied from official Docker image to avoid slow download) WORKDIR ${HOME} +# Install FreeSurfer runtime dependencies RUN apt-get update && apt-get install -y tcsh bc libgomp1 perl-modules \ && rm -rf /var/lib/apt/lists/* -RUN wget -N -qO- ftp://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.0/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.0.tar.gz | tar -xzv -C ${HOME} -# \ && rm -rf ${HOME}/freesurfer/subjects # we actually need subjects/fsaverage for recon-all -ENV FREESURFER_HOME ${HOME}/freesurfer -COPY freesurfer_license.txt ${FREESURFER_HOME}/license.txt -ENV FSFAST_HOME==$FREESURFER_HOME/fsfast \ - MINC_BIN_DIR=$FREESURFER_HOME/mni/bin \ - MNI_DIR=$FREESURFER_HOME/mni \ - PERL5LIB=$FREESURFER_HOME/mni/share/perl5 +# Copy FreeSurfer installation from official Docker image +COPY --from=freesurfer-source /usr/local/freesurfer /usr/local/freesurfer +# Set up FreeSurfer environment variables +ENV FREESURFER_HOME=/usr/local/freesurfer/7.4.1 \ + FSFAST_HOME=$FREESURFER_HOME/fsfast \ + MINC_BIN_DIR=$FREESURFER_HOME/mni/bin \ + MNI_DIR=$FREESURFER_HOME/mni \ + PERL5LIB=$FREESURFER_HOME/mni/share/perl5 ENV PATH=$FREESURFER_HOME/bin:$MINC_BIN_DIR:$PATH +# Copy license file to FreeSurfer home (v7 method) +COPY freesurfer_license.txt $FREESURFER_HOME/license.txt ############################################################ ## FSL @@ -119,17 +127,19 @@ ENV PATH=$PATH:$HOME/c3d-1.0.0-Linux-x86_64/bin/ ############################################################ ## python packages in requirements.in -## before pip install fsleyes, we need to install wxPython: +## fsleyes requires wxPython, which has pre-built wheels available WORKDIR ${HOME} -RUN .venv/bin/pip --no-cache install -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxpython &&\ - .venv/bin/pip install attrdict COPY --chown=$NB_UID:$NB_GID requirements.in ${NOTEBOOK_BASE_DIR}/requirements.in RUN .venv/bin/pip --no-cache install pip-tools &&\ ## rename the previously existing "requirements.txt" from the jupyter-math service (we want to keep it for user reference) mv ${NOTEBOOK_BASE_DIR}/requirements.txt ${NOTEBOOK_BASE_DIR}/requirements_base_math.txt &&\ + ## Run pip-compile with find-links and only-binary to ensure wxpython wheel is used + PIP_FIND_LINKS=https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 \ + PIP_ONLY_BINARY=wxpython \ .venv/bin/pip-compile --build-isolation --output-file ${NOTEBOOK_BASE_DIR}/requirements.txt ${NOTEBOOK_BASE_DIR}/requirements.in &&\ - .venv/bin/pip --no-cache install -r ${NOTEBOOK_BASE_DIR}/requirements.txt && \ + ## Install all packages, ensuring wxpython comes from the wheel + .venv/bin/pip --no-cache install --only-binary=wxpython --find-links https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 -r ${NOTEBOOK_BASE_DIR}/requirements.txt && \ rm ${NOTEBOOK_BASE_DIR}/requirements.in && \ echo "Your environment contains these python packages:" && \ .venv/bin/pip list diff --git a/Makefile b/Makefile index da87b7a..e02ca50 100755 --- a/Makefile +++ b/Makefile @@ -5,13 +5,14 @@ SHELL = /bin/sh export DOCKER_IMAGE_NAME ?= jupyter-medimproc export DOCKER_IMAGE_TAG ?= 1.2.1 +export CI_SERVICE_INTEGRATION_LIBRARY ?= itisfoundation/ci-service-integration-library:v2.1.25 define _bumpversion # upgrades as $(subst $(1),,$@) version, commits and tags @docker run -it --rm -v $(PWD):/${DOCKER_IMAGE_NAME} \ -u $(shell id -u):$(shell id -g) \ - itisfoundation/ci-service-integration-library:v2.0.10 \ + ${CI_SERVICE_INTEGRATION_LIBRARY} \ sh -c "cd /${DOCKER_IMAGE_NAME} && bump2version --verbose --config-file $(1) $(subst $(2),,$@)" endef @@ -25,7 +26,7 @@ version-patch version-minor version-major: .bumpversion.cfg ## increases service compose-spec: ## runs ooil to assemble the docker-compose.yml file @docker run -it --rm -v $(PWD):/${DOCKER_IMAGE_NAME} \ -u $(shell id -u):$(shell id -g) \ - itisfoundation/ci-service-integration-library:v2.0.10 \ + ${CI_SERVICE_INTEGRATION_LIBRARY} \ sh -c "cd /${DOCKER_IMAGE_NAME} && ooil compose" .PHONY: build diff --git a/README.md b/README.md index 0515237..8654660 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,20 @@ # JupyterLab for Medical Image Processing (MedImProc) + + This is the source code of the JupyterLab Medical Image Processing OSPARC service. It is mostly centered on MRI data, and contains the following packages: "[JupyterLab](https://jupyter.org/) with a variety of Medical Image Processing packages pre-installed, mostly centered on MRI data: - [FSL](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki), a comprehensive library of analysis tools for FMRI, MRI and DTI brain imaging data. - - [FreeSurfer](https://surfer.nmr.mgh.harvard.edu/), an open source neuroimaging toolkit for processing, analyzing, and visualizing human brain MR images- + - [FreeSurfer](https://surfer.nmr.mgh.harvard.edu/) version 7.4.1 (June 2023), an open source neuroimaging toolkit for processing, analyzing, and visualizing human brain MR images. - [MRtrix3](https://www.mrtrix.org/) provides a set of tools to perform various types of diffusion MRI analyses. - - [Spinal Cord Toolbox](https://spinalcordtoolbox.com/), a comprehensive, free and open-source set of command-line tools dedicated to the processing and analysis of spinal cord MRI data. + - [Synb0 Disco](https://github.com/MASILab/Synb0-DISCO#readme), for distortion correction of diffusion weighted MRI without reverse phase-encoding scans or field-maps. - Python packages like [nibabel](https://nipy.org/nibabel/), [pyvista](https://docs.pyvista.org/version/stable/), [fsleyes](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLeyes) and [cc3d](https://github.com/seung-lab/connected-components-3d#readme). diff --git a/requirements.in b/requirements.in index b62f4d1..ca3903b 100755 --- a/requirements.in +++ b/requirements.in @@ -1,7 +1,9 @@ -nibabel -pyvista +# Medical image processing and visualization packages +# Pinned versions for reproducibility (checked December 2025) -PyOpenGL -PyOpenGL_accelerate -fsleyes -connected-components-3d \ No newline at end of file +nibabel==5.3.2 # 23 Oct 2024 +pyvista==0.46.4 # 30 Oct 2025 +PyOpenGL==3.1.10 # 18 Aug 2025 +PyOpenGL_accelerate==3.1.10 # 18 Aug 2025 +fsleyes==1.16.3 # 21 Nov 2025 +connected-components-3d==3.26.1 # 3 Nov 2025