Commit 757570af authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

RF,ENH: Move to fsl.utils. New strict option to isBIDSFile, allowing the

directory check to be skipped
parent 8fa664c1
...@@ -53,9 +53,9 @@ import fsl.utils.notifier as notifier ...@@ -53,9 +53,9 @@ import fsl.utils.notifier as notifier
import fsl.utils.memoize as memoize import fsl.utils.memoize as memoize
import fsl.utils.path as fslpath import fsl.utils.path as fslpath
import fsl.utils.deprecated as deprecated import fsl.utils.deprecated as deprecated
import fsl.utils.bids as fslbids
import fsl.data.constants as constants import fsl.data.constants as constants
import fsl.data.imagewrapper as imagewrapper import fsl.data.imagewrapper as imagewrapper
import fsl.data.bids as fslbids
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
isBIDSFile isBIDSFile
loadMetadata loadMetadata
All of the other functions in this module should not be considered part of the
public API.
.. note:: The `pybids <https://bids-standard.github.io/pybids/>`_ library is .. note:: The `pybids <https://bids-standard.github.io/pybids/>`_ library is
a more suitable choice if you are after a more robust and featured a more suitable choice if you are after a more robust and featured
...@@ -73,20 +76,24 @@ class BIDSFile(object): ...@@ -73,20 +76,24 @@ class BIDSFile(object):
def parseFilename(filename): def parseFilename(filename):
"""Parses a BIDS-like file name. The file name is assumed to consist of """Parses a BIDS-like file name. The file name must consist of zero or more
zero or more "entities" (alpha-numeric ``name-value`` pairs), a "suffix", "entities" (alpha-numeric ``name-value`` pairs), a "suffix", all separated
all separated by underscores, and a regular file extension. For example, by underscores, and a regular file extension. For example, the following
the following file:: file::
sub-01_ses-01_task-stim_bold.nii.gz sub-01_ses-01_task-stim_bold.nii.gz
has suffix ``bold``, and entities ``sub=01``, ``ses=01`` and ``task=stim``. has suffix ``bold``, and entities ``sub=01``, ``ses=01`` and ``task=stim``.
:returns: A tuple containing: :returns: A tuple containing:
- A dict containing the entities. - A dict containing the entities
- The suffix, or ``None`` if there is no suffix. - The suffix
""" """
if not isBIDSFile(filename, strict=False):
raise ValueError('Does not look like a BIDS '
'file: {}'.format(filename))
suffix = None suffix = None
entities = [] entities = []
filename = op.basename(filename) filename = op.basename(filename)
...@@ -96,11 +103,7 @@ def parseFilename(filename): ...@@ -96,11 +103,7 @@ def parseFilename(filename):
for part in parts[:-1]: for part in parts[:-1]:
entities.append(part.split('-')) entities.append(part.split('-'))
part = parts[-1].split('-') suffix = parts[-1]
if len(part) == 1: suffix = part[0]
else: entities.append(part.split('-'))
entities = dict(entities) entities = dict(entities)
return entities, suffix return entities, suffix
...@@ -136,15 +139,20 @@ def inBIDSDir(filename): ...@@ -136,15 +139,20 @@ def inBIDSDir(filename):
return inBIDS return inBIDS
def isBIDSFile(filename): def isBIDSFile(filename, strict=True):
"""Returns ``True`` if ``filename`` looks like a BIDS image or JSON file. """Returns ``True`` if ``filename`` looks like a BIDS image or JSON file.
: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`.
""" """
name = op.basename(filename) name = op.basename(filename)
pattern = r'([a-z0-9]+-[a-z0-9]+_)*([a-z0-9])+\.(nii|nii\.gz|json)' pattern = r'([a-z0-9]+-[a-z0-9]+_)*([a-z0-9])+\.(nii|nii\.gz|json)'
flags = re.ASCII | re.IGNORECASE flags = re.ASCII | re.IGNORECASE
match = re.fullmatch(pattern, name, flags)
return inBIDSDir(filename) and re.fullmatch(pattern, name, flags) return ((not strict) or inBIDSDir(filename)) and match
@memoize.memoize @memoize.memoize
...@@ -177,7 +185,9 @@ def loadMetadata(filename): ...@@ -177,7 +185,9 @@ def loadMetadata(filename):
# Gather all json files in this # Gather all json files in this
# directory with matching entities # directory with matching entities
# and suffix, sorted alphabetically # and suffix, sorted alphabetically
files = sorted(glob.glob(op.join(dirname, '*.json'))) # and reversed, so that earlier
# ones take precedence
files = reversed(sorted(glob.glob(op.join(dirname, '*.json'))))
files = [BIDSFile(f) for f in files if isBIDSFile(f)] files = [BIDSFile(f) for f in files if isBIDSFile(f)]
files = [f.filename for f in files if bfile.match(f)] files = [f.filename for f in files if bfile.match(f)]
......
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