示例#1
0
def test_getAnalysisDir():

    paths = ['analysis.feat/filtered_func_data.nii.gz',
             'analysis.feat/design.fsf',
             'analysis.feat/design.mat',
             'analysis.feat/design.con']

    testpaths = ['analysis.feat/filtered_func_data.nii.gz',
                 'analysis.feat/stats/zstat1.nii.gz',
                 'analysis.feat/logs/feat4_post',
                 'analysis.feat/.ramp.gif']

    with tests.testdir(paths) as testdir:
        expected = op.join(testdir, 'analysis.feat')
        for t in testpaths:
            t = op.join(testdir, t)
            assert featanalysis.getAnalysisDir(t) == expected
示例#2
0
def findFEATImage(overlayList, overlay):
    """Searches the given :class:`.OverlayList` to see if there is a
    :class:`.FEATImage` associated with the given ``overlay``. Returns the
    ``FEATImage`` if found, otherwise returns ``None``.
    """

    import fsl.data.featanalysis as featanalysis
    import fsl.data.featimage as featimage

    if isinstance(overlay, featimage.FEATImage): return overlay
    if overlay is None: return None
    if overlay.dataSource is None: return None

    featPath = featanalysis.getAnalysisDir(overlay.dataSource)

    if featPath is None:
        return None

    dataPath = featanalysis.getDataFile(featPath)
    featImage = overlayList.find(dataPath)

    return featImage
示例#3
0
def guessFlirtFiles(path):
    """Given a ``path`` to a NIFTI image file, tries to guess an appropriate
    FLIRT transformation matrix file and reference image. The guess is based
    on the path location (e.g. if it is a FEAT or MELODIC image).

    Returns a tuple containing paths to the matrix file and reference image,
    or ``(None, None)`` if a guess couldn't be made.
    """

    import fsl.data.featanalysis as featanalysis
    import fsl.data.melodicanalysis as melodicanalysis

    if path is None:
        return None, None

    filename = op.basename(path)
    dirname = op.dirname(path)
    regDir = None
    srcRefMap = {}

    func2struc = 'example_func2highres.mat'
    struc2std = 'highres2standard.mat'

    featDir = featanalysis.getAnalysisDir(dirname)
    melDir = melodicanalysis.getAnalysisDir(dirname)

    # TODO more heuristics
    if featDir is not None:

        regDir = op.join(featDir, 'reg')
        srcRefMap = {
            'example_func': ('highres', func2struc),
            'filtered_func_data': ('highres', func2struc),
            'mean_func': ('highres', func2struc),
            'thresh_zstat': ('highres', func2struc),
            op.join('stats', 'zstat'): ('highres', func2struc),
            op.join('stats', 'tstat'): ('highres', func2struc),
            op.join('stats', 'cope'): ('highres', func2struc),
            op.join('stats', 'pe'): ('highres', func2struc),
            'highres': ('standard', struc2std),
            'highres_head': ('standard', struc2std),
            'struc': ('standard', struc2std),
            'struct': ('standard', struc2std),
            'struct_brain': ('standard', struc2std),
            'struc_brain': ('standard', struc2std),
        }

    elif melodicanalysis.isMelodicDir(dirname):

        if melDir.startswith('filtered_func_data'):
            regDir = op.join(melDir, '..', 'reg')
        else:
            regDir = op.join(melDir, 'reg')

        srcRefMap = {
            'filtered_func_data': ('highres', func2struc),
            'melodic_IC': ('highres', func2struc),
            'example_func': ('highres', func2struc),
            'mean_func': ('highres', func2struc),
            'highres': ('standard', struc2std),
            'highres_head': ('standard', struc2std),
            'struc': ('standard', struc2std),
            'struct': ('standard', struc2std),
            'struct_brain': ('standard', struc2std),
            'struc_brain': ('standard', struc2std),
        }

    matFile = None
    refFile = None

    for src, (ref, mat) in srcRefMap.items():

        if not filename.startswith(src):
            continue

        mat = op.join(regDir, mat)
        ref = op.join(regDir, ref)

        try:
            ref = fslimage.addExt(ref)
        except Exception:
            continue

        if op.exists(mat):
            matFile = mat
            refFile = ref
            break

    return matFile, refFile
示例#4
0
    def __selectedOverlayChanged(self, *a):
        """Called when the :attr:`.DisplayContext.selectedOverlay` changes,
        and by the :meth:`__overlayListChanged` method.

        If the newly selected overlay is a :class:`.FEATImage` (or is otherwise
        associated with a FEAT analysis) which has cluster results, they are
        loaded in, and displayed on a :class:`.WidgetGrid`.
        """

        prevOverlay = self.__selectedOverlay
        self.__selectedOverlay = None

        # No overlays are loaded
        if len(self.overlayList) == 0:
            self.__disable(strings.messages[self, 'noOverlays'])
            return

        overlay = self.displayCtx.getSelectedOverlay()

        # Overlay is in-memory
        if overlay.dataSource is None:
            self.__disable(strings.messages[self, 'notFEAT'])
            return

        featDir = featanalysis.getAnalysisDir(overlay.dataSource)

        # No FEAT analysis, or not an Image,
        # can't do anything with that
        if featDir is None or not isinstance(overlay, fslimage.Nifti):
            log.debug('Overlay {} is not part of a feat '
                      'analysis, or is not Nifti'.format(overlay))
            self.__disable(strings.messages[self, 'notFEAT'])
            return

        # Selected overlay is either the
        # same one (maybe the overlay list,
        # rather than the selected overlay,
        # changed) or the newly selected
        # overlay is from the same FEAT
        # analysis. No need to do anything.
        if prevOverlay is not None:

            prevFeatImage = self.__featImages.get(prevOverlay)

            if prevOverlay is overlay or \
               (prevFeatImage is not None and
                    featDir == prevFeatImage.getFEATDir()):

                log.debug('Overlay {} is already selected.'.format(overlay))

                # Make sure the overlay -> FEATImage
                # mapping is present, and (re-)cache
                # a reference to the selected overlay.
                self.__featImages[overlay] = prevFeatImage
                self.__selectedOverlay = overlay

                return

        # We're in business. The newly selected
        # overlay is a part of a FEAT analysis
        # which is not currently being displayed.
        self.__selectedOverlay = overlay

        # Clear the stat selection combo box.
        self.__statSelect.Clear()

        # Get the FEATImage associated with
        # this overlay, so we can get
        # information about the FEAT analysis
        featImage = self.__featImages.get(overlay)
        if featImage is None:

            # If the overlay itself is a FEATImage,
            # then we have nothing to do.
            if isinstance(overlay, featimage.FEATImage):
                featImage = overlay
            else:
                # The FEATImage might already
                # be in the overlay list -
                # let's search for it.
                for ovl in self.overlayList:
                    if isinstance(ovl, featimage.FEATImage) and \
                       ovl.getFEATDir() == featDir:
                        featImage = ovl

            # As a last resort, if the FEATImage is not
            # in the overlay list, we'll create one.
            if featImage is None:
                featImage = featimage.FEATImage(featDir,
                                                loadData=False,
                                                calcRange=False)

            self.__featImages[overlay] = featImage

        log.debug('Identified FEAT analysis associated with overlay '
                  '{}: {}'.format(overlay, featImage.getFEATDir()))

        # Get the contrast and cluster
        # information for the FEAT analysis.
        display = self.displayCtx.getDisplay(overlay)
        numCons = featImage.numContrasts()
        conNames = featImage.contrastNames()

        try:
            # clusts is a list of (contrast, clusterList) tuples
            clusts = [(c, featImage.clusterResults(c)) for c in range(numCons)]
            clusts = [c for c in clusts if c[1] is not None]

        # Error parsing the cluster data
        except Exception as e:
            log.warning('Error parsing cluster data for '
                        '{}: {}'.format(featImage.name, str(e)),
                        exc_info=True)
            self.__disable(strings.messages[self, 'badData'])
            return

        # No cluster results exist
        # for any contrast
        if len(clusts) == 0:
            self.__disable(strings.messages[self, 'noClusters'])
            return

        # Populate the stat selection combo box
        for contrast, clusterList in clusts:
            name = conNames[contrast]
            name = strings.labels[self, 'clustName'].format(contrast + 1, name)

            self.__statSelect.Append(name, clusterList)

        self.__overlayName.SetLabel(display.name)

        # Refresh the widget grid
        self.__statSelect.SetSelection(0)
        self.__statSelected()

        self.Layout()