diff --git a/fsl/data/featimage.py b/fsl/data/featimage.py index a535ba92cfc20891164718280c053fe304433d8a..240ab15fe24e1e51f415098a8c32278c25b493ee 100644 --- a/fsl/data/featimage.py +++ b/fsl/data/featimage.py @@ -105,6 +105,14 @@ class FEATImage(fslimage.Image): name, minus the ``.feat`` / ``.gfeat`` suffix. """ return self.__analysisName + + + def getTopLevelAnalysisDir(self): + """Returns the path to the higher level analysis directory of + which this FEAT analysis is a part, or ``None`` if this analysis + is not part of another analysis. + """ + return featresults.getTopLevelAnalysisDir(self.__featDir) def getDesign(self): diff --git a/fsl/data/featresults.py b/fsl/data/featresults.py index 5250788f65325f3762a46ecc9df442956e9c7915..68a64aa2f243a52e0ba994ad4aa2ba43a713609f 100644 --- a/fsl/data/featresults.py +++ b/fsl/data/featresults.py @@ -16,6 +16,8 @@ following functions are provided: isFEATImage isFEATDir hasMelodicDir + getAnalysisDir + getTopLevelAnalysisDir loadDesign loadContrasts loadSettings @@ -102,6 +104,55 @@ def hasMelodicDir(featdir): return op.exists(getMelodicFile(featdir)) +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. + """ + + # This is basically the opposite to + # the getTopLevelAnalysisDir function + + 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)) + + +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. + """ + + 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 + + def loadDesign(featdir): """Loads the design matrix from a FEAT directory. diff --git a/fsl/data/melodicresults.py b/fsl/data/melodicresults.py index 18e5777c7302c6299d20ee857694e997e69419c5..89b45a913507d1640da16907158090f582fa753e 100644 --- a/fsl/data/melodicresults.py +++ b/fsl/data/melodicresults.py @@ -38,7 +38,8 @@ import numpy as np import props -import fsl.data.image as fslimage +import fsl.data.image as fslimage +import fsl.data.featresults as featresults log = logging.getLogger(__name__) @@ -90,30 +91,7 @@ def isMelodicDir(path): return True -def getTopLevelAnalysisDir(path): - """If the given path is a MELODIC directory, and it is contained within - a FEAT directory, or another MELODIC directory, the path to the latter - 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 +getTopLevelAnalysisDir = featresults.getTopLevelAnalysisDir def getDataFile(meldir): diff --git a/fsl/data/strings.py b/fsl/data/strings.py index f3c1316be5b6491dd0a1eee25dc46820669d559f..ca43e65ff45c86b0c196cb55bde7bc2657cf3122 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -787,17 +787,20 @@ nifti = TypeDict({ feat = TypeDict({ - 'analysisName' : 'Analysis name', - 'numPoints' : 'Number of volumes', - 'numEVs' : 'Number of EVs', - 'numContrasts' : 'Number of contrasts', - 'report' : 'Link to report', + 'analysisName' : 'Analysis name', + 'analysisDir' : 'Analysis directory', + 'partOfAnalysis' : 'Part of higher level analysis', + 'numPoints' : 'Number of volumes', + 'numEVs' : 'Number of EVs', + 'numContrasts' : 'Number of contrasts', + 'report' : 'Link to report', }) melodic = TypeDict({ 'dataFile' : 'Data file', - 'partOfAnalysis' : 'Part of analysis', + 'analysisDir' : 'Analysis directory', + 'partOfAnalysis' : 'Part of higher level analysis', 'numComponents' : 'Number of ICs', 'tr' : 'TR time', 'report' : 'Link to report', diff --git a/fsl/fsleyes/controls/overlayinfopanel.py b/fsl/fsleyes/controls/overlayinfopanel.py index 7a201486166a6add550d647546eca1b0f8c9f50c..048bd9f4124bb2e9287b159a29317202b99f3f35 100644 --- a/fsl/fsleyes/controls/overlayinfopanel.py +++ b/fsl/fsleyes/controls/overlayinfopanel.py @@ -276,17 +276,22 @@ class OverlayInfoPanel(fslpanel.FSLEyesPanel): """ info = self.__getImageInfo(overlay, display) - featInfo = collections.OrderedDict([ + featInfo = [ ('analysisName', overlay.getAnalysisName()), + ('analysisDir', overlay.getFEATDir()), ('numPoints', overlay.numPoints()), ('numEVs', overlay.numEVs()), - ('numContrasts', overlay.numContrasts()), - ]) + ('numContrasts', overlay.numContrasts())] + + topLevel = overlay.getTopLevelAnalysisDir() + + if topLevel is not None: + featInfo.insert(2, ('partOfAnalysis', topLevel)) secName = strings.labels[self, overlay, 'featInfo'] info.addSection(secName) - for k, v in featInfo.items(): + for k, v in featInfo: info.addInfo(strings.feat[k], v, section=secName) return info @@ -303,17 +308,21 @@ class OverlayInfoPanel(fslpanel.FSLEyesPanel): info = self.__getImageInfo(overlay, display) - melInfo = collections.OrderedDict([ - ('tr', overlay.tr), + melInfo = [ ('dataFile', overlay.getDataFile()), - ('partOfAnalysis', overlay.getTopLevelAnalysisDir()), - ('numComponents', overlay.numComponents()), - ]) + ('analysisDir', overlay.getMelodicDir()), + ('tr', overlay.tr), + ('numComponents', overlay.numComponents())] + + topLevel = overlay.getTopLevelAnalysisDir() + + if topLevel is not None: + melInfo.insert(2, ('partOfAnalysis', topLevel)) secName = strings.labels[self, overlay, 'melodicInfo'] info.addSection(secName) - for k, v in melInfo.items(): + for k, v in melInfo: info.addInfo(strings.melodic[k], v, section=secName) return info