Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
FSL
fslpy
Commits
5917cf19
Commit
5917cf19
authored
Nov 12, 2021
by
Paul McCarthy
🚵
Browse files
Merge branch 'rel/3.7.1' into 'v3.7'
Rel/3.7.1 See merge request fsl/fslpy!314
parents
33999995
7a054c5b
Pipeline
#11474
passed with stages
in 5 minutes and 16 seconds
Changes
10
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
5917cf19
...
...
@@ -171,6 +171,12 @@ test:3.9:
<<
:
*test_template
# test:3.10:
# stage: test
# image: pauldmccarthy/fsleyes-py310-wxpy4-gtk3
# <<: *test_template
test:build-pypi-dist:
stage
:
test
image
:
pauldmccarthy/fsleyes-py37-wxpy4-gtk3
...
...
CHANGELOG.rst
View file @
5917cf19
...
...
@@ -2,6 +2,26 @@ This document contains the ``fslpy`` release history in reverse chronological
order.
3.7.1 (Friday 12th November 2021)
---------------------------------
Changed
^^^^^^^
* BIDS and ``dcm2niix`` ``.json`` sidecar files with control characters
are now accepted (!312).
Fixed
^^^^^
* Fixed an issue with temporary input files created by :mod:`fsl.wrappers`
functions not being deleted (!313).
3.7.0 (Friday 20th August 2021)
-------------------------------
...
...
@@ -11,7 +31,7 @@ Added
* New :mod:`fsl.wrappers.fsl_sub` wrapper function for the ``fsl_sub``
command.
command
(!309)
.
Changed
...
...
@@ -20,19 +40,19 @@ Changed
* Performance of the :mod:`.imglob`, :mod:`.imln`, :mod:`imtest`, :mod:`.imrm`
and :mod:`.remove_ext` scripts has been improved, by re-organising them to
avoid unnecessary and expensive imports such as ``numpy``.
avoid unnecessary and expensive imports such as ``numpy``
(!310)
.
* The default behaviour of the :func:`fsl.utils.run.run` function (and hence
that of all :mod:`fsl.wrappers` functions) has been changed so that the
standard output and error of the called command is now forwarded to the
calling Python process, in addition to being returned from ``run`` as
strings. In other words, the default behaviour of ``run('cmd')``, is now
equivalent to ``run('cmd', log={"tee":True})``. The previous default
behaviour can be achieved with ``run('cmd', log={"tee":False})``.
behaviour can be achieved with ``run('cmd', log={"tee":False})``
(!309)
.
* The :func:`fsl.utils.run.run` and :func:`fsl.utils.run.runfsl` functions
(and hence all :mod:`fsl.wrappers` functions) have been modified to use
``fsl.wrappers.fsl_sub`` instead of ``fsl.utils.fslsub.submit``. This is an
internal change which should not affect the usage of the ``run``, ``runfsl``
or wrapper functions.
or wrapper functions
(!309)
.
Deprecated
...
...
@@ -41,10 +61,10 @@ Deprecated
* :class:`fsl.utils.fslsub.SubmitParams` and :func:`fsl.utils.fslsub.submit`
have been deprecated in favour of using the ``fsl.wrappers.fsl_sub`` wrapper
function.
function
(!309)
.
* The :func:`fsl.utils.fslsub.info` function has been deprecated in favour of
using the ``fsl_sub.report`` function, from the separate `fsl_sub
<https://git.fmrib.ox.ac.uk/fsl/fsl_sub>`_ Python library.
<https://git.fmrib.ox.ac.uk/fsl/fsl_sub>`_ Python library
(!309)
.
3.6.4 (Tuesday 3rd August 2021)
...
...
README.rst
View file @
5917cf19
...
...
@@ -19,7 +19,7 @@ programming library written in Python. It is used by `FSLeyes
<https://git.fmrib.ox.ac.uk/fsl/fsleyes/fsleyes/>`_.
``fslpy`` is tested against Python versions 3.7, 3.8 and 3.
9
.
``fslpy`` is tested against Python versions 3.7, 3.8
, 3.9,
and 3.
10
.
Installation
...
...
fsl/data/image.py
View file @
5917cf19
...
...
@@ -1569,7 +1569,7 @@ def loadMetadata(image):
jsonfile
=
op
.
join
(
dirname
,
'{}.json'
.
format
(
basename
))
if
op
.
exists
(
jsonfile
):
with
open
(
jsonfile
,
'rt'
)
as
f
:
return
json
.
load
(
f
)
return
json
.
load
(
f
,
strict
=
False
)
return
{}
...
...
fsl/utils/bids.py
View file @
5917cf19
...
...
@@ -187,7 +187,7 @@ def isBIDSFile(filename, strict=True):
def
loadMetadataFile
(
filename
):
"""Load ``filename`` (assumed to be JSON), returning its contents. """
with
open
(
filename
,
'rt'
)
as
f
:
return
json
.
load
(
f
)
return
json
.
load
(
f
,
strict
=
False
)
def
loadMetadata
(
filename
):
...
...
fsl/version.py
View file @
5917cf19
...
...
@@ -47,7 +47,7 @@ import re
import
string
__version__
=
'3.7.
0
'
__version__
=
'3.7.
1
'
"""Current version number, as a string. """
...
...
fsl/wrappers/wrapperutils.py
View file @
5917cf19
...
...
@@ -1046,9 +1046,16 @@ def fileOrImage(*args, **kwargs):
# in-memory image - we have
# to save it out to a file
if
infile
is
None
:
hd
,
infile
=
tempfile
.
mkstemp
(
fslimage
.
defaultExt
())
if
infile
is
None
or
not
op
.
exists
(
infile
):
hd
,
infile
=
tempfile
.
mkstemp
(
fslimage
.
defaultExt
(),
dir
=
workdir
)
os
.
close
(
hd
)
# Create a copy of the input image and
# save that, so the original doesn't
# get associated with the temp file
val
=
nib
.
nifti1
.
Nifti1Image
(
np
.
asanyarray
(
val
.
dataobj
),
None
,
val
.
header
)
val
.
to_filename
(
infile
)
return
infile
...
...
@@ -1110,7 +1117,7 @@ def fileOrArray(*args, **kwargs):
infile
=
None
if
isinstance
(
val
,
np
.
ndarray
):
hd
,
infile
=
tempfile
.
mkstemp
(
'.txt'
)
hd
,
infile
=
tempfile
.
mkstemp
(
'.txt'
,
dir
=
workdir
)
os
.
close
(
hd
)
np
.
savetxt
(
infile
,
val
,
fmt
=
'%0.18f'
)
...
...
@@ -1176,6 +1183,7 @@ def fileOrText(*args, **kwargs):
if
not
isinstance
(
val
,
pathlib
.
Path
):
with
tempfile
.
NamedTemporaryFile
(
mode
=
'w'
,
suffix
=
'.txt'
,
dir
=
workdir
,
delete
=
False
)
as
f
:
f
.
write
(
val
)
infile
=
f
.
name
...
...
tests/test_bids.py
View file @
5917cf19
...
...
@@ -110,6 +110,21 @@ def test_loadMetadata():
assert
fslbids
.
loadMetadata
(
t1
)
==
{
**
meta4
,
**
meta2
,
**
meta1
}
def
test_loadMetadata_control_characters
():
dd
=
Path
(
'dataset_description.json'
)
t1
=
Path
(
'sub-01/func/sub-01_task-stim_bold.nii.gz'
)
json1
=
Path
(
'sub-01/func/sub-01_task-stim_bold.json'
)
meta1
=
{
"a"
:
"1"
,
"b"
:
"2
\x19\x20
"
}
smeta1
=
'{"a" : "1", "b" : "2
\x19\x20
"}'
with
tempdir
():
dd
.
touch
()
Path
(
op
.
dirname
(
t1
)).
mkdir
(
parents
=
True
)
t1
.
touch
()
assert
fslbids
.
loadMetadata
(
t1
)
==
{}
json1
.
write_text
(
smeta1
)
assert
fslbids
.
loadMetadata
(
t1
)
==
meta1
def
test_loadMetadata_symlinked
():
ddreal
=
Path
(
'a'
)
...
...
tests/test_image.py
View file @
5917cf19
...
...
@@ -1484,6 +1484,21 @@ def test_loadMeta_badJSON():
assert
list
(
img
.
metaKeys
())
==
[]
def
test_loadMeta_control_characters
():
with
tempdir
():
make_image
(
'image.nii.gz'
)
with
open
(
'image.json'
,
'wt'
)
as
f
:
f
.
write
(
'{"a" : 1, "b" : "abc
\x19\x1b
"}'
)
# bad json should not cause failure
img
=
fslimage
.
Image
(
'image.nii.gz'
,
loadMeta
=
True
)
assert
list
(
img
.
metaKeys
())
==
[
'a'
,
'b'
]
assert
img
.
getMeta
(
'a'
)
==
1
assert
img
.
getMeta
(
'b'
)
==
'abc
\x19\x1b
'
def
test_loadMetadata
():
with
tempdir
():
make_image
(
'image.nii.gz'
)
...
...
tests/test_wrappers/test_wrapperutils.py
View file @
5917cf19
...
...
@@ -876,3 +876,61 @@ def test_cmdwrapper_cmdonly_assert():
assert
func
()[
0
].
strip
()
==
'hello'
os
.
remove
(
'file'
)
assert
func
(
cmdonly
=
True
)
==
[
'echo'
,
'hello'
]
def
test_fileOrArray_all_tempfiles_cleared
():
tempfiles
=
[]
@
wutils
.
fileOrArray
(
'in_'
,
'out'
)
def
array
(
in_
,
out
):
tempfiles
.
extend
((
in_
,
out
))
i
=
np
.
loadtxt
(
in_
)
i
=
i
+
1
np
.
savetxt
(
out
,
i
)
arr
=
np
.
array
([[
1
,
2
],
[
3
,
4
]])
arrout
=
array
(
arr
,
wutils
.
LOAD
).
out
assert
np
.
all
(
np
.
isclose
(
arrout
,
arr
+
1
))
assert
len
(
tempfiles
)
==
2
assert
not
any
(
op
.
exists
(
f
)
for
f
in
tempfiles
)
def
test_fileOrImage_all_tempfiles_cleared
():
tempfiles
=
[]
@
wutils
.
fileOrImage
(
'in_'
,
'out'
)
def
image
(
in_
,
out
):
tempfiles
.
extend
((
in_
,
out
))
i
=
nib
.
load
(
in_
)
i
=
nib
.
Nifti1Image
(
i
.
get_fdata
()
+
1
,
np
.
eye
(
4
))
i
.
to_filename
(
out
)
arr
=
np
.
array
([[
1
,
2
],
[
3
,
4
]])
img
=
nib
.
nifti1
.
Nifti1Image
(
arr
,
np
.
eye
(
4
))
imgout
=
image
(
img
,
wutils
.
LOAD
).
out
assert
np
.
all
(
np
.
isclose
(
imgout
.
get_fdata
(),
img
.
get_fdata
()
+
1
))
assert
len
(
tempfiles
)
==
2
assert
not
any
(
op
.
exists
(
f
)
for
f
in
tempfiles
)
def
test_fileOrText_all_tempfiles_cleared
():
tempfiles
=
[]
@
wutils
.
fileOrText
(
'in_'
,
'out'
)
def
text
(
in_
,
out
):
tempfiles
.
extend
((
in_
,
out
))
with
open
(
in_
,
'rt'
)
as
inf
,
open
(
out
,
'wt'
)
as
outf
:
outf
.
write
(
inf
.
read
())
outf
.
write
(
'456'
)
txt
=
'123'
txtout
=
text
(
txt
,
wutils
.
LOAD
).
out
assert
txtout
==
'123456'
assert
len
(
tempfiles
)
==
2
assert
not
any
(
op
.
exists
(
f
)
for
f
in
tempfiles
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment