Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add gif #7

Closed
wants to merge 22 commits into from
Closed
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
11 changes: 9 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ jobs:
with:
python-version: ${{ matrix.python }}
- run: pip install -U -e .[dev]
- run: pytest
- run: pytest -k "not gif"
- uses: codecov/codecov-action@v1
cuda:
if: github.event_name != 'pull_request' || github.repository_owner != 'AMYPAD'
name: CUDA py${{ matrix.python }}
runs-on: [self-hosted, python, matlab, cuda]
timeout-minutes: 4320
strategy:
matrix:
python: [3.9]
Expand All @@ -60,8 +61,14 @@ jobs:
fetch-depth: 0
- name: Run setup-python
run: setup-python -p${{ matrix.python }} miutil scikit-build cmake ninja
- name: SimpleITK
run: pip install -U 'SimpleITK>=1.2.0,<2'
env:
CXX: g++-8
CC: gcc-8
- name: Install
run: pip install -U --no-binary nimpa,nipet -e .[dev,niftypet]
run: |
pip install -U --no-binary nimpa,nipet -e .[dev,niftypet,gif]
- run: pytest
- uses: codecov/codecov-action@v1
- name: Post Run setup-python
Expand Down
47 changes: 47 additions & 0 deletions amypet/gif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Parcellation

Usage:
GIF [options] <fimin>

Arguments:
<fimin> : NIfTI image input file (T1w MR image) [default: FileChooser]

Options:
--outpath DIR : where to write outputs of GIF
--gif DIR : GIF directory (containing `bin/` & `db/`)
(default: ${PATHTOOLS}/GIF_AMYPET) [default: DirChooser]
"""
import errno
import subprocess
from os import fspath, getenv
from pathlib import Path

from .utils import cpu_count


def run(fimin, outpath=None, gif=None):
if not gif and getenv("PATHTOOLS"):
gif = Path(getenv("PATHTOOLS")) / "GIF_AMYPET"
gif = Path(gif)
if not all(i.is_dir() for i in [gif, gif / "bin", gif / "db"]):
raise FileNotFoundError("GIF required")

fimin = Path(fimin)
if not fimin.is_file() or "nii" not in fspath(fimin):
raise IOError(errno.ENOENT, "Nifty input file required", fimin)

if outpath is None:
opth = fimin.parent / "out"
else:
opth = Path(outpath)
opth.mkdir(mode=0o775, parents=True, exist_ok=True)
gifresults = subprocess.run([
fspath(gif / "bin" / "seg_GIF"), '-in', fimin, '-db',
fspath(gif / "db" / "db.xml"), '-v', "1", '-regNMI', '-segPT', "0.1", '-out',
fspath(opth), '-temper', "0.05", '-lncc_ker', "-4", '-omp',
str(cpu_count()), '-regBE', "0.001", '-regJL', "0.00005"], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(opth / "out.log").write_bytes(gifresults.stdout)
(opth / "err.log").write_bytes(gifresults.stderr)

return gifresults
4 changes: 3 additions & 1 deletion amypet/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def get_main_parser(gui_mode=True, argparser=MyParser):
import niftypad.api
import niftypad.models

from amypet import centiloid, dcm2nii, imscroll, imtrimup
from amypet import centiloid, dcm2nii, gif, imscroll, imtrimup

def fix_subparser(subparser, gui_mode=gui_mode):
subparser.add_argument(
Expand Down Expand Up @@ -257,6 +257,8 @@ def argparser(prog, description=None, epilog=None, formatter_class=None):
Func(imtrimup.run, imtrimup.__doc__, version=niftypad.__version__, python_deps=["nimpa"],
argparser=argparser)

Func(gif.run, gif.__doc__, version=niftypad.__version__, python_deps=[], argparser=argparser)

Func(centiloid.run, centiloid.__doc__, version=niftypad.__version__,
python_deps=["miutil[nii]", "setuptools", "spm12", "tqdm"], argparser=argparser)

Expand Down
77 changes: 77 additions & 0 deletions scripts/amypet_gif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Usage:
amypet_gif [options] <path>

Options:
-O, --overwrite-existing : whether to run even if outputs already exist

Arguments:
<path> : directory. Layout: <path>/*/*/*MPRAGE*.nii*
"""
import logging
import os
import subprocess
from pathlib import Path
from textwrap import dedent

from argopt import argopt
from miutil import hasext, nsort
from niftypet import nimpa

from amypet import gif

log = logging.getLogger(__name__)


def filter_dir(path):
return filter(lambda i: i.is_dir(), path)


def filter_nii(path):
return list(filter(lambda i: i.is_file() and hasext(i, ("nii", "nii.gz")), path))


def main(argv=None):
args = argopt(__doc__).parse_args(args=argv)
gpth = Path(args.path)
assert gpth.is_dir()

for spth in filter_dir(gpth.iterdir()):
for tpth in spth.iterdir():
for fldr in filter_dir(tpth.glob("*MPRAGE*")):
fnii = filter_nii(tpth.glob("*MPRAGE*"))
if not len(fnii):
# convert DICOMs to NIfTI
subprocess.run([nimpa.resources.DCM2NIIX] + "-i y -v n -f %f_%s".split() +
["-o", tpth, fldr])

fn4b = list((tpth / "N4bias").glob("*N4bias*.nii*"))
fgif = list((tpth / "GIF").glob("*Parcellation*.nii*"))

if len(fn4b) < 1:
fnii = filter_nii(tpth.glob("*MPRAGE*"))
log.info("N4bias input:%s", fnii)
biascorr = nimpa.bias_field_correction(fnii[0], executable="sitk", outpath=tpth)
try:
fingif = biascorr["fim"]
except TypeError:
raise ImportError(
dedent("""\
please install SimpleITK:
`conda install -c simpleitk simpleitk` or
`pip install SimpleITK`"""))
else:
if len(fn4b) > 1:
log.warning("%d inputs found, selecting latest")
fingif = nsort(list(map(str, fn4b)))[-1]
log.debug("found N4-bias corrected:%s", fingif)
if fgif and not args.overwrite_existing:
log.warning("skipping")
continue

log.info("running GIF on:%s", fingif)
gif.run(fingif, outpath=os.path.join(tpth, "GIF"))


if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
main()
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ dev=
gui=Gooey>=1.0.8
web=streamlit>=0.85.2
niftypet=niftypet>=0.0.1
gif=
miutil>=0.9.0
SimpleITK>=1.2.0,<2
[options.entry_points]
console_scripts=
amypet=amypet.cli:main
Expand Down
29 changes: 29 additions & 0 deletions tests/test_gif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from os import fspath

import pytest


def test_gif(fimin):
gif = pytest.importorskip("amypet.gif")
outpath = fimin.parent

if "N4bias" not in fspath(fimin):
nimpa = pytest.importorskip("niftypet.nimpa")
pytest.importorskip(
"SimpleITK",
reason="conda install -c simpleitk simpleitk or pip install SimpleITK",
)
biascorr = nimpa.bias_field_correction(fspath(fimin), executable="sitk",
outpath=fspath(outpath))
fin = biascorr["fim"][0]
else:
fin = fimin

print(fin)
gif.run(fin, outpath=outpath / "GIF")


@pytest.mark.timeout(60 * 60 * 24)
def test_amypet_gif(dimin, caplog):
amypet_gif = pytest.importorskip("scripts.amypet_gif")
amypet_gif.main(["-O", fspath(dimin)])