Commit 3c4c5bdd authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'enh/nifti-adjust' into 'master'

Enh/nifti adjust

See merge request fsl/fslpy!183
parents 9ea752cb 5f31b9e5
Pipeline #4799 failed with stages
in 12 minutes and 39 seconds
......@@ -22,6 +22,8 @@ Fixed
* Improved the algorithm used by the :func:`.mesh.needsFixing` function.
* The :meth:`.fslmaths.run` method now accepts :attr:`.wrappers.LOAD` as an
output specification.
Deprecated
......
......@@ -63,11 +63,11 @@ if we want to FLIRT two images and get the result, we can do this::
Similarly, we can run a ``fslmaths`` command on in-memory images::
import nibabel as nib
from fsl.wrappers import fslmaths, LOAD
from fsl.wrappers import fslmaths
image = nib.load('image.nii')
mask = nib.load('mask.nii')
output = fslmaths(image).mas(mask).bin().run(LOAD)
output = fslmaths(image).mas(mask).bin().run()
If you are *writing* wrapper functions, take a look at the
......
......@@ -13,7 +13,28 @@ from . import wrapperutils as wutils
class fslmaths(object):
"""Perform mathematical manipulation of images."""
"""Perform mathematical manipulation of images.
``fslmaths`` is unlike the other FSL wrapper tools in that it provides an
object-oriented method-chaining interface, which is hopefully easier to
use than constructing a ``fslmaths`` command-line call. For example, the
following call to the ``fslmaths`` wrapper function::
fslmaths('input.nii').thr(0.25).mul(-1).run('output.nii')
will be translated into the following command-line call::
fslmaths input.nii -thr 0.25 -mul -1 output.nii
The ``fslmaths`` wrapper function can also be used with in-memory
images. If no output file name is passed to the :meth:`run` method, the
result is loaded into memory and returned as a ``nibabel`` image. For
example::
import nibabel as nib
input = nib.load('input.nii')
output = fslmaths(input).thr(0.25).mul(-1).run()
"""
def __init__(self, input):
"""Constructor."""
......@@ -138,20 +159,24 @@ class fslmaths(object):
return self
def run(self, output=None):
"""Save output of operations to image."""
"""Save output of operations to image. Set ``output`` to a filename to have
the result saved to file, or omit ``output`` entirely to have the
result returned as a ``nibabel`` image.
"""
cmd = ['fslmaths', self.__input] + self.__args
if output is None: cmd += [wutils.LOAD]
else: cmd += [output]
if output is None:
output = wutils.LOAD
cmd += [output]
result = self.__run(*cmd)
# if output is LOADed, there
# will only be one entry in
# the result dict.
if output is None: return list(result.values())[0]
else: return result
if output == wutils.LOAD: return list(result.values())[0]
else: return result
@wutils.fileOrImage()
@wutils.fslwrapper
......
......@@ -50,7 +50,10 @@ def mockFSLDIR(**kwargs):
if not op.isdir(subdir):
os.makedirs(subdir)
for fname in files:
touch(op.join(subdir, fname))
fname = op.join(subdir, fname)
touch(fname)
if subdir == bindir:
os.chmod(fname, 0o755)
fslplatform.fsldir = fsldir
fslplatform.fsldevdir = None
......
......@@ -5,14 +5,19 @@
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import os
import os.path as op
import itertools as it
import textwrap as tw
import numpy as np
import fsl.wrappers as fw
import fsl.utils.assertions as asrt
import fsl.utils.run as run
from fsl.utils.tempdir import tempdir
from . import mockFSLDIR
from . import mockFSLDIR, make_random_image
def checkResult(cmd, base, args, stripdir=None):
......@@ -272,7 +277,23 @@ def test_fslmaths():
assert result.output[0] == expected
# TODO test LOAD output
# test LOAD output
with tempdir() as td, mockFSLDIR(bin=('fslmaths',)) as fsldir:
expect = make_random_image(op.join(td, 'output.nii.gz'))
with open(op.join(fsldir, 'bin', 'fslmaths'), 'wt') as f:
f.write(tw.dedent("""
#!/usr/bin/env python
import sys
import shutil
shutil.copy('{}', sys.argv[2])
""".format(op.join(td, 'output.nii.gz'))).strip())
os.chmod(op.join(fsldir, 'bin', 'fslmaths'), 0o755)
got = fw.fslmaths('input').run()
assert np.all(expect.dataobj[:] == got.dataobj[:])
got = fw.fslmaths('input').run(fw.LOAD)
assert np.all(expect.dataobj[:] == got.dataobj[:])
def test_fast():
with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fast',)) as fsldir:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment