forked from sofia-urosa/brain-masking
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ccedd9d
commit 542c18c
Showing
18 changed files
with
400 additions
and
375 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.git | ||
.mambaenv | ||
*.egg-info | ||
__pycache__ | ||
|
||
.dockerignore | ||
Dockerfile | ||
|
||
/in | ||
/out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Continuous integration testing for ChRIS Plugin. | ||
# https://github.com/FNNDSC/python-chrisapp-template/wiki/Continuous-Integration | ||
# | ||
# - on push and PR: run pytest | ||
# - on push to main: build and push container images as ":latest" | ||
# - on push to semver tag: build and push container image with tag and | ||
# upload plugin description to https://chrisstore.co | ||
|
||
name: build | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
tags: | ||
- "v?[0-9]+.[0-9]+.[0-9]+*" | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: ubuntu-22.04 | ||
|
||
steps: | ||
- name: Decide image tags | ||
id: info | ||
shell: python | ||
run: | | ||
import os | ||
import itertools | ||
def join_tag(t): | ||
registry, repo, tag = t | ||
return f'{registry}/{repo}:{tag}'.lower() | ||
registries = ['docker.io', 'ghcr.io'] | ||
repos = ['${{ github.repository }}'] | ||
if '${{ github.ref_type }}' == 'branch': | ||
tags = ['latest'] | ||
elif '${{ github.ref_type }}' == 'tag': | ||
tag = '${{ github.ref_name }}' | ||
version = tag[1:] if tag.startswith('v') else tag | ||
tags = ['latest', version] | ||
else: | ||
tags = [] | ||
if '${{ github.ref_type }}' == 'tag': | ||
local_tag = join_tag(('ghcr.io', '${{ github.repository }}', version)) | ||
else: | ||
local_tag = join_tag(('localhost', '${{ github.repository }}', 'latest')) | ||
product = itertools.product(registries, repos, tags) | ||
tags_csv = ','.join(map(join_tag, product)) | ||
outputs = { | ||
'tags_csv' : tags_csv, | ||
'push' : 'true' if tags_csv else 'false', | ||
'local_tag': local_tag | ||
} | ||
with open(os.environ['GITHUB_OUTPUT'], 'a') as out: | ||
for k, v in outputs.items(): | ||
out.write(f'{k}={v}\n') | ||
- uses: actions/checkout@v3 | ||
- uses: docker/setup-buildx-action@v3 | ||
with: | ||
driver-opts: network=host | ||
|
||
# Here, we want to do the docker build twice: | ||
# The first build pushes to our local registry for testing. | ||
# The second build pushes to Docker Hub and ghcr.io | ||
- name: Build (local only) | ||
uses: docker/build-push-action@v3 | ||
id: docker_build | ||
with: | ||
context: . | ||
file: ./Dockerfile | ||
tags: ${{ steps.info.outputs.local_tag }} | ||
load: true | ||
cache-from: type=gha | ||
|
||
- name: Login to DockerHub | ||
if: (github.event_name == 'push' || github.event_name == 'release') && contains(steps.info.outputs.tags_csv, 'docker.io') | ||
uses: docker/login-action@v3 | ||
with: | ||
username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
password: ${{ secrets.DOCKERHUB_PASSWORD }} | ||
- name: Login to GitHub Container Registry | ||
if: (github.event_name == 'push' || github.event_name == 'release') && contains(steps.info.outputs.tags_csv, 'ghcr.io') | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.repository_owner }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Build and push | ||
uses: docker/build-push-action@v3 | ||
if: (github.event_name == 'push' || github.event_name == 'release') | ||
with: | ||
context: . | ||
file: ./Dockerfile | ||
tags: ${{ steps.info.outputs.tags_csv }} | ||
platforms: linux/amd64 | ||
push: ${{ steps.info.outputs.push }} | ||
cache-to: type=gha,mode=max | ||
|
||
- name: Upload ChRIS Plugin | ||
id: upload | ||
if: github.ref_type == 'tag' | ||
uses: FNNDSC/upload-chris-plugin@v1 | ||
with: | ||
dock_image: ${{ steps.info.outputs.local_tag }} | ||
username: ${{ secrets.CHRISPROJECT_USERNAME }} | ||
password: ${{ secrets.CHRISPROJECT_PASSWORD }} | ||
chris_url: https://cube.chrisproject.org/api/v1/ | ||
compute_names: galena | ||
|
||
- name: Update DockerHub description | ||
if: steps.upload.outcome == 'success' | ||
uses: peter-evans/dockerhub-description@v3 | ||
continue-on-error: true # it is not crucial that this works | ||
with: | ||
username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
password: ${{ secrets.DOCKERHUB_PASSWORD }} | ||
short-description: ${{ steps.upload.outputs.title }} | ||
readme-filepath: ./README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
__pycache__ | ||
*.egg-info | ||
|
||
.idea | ||
.mambaenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM docker.io/tensorflow/tensorflow:2.11.0 | ||
|
||
COPY requirements.txt /app/requirements.txt | ||
RUN --mount=type=cache,target=/root/.cache,sharing=private pip install -r /app/requirements.txt | ||
|
||
COPY . /app | ||
RUN pip install /app && rm -rf /app | ||
|
||
CMD ["emerald"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
__version__ = '0.1.0' | ||
|
||
DISPLAY_TITLE = r""" | ||
_ _ _ | ||
| | | | | | | ||
_ __ | |______ ___ _ __ ___ ___ _ __ __ _| | __| | | ||
| '_ \| |______/ _ \ '_ ` _ \ / _ \ '__/ _` | |/ _` | | ||
| |_) | | | __/ | | | | | __/ | | (_| | | (_| | | ||
| .__/|_| \___|_| |_| |_|\___|_| \__,_|_|\__,_| | ||
| | | ||
|_| | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/usr/bin/env python | ||
|
||
from pathlib import Path | ||
from argparse import ArgumentParser, Namespace, ArgumentDefaultsHelpFormatter | ||
|
||
from chris_plugin import chris_plugin, PathMapper, curry_name_mapper | ||
|
||
from emerald import DISPLAY_TITLE | ||
from emerald.emerald import emerald | ||
from emerald.model import Unet | ||
from skimage.morphology import square, disk, cube | ||
|
||
|
||
__AVAILABLE_FUNCTIONS = [square, disk, cube] | ||
"""Functions which (might) get called by eval.""" | ||
|
||
|
||
parser = ArgumentParser(description='Fetal brain masking', | ||
formatter_class=ArgumentDefaultsHelpFormatter) | ||
parser.add_argument('-p', '--pattern', type=str, default='**/*.nii', | ||
help='Input files pattern') | ||
parser.add_argument('-s', '--output-suffix', type=str, default='_mask.nii', | ||
help='Output file suffix') | ||
parser.add_argument('--no-post-processing', dest='post_processing', action='store_false', | ||
help='Predicted mask should not be post processed (morphological closing and defragmentation)') | ||
parser.add_argument('--dilation-footprint', default='disk(2)', type=str, | ||
help='Dilation footprint: either a Python expression or None.') | ||
|
||
|
||
@chris_plugin( | ||
parser=parser, | ||
title='Fetal brain masking', | ||
category='MRI', | ||
min_memory_limit='2Gi', # supported units: Mi, Gi | ||
min_cpu_limit='1000m', # millicores, e.g. "1000m" = 1 CPU core | ||
min_gpu_limit=0 # set min_gpu_limit=1 to enable GPU | ||
) | ||
def main(options: Namespace, inputdir: Path, outputdir: Path): | ||
print(DISPLAY_TITLE, flush=True) | ||
|
||
model = Unet() | ||
footprint = eval(options.dilation_footprint) | ||
|
||
mapper = PathMapper.file_mapper(inputdir, outputdir, | ||
glob=options.pattern, name_mapper=curry_name_mapper('{}_mask.nii')) | ||
for input_file, output_file in mapper: | ||
emerald(model, input_file, output_file, options.post_processing, footprint) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.