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
3c57660e
Commit
3c57660e
authored
Feb 23, 2021
by
Paul McCarthy
🚵
Browse files
Merge branch 'rf/bids' into 'master'
Rf/bids See merge request fsl/fslpy!287
parents
33f85a0a
02a84b76
Pipeline
#7905
passed with stages
in 14 minutes and 16 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.rst
View file @
3c57660e
...
...
@@ -13,6 +13,8 @@ Changed
* The :class:`.TaskThread` now allows an error handler function to be
specified, which is run on the :mod:`.idle` loop.
* The :func:`.bids.loadMetadata` function no long resolves sym-links when
determining whether a file is contained within a BIDS data set.
Deprecated
...
...
fsl/utils/bids.py
View file @
3c57660e
...
...
@@ -18,6 +18,7 @@
All of the other functions in this module should not be considered part of the
public API.
.. see:: https://bids-specification.readthedocs.io/en/stable/
.. note:: The `pybids <https://bids-standard.github.io/pybids/>`_ library is
a more suitable choice if you are after a more robust and featured
...
...
@@ -36,8 +37,8 @@ import fsl.utils.path as fslpath
class
BIDSFile
(
object
):
"""The ``BIDSFile`` class parses and stores the entities and suffix
contained
in a BIDS file. See the :func:`parseFilename` function.
"""The ``BIDSFile`` class parses and stores the entities and suffix
contained
in a BIDS file. See the :func:`parseFilename` function.
The :meth:`match` method can be used to compare two ``BIDSFile`` instances.
...
...
@@ -91,15 +92,9 @@ class BIDSFile(object):
def
parseFilename
(
filename
):
"""Parses a BIDS-like file name. The file name must consist of zero or more
"entities" (alpha-numeric ``name-value`` pairs), a "suffix", all separated
by underscores, and a regular file extension. For example, the following
file::
sub-01_ses-01_task-stim_bold.nii.gz
has suffix ``bold``, entities ``sub=01``, ``ses=01`` and ``task=stim``, and
extension ``.nii.gz``.
"""Parses a BIDS-like file name, returning the entities and suffix encoded
in the name. See the :func:`isBIDSFile` function for an explanation of
what is considered to be a valid BIDS file name.
.. note:: This function assumes that no period (``.``) characters occur in
the body of a BIDS filename.
...
...
@@ -161,11 +156,24 @@ def inBIDSDir(filename):
def
isBIDSFile
(
filename
,
strict
=
True
):
"""Returns ``True`` if ``filename`` looks like a BIDS image or JSON file.
A BIDS file name must consist of zero or more "entities" (alpha-numeric
``name-value`` pairs), a "suffix", all separated by underscores, and a
regular file extension. For example, the following file::
sub-01_ses-01_task-stim_bold.nii.gz
has suffix ``bold``, entities ``sub=01``, ``ses=01`` and ``task=stim``, and
extension ``.nii.gz``.
:arg filename: Name of file to check
:arg strict: If ``True`` (the default), the file must be within a BIDS
dataset directory, as defined by :func:`inBIDSDir`.
"""
# Zero or more entities because sidecar files
# do not necessarily need to contain any
# entities (e.g. ``T1w.json`` is valid)
name
=
op
.
basename
(
filename
)
pattern
=
r
'([a-z0-9]+-[a-z0-9]+_)*([a-z0-9])+\.(.+)'
flags
=
re
.
ASCII
|
re
.
IGNORECASE
...
...
@@ -189,7 +197,7 @@ def loadMetadata(filename):
``filename``
"""
filename
=
op
.
realpath
(
op
.
abspath
(
filename
)
)
filename
=
op
.
abspath
(
filename
)
bfile
=
BIDSFile
(
filename
)
dirname
=
op
.
dirname
(
filename
)
prevdir
=
filename
...
...
tests/test_bids.py
View file @
3c57660e
...
...
@@ -18,8 +18,11 @@ import fsl.utils.bids as fslbids
def
test_parseFilename
():
with
pytest
.
raises
(
ValueError
):
fslbids
.
parseFilename
(
'bad_file.txt'
)
badtests
=
[
'bad_file.txt'
]
for
test
in
badtests
:
with
pytest
.
raises
(
ValueError
):
fslbids
.
parseFilename
(
test
)
tests
=
[
(
'sub-01_ses-01_t1w.nii.gz'
,
...
...
@@ -105,3 +108,41 @@ def test_loadMetadata():
assert
fslbids
.
loadMetadata
(
t1
)
==
{
**
meta2
,
**
meta1
}
json4
.
write_text
(
json
.
dumps
(
meta4
))
assert
fslbids
.
loadMetadata
(
t1
)
==
{
**
meta4
,
**
meta2
,
**
meta1
}
def
test_loadMetadata_symlinked
():
ddreal
=
Path
(
'a'
)
t1real
=
Path
(
'b'
)
j1real
=
Path
(
'c'
)
j2real
=
Path
(
'd'
)
j3real
=
Path
(
'e'
)
j4real
=
Path
(
'f'
)
dd
=
Path
(
'data/dataset_description.json'
)
t1
=
Path
(
'data/sub-01/func/sub-01_task-stim_bold.nii.gz'
)
json1
=
Path
(
'data/sub-01/func/sub-01_task-stim_bold.json'
)
json2
=
Path
(
'data/sub-01/sub-01_bold.json'
)
json3
=
Path
(
'data/sub-01_t1w.json'
)
json4
=
Path
(
'data/sub-01/task-stim_bold.json'
)
meta1
=
{
'a'
:
'1'
,
'b'
:
'2'
}
meta2
=
{
'a'
:
'10'
,
'c'
:
'3'
}
meta3
=
{
'a'
:
'109'
,
'b'
:
'99'
}
meta4
=
{
'c'
:
'9'
,
'd'
:
'5'
}
with
tempdir
():
ddreal
.
touch
()
t1real
.
touch
()
j1real
.
write_text
(
json
.
dumps
(
meta1
))
j2real
.
write_text
(
json
.
dumps
(
meta2
))
j3real
.
write_text
(
json
.
dumps
(
meta3
))
j4real
.
write_text
(
json
.
dumps
(
meta4
))
Path
(
op
.
dirname
(
t1
)).
mkdir
(
parents
=
True
)
dd
.
symlink_to
(
op
.
join
(
'..'
,
ddreal
))
t1
.
symlink_to
(
op
.
join
(
'..'
,
'..'
,
'..'
,
t1real
))
json1
.
symlink_to
(
op
.
join
(
'..'
,
'..'
,
'..'
,
j1real
))
json2
.
symlink_to
(
op
.
join
(
'..'
,
'..'
,
j2real
))
json3
.
symlink_to
(
op
.
join
(
'..'
,
j3real
))
json4
.
symlink_to
(
op
.
join
(
'..'
,
'..'
,
j4real
))
assert
fslbids
.
loadMetadata
(
t1
)
==
{
**
meta4
,
**
meta2
,
**
meta1
}
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