Skip to content
Snippets Groups Projects
Commit b1d11da0 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Merge branch 'enh/cluster' into 'main'

ENH: Wrapper function for FSL `cluster` command

See merge request fsl/fslpy!417
parents 3bffd560 ab598b91
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,12 @@ order. ...@@ -6,6 +6,12 @@ order.
-------------------------- --------------------------
Added
^^^^^
* New :func:`.cluster` wrapper function for the FSL ``cluster`` /
``fsl-cluster`` command (!417).
Changed Changed
^^^^^^^ ^^^^^^^
......
...@@ -46,3 +46,4 @@ def testenv(*fslexes): ...@@ -46,3 +46,4 @@ def testenv(*fslexes):
fslexes = [op.join(fsldir, 'bin', e) for e in fslexes] fslexes = [op.join(fsldir, 'bin', e) for e in fslexes]
if len(fslexes) == 1: yield fslexes[0] if len(fslexes) == 1: yield fslexes[0]
else: yield fslexes else: yield fslexes
testenv.__test__ = False
#!/usr/bin/env python
#
# test_cluster.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import contextlib
import os
import os.path as op
import sys
import numpy as np
from fsl.wrappers.cluster import cluster, _cluster
from . import testenv
from .. import mockFSLDIR
@contextlib.contextmanager
def reseed(seed):
state = np.random.get_state()
np.random.seed(seed)
try:
yield
finally:
np.random.set_state(state)
def test_cluster_wrapper():
with testenv('fsl-cluster') as cluster_exe:
result = _cluster('input', 10, mm=True)
expected = [cluster_exe, '-i', 'input', '-t', '10', '--mm']
expected = ' '.join(expected)
assert result.stdout[0] == expected
mock_titles = 'ABCDEFGHIJ'
mock_cluster = f"""
#!{sys.executable}
import numpy as np
np.random.seed(12345)
data = np.random.randint(1, 10, (10, 10))
print('\t'.join('{mock_titles}'))
for row in data:
print('\t'.join([str(val) for val in row]))
""".strip()
def test_cluster():
with mockFSLDIR() as fsldir:
cluster_exe = op.join(fsldir, 'bin', 'fsl-cluster')
with open(cluster_exe, 'wt') as f:
f.write(mock_cluster)
os.chmod(cluster_exe, 0o755)
data, titles, result1 = cluster('input', 3.5)
result2 = cluster('input', 3.5, load=False)
with reseed(12345):
expected = np.random.randint(1, 10, (10, 10))
assert np.all(np.isclose(data, expected))
assert ''.join(titles) == mock_titles
assert result1.stdout == result2.stdout
...@@ -103,6 +103,7 @@ from fsl.wrappers.wrapperutils import (LOAD, ...@@ -103,6 +103,7 @@ from fsl.wrappers.wrapperutils import (LOAD,
fslwrapper, fslwrapper,
funcwrapper) funcwrapper)
from fsl.wrappers import (tbss,) from fsl.wrappers import (tbss,)
from fsl.wrappers.cluster import (cluster,)
from fsl.wrappers.bet import (bet, from fsl.wrappers.bet import (bet,
robustfov) robustfov)
from fsl.wrappers.eddy import (eddy, from fsl.wrappers.eddy import (eddy,
......
#!/usr/bin/env python
#
# cluster.py - Wrapper for the FSL cluster command.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module contains the :func:`cluster` function, which calls
the FSL ``cluster`` / ``fsl-cluster``command.
"""
import io
import numpy as np
from . import wrapperutils as wutils
def cluster(infile, thres, load=True, **kwargs):
"""Wrapper function for the FSL ``cluster`/``fsl-cluster``) command.
If ``load is True`` (the default) a tuple is returned, containing:
- A numpy array containing the cluster table
- A list of column titles
- A dictionary containing references to the standard output as an
attribute called ``stdout``, and to the output images if any,
e.g. ``--oindex``.
If ``load is False``, only the dictionary is returned.
"""
result = _cluster(infile, thres, **kwargs)
if load:
header, data = result.stdout[0].split('\n', 1)
titles = header.split('\t')
data = np.loadtxt(io.StringIO(data), delimiter='\t')
return data, titles, result
else:
return result
@wutils.fileOrImage('infile', 'othresh', 'olmaxim', 'osize',
'omax', 'omean', 'opvals', 'cope', 'warpvol',)
@wutils.fslwrapper
def _cluster(infile, thresh, **kwargs):
"""Actual wrapper function for the FSL ``cluster``/``fsl-cluster`` command.
"""
valmap = {
'fractional' : wutils.SHOW_IF_TRUE,
'mm' : wutils.SHOW_IF_TRUE,
'min' : wutils.SHOW_IF_TRUE,
'no_table' : wutils.SHOW_IF_TRUE,
'minclustersize' : wutils.SHOW_IF_TRUE,
'scalarname' : wutils.SHOW_IF_TRUE,
'verbose' : wutils.SHOW_IF_TRUE,
'voxthresh' : wutils.SHOW_IF_TRUE,
'voxuncthresh' : wutils.SHOW_IF_TRUE,
}
cmd = ['fsl-cluster', '-i', infile, '-t', str(thresh)]
cmd += wutils.applyArgStyle('--=', valmap=valmap, **kwargs)
return cmd
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment