Beispiel #1
0
def loadColourMapFile(fname, aslut=False):
    """Load the given file, assumed to be a colour map.

    :arg fname: FSLeyes or FSLView (VEST) colour map file

    :arg aslut: If ``True``, the returned array will contain a label for
                each colour, ranging from ``1`` to ``N``, where ``N`` is
                the number of colours in the file.

    :returns:   A ``numpy`` array of shape ``(N, 3)`` containing the
                RGB values for ``N`` colours. Or, if ``aslut is True``,
                A ``numpy`` array of shape ``(N, 4)`` containing a
                label, and the RGB values for ``N`` colours.
    """

    # The file could be a FSLView style VEST LUT
    if vest.looksLikeVestLutFile(fname):
        data = vest.loadVestLutFile(fname, normalise=False)

    # Or just a plain 2D text array
    else:
        data = np.loadtxt(fname)

    if aslut:
        lbls = np.arange(1, data.shape[0] + 1).reshape(-1, 1)
        data = np.hstack((lbls, data))

    return data
Beispiel #2
0
def test_loadVestLutFile():

    testdir   = tempfile.mkdtemp()
    testfiles = [
        op.join(testdir, 'testfile1.txt'),
        op.join(testdir, 'testfile2.txt'),
        op.join(testdir, 'testfile3.txt'),
        op.join(testdir, 'testfile4.txt'),
        op.join(testdir, 'testfile5.txt')]
    testdata = [
        testfile1Colours,
        testfile2Colours,
        testfile3Colours,
        testfile4Colours]

    try:
        _createFiles(testdir)

        with pytest.raises(Exception):
            vest.loadVestLutFile(testfiles[4])
            vest.loadVestLutFile(testfiles[4], normalise=False)

        for i in range(4):
            f       = testfiles[i]
            d       = testdata[ i]

            with warnings.catch_warnings():
                warnings.simplefilter('ignore')
                dnorm   = (d - d.min()) / (d.max() - d.min())
                lutnorm = vest.loadVestLutFile(f)
                lut     = vest.loadVestLutFile(f, normalise=False)

            assert lut.shape     == d.shape
            assert lutnorm.shape == dnorm.shape
            assert np.all(np.isclose(lut,     d))

            if (d.max() - d.min()) != 0:
                assert np.all(np.isclose(lutnorm, dnorm))
            else:
                assert np.all(np.isnan(dnorm))
                assert np.all(np.isnan(lutnorm))

    finally:
        shutil.rmtree(testdir)
Beispiel #3
0
def registerColourMap(cmapFile,
                      overlayList=None,
                      displayCtx=None,
                      key=None,
                      name=None):
    """Loads RGB data from the given file, and registers
    it as a :mod:`matplotlib` :class:`~matplotlib.colors.ListedColormap`
    instance.

    .. note:: If the ``overlayList`` and ``displayContext`` arguments are
              provided, the ``cmap`` property of all :class:`.VolumeOpts`
              instances are updated to support the new colour map.

    :arg cmapFile:    Name of a file containing RGB values

    :arg overlayList: A :class:`.OverlayList` instance which contains all
                      overlays that are being displayed (can be ``None``).

    :arg displayCtx:  A :class:`.DisplayContext` instance describing how
                      the overlays in ``overlayList`` are being displayed.
                      Must be provided if ``overlayList`` is provided.

    :arg key:         Name to give the colour map. If ``None``, defaults
                      to the file name prefix.

    :arg name:        Display name for the colour map. If ``None``, defaults
                      to the ``name``.
    """

    import matplotlib.cm as mplcm
    import matplotlib.colors as colors

    if key is not None and not isValidMapKey(key):
        raise ValueError('{} is not a valid colour map identifier'.format(key))

    if key is None:
        key = op.basename(cmapFile).split('.')[0]
        key = makeValidMapKey(key)

    if name is None: name = key
    if overlayList is None: overlayList = []

    # The file could be a FSLView style VEST-LUT
    if vest.looksLikeVestLutFile(cmapFile):
        data = vest.loadVestLutFile(cmapFile, normalise=False)

    # Or just a plain 2D text array
    else:
        data = np.loadtxt(cmapFile)

    cmap = colors.ListedColormap(data, key)

    log.debug('Loading and registering custom '
              'colour map: {}'.format(cmapFile))

    mplcm.register_cmap(key, cmap)

    _cmaps[key] = _Map(key, name, cmap, cmapFile, False)

    log.debug('Patching DisplayOpts instances and class '
              'to support new colour map {}'.format(key))

    import fsleyes.displaycontext as fsldisplay

    # A list of all DisplayOpts colour map properties.
    # n.b. We can't simply list the ColourMapOpts class
    # here, because it is a mixin, and does not actually
    # derive from props.HasProperties.
    #
    # TODO Any new DisplayOpts sub-types which have a
    #      colour map will need to be patched here
    cmapProps = []
    cmapProps.append((fsldisplay.VolumeOpts, 'cmap'))
    cmapProps.append((fsldisplay.VolumeOpts, 'negativeCmap'))
    cmapProps.append((fsldisplay.VectorOpts, 'cmap'))
    cmapProps.append((fsldisplay.MeshOpts, 'cmap'))
    cmapProps.append((fsldisplay.MeshOpts, 'negativeCmap'))

    # Update the colour map properties
    # for any existing instances
    for overlay in overlayList:
        opts = displayCtx.getOpts(overlay)

        for cls, propName in cmapProps:
            if isinstance(opts, cls):
                prop = opts.getProp(propName)
                prop.addColourMap(key, opts)

    # and for all future overlays
    for cls, propName in cmapProps:

        prop = cls.getProp(propName)
        prop.addColourMap(key)