From 37cdaf1f1a34e8212b39cd6eb80ab5899b8d3025 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Fri, 18 Mar 2016 16:18:43 +0000 Subject: [PATCH] Moved feat/melodic directory search routines to a separate generic module. Hopefully fixed TimeSeries confusion w.r.t. nested .feat/.ica directories --- fsl/data/featresults.py | 46 ++++----------------- fsl/data/melodicresults.py | 24 ++++++++++- fsl/fsleyes/views/timeseriespanel.py | 14 ++++++- fsl/utils/path.py | 62 ++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 fsl/utils/path.py diff --git a/fsl/data/featresults.py b/fsl/data/featresults.py index 2d1015f60..00fb3c722 100644 --- a/fsl/data/featresults.py +++ b/fsl/data/featresults.py @@ -48,6 +48,7 @@ import os.path as op import numpy as np import fsl.data.image as fslimage +import fsl.utils.path as fslpath import fsl.utils.transform as transform @@ -120,49 +121,20 @@ def getAnalysisDir(path): """If the given path is contained within a FEAT directory, the path to that FEAT directory is returned. Otherwise, ``None`` is returned. """ + featdir = fslpath.deepest(path, ['.feat', '.gfeat']) - # This is basically the opposite to - # the getTopLevelAnalysisDir function + if featdir is not None and isFEATDir(featdir): + return featdir - path = path.strip() - - if path == op.sep or path == '': - return None - - path = path.rstrip(op.sep) - - sufs = ['.feat', '.gfeat'] - - if any([path.endswith(suf) for suf in sufs]): - return path - - return getAnalysisDir(op.dirname(path)) + return None def getTopLevelAnalysisDir(path): - """If the given path is contained within a FEAT directory, or a - MELODIC directory, the path to the latter directory is returned. - Otherwise, ``None`` is returned. + """If the given path is contained within a hierarchy of FEAT or MELODIC + directories, the path to the highest-level (i.e. the shallowest in the + file system) directory is returned. Otherwise, ``None`` is returned. """ - - path = path.strip() - - # We've reached the root of the file system - if path == op.sep or path == '': - return None - - path = path.rstrip(op.sep) - parent = getTopLevelAnalysisDir(op.dirname(path)) - - if parent is not None: - return parent - - sufs = ['.ica', '.gica', '.feat', '.gfeat'] - - if any([path.endswith(suf) for suf in sufs]): - return path - - return None + return fslpath.shallowest(path, ['.ica', '.gica', '.feat', '.gfeat']) def loadDesign(featdir): diff --git a/fsl/data/melodicresults.py b/fsl/data/melodicresults.py index c663aa9b4..4c46c57f5 100644 --- a/fsl/data/melodicresults.py +++ b/fsl/data/melodicresults.py @@ -16,6 +16,7 @@ following functions are provided: isMelodicImage isMelodicDir + getAnalysisDir getTopLevelAnalysisDir getDataFile getICFile @@ -38,6 +39,7 @@ import numpy as np import props +import fsl.utils.path as fslpath import fsl.data.image as fslimage import fsl.data.featresults as featresults @@ -91,7 +93,27 @@ def isMelodicDir(path): return True -getTopLevelAnalysisDir = featresults.getTopLevelAnalysisDir +def getAnalysisDir(path): + """If the given path is contained within a MELODIC directory, the path + to that MELODIC directory is returned. Otherwise, ``None`` is returned. + """ + + meldir = fslpath.deepest(path, ['.ica', '.gica']) + + if meldir is not None and isMelodicDir(meldir): + return meldir + + return None + + +def getTopLevelAnalysisDir(path): + """If the given path is contained within a hierarchy of FEAT or MELODIC + directories, the path to the highest-level (i.e. the shallowest in the + file system) directory is returned. Otherwise, ``None`` is returned. + + See :func:`.featresults.getTopLevelAnalysisDir`. + """ + return featresults.getTopLevelAnalysisDir(path) def getDataFile(meldir): diff --git a/fsl/fsleyes/views/timeseriespanel.py b/fsl/fsleyes/views/timeseriespanel.py index b68a7880b..9b38b0425 100644 --- a/fsl/fsleyes/views/timeseriespanel.py +++ b/fsl/fsleyes/views/timeseriespanel.py @@ -17,8 +17,9 @@ import props import plotpanel import fsl.data.featimage as fslfeatimage -import fsl.data.featresults as featresults import fsl.data.melodicimage as fslmelimage +import fsl.data.featresults as featresults +import fsl.data.melodicresults as melresults import fsl.data.image as fslimage import fsl.fsleyes.actions as actions import fsl.fsleyes.plotting as plotting @@ -252,9 +253,18 @@ class TimeSeriesPanel(plotpanel.OverlayPlotPanel): if overlay.dataSource is not None: featPath = featresults.getAnalysisDir(overlay.dataSource) + melPath = melresults .getAnalysisDir(overlay.dataSource) else: featPath = None - + melPath = None + + # If this overlay is from an .ica dir + # inside a .feat dir or vice versa, + # the longer/deeper path takes precedence. + if (featPath is not None) and (melPath is not None): + if len(melPath) > len(featPath): featPath = None + else: melPath = None + # Is this a FEAT filtered_func_data image, # or an image in a FEAT directory? if isinstance(overlay, fslfeatimage.FEATImage) or featPath is not None: diff --git a/fsl/utils/path.py b/fsl/utils/path.py new file mode 100644 index 000000000..4c22cd410 --- /dev/null +++ b/fsl/utils/path.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# +# path.py - Utility functions for working with file/directory paths. +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# +"""This module contains a few utility functions for working with file system +paths. + + +.. autosummary:: + :nosignatures: + + deepest + shallowest +""" + + +import os.path as op + + +def deepest(path, suffixes): + """Finds the deepest directory which ends with one of the given + sequence of suffixes, or returns ``None`` if no directories end + with any of the suffixes. + """ + + path = path.strip() + + if path == op.sep or path == '': + return None + + path = path.rstrip(op.sep) + + if any([path.endswith(s) for s in suffixes]): + return path + + return deepest(op.dirname(path), suffixes) + + +def shallowest(path, suffixes): + """Finds the shallowest directory which ends with one of the given + sequence of suffixes, or returns ``None`` if no directories end + with any of the suffixes. + """ + + path = path.strip() + + # We've reached the root of the file system + if path == op.sep or path == '': + return None + + path = path.rstrip(op.sep) + parent = shallowest(op.dirname(path), suffixes) + + if parent is not None: + return parent + + if any([path.endswith(s) for s in suffixes]): + return path + + return None -- GitLab