Beispiel #1
0
def test_defaultExt():

    fslOutputTypes = ['NIFTI', 'NIFTI_PAIR', 'NIFTI_GZ']
    exts = ['.nii', '.img', '.nii.gz']

    os.environ.pop('FSLOUTPUTTYPE', None)
    assert fslimage.defaultExt() == '.nii.gz'

    for o, e in zip(fslOutputTypes, exts):

        os.environ['FSLOUTPUTTYPE'] = o

        assert fslimage.defaultExt() == e
Beispiel #2
0
    def prepIn(workdir, name, val):

        infile = None

        if isinstance(val, fslimage.Image):
            intypes.append(fslimage.Image)

        elif isinstance(val, nib.nifti1.Nifti1Image):
            intypes.append(nib.nifti1.Nifti1Image)

        if isinstance(val, fslimage.Image):
            val = val.nibImage

        if isinstance(val, nib.nifti1.Nifti1Image):
            infile = val.get_filename()

            # in-memory image - we have
            # to save it out to a file
            if infile is None or not op.exists(infile):
                hd, infile = tempfile.mkstemp(fslimage.defaultExt(),
                                              dir=workdir)
                os.close(hd)

                # Create a copy of the input image and
                # save that, so the original doesn't
                # get associated with the temp file
                val = nib.nifti1.Nifti1Image(
                    np.asanyarray(val.dataobj), None, val.header)
                val.to_filename(infile)

        return infile
Beispiel #3
0
def test_defaultExt():

    fslOutputTypes = [
        'NIFTI', 'NIFTI_PAIR', 'NIFTI_GZ', 'NIFTI_PAIR_GZ', 'NIFTI2',
        'NIFTI2_PAIR', 'NIFTI2_GZ', 'NIFTI2_PAIR_GZ'
    ]
    exts = ['.nii', '.img', '.nii.gz', '.img.gz'] * 2

    env = os.environ.copy()

    env.pop('FSLOUTPUTTYPE', None)

    with mock.patch('os.environ', env):
        assert fslimage.defaultExt() == '.nii.gz'
        for o, e in zip(fslOutputTypes, exts):
            env['FSLOUTPUTTYPE'] = o
            assert fslimage.defaultExt() == e
Beispiel #4
0
def test_addExt():
    """Test the addExt function. """

    default = fslimage.defaultExt()
    testdir = tempfile.mkdtemp()

    toCreate = [
        'compressed.nii.gz', 'uncompressed.nii', 'img_hdr_pair.img',
        'compressed_img_hdr_pair.img.gz', 'ambiguous.nii', 'ambiguous.nii.gz',
        'ambiguous.img', 'ambiguous.img.gz'
    ]

    # (file, mustExist, expected)
    tests = [('blah', False, 'blah{}'.format(default)),
             ('blah.nii', False, 'blah.nii'),
             ('blah.nii.gz', False, 'blah.nii.gz'),
             ('blah.img', False, 'blah.img'), ('blah.hdr', False, 'blah.hdr'),
             ('blah.img.gz', False, 'blah.img.gz'),
             ('blah.hdr.gz', False, 'blah.hdr.gz'),
             ('compressed', True, 'compressed.nii.gz'),
             ('compressed.nii.gz', True, 'compressed.nii.gz'),
             ('uncompressed', True, 'uncompressed.nii'),
             ('uncompressed.nii', True, 'uncompressed.nii'),
             ('img_hdr_pair', True, 'img_hdr_pair.hdr'),
             ('img_hdr_pair.hdr', True, 'img_hdr_pair.hdr'),
             ('img_hdr_pair.img', True, 'img_hdr_pair.img'),
             ('compressed_img_hdr_pair', True,
              'compressed_img_hdr_pair.hdr.gz'),
             ('compressed_img_hdr_pair.img.gz', True,
              'compressed_img_hdr_pair.img.gz'),
             ('compressed_img_hdr_pair.hdr.gz', True,
              'compressed_img_hdr_pair.hdr.gz'),
             ('ambiguous.nii', True, 'ambiguous.nii'),
             ('ambiguous.nii.gz', True, 'ambiguous.nii.gz'),
             ('ambiguous.img', True, 'ambiguous.img'),
             ('ambiguous.hdr', True, 'ambiguous.hdr'),
             ('ambiguous.img.gz', True, 'ambiguous.img.gz'),
             ('ambiguous.hdr.gz', True, 'ambiguous.hdr.gz')]

    for path in toCreate:
        path = op.abspath(op.join(testdir, path))
        make_random_image(path)

    try:
        for path, mustExist, expected in tests:

            path = op.abspath(op.join(testdir, path))
            expected = op.abspath(op.join(testdir, expected))

            assert fslimage.addExt(path, mustExist) == expected

        # Make sure that an ambiguous path fails
        with pytest.raises(fslimage.PathError):
            path = op.join(testdir, 'ambiguous')
            fslimage.addExt(path, mustExist=True)
    finally:
        shutil.rmtree(testdir)
Beispiel #5
0
def reg_bbr(wsp):
    """
    Perform BBR registration

    :param reg_img: Data to register, e.g. PWI or calibration image. Normally would be brain extracted
    :param struc_img: Structural image
    :param struc_brain_img: Brain-extracted structural image

    Optional keyword arguments:

    :param inweight:
    :param init: Initial transform matrix

    Optional keyword arguments for fieldmap distortion correction:

    :param fmap: Fieldmap image
    :param fmapmag: Fieldmap magnitude image
    :param fmapmagbrain: Fieldmap magnitude image - brain extracted
    :param pedir: Phase encoding direction (x, -x, y, -y, z, -z)
    :param echospacing: Echo spacing

    :return Tuple of registered image, transform matrix
    """
    struc.segment(wsp)

    wsp.log.write("  - BBR registration using epi_reg...")
    # Windows can't run epi_reg as it's a batch script. Use our experimental python
    # implementation but use the standard epi_reg on other platforms until the python
    # version is better tested
    if sys.platform.startswith("win"):
        import oxasl.epi_reg as pyepi
        result = pyepi.epi_reg(wsp, wsp.reg.nativeref)
    else:
        result = epi_reg(epi=wsp.reg.nativeref,
                         t1=wsp.structural.struc,
                         t1brain=wsp.structural.brain,
                         out=fsl.LOAD,
                         wmseg=wsp.structural.wm_seg,
                         init=wsp.reg.asl2struc,
                         inweight=wsp.inweight,
                         log=wsp.fsllog)
    wsp.log.write(" DONE\n")
    return result["out%s" % defaultExt()], result["out"]
Beispiel #6
0
    def prepIn(workdir, name, val):

        infile = None

        if isinstance(val, fslimage.Image):
            intypes.append(fslimage.Image)

        elif isinstance(val, nib.nifti1.Nifti1Image):
            intypes.append(nib.nifti1.Nifti1Image)

        if isinstance(val, fslimage.Image):
            val = val.nibImage

        if isinstance(val, nib.nifti1.Nifti1Image):
            infile = val.get_filename()

            # in-memory image - we have
            # to save it out to a file
            if infile is None:
                hd, infile = tempfile.mkstemp(fslimage.defaultExt())
                os.close(hd)
                val.to_filename(infile)

        return infile
Beispiel #7
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
Beispiel #8
0
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)