Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michiel Cottaar
fslpy
Commits
f011b82f
Commit
f011b82f
authored
7 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
further experimentation
parent
0634907a
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
fsl/wrappers/__init__.py
+28
-22
28 additions, 22 deletions
fsl/wrappers/__init__.py
fsl/wrappers/bet.py
+4
-1
4 additions, 1 deletion
fsl/wrappers/bet.py
fsl/wrappers/flirt.py
+38
-52
38 additions, 52 deletions
fsl/wrappers/flirt.py
fsl/wrappers/wrapperutils.py
+365
-101
365 additions, 101 deletions
fsl/wrappers/wrapperutils.py
with
435 additions
and
176 deletions
fsl/wrappers/__init__.py
+
28
−
22
View file @
f011b82f
...
...
@@ -8,25 +8,31 @@
them to be called from Python.
"""
from
.bet
import
(
bet
,)
# noqa
from
.eddy
import
(
eddy_cuda
,
# noqa
topup
)
from
.flirt
import
(
flirt
,
# noqa
invxfm
,
applyxfm
,
concatxfm
,
mcflirt
)
from
.fnirt
import
(
fnirt
,
# noqa
applywarp
,
invwarp
,
convertwarp
)
from
.fslmaths
import
(
fslmaths
,)
# noqa
from
.fugue
import
(
fugue
,
# noqa
sigloss
)
from
.melodic
import
(
melodic
,
# noqa
fsl_regfilt
)
from
.misc
import
(
fslreorient2std
,
# noqa
fslroi
,
slicer
,
cluster
)
from
.wrapperutils
import
(
applyArgStyle
,
# noqa
required
,
fileOrImage
,
fileOrArray
,
RETURN
,
SHOW_IF_TRUE
,
HIDE_IF_TRUE
)
from
.bet
import
(
bet
,)
# noqa
from
.eddy
import
(
eddy_cuda
,
# noqa
topup
)
from
.flirt
import
(
flirt
,
# noqa
invxfm
,
applyxfm
,
concatxfm
,
mcflirt
)
from
.fnirt
import
(
fnirt
,
# noqa
applywarp
,
invwarp
,
convertwarp
)
from
.fslmaths
import
(
fslmaths
,)
# noqa
from
.fugue
import
(
fugue
,
# noqa
sigloss
)
from
.melodic
import
(
melodic
,
# noqa
fsl_regfilt
)
from
.misc
import
(
fslreorient2std
,
# noqa
fslroi
,
slicer
,
cluster
)
This diff is collapsed.
Click to expand it.
fsl/wrappers/bet.py
+
4
−
1
View file @
f011b82f
...
...
@@ -11,6 +11,10 @@ import fsl.utils.run as run
from
.
import
wrapperutils
as
wutils
def
pybet
():
# ??
pass
@wutils.fileOrImage
(
'
input
'
,
'
output
'
)
def
bet
(
input
,
output
,
**
kwargs
):
"""
Delete non-brain tissue from an image of the whole head.
...
...
@@ -20,7 +24,6 @@ def bet(input, output, **kwargs):
:arg mask:
:arg robust:
:arg fracintensity:
:arg seg:
Refer to the ``bet`` command-line help for details on all arguments.
"""
...
...
This diff is collapsed.
Click to expand it.
fsl/wrappers/flirt.py
+
38
−
52
View file @
f011b82f
...
...
@@ -20,60 +20,34 @@
import
fsl.utils.run
as
run
import
fsl.utils.assertions
as
asrt
import
fsl.data.image
as
fslimage
from
.
import
wrapperutils
as
wutils
def
flirt
(
src
,
ref
,
out
=
None
,
omat
=
None
,
dof
=
None
,
cost
=
None
,
wmseg
=
None
,
init
=
None
,
schedule
=
None
,
echospacing
=
None
,
pedir
=
None
,
fieldmap
=
None
,
fieldmapmask
=
None
,
bbrslope
=
None
,
bbrtype
=
None
,
interp
=
None
,
refweight
=
None
,
applyisoxfm
=
None
,
usesqform
=
False
,
nosearch
=
False
,
verbose
=
0
):
@wutils.required
(
'
src
'
,
'
ref
'
)
@wutils.fileOrImage
(
'
src
'
,
'
ref
'
,
'
out
'
,
'
wmseg
'
,
'
fieldmap
'
,
'
fieldmapmask
'
)
@wutils.fileOrArray
(
'
init
'
,
'
omat
'
,
'
wmcoords
'
,
'
wmnorms
'
)
def
flirt
(
src
,
ref
,
**
kwargs
):
"""
FLIRT (FMRIB
'
s Linear Image Registration Tool).
"""
asrt
.
assertIsNifti
(
src
,
ref
)
asrt
.
assertFileExists
(
src
,
ref
)
cmd
=
"
flirt -in {0} -ref {1}
"
.
format
(
src
,
ref
)
if
out
is
not
None
:
asrt
.
assertIsNifti
(
out
)
cmd
+=
"
-out {0}
"
.
format
(
out
)
if
omat
is
not
None
:
cmd
+=
"
-omat {0}
"
.
format
(
omat
)
if
dof
is
not
None
:
cmd
+=
"
-dof {0}
"
.
format
(
dof
)
if
cost
is
not
None
:
cmd
+=
"
-cost {0}
"
.
format
(
cost
)
if
wmseg
is
not
None
:
asrt
.
assertIsNifti
(
wmseg
)
cmd
+=
"
-wmseg {0}
"
.
format
(
wmseg
)
if
init
is
not
None
:
cmd
+=
"
-init {0}
"
.
format
(
init
)
if
schedule
is
not
None
:
cmd
+=
"
-schedule {0}
"
.
format
(
schedule
)
if
echospacing
is
not
None
:
cmd
+=
"
-echospacing {0}
"
.
format
(
echospacing
)
if
pedir
is
not
None
:
cmd
+=
"
-pedir {0}
"
.
format
(
pedir
)
if
fieldmap
is
not
None
:
cmd
+=
"
-fieldmap {0}
"
.
format
(
fieldmap
)
if
fieldmapmask
is
not
None
:
cmd
+=
"
-fieldmapmask {0}
"
.
format
(
fieldmapmask
)
if
bbrslope
is
not
None
:
cmd
+=
"
-bbrslope {0}
"
.
format
(
bbrslope
)
if
bbrtype
is
not
None
:
cmd
+=
"
-bbrtype {0}
"
.
format
(
bbrtype
)
if
interp
is
not
None
:
cmd
+=
"
-interp {0}
"
.
format
(
interp
)
if
refweight
is
not
None
:
asrt
.
assertIsNifti
(
refweight
)
cmd
+=
"
-refweight {0}
"
.
format
(
refweight
)
if
applyisoxfm
is
not
None
:
cmd
+=
"
-applyisoxfm {0}
"
.
format
(
applyisoxfm
)
if
verbose
is
not
None
:
cmd
+=
"
-verbose {0}
"
.
format
(
verbose
)
if
usesqform
:
cmd
+=
"
-usesqform
"
if
nosearch
:
cmd
+=
"
-nosearch
"
valmap
=
{
'
usesqform
'
:
wutils
.
SHOW_IF_TRUE
,
'
displayinit
'
:
wutils
.
SHOW_IF_TRUE
,
'
noresample
'
:
wutils
.
SHOW_IF_TRUE
,
'
forcescaling
'
:
wutils
.
SHOW_IF_TRUE
,
'
applyxfm
'
:
wutils
.
SHOW_IF_TRUE
,
'
nosearch
'
:
wutils
.
SHOW_IF_TRUE
,
'
noclamp
'
:
wutils
.
SHOW_IF_TRUE
,
'
noresampblur
'
:
wutils
.
SHOW_IF_TRUE
,
'
2D
'
:
wutils
.
SHOW_IF_TRUE
,
'
v
'
:
wutils
.
SHOW_IF_TRUE
,
'
version
'
:
wutils
.
SHOW_IF_TRUE
,
'
help
'
:
wutils
.
SHOW_IF_TRUE
,
}
cmd
=
[
'
flirt
'
,
'
-in
'
,
src
,
'
-ref
'
,
ref
]
cmd
+=
wutils
.
applyArgStyle
(
'
-
'
,
valmap
=
valmap
,
**
kwargs
)
return
run
.
runfsl
(
cmd
)
...
...
@@ -94,13 +68,25 @@ def applyxfm(src, ref, mat, out, interp='spline'):
cmd
=
"
flirt -init {0} -in {1} -ref {2} -applyxfm -out {3} -interp {4}
"
return
run
.
runfsl
(
cmd
.
format
(
mat
,
src
,
ref
,
out
,
interp
))
@wutils.required
(
'
inmat1
'
,
'
inmat2
'
,
'
outmat
'
)
@wutils.fileOrArray
(
'
inmat1
'
,
'
inmat2
'
,
'
outmat
'
)
def
concatxfm
(
inmat1
,
inmat2
,
outmat
):
"""
Tool to concatenate two FSL transformation matrices.
"""
print
(
'
inmat1
'
,
inmat1
)
print
(
'
inmat2
'
,
inmat2
)
print
(
'
outmat
'
,
outmat
)
asrt
.
assertFileExists
(
inmat1
,
inmat2
)
cmd
=
"
convert_xfm -omat {0} -concat {1} {2}
"
return
run
.
runfsl
(
cmd
.
format
(
outmat
,
inmat2
,
inmat1
))
cmd
=
[
'
convert_xfm
'
,
'
-omat
'
,
outmat
,
'
-concat
'
,
inmat2
,
inmat1
]
return
run
.
runfsl
(
cmd
)
def
mcflirt
(
infile
,
outfile
,
reffile
=
None
,
spline_final
=
True
,
plots
=
True
,
...
...
This diff is collapsed.
Click to expand it.
fsl/wrappers/wrapperutils.py
+
365
−
101
View file @
f011b82f
#!/usr/bin/env python
#
# wrapperutils.py -
# wrapperutils.py - Functions and decorators used by the FSL wrapper
# functions.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""
This module contains functions and decorators used by the FSL wrapper
functions.
.. autosummary::
:nosignatures:
applyArgStyle
required
fileOrImage
fileOrArray
"""
import
os.path
as
op
import
os
import
sys
import
inspect
import
tempfile
import
warnings
...
...
@@ -16,50 +29,133 @@ import collections
import
six
import
nibabel
as
nib
import
numpy
as
np
import
fsl.utils.tempdir
as
tempdir
import
fsl.data.image
as
fslimage
class
_BooleanFlag
(
object
):
def
__init__
(
self
,
show
):
self
.
show
=
show
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
type
(
self
)
and
self
.
show
==
other
.
show
def
_update_wrapper
(
wrapper
,
wrapped
,
*
args
,
**
kwargs
):
"""
Replacement for the built-in ``functools.update_wrapper``. This
implementation ensures that the wrapper function has an attribute
called ``__wrapped__``, which refers to the ``wrapped`` function.
This behaviour is only required in Python versions < 3.4.
"""
wrapper
=
functools
.
update_wrapper
(
wrapper
,
wrapped
,
*
args
,
**
kwargs
)
# Python >= 3.4 does things right
if
sys
.
version_info
[
0
]
*
10
+
sys
.
version_info
[
1
]
<
3.4
:
wrapper
.
__wrapped__
=
wrapped
return
wrapper
SHOW_IF_TRUE
=
_BooleanFlag
(
True
)
HIDE_IF_TRUE
=
_BooleanFlag
(
False
)
def
_unwrap
(
func
):
"""
Replacement for the built-in ``inspect.unwrap`` function, which
is not present in Python versions prior to 3.4.
"""
# Python >= 3.4 has an inspect.unwrap function
if
sys
.
version_info
[
0
]
*
10
+
sys
.
version_info
[
1
]
<
3.4
:
return
inspect
.
unwrap
(
func
)
# Otherwise we follow the __wrapped__ chain ourselves
if
hasattr
(
func
,
'
__wrapped__
'
):
return
_unwrap
(
func
.
__wrapped__
)
return
func
SHOW_IF_TRUE
=
object
()
"""
Constant to be used in the ``valmap`` passed to the :func:`applyArgStyle`
function.
When a ``SHOW_IF_TRUE`` argument is ``True``, it is added to the generated
command line arguments.
"""
HIDE_IF_TRUE
=
object
()
"""
Constant to be used in the ``valmap`` passed to the :func:`applyArgStyle`
function.
When a ``HIDE_IF_TRUE`` argument is ``True``, it is suppressed from the
generated command line arguments.
"""
def
applyArgStyle
(
style
,
argmap
=
None
,
valmap
=
None
,
**
kwargs
):
"""
Turns the given ``kwargs`` into command line options. This function
is intended to be used to automatically generate command line options
from arguments passed into a Python function.
:arg style: Controls how the ``kwargs`` are converted into command-line
options - must be one of the following:
- `
'
-
'
`: ``-name val``
- `
'
--
'
`: ``--name val``
- `
'
-=
'
`: ``-name=val``
- `
'
--=
'
`: ``--name=val``
:arg argmap: Dictionary of ``{kwarg-name : cli-name}`` mappings. This can
be used if you want to use different argument names in your
Python function for the command-line options.
:arg valmap: Dictionary of ``{cli-name : value}`` mappings. This can be
used to define specific semantics for some command-line
options. Acceptable values for ``value`` are as follows
- :data:`SHOW_IF_TRUE` - if the argument is present, and
``True`` in ``kwargs``, the command line option
will be added (without any arguments).
- :data:`HIDE_IF_TRUE` - if the argument is present, and
``False`` in ``kwargs``, the command line option
will be added (without any arguments).
- Any other constant value. If the argument is present
in ``kwargs``, its command-line option will be
added, with the constant value as its argument.
The argument for any options not specified in the ``valmap``
will be converted into strings.
def
fmtarg
(
arg
,
style
):
:arg kwargs: Arguments to be converted into command-line options.
:returns: A list containing the generated command-line options.
"""
if
style
not
in
(
'
-
'
,
'
--
'
,
'
-=
'
,
'
--=
'
):
raise
ValueError
(
'
Invalid style: {}
'
.
format
(
style
))
if
argmap
is
None
:
argmap
=
{}
if
valmap
is
None
:
valmap
=
{}
def
fmtarg
(
arg
):
if
style
in
(
'
-
'
,
'
-=
'
):
arg
=
'
-{}
'
.
format
(
arg
)
elif
style
in
(
'
--
'
,
'
--=
'
):
arg
=
'
--{}
'
.
format
(
arg
)
return
arg
def
fmtval
(
val
,
style
=
None
):
def
fmtval
(
val
):
if
isinstance
(
val
,
collections
.
Sequence
)
and
\
not
isinstance
(
val
,
six
.
string_types
):
return
'
'
.
join
([
str
(
v
)
for
v
in
val
])
else
:
return
str
(
val
)
if
style
not
in
(
'
-
'
,
'
--
'
,
'
-=
'
,
'
--=
'
):
raise
ValueError
(
'
Invalid style: {}
'
.
format
(
style
))
args
=
[]
for
k
,
v
in
kwargs
.
items
():
k
=
argmap
.
get
(
k
,
k
)
mapv
=
valmap
.
get
(
k
,
fmtval
(
v
,
style
))
k
=
fmtarg
(
k
,
style
)
mapv
=
valmap
.
get
(
k
,
fmtval
(
v
))
k
=
fmtarg
(
k
)
if
(
mapv
is
SHOW_IF_TRUE
and
v
)
or
\
(
mapv
is
HIDE_IF_TRUE
and
not
v
):
args
.
append
(
k
)
if
mapv
in
(
SHOW_IF_TRUE
,
HIDE_IF_TRUE
):
if
v
==
mapv
.
show
:
args
.
append
(
k
)
elif
'
=
'
in
style
:
args
.
append
(
'
{}={}
'
.
format
(
k
,
mapv
))
else
:
...
...
@@ -72,110 +168,216 @@ def required(*reqargs):
"""
Decorator which makes sure that all specified keyword arguments are
present before calling the decorated function.
"""
def
decorator
(
func
):
def
wrapper
(
**
kwargs
):
def
wrapper
(
*
args
,
**
kwargs
):
kwargs
=
kwargs
.
copy
()
kwargs
.
update
(
argsToKwargs
(
func
,
args
))
for
reqarg
in
reqargs
:
assert
reqarg
in
kwargs
return
func
(
**
kwargs
)
return
wrapper
return
_update_wrapper
(
wrapper
,
func
)
return
decorator
def
argsToKwargs
(
func
,
args
):
"""
Given a function, and a sequence of positional arguments destined
for that function, converts the positional arguments into a dict
of keyword arguments. Used by the :class:`_FileOr
Image
` class.
of keyword arguments. Used by the :class:`_FileOr
Thing
` class.
"""
# getfullargspec is the only way to get the names
# of positional arguments in Python 2.x. It is
# deprecated in python 3.5, but not in python 3.6.
with
warnings
.
catch_warnings
():
warnings
.
filterwarnings
(
'
ignore
'
,
category
=
DeprecationWarning
)
spec
=
inspect
.
getfullargspec
(
func
)
func
=
_unwrap
(
func
)
# getargspec is the only way to get the names
# of positional arguments in Python 2.x.
if
sys
.
version_info
[
0
]
<
3
:
argnames
=
inspect
.
getargspec
(
func
).
args
# getargspec is deprecated in python 3.x
else
:
# getfullargspec is deprecated in
# python 3.5, but not in python 3.6.
with
warnings
.
catch_warnings
():
warnings
.
filterwarnings
(
'
ignore
'
,
category
=
DeprecationWarning
)
argnames
=
inspect
.
getfullargspec
(
func
).
args
kwargs
=
collections
.
OrderedDict
()
for
name
,
val
in
zip
(
spec
.
arg
s
,
args
):
for
name
,
val
in
zip
(
argname
s
,
args
):
kwargs
[
name
]
=
val
return
kwargs
RETURN
=
object
()
"""
"""
Constant used by the :class:`_FileOrThing` class to indicate that an output
file should be loaded into memory and returned as a Python object.
"""
class
_FileOrImage
(
object
):
"""
class
_FileOrThing
(
object
):
"""
Decorator which ensures that certain arguments which are passed into the
decorated function are always passed as file names. Both positional and
keyword arguments can be specified.
The ``_FileOrThing`` class is not intended to be used directly - see the
:func:`fileOrImage` and :func:`fileOrArray` decorator functions for more
details.
These decorators are intended for functions which wrap a command-line tool,
i.e. where some inputs/outputs need to be specified as file names.
**Inputs**
Any arguments which are not of type ``Thing`` are passed through to the
decorated function unmodified. Arguments which are of type ``Thing`` are
saved to a temporary file, and the name of that file is passed to the
function.
Inputs:
- In-memory nibabel images loaded from a file. The image is replaced with
its file name.
**Outputs**
- In-memory nibabel images. The image is saved to a temporary file, and
replaced with the temporary file
'
s name. The file is deleted after the
function has returned.
Outputs:
- File name: The file name is passed straight through to the function.
- ``RETURN``: A temporary file name is passed to the function. After the
function has completed, the image is loaded into memory and the
temporary file is deleted. The image is returned from the function
call.
If an argument is given the special :data:`RETURN` value, it is assumed
to be an output argument. In this case, it is replaced with a temporary
file name then, after the function has completed, that file is loaded
into memory, and the value returned (along with the function
'
s output,
and any other arguments with a value of ``RETURN``).
**Return value**
Functions decorated with a ``_FileOrThing`` decorator will always return a
tuple, where the first element is the function
'
s actual return value. The
remainder of the tuple will contain any arguments that were given the
special ``RETURN`` value. ``None`` is returned for any ``RETURN``
arguments corresponded to output files that were not generated by the
function.
**Example**
As an example of using the ``fileOrArray`` decorator on a function
which concatenates two files containing affine transformations, and
saves the output to a file::
# if atob, btoc, or output are passed
# in as arrays, they are converted to
# file names.
@fileOrArray(
'
atob
'
,
'
btoc
'
,
'
output
'
)
def concat(atob, btoc, output=None):
# inputs are guaranteed to be files
atob = np.loadtxt(atob)
btoc = np.loadtxt(atoc)
atoc = np.dot(btoc, atob)
if output is not None:
np.savetxt(output, atoc)
Because we have decorated the ``concat`` function with :func:`fileToArray`,
it can be called with either file names, or Numpy arrays::
# All arguments are passed through
# unmodified - the output will be
# saved to a file called atoc.mat
concat(
'
atob.txt
'
,
'
btoc.txt
'
,
'
atoc.mat
'
)
# The output is returned as a numpy
# array (in a tuple with the concat
# function
'
s return value)
atoc = concat(
'
atob.txt
'
,
'
btoc.txt
'
, RETURN)[1]
# The inputs are saved to temporary
# files, and those file names are
# passed to the concat function.
atoc = concat(np.diag([2, 2, 2, 0]), np.diag([3, 3, 3, 3]), RETURN)[1]
"""
def
__init__
(
self
,
*
imgargs
):
"""
def
__init__
(
self
,
prepareThing
,
loadThing
,
*
things
):
"""
Initialise a ``_FileOrThing`` decorator.
:arg prepareThing: Function which
:arg loadThing: Function which is called for arguments that
were set to :data:`RETURN`.
:arg things:
"""
self
.
__imgargs
=
imgargs
self
.
__prepareThing
=
prepareThing
self
.
__loadThing
=
loadThing
self
.
__things
=
things
def
__call__
(
self
,
func
):
"""
"""
return
functools
.
partial
(
self
.
__wrapper
,
func
)
"""
Creates and returns the real decorator function.
"""
self
.
__func
=
func
self
.
__isFileOrThing
=
False
if
hasattr
(
func
,
'
__self__
'
):
self
.
__isFileOrThing
=
isinstance
(
func
.
__self__
,
_FileOrThing
)
wrapper
=
functools
.
partial
(
self
.
__wrapper
,
func
)
return
_update_wrapper
(
wrapper
,
func
)
def
__wrapper
(
self
,
func
,
*
args
,
**
kwargs
):
"""
"""
Function which wraps ``func``, ensuring that any arguments of
type ``Thing`` are saved to temporary files, and any arguments
with the value :data:`RETURN` are loaded and returned.
"""
func
=
self
.
__func
isFileOrThing
=
self
.
__isFileOrThing
kwargs
=
kwargs
.
copy
()
kwargs
.
update
(
argsToKwargs
(
func
,
args
))
# Create a tempdir to store any temporary
# input/output
image
s, but don't change
# input/output
thing
s, but don't change
# into it, as file paths passed to the
# function may be relative.
with
tempdir
.
tempdir
(
changeto
=
False
)
as
td
:
kwargs
,
infiles
,
outfiles
=
self
.
__prepare
Ar
gs
(
td
,
kwargs
)
kwargs
,
infiles
,
outfiles
=
self
.
__prepare
Thin
gs
(
td
,
kwargs
)
# Call the function
result
=
func
(
**
kwargs
)
result
=
func
(
**
kwargs
)
# Load the output
image
s that
# Load the output
thing
s that
# were specified as RETURN
out
im
gs
=
[]
out
thin
gs
=
[]
for
of
in
outfiles
:
# output file didn't get created
if
not
op
.
exists
(
of
):
o
i
=
None
o
t
=
None
# load the file, and create
# an in-memory copy (the file
# is going to get deleted)
# load the thing
else
:
oi
=
nib
.
load
(
of
)
oi
=
nib
.
nifti1
.
Nifti1Image
(
oi
.
get_data
(),
None
,
oi
.
header
)
ot
=
self
.
__loadThing
(
of
)
out
im
gs
.
append
(
o
i
)
out
thin
gs
.
append
(
o
t
)
return
tuple
([
result
]
+
outimgs
)
if
isFileOrThing
:
things
=
result
[
1
:]
result
=
result
[
0
]
return
tuple
([
result
]
+
things
+
outthings
)
else
:
return
tuple
([
result
]
+
outthings
)
def
__prepare
Ar
gs
(
self
,
workdir
,
kwargs
):
def
__prepare
Thin
gs
(
self
,
workdir
,
kwargs
):
"""
"""
...
...
@@ -183,48 +385,110 @@ class _FileOrImage(object):
infiles
=
[]
outfiles
=
[]
for
imgarg
in
self
.
__
imgar
gs
:
for
tname
in
self
.
__
thin
gs
:
img
=
kwargs
.
get
(
imgarg
,
None
)
tval
=
kwargs
.
get
(
tname
,
None
)
# Not specified, nothing to do
if
img
is
None
:
if
tval
is
None
:
continue
# This is an input image which has
# been specified as an in-memory
# nibabel image. if the image has
# a backing file, replace the image
# object with the file name.
# Otherwise, save the image out to
# a temporary file, and replace the
# image with the file name.
if
isinstance
(
img
,
nib
.
nifti1
.
Nifti1Image
):
imgfile
=
img
.
get_filename
()
# in-memory image - we have
# to save it out to a file
if
imgfile
is
None
:
hd
,
imgfile
=
tempfile
.
mkstemp
(
fslimage
.
defaultExt
())
os
.
close
(
hd
)
img
.
to_filename
(
imgfile
)
infiles
.
append
(
imgfile
)
# replace the image with its
# file name
kwargs
[
img
]
=
imgfile
# This is an output image, and the
# caller has requested that it be
# returned from the function call
# as an in-memory image.
if
img
==
RETURN
:
kwargs
[
imgarg
]
=
'
{}.nii.gz
'
.
format
(
imgarg
)
outfiles
.
append
(
imgarg
)
tval
,
infile
,
outfile
=
self
.
__prepareThing
(
workdir
,
tname
,
tval
)
if
infile
is
not
None
:
infiles
.
append
(
infile
)
if
outfile
is
not
None
:
outfiles
.
append
(
outfile
)
kwargs
[
tname
]
=
tval
return
kwargs
,
infiles
,
outfiles
fileOrImage
=
_FileOrImage
def
fileOrImage
(
*
imgargs
):
"""
Decorator which can be used to ensure that any NIfTI images are saved
to file, and output images can be loaded and returned as ``nibabel``
image objects.
"""
def
prepareArg
(
workdir
,
name
,
val
):
newval
=
val
infile
=
None
outfile
=
None
# This is an input image which has
# been specified as an in-memory
# nibabel image. if the image has
# a backing file, replace the image
# object with the file name.
# Otherwise, save the image out to
# a temporary file, and replace the
# image with the file name.
if
isinstance
(
val
,
nib
.
nifti1
.
Nifti1Image
):
imgfile
=
val
.
get_filename
()
# in-memory image - we have
# to save it out to a file
if
imgfile
is
None
:
hd
,
imgfile
=
tempfile
.
mkstemp
(
fslimage
.
defaultExt
())
os
.
close
(
hd
)
val
.
to_filename
(
imgfile
)
infile
=
imgfile
# replace the image with its
# file name
newval
=
imgfile
# This is an output image, and the
# caller has requested that it be
# returned from the function call
# as an in-memory image.
elif
val
==
RETURN
:
newval
=
op
.
join
(
workdir
,
'
{}.nii.gz
'
.
format
(
name
))
outfile
=
newval
return
newval
,
infile
,
outfile
def
loadImage
(
path
):
# create an independent in-memory
# copy of the image file
img
=
nib
.
load
(
path
)
return
nib
.
nifti1
.
Nifti1Image
(
img
.
get_data
(),
None
,
img
.
header
)
return
_FileOrThing
(
prepareArg
,
loadImage
,
*
imgargs
)
def
fileOrArray
(
*
arrargs
):
"""
Decorator which can be used to ensure that any Numpy arrays are saved
to text files, and output files can be loaded and returned as Numpy arrays.
"""
def
prepareArg
(
workdir
,
name
,
val
):
newval
=
val
infile
=
None
outfile
=
None
# Input has been provided as a numpy
# array - save it to a file, and
# replace the argument with the file
# name
if
isinstance
(
val
,
np
.
ndarray
):
hd
,
arrfile
=
tempfile
.
mkstemp
(
'
.txt
'
)
os
.
close
(
hd
)
np
.
savetxt
(
arrfile
,
val
,
fmt
=
'
%0.18f
'
)
newval
=
arrfile
# This is an output, and the caller has
# requested that it be returned from the
# function call as an in-memory array.
elif
val
==
RETURN
:
newval
=
op
.
join
(
workdir
,
'
{}.txt
'
.
format
(
name
))
outfile
=
newval
return
newval
,
infile
,
outfile
return
_FileOrThing
(
prepareArg
,
np
.
loadtxt
,
*
arrargs
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment