From dbafefba6b43a32843655f553c91e6ae19d93b4b Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Thu, 16 Feb 2017 11:12:35 +0000 Subject: [PATCH] New path function which determines the unique prefix of a file name. Used by new gifti function relatedFiles --- fsl/data/gifti.py | 65 ++++++++++++++++++++++++++++++++++++++++++----- fsl/utils/path.py | 35 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/fsl/data/gifti.py b/fsl/data/gifti.py index 41d38e3ba..8472b6005 100644 --- a/fsl/data/gifti.py +++ b/fsl/data/gifti.py @@ -17,10 +17,12 @@ are available: :nosignatures: GiftiSurface - extractGiftiSurface + loadGiftiSurface + relatedFiles """ +import glob import os.path as op import nibabel as nib @@ -49,12 +51,11 @@ class GiftiSurface(mesh.TriangleMesh): """Load the given GIFTI file using ``nibabel``, and extracts surface data using the :func:`extractGiftiSurface` function. - :arg infile: A GIFTI surface file + :arg infile: A GIFTI surface file (``*.surf.gii``). """ - surfimg = nib.load(infile) - vertices, indices = extractGiftiSurface(surfimg) + vertices, indices = loadGiftiSurface(surfimg) mesh.TriangleMesh.__init__(self, vertices, indices) @@ -67,10 +68,19 @@ class GiftiSurface(mesh.TriangleMesh): def loadVertexData(self, dataSource): - """Attempts to load scalar data associated with each vertex of this - ``GiftiSurface`` from the given ``dataSource``. + """Attempts to load data associated with each vertex of this + ``GiftiSurface`` from the given ``dataSource``. + + Currently, only the first ``DataArray`` contained in the + file is returned. + + - ``*.func.gii`` + - ``*.shape.gii`` + - ``*.label.gii`` + - ``*.time.gii`` """ + # TODO support 4D # TODO make this more robust norms = nib.load(dataSource) return norms.darrays[0].data @@ -87,7 +97,7 @@ EXTENSION_DESCRIPTIONS = ['GIFTI surface file', 'GIFTI surface file'] """ -def extractGiftiSurface(surfimg): +def loadGiftiSurface(surfimg): """Extracts surface data from the given ``nibabel.gifti.GiftiImage``. The image is expected to contain the following``<DataArray>`` elements: @@ -140,3 +150,44 @@ def extractGiftiSurface(surfimg): raise ValueError('no array witbh intent "triangle"found') return vertices, indices + + +def relatedFiles(fname): + """Given a GIFTI file, returns a list of other GIFTI files in the same + directory which appear to be related with the given one. Files which + share the same prefix are assumed to be related to the given file. + + """ + + try: + # We want to return all files in the same + # directory which have the following name: + + # + # [prefix].*.[type].gii + # + # where + # - prefix is the file prefix, and which + # may include periods. + # + # - we don't care about the middle + # + # - type is func, shape, label, or time + + # We determine the unique prefix of the + # given file, and back-up to the most + # recent period. Then search for other + # files which have that same (non-unique) + # prefix. + prefix = fslpath.uniquePrefix(fname) + prefix = prefix[:prefix.rfind('.')] + + funcs = glob.glob('{}*.func.gii' .format(prefix)) + shapes = glob.glob('{}*.shape.gii'.format(prefix)) + labels = glob.glob('{}*.label.gii'.format(prefix)) + times = glob.glob('{}*.time.gii' .format(prefix)) + + return funcs + shapes + labels + times + + except: + return [] diff --git a/fsl/utils/path.py b/fsl/utils/path.py index 7ee72abf3..86fd939c1 100644 --- a/fsl/utils/path.py +++ b/fsl/utils/path.py @@ -19,9 +19,11 @@ paths. splitExt getFileGroup removeDuplicates + uniquePrefix """ +import glob import os.path as op @@ -404,3 +406,36 @@ def removeDuplicates(paths, allowedExts=None, fileGroups=None): unique.append(groupFiles[0]) return unique + + +def uniquePrefix(path): + """Return the longest prefix for the given file name which unambiguously + identifies it, relative to the other files in the same directory. + + Raises a :exc:`ValueError` if a unique prefix could not be found (which + will never happen if the path is valid). + """ + + dirname, filename = op.split(path) + + idx = 0 + prefix = op.join(dirname, filename[0]) + hits = glob.glob('{}*'.format(prefix)) + + while True: + + # Found a unique prefix + if len(hits) == 1: + break + + # Should never happen if path is valid + elif len(hits) == 0 or idx >= len(filename) - 1: + raise ValueError('No unique prefix for {}'.format(filename)) + + # Not unique - continue looping + else: + idx += 1 + prefix = prefix + filename[idx] + hits = [h for h in hits if h.startswith(prefix)] + + return prefix -- GitLab