Source code for pyrobex.robex
# -*- coding: utf-8 -*-
"""
pyrobex.robex
main python wrapper functions for robex
Author: Jacob Reinhold (jcreinhold@gmail.com)
Created on: May 5, 2021
"""
__all__ = [
"robex",
"robex_mask",
"robex_stripped",
]
import logging
import subprocess
import tempfile
from pathlib import Path
from pyrobex.errors import PyRobexError
from pyrobex.io import NiftiImage, NiftiImagePair
logger = logging.getLogger(__name__)
def _find_robex_dir() -> str:
"""finds the ROBEX source code directory"""
file_path = Path(__file__).resolve()
pyrobex_dir = file_path.parent
robex_dist = pyrobex_dir / "ROBEX"
return str(robex_dist)
def _find_robex_script() -> str:
"""finds the ROBEX shell script"""
robex_dist = Path(_find_robex_dir())
robex_script = robex_dist / "runROBEX.sh"
if not robex_script.is_file():
raise PyRobexError("Could not find `runROBEX.sh` script.")
return str(robex_script)
[docs]def robex_mask(image: NiftiImage, seed: int = 0) -> NiftiImage:
"""
Takes a NIfTI image from nibabel or antspy and performs
ROBEX brain extraction on the image volume and returns
only the mask
Args:
image (NiftiImage): a nibabel NIfTI image, e.g.,
nib.Nifti1Image, or an antspy image
seed (int): random seed for reproducibility
Returns:
mask (NiftiImage): depending on the input,
returns a nibabel NIfTI image or an antspy
image of a binary mask of the brain
Raises:
PyRobexError: when ROBEX is not found or fails
"""
_, mask = robex(image, seed)
return mask
[docs]def robex_stripped(image: NiftiImage, seed: int = 0) -> NiftiImage:
"""
Takes a NIfTI image from nibabel or antspy and performs
ROBEX brain extraction on the image volume and returns
only the extracted brain image
Args:
image (NiftiImage): a nibabel NIfTI image, e.g.,
nib.Nifti1Image, or an antspy image
seed (int): random seed for reproducibility
Returns:
stripped (NiftiImage): depending on the input,
returns a nibabel NIfTI image or an antspy
image of the extracted brain
Raises:
PyRobexError: when ROBEX is not found or fails
"""
stripped, _ = robex(image, seed)
return stripped
[docs]def robex(image: NiftiImage, seed: int = 0) -> NiftiImagePair:
"""
Takes a NIfTI image from nibabel or antspy and performs
ROBEX brain extraction on the image volume
Args:
image (NiftiImage): a nibabel NIfTI image, e.g.,
nib.Nifti1Image, or an antspy image
seed (int): random seed for reproducibility
Returns:
stripped (NiftiImage): depending on the input,
returns a nibabel NIfTI image or an antspy
image of the extracted brain
mask (NiftiImage): depending on the input,
returns a nibabel NIfTI image or an antspy
image of a binary mask of the brain
Raises:
PyRobexError: when ROBEX is not found or fails
"""
with tempfile.TemporaryDirectory() as td:
tdp = Path(td)
robex_script = _find_robex_script()
tmp_img_fn = tdp / "img.nii"
image.to_filename(str(tmp_img_fn))
stripped_fn = tdp / "stripped.nii"
mask_fn = tdp / "mask.nii"
args = [robex_script, tmp_img_fn, stripped_fn, mask_fn, seed]
str_args = list(map(str, args))
out = subprocess.run(str_args, capture_output=True)
if out.returncode != 0:
msg = f"Nonzero return code {out.returncode}.\n"
msg += f"ROBEX Output:\n{str(out.stdout)}"
raise PyRobexError(msg)
logger.debug(f"ROBEX Output:\n{str(out.stdout)}")
stripped = NiftiImage.load(str(stripped_fn))
mask = NiftiImage.load(str(mask_fn))
return stripped, mask