Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ebc94ab
Add package installer tool for macos
OtabekRintaro Oct 15, 2025
ba16a01
Move docker and singularity into tools
OtabekRintaro Oct 15, 2025
101df1a
Create workflow for MacOS package deployment
OtabekRintaro Oct 15, 2025
6c67a96
Apply suggestions from code review
dkuegler Oct 17, 2025
f910b59
Reformat scripts and fix broken paths
OtabekRintaro Oct 22, 2025
6f50c3b
Upload assets instead of artifacts in deploy.yml
OtabekRintaro Oct 22, 2025
6ef6be8
Fix script imports style
OtabekRintaro Oct 22, 2025
ab05695
Add config file for tools
OtabekRintaro Oct 29, 2025
7731f72
This commit fixes a couple of effects to the docker build settings in…
dkuegler Oct 22, 2025
b992ed3
Fix MacOS documentation:
dkuegler Nov 4, 2025
4406f89
Fix missing build paths
OtabekRintaro Nov 4, 2025
302092e
Fix problem with float cast
OtabekRintaro Nov 4, 2025
e3364ff
Apply suggestions from code review
dkuegler Nov 4, 2025
aa8f852
Fix deployment workflow
OtabekRintaro Nov 5, 2025
82a8f2e
Apply suggestion from @m-reuter
m-reuter Nov 5, 2025
0bf71a4
Update installation instructions for MacOS
OtabekRintaro Nov 5, 2025
ff24f54
Update the macOS installation documentation.
dkuegler Nov 6, 2025
21feb8d
Fix backslash in docker installation instructions
dkuegler Nov 6, 2025
2384a17
Apply suggestion from @m-reuter
m-reuter Nov 6, 2025
ba07f37
Apply suggestions from reviews
OtabekRintaro Nov 14, 2025
f94e498
Fix workflow missing dependency
OtabekRintaro Nov 14, 2025
2bb3416
Install aria2 (and aria2c) in the Docker base build image, so the fre…
dkuegler Nov 12, 2025
a8f8084
terminate install_fs_pruned if download is not successful!
dkuegler Nov 14, 2025
ea21063
Run py2app directly in macos_build directory
OtabekRintaro Nov 14, 2025
a4867ea
Formatting changes in install_fs_pruned.sh
dkuegler Nov 14, 2025
3771eb4
fix typo in error message
m-reuter Nov 18, 2025
3a8311c
fix English
m-reuter Nov 18, 2025
937e0e8
Fix Copilot comments.
dkuegler Nov 18, 2025
b8328ed
Fix applet generation
OtabekRintaro Nov 18, 2025
9045517
Add claryfing comments to brew update
OtabekRintaro Nov 18, 2025
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
5 changes: 3 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
**/.git
**/.github
checkpoints
Singularity
doc
test
venv
Tutorial
**/*.md
Docker/Dockerfile*
/tools/Docker/Dockerfile*
/tools/macos_build
/tools/export_pip-r.sh
*.txt
venv
/srun_fastsurfer.sh
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/build-docker/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ runs:
image_name="fastsurfer:cpu-${v/+/_}"
fi
if [[ -z "$(which python)" ]] ; then echo "ERROR: Cannot find python!" ; fi
cmd=(python "$FASTSURFER_HOME/Docker/build.py" --device cpu --tag "$image_name" --target "${{ inputs.target }}")
cmd=(python "$FASTSURFER_HOME/tools/Docker/build.py" --device cpu --tag "$image_name" --target "${{ inputs.target }}")
if [[ "${{ inputs.freesurfer-build-image }}" != "rebuild" ]] ; then
cmd+=(--freesurfer_build_image "${{ inputs.freesurfer-build-image }}")
fi
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/QUICKTEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This job sets up the necessary environments for the workflow. It depends on the

### Build Singularity Image

This job builds a Docker image and converts it to a Singularity image. It depends on the successful completion of the `prepare-job`. The Docker image is built using a Python script `Docker/build.py` with the `--device cuda --tag fastsurfer_gpu:cuda` flags. The Docker image is then converted to a Singularity image.
This job builds a Docker image and converts it to a Singularity image. It depends on the successful completion of the `prepare-job`. The Docker image is built using a Python script `tools/Docker/build.py` with the `--device cuda --tag fastsurfer_gpu:cuda` flags. The Docker image is then converted to a Singularity image.

### Run FastSurfer

Expand Down
75 changes: 35 additions & 40 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,55 +1,50 @@
name: MAN deploy-docker
name: MAN release/deploy

on:
# release:
# types:
# - published
release:
types:
- published
workflow_dispatch:

jobs:
deploy-gpu:
runs-on: ubuntu-latest
deploy-mac:
runs-on: macos-14
timeout-minutes: 120

env:
RELEASE_ASSETS: true
strategy:
matrix:
arch: [intel, arm]
steps:
- name: Get repository name.
run: echo "FASTSURFER_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker
uses: docker/login-action@v2
- name: Set up python environment
uses: actions/setup-python@v6
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build Docker image GPU
run: python Docker/build.py --device cuda --tag ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:gpu-${{ github.event.release.tag_name }}
- name: Add additional tags
python-version: '3.10'
- name: install dependencies
run: |
docker tag ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:gpu-${{ github.event.release.tag_name }} ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:gpu-latest
docker tag ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:gpu-${{ github.event.release.tag_name }} ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:latest
- name: Push Docker image GPU
run: docker push --all-tags ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:gpu-${{ github.event.release.tag_name }}
deploy-cpu:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build Docker image CPU
run: python Docker/build.py --device cpu --tag ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:cpu-${{ github.event.release.tag_name }}
- name: Add additional tags
python -m pip install py2app tomli

# update system to the newest version, not pin pointing package version on purpose
brew update
brew upgrade || true
brew install aria2
- name: package app for ${{ matrix.arch }}
run: tools/macos_build/build_release_package.sh ${{ matrix.arch }}
- name: Move assets.
if: env.RELEASE_ASSETS == 'true'
run: |
docker tag ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:cpu-${{ github.event.release.tag_name }} ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:cpu-latest
- name: Push Docker image CPU
run: docker push --all-tags ${{ secrets.DOCKERHUB_USERNAME }}/fastsurfer:cpu-${{ github.event.release.tag_name }}
mkdir assets
mv tools/macos_build/installer/* assets/
- name: Upload release assets.
uses: softprops/action-gh-release@v2
if: env.RELEASE_ASSETS == 'true'
with:
files: ${{ env.FASTSURFER_DIR }}/assets/*

14 changes: 6 additions & 8 deletions .github/workflows/quicktest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ on:
default: build-cached
type: string
freesurfer-build-image:
description: 'FreeSurfer build image to build with ("" (default) => deepmi/fastsurfer-build:freesurferXXX; extract version from Docker/install_fs_pruned.sh)'
description: 'FreeSurfer build image to build with ("" (default) => deepmi/fastsurfer-build:freesurferXXX; extract version from pyproject.toml)'
type: string

permissions:
Expand Down Expand Up @@ -139,10 +139,11 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ steps.parse.outputs.DOCKER_IMAGE }}
- name: Setup Python 3.10
- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.11'
# python 3.11 is needed to read pyproject.toml (tomllib)
architecture: 'x64'
# no cache is needed, no installations and no cache is faster
# cache: 'pip' # caching pip dependencies
Expand All @@ -152,12 +153,9 @@ jobs:
shell: bash
id: parse-version
run: |
# get the FreeSurfer version from install_fs_pruned.sh
# get the FreeSurfer version from pyproject.toml
{
fslink="$(grep "^fslink=" ./Docker/install_fs_pruned.sh)"
fslink="${fslink:7}"
if [[ "${fslink:0:1}" == '"' ]] || [[ "${fslink:0:1}" == "'" ]] ; then fslink="${fslink:1:-1}" ; fi
fs_version="$(basename "$(dirname "$fslink")")"
fs_version="$(python ./tools/read_toml.py --file ./pyproject.toml --key tool.freesurfer.version)"
fs_version_short="${fs_version//\./}"
echo "FS_VERSION=$fs_version"
echo "FS_VERSION_SHORT=$fs_version_short"
Expand Down
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/BUILD.info
/Docker/BUILD.info
/Docker/custom-ssl.crt
/tools/Docker/BUILD.info
/tools/Docker/custom-ssl.crt
/.idea/**
/rough_work/**

Expand All @@ -9,3 +9,5 @@ __pycache__/
*.py[cod]
*$py.class
*/stub

.DS_Store
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion FastSurferCNN/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def eval(

# add prediction logits into the output (same as multiplying probabilities)
ii[index_of_current_plane] = slice(start_index, end_index)
out[tuple(ii)].add_(pred, alpha=self.alpha.get(plane, 0.4))
out[tuple(ii)].add_(pred.half(), alpha=self.alpha.get(plane, 0.4))
start_index = end_index

except:
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ Notwithstanding module-specific limitations, resolution should be between 1mm an
## Getting started

### Installation
There are two ways to run FastSurfer (links are to installation instructions):
There are three ways to run FastSurfer (links are to installation instructions):

1. In a container ([Singularity](doc/overview/INSTALL.md#singularity) or [Docker](doc/overview/INSTALL.md#docker)) (OS: [Linux](doc/overview/INSTALL.md#linux), [Windows](doc/overview/INSTALL.md#windows), [MacOS on Intel](doc/overview/INSTALL.md#docker-currently-only-supported-for-intel-cpus)),
2. As a [native install](doc/overview/INSTALL.md#native-ubuntu-2004-or-ubuntu-2204) (all OS for segmentation part).
1. For Linux and Windows users, we recommend running FastSurfer in a container [Singularity/Apptainer](doc/overview/INSTALL.md#singularity) or [Docker](doc/overview/INSTALL.md#docker): (OS: [Linux](doc/overview/INSTALL.md#linux), [Windows](doc/overview/INSTALL.md#windows), [MacOS on Intel](doc/overview/INSTALL.md#docker-currently-only-supported-for-intel-cpus)),
2. for macOS users, we recommend [installing the FastSurfer package](doc/overview/INSTALL.md#package), and
3. for developers, the native install gives full control (only documented for [Linux](doc/overview/INSTALL.md#native-ubuntu-2004-or-ubuntu-2204)).

We recommended you use Singularity or Docker on a Linux host system with a GPU. The images we provide on [DockerHub](https://hub.docker.com/r/deepmi/fastsurfer) conveniently include everything needed for FastSurfer. You will also need a [FreeSurfer license](https://surfer.nmr.mgh.harvard.edu/fswiki/License) file for the [Surface pipeline](#surface-reconstruction). We have detailed per-OS Installation instructions in the [INSTALL.md](doc/overview/INSTALL.md) file.
The images we provide on [DockerHub](https://hub.docker.com/r/deepmi/fastsurfer) conveniently include everything needed for FastSurfer. You will also need a [FreeSurfer license](https://surfer.nmr.mgh.harvard.edu/fswiki/License) file for the [Surface pipeline](#surface-reconstruction). We have detailed per-OS Installation instructions in the [INSTALL.md](doc/overview/INSTALL.md) file.

### Usage

Expand All @@ -76,11 +77,11 @@ All installation methods use the `run_fastsurfer.sh` call interface (replace `*f
```
The `--nv` flag is needed to allow FastSurfer to run on the GPU (otherwise FastSurfer will run on the CPU).

The `--no-home` flag tells singularity to not mount the home directory (see [Singularity documentation](Singularity/README.md#mounting-home) for more info).
The `--no-home` flag tells singularity to not mount the home directory (see [Singularity documentation](doc/overview/SINGULARITY.md#mounting-home) for more info).

The `-B` flag is used to tell singularity, which folders FastSurfer can read and write to.

See also __[Example 2](doc/overview/EXAMPLES.md#example-2-fastsurfer-singularity)__ for a full singularity FastSurfer run command and [the Singularity documentation](Singularity/README.md#fastsurfer-singularity-image-usage) for details on more singularity flags.
See also __[Example 2](doc/overview/EXAMPLES.md#example-2-fastsurfer-singularity)__ for a full singularity FastSurfer run command and [the Singularity documentation](doc/overview/SINGULARITY.md#fastsurfer-singularity-image-usage) for details on more singularity flags.

(b) For __docker__, the syntax is
```
Expand All @@ -96,7 +97,7 @@ All installation methods use the `run_fastsurfer.sh` call interface (replace `*f

The `-v` flag is used to tell docker, which folders FastSurfer can read and write to.

See also __[Example 1](doc/overview/EXAMPLES.md#example-1-fastsurfer-docker)__ for a full FastSurfer run inside a Docker container and [the Docker documentation](Docker/README.md#docker-flags) for more details on the docker flags including `--rm` and `--user`.
See also __[Example 1](doc/overview/EXAMPLES.md#example-1-fastsurfer-docker)__ for a full FastSurfer run inside a Docker container and [the Docker documentation](tools/Docker/README.md#docker-flags) for more details on the docker flags including `--rm` and `--user`.

2. For a __native install__, you need to activate your FastSurfer environment (e.g. `conda activate fastsurfer_gpu`) and make sure you have added the FastSurfer path to your `PYTHONPATH` variable, e.g. `export PYTHONPATH=$(pwd)`.

Expand Down
4 changes: 2 additions & 2 deletions Tutorial/Complete_FastSurfer_Tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@
"\n",
"For [conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html) you are creating a [conda environment](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html#managing-environments) containing all the dependencies (fastsurfer_gpu or fastsurfer_cpu). You need to activate this environment with conda activate. To deactivate it, simply type conda deactivate. You have to activate the environment every time you want to run FastSurfer code.\n",
"\n",
"For [docker](https://docs.docker.com/), you are simply downloading the fastsurfer image (deepmi/fastsurfer:gpu-v2.0.0). Alternatively, you could also download deepmi/fastsurfer:segonly-gpu-v2.0.0, deepmi/fastsurfer:segonly-cpu-v2.0.0, deepmi/fastsurfer:cpu-v2.0.0 or deepmi/fastsurfer:surfonly-cpu-v2.0.0. The first part of the name indicates what you are running (fastsurfer from the deepmi website). The tag is split into two parts. The first defines what part of the pipeline you can run with it (segonly=only segmentation, surfonly=only surface pipeline, no prefix=both options can be run) and the second defines on what you run it (cpu or gpu). If you want to modify the image, you can find the Dockerfiles the images are based on in our github page (in the [Docker folder](https://github.com/Deep-MI/FastSurfer/blob/stable/Docker/)). The [README](https://github.com/Deep-MI/FastSurfer/blob/stable/Docker/README.md) there also contains information on how to build the docker from source."
"For [docker](https://docs.docker.com/), you are simply downloading the fastsurfer image (deepmi/fastsurfer:gpu-v2.0.0). Alternatively, you could also download deepmi/fastsurfer:segonly-gpu-v2.0.0, deepmi/fastsurfer:segonly-cpu-v2.0.0, deepmi/fastsurfer:cpu-v2.0.0 or deepmi/fastsurfer:surfonly-cpu-v2.0.0. The first part of the name indicates what you are running (fastsurfer from the deepmi website). The tag is split into two parts. The first defines what part of the pipeline you can run with it (segonly=only segmentation, surfonly=only surface pipeline, no prefix=both options can be run) and the second defines on what you run it (cpu or gpu). If you want to modify the image, you can find the Dockerfiles the images are based on in our github page (in the [Docker folder](https://github.com/Deep-MI/FastSurfer/blob/dev/tools/Docker/)). The [README](https://github.com/Deep-MI/FastSurfer/blob/dev/tools/Docker/README.md) there also contains information on how to build the docker from source."
]
},
{
Expand Down Expand Up @@ -2192,7 +2192,7 @@
"\n",
"For [conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html) you are creating a [conda environment](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html#managing-environments) containing all the dependencies (fastsurfer_gpu or fastsurfer_cpu). You need to activate this environment with conda activate. To deactivate it, simply type conda deactivate. You have to activate the environment every time you want to run FastSurfer code.\n",
"\n",
"For [docker](https://docs.docker.com/), you are simply downloading the fastsurfer image (deepmi/fastsurfer:gpu-v2.0.0. Alternatively, you could also download deepmi/fastsurfer:segonly-gpu-v2.0.0, deepmi/fastsurfer:segonly-cpu-v2.0.0, deepmi/fastsurfer:cpu-v2.0.0 or deepmi/fastsurfer:surfonly-cpu-v2.0.0. The first part of the name indicates what you are running (fastsurfer from the deepmi website). The tag is split into two parts. The first defines what part of the pipeline you can run with it (segonly=only segmentation, surfonly=only surface pipeline, no prefix=both options can be run) and the second defines on what you run it (cpu or gpu). If you want to modify the image, you can find the Dockerfiles the images are based on in our github page (in the [Docker folder](https://github.com/Deep-MI/FastSurfer/blob/stable/Docker/)). The [README](https://github.com/Deep-MI/FastSurfer/blob/stable/Docker/README.md) there also contains information on how to build the docker from source."
"For [docker](https://docs.docker.com/), you are simply downloading the fastsurfer image (deepmi/fastsurfer:gpu-v2.0.0. Alternatively, you could also download deepmi/fastsurfer:segonly-gpu-v2.0.0, deepmi/fastsurfer:segonly-cpu-v2.0.0, deepmi/fastsurfer:cpu-v2.0.0 or deepmi/fastsurfer:surfonly-cpu-v2.0.0. The first part of the name indicates what you are running (fastsurfer from the deepmi website). The tag is split into two parts. The first defines what part of the pipeline you can run with it (segonly=only segmentation, surfonly=only surface pipeline, no prefix=both options can be run) and the second defines on what you run it (cpu or gpu). If you want to modify the image, you can find the Dockerfiles the images are based on in our github page (in the [Docker folder](https://github.com/Deep-MI/FastSurfer/blob/dev/tools/Docker/)). The [README](https://github.com/Deep-MI/FastSurfer/blob/dev/tools/Docker/README.md) there also contains information on how to build the docker from source."
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ def linkcode_resolve(domain, info):
"^/?(.*)#(.*)ubuntu-(\\d{2})(\\d{2})": ("/\\1#\\2ubuntu-\\3-\\4",),
f"{_up}readme{_end}": ("/index.rst\\1", "/overview/intro.rst\\1"),
"^/overview/intro(#.*)?$": ("/overview/index.rst\\2",),
f"{_up}(singularity|docker)/readme{_end}": ("/overview/\\1.rst\\2",),
f"{_up}/tools/docker/readme{_end}": ("/overview/docker.rst\\2",),
f"{_up}({_re_script_dirs})/readme{_end}": ("/scripts/\\1.rst\\2",),
f"{_up}license": ("/overview/license.rst",),
}
Expand Down
Binary file added doc/images/fastsurfer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions doc/overview/EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ Note, that the paths following `--fs_license`, `--t1`, and `--sd` are __inside__

A directory with the name as specified in `--sid` (here subjectX) will be created in the output directory if it does not exist. So in this example output will be written to /home/user/my_fastsurfer_analysis/subjectX/ . Make sure the output directory is empty, to avoid overwriting existing files.

If you do not have a GPU, you can also run our CPU-Docker by dropping the `--gpus all` flag and specifying `--device cpu` at the end as a FastSurfer flag, see also [FastSurfer's docker documentation](../../Docker/README.md) for more details.
If you do not have a GPU, you can also run our CPU-Docker by dropping the `--gpus all` flag and specifying `--device cpu` at the end as a FastSurfer flag, see also [FastSurfer's docker documentation](../../tools/Docker/README.md) for more details.

## Example 2: FastSurfer Singularity
After building the Singularity image (see below or [these instructions](../../Singularity/README.md)), you also need to register at the FreeSurfer website (https://surfer.nmr.mgh.harvard.edu/registration.html) to acquire a valid license (for free) - same as when using Docker. This license needs to be passed to the script via the `--fs_license` flag. This is not necessary if you want to run the segmentation only.
After building the Singularity image (see below or [these instructions](SINGULARITY.md)), you also need to register at the FreeSurfer website (https://surfer.nmr.mgh.harvard.edu/registration.html) to acquire a valid license (for free) - same as when using Docker. This license needs to be passed to the script via the `--fs_license` flag. This is not necessary if you want to run the segmentation only.

To run FastSurfer on a given subject using the Singularity image with GPU access, execute the following commands from a directory where you want to store singularity images. This will create a singularity image from our Dockerhub image and execute it:

Expand Down
Loading