Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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
10 changes: 5 additions & 5 deletions .github/workflows/check-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
42 changes: 26 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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/*

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# JupyterLab for Medical Image Processing (MedImProc)

<!-- TODO'S
- DONE fix build process
- bump version to 2.2.0 after bump in FreeSurfer + make sure pipeline Fariba runs end to end
- add version details in the README
- add badges
- then keep going through modernization plan (reduce image size, build time etc); add these learning to my Obsidian notes
- in future, download FreeSurfer 8.1.0 .deb and put in filesrv and fetch from there (like in ASCENT service) so we can have the latest version without increasing build time
-->
Comment on lines +3 to +10
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address this TODO and remove it


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.
<!-- - [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).

Expand Down
14 changes: 8 additions & 6 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -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
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
Loading