示例#1
0
def checkFilesToExpect(files, outdir, outputType, datahashes):

    exts = {
        'NIFTI'      : ['.nii'],
        'NIFTI_PAIR' : ['.hdr', '.img'],
        'NIFTI_GZ'   : ['.nii.gz'],
        ''           : ['.nii.gz'],
    }.get(outputType, None)

    allFiles = []

    if isinstance(files, str):
        files = files.split()

    for f in files:

        f, fe = fslimage.splitExt(f)
        fexts = exts

        if fexts is None:
            fexts = {
                '.img'    : ['.hdr', '.img'],
                '.hdr'    : ['.hdr', '.img'],
                '.nii'    : ['.nii'],
                '.nii.gz' : ['.nii.gz']
            }.get(fe, [])
        # filename already has a different extension
        elif fe != '' and fe not in fexts:
            fexts = [fe]

        for e in fexts:

            expected = op.join(outdir, f + e)

            allFiles.append(expected)

            print('  ', expected)

            assert op.exists(expected)

    allThatExist = os.listdir(outdir)
    allThatExist = [f for f in allThatExist if op.isfile(op.join(outdir, f))]

    assert len(allThatExist) == len(allFiles)

    for i, f in enumerate(files):
        f = fslimage.addExt(op.join(outdir, f), mustExist=True)

        if isinstance(datahashes, list):
            if len(datahashes) > len(files):
                diff = len(datahashes) - len(files)
                h    = datahashes[i + diff]

            else:
                h = datahashes[i]
        else:
            h = datahashes[op.basename(f)]

        checkImageHash(f, h)
示例#2
0
def test_splitExt():

    exts = ['.nii.gz', '.nii', '.img', '.img.gz', '.hdr', '.hdr.gz']

    for e in exts:
        prefix = 'blob'
        fname = '{}{}'.format(prefix, e)

        assert fslimage.splitExt(fname) == (prefix, e)
示例#3
0
def saveOverlay(overlay, display=None):
    """Saves the currently selected overlay (only if it is a :class:`.Image`),
    by a call to :meth:`.Image.save`. If a ``display`` is provided, the
    :attr:`.Display.name` may be updated to match the new overlay file name.

    :arg overlay: The :class:`.Image` overlay to save
    :arg display: The :class:`.Display` instance associated with the overlay.
    """

    import wx

    # TODO support for other overlay types
    if not isinstance(overlay, fslimage.Image):
        raise RuntimeError('Non-volumetric types not supported yet')

    # If this image has been loaded from a file,
    # ask the user whether they want to overwrite
    # that file, or save the image to a new file.
    #
    if overlay.dataSource is not None:

        # If the data source is not nifti (e.g.
        # mgz), we are not going to overwrite it,
        # so we don't ask.
        if fslimage.looksLikeImage(overlay.dataSource):

            msg = strings.messages['SaveOverlayAction.overwrite'].format(
                overlay.dataSource)
            title = strings.titles['SaveOverlayAction.overwrite'].format(
                overlay.dataSource)

            dlg = wx.MessageDialog(wx.GetTopLevelWindows()[0],
                                   message=msg,
                                   caption=title,
                                   style=(wx.ICON_WARNING | wx.YES_NO
                                          | wx.CANCEL | wx.NO_DEFAULT))
            dlg.SetYesNoCancelLabels(
                strings.labels['SaveOverlayAction.overwrite'],
                strings.labels['SaveOverlayAction.saveNew'],
                strings.labels['SaveOverlayAction.cancel'])

            response = dlg.ShowModal()

            # Cancel == cancel the save
            # Yes    == overwrite the existing file
            # No     == save to a new file (prompt the user for the file name)
            if response == wx.ID_CANCEL:
                return

            if response == wx.ID_YES:
                doSave(overlay)
                return

        fromDir = op.dirname(overlay.dataSource)
        filename = fslimage.removeExt(op.basename(overlay.dataSource))
        filename = '{}_copy'.format(filename)
    else:
        fromDir = fslsettings.read('loadSaveOverlayDir', os.getcwd())

        if display is not None: filename = display.name
        else: filename = overlay.name

    filename = filename.replace('/', '_')
    filename = filename.replace('\\', '_')

    # Ask the user where they
    # want to save the image
    msg = strings.titles['SaveOverlayAction.saveFile']
    dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
                        message=msg,
                        defaultDir=fromDir,
                        defaultFile=filename,
                        style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

    if dlg.ShowModal() != wx.ID_OK:
        return

    # Make sure that the user chose a supported
    # extension. If not, use the default extension.
    savePath = dlg.GetPath()
    prefix, suffix = fslimage.splitExt(savePath)

    if suffix == '':
        savePath = '{}{}'.format(prefix, fslimage.defaultExt())

    oldPath = overlay.dataSource
    saveDir = op.dirname(savePath)

    if doSave(overlay, savePath):

        # Cache the save directory for next time.
        fslsettings.write('loadSaveOverlayDir', saveDir)

        # If image was in memory, or its old
        # name equalled the old datasource
        # base name, update its name.
        if oldPath is None or \
           fslimage.removeExt(op.basename(oldPath)) == overlay.name:

            overlay.name = fslimage.removeExt(op.basename(savePath))

            if display is not None:
                display.name = overlay.name
示例#4
0
文件: imcp.py 项目: neurodebian/fslpy
def imcp(src,
         dest,
         overwrite=False,
         useDefaultExt=False,
         move=False):
    """Copy the given ``src`` file to destination ``dest``.

    A :class:`.fsl.utils.path.PathError` is raised if anything goes wrong.

    :arg src:           Path to copy. If ``allowedExts`` is provided,
                        the file extension can be omitted.

    :arg dest:          Destination path. Can be an incomplete file
                        specification (i.e. without the extension), or a
                        directory.

    :arg overwrite:     If ``True`` this function will overwrite files that
                        already exist. Defaults to ``False``.

    :arg useDefaultExt: Defaults to ``False``. If ``True``, the destination
                        file type will be set according to the default
                        extension, specified by
                        :func:`~fsl.data.image.defaultExt`. If the source
                        file does not have the same type as the default
                        extension, it will be converted. If ``False``, the
                        source file type is not changed.

    :arg move:          If ``True``, the files are moved, instead of being
                        copied. See :func:`immv`.
    """

    import nibabel as nib

    if op.isdir(dest):
        dest = op.join(dest, op.basename(src))

    srcBase,  srcExt  = fslimage.splitExt(src)
    destBase, destExt = fslimage.splitExt(dest)

    # src was specified without an
    # extension, or the specified
    # src does not have an allowed
    # extension.
    if srcExt == '':

        # Try to resolve the specified src
        # path - if src does not exist, or
        # does not have an allowed extension,
        # addExt will raise an error
        src = fslimage.addExt(src, mustExist=True)

        # We've resolved src to a
        # full filename - split it
        # again to get its extension
        srcBase, srcExt = fslimage.splitExt(src)

    if not op.exists(src):
        raise fslpath.PathError('imcp error - source path '
                                'does not exist: {}'.format(src))

    # Figure out the destination file
    # extension/type. If useDefaultExt
    # is True, we use the default
    # extension. Otherwise, if no
    # destination file extension is
    # provided, we use the source
    # extension.
    if   useDefaultExt: destExt = fslimage.defaultExt()
    elif destExt == '': destExt = srcExt

    # Resolve any file group differences
    # e.g. we don't care if the src is
    # specified as file.hdr, and the dest
    # is specified as file.img - if src
    # and dest are part of the same file
    # group, we replace the dest extension
    # with the src extension.
    if srcExt != destExt:
        for group in fslimage.FILE_GROUPS:
            if srcExt in group and destExt in group:
                destExt = srcExt
                break

    dest = destBase + destExt

    # Give up if we don't have permission.
    if          not os.access(op.dirname(dest), os.W_OK | os.X_OK):
        raise fslpath.PathError('imcp error - cannot write to {}'.format(dest))

    if move and not os.access(op.dirname(src),  os.W_OK | os.X_OK):
        raise fslpath.PathError('imcp error - cannot move from {}'.format(src))

    # If the source file type does not
    # match the destination file type,
    # we need to perform a conversion.
    #
    # This is more expensive in terms of
    # io and cpu, but programmatically
    # very easy - nibabel does all the
    # hard work.
    if srcExt != destExt:

        if not overwrite and op.exists(dest):
            raise fslpath.PathError('imcp error - destination already '
                                    'exists ({})'.format(dest))

        img = nib.load(src)
        nib.save(img, dest)

        if move:
            os.remove(src)

        return

    # Otherwise we do a file copy. This
    # is actually more complicated than
    # converting the file type due to
    # hdr/img pairs ...
    #
    # If the source is part of a file group,
    # e.g. src.img/src.hdr), we need to copy
    # the whole set of files. So here we
    # build a list of source files that need
    # to be copied/moved. The getFileGroup
    # function returns all other files that
    # are associated with this file (i.e.
    # part of the same group).
    #
    # We store the sources as separate
    # (base, ext) tuples, so we don't
    # have to re-split when creating
    # destination paths.
    #
    # The unambiguous flag tells getFileGroup
    # to raise an error if the source appears
    # to be part of an incopmlete file group
    # (e.g. file.hdr without an accompanying
    # file.img).
    copySrcs = fslpath.getFileGroup(src,
                                    fslimage.ALLOWED_EXTENSIONS,
                                    fslimage.FILE_GROUPS,
                                    fullPaths=False,
                                    unambiguous=True)
    copySrcs = [(srcBase, e) for e in copySrcs]

    # Build a list of destinations for each
    # copy source - we build this list in
    # advance, so we can fail if any of the
    # destinations already exist. We also
    # re-combine the source bases/extensions.
    copyDests = [destBase + e for (b, e) in copySrcs]
    copySrcs  = [b        + e for (b, e) in copySrcs]

    # Fail if any of the destination
    # paths already exist
    if not overwrite and any([op.exists(d) for d in copyDests]):
        raise fslpath.PathError('imcp error - a destination path already '
                                'exists ({})'.format(', '.join(copyDests)))

    # Do the copy/move
    for src, dest in zip(copySrcs, copyDests):
        if move: shutil.move(src, dest)
        else:    shutil.copy(src, dest)