Ejemplo n.º 1
0
def apply_mask_and_get_affinity(seeds,
                                niimg,
                                radius,
                                allow_overlap,
                                n_jobs=1,
                                mask_img=None):
    import time
    start = time.time()

    seeds = list(seeds)
    affine = niimg.affine

    # Compute world coordinates of all in-mask voxels.
    mask_img = check_niimg_3d(mask_img)
    mask_img = image.resample_img(mask_img,
                                  target_affine=affine,
                                  target_shape=niimg.shape[:3],
                                  interpolation='nearest')
    mask, _ = masking._load_mask_img(mask_img)
    mask_coords = list(zip(*np.where(mask != 0)))

    X = masking._apply_mask_fmri(niimg, mask_img)

    # For each seed, get coordinates of nearest voxel
    nearests = joblib.Parallel(n_jobs=n_jobs)(
        joblib.delayed(seed_nearest)(seed_chunk, affine, mask_coords)
        for thread_id, seed_chunk in enumerate(np.array_split(seeds, n_jobs)))
    nearests = [i for j in nearests for i in j]

    mask_coords = np.asarray(list(zip(*mask_coords)))
    mask_coords = coord_transform(mask_coords[0], mask_coords[1],
                                  mask_coords[2], affine)
    mask_coords = np.asarray(mask_coords).T

    clf = neighbors.NearestNeighbors(radius=radius)
    A = clf.fit(mask_coords).radius_neighbors_graph(seeds)
    A = A.tolil()
    for i, nearest in enumerate(nearests):
        if nearest is None:
            continue
        A[i, nearest] = True
    # Include the voxel containing the seed itself if not masked
    mask_coords = mask_coords.astype(int).tolist()
    for i, seed in enumerate(seeds):
        try:
            A[i, mask_coords.index(seed)] = True
        except ValueError:
            # seed is not in the mask
            pass

    if not allow_overlap:
        if np.any(A.sum(axis=0) >= 2):
            raise ValueError('Overlap detected between spheres')

    return X, A
Ejemplo n.º 2
0
def _mask_stat_map(stat_map_img, threshold=None):
    """ Load a stat map and apply a threshold.
        Returns: mask_img, stat_map_img, data, threshold
    """
    # Load stat map
    stat_map_img = check_niimg_3d(stat_map_img, dtype="auto")
    data = _safe_get_data(stat_map_img, ensure_finite=True)

    # threshold the stat_map
    if threshold is not None:
        data, mask, threshold = _threshold_data(data, threshold)
        mask_img = new_img_like(stat_map_img, mask, stat_map_img.affine)
    else:
        mask_img = new_img_like(stat_map_img, np.zeros(data.shape),
                                stat_map_img.affine)
    return mask_img, stat_map_img, data, threshold
Ejemplo n.º 3
0
def view_img_on_surf(stat_map_img,
                     surf_mesh='fsaverage5',
                     threshold=None,
                     cmap=cm.cold_hot,
                     black_bg=False,
                     vmax=None,
                     vmin=None,
                     symmetric_cmap=True,
                     colorbar=True,
                     colorbar_height=.5,
                     colorbar_fontsize=25,
                     title=None,
                     title_fontsize=25,
                     vol_to_surf_kwargs={}):
    """Insert a surface plot of a statistical map into an HTML page.

    Parameters
    ----------
    stat_map_img : Niimg-like object, 3D
        See http://nilearn.github.io/manipulating_images/input_output.html

    surf_mesh : str or dict, optional.
        if 'fsaverage5', use fsaverage5 mesh from nilearn.datasets
        if 'fsaverage', use fsaverage mesh from nilearn.datasets
        if a dictionary, it should have the same structure as those returned by
        nilearn.datasets.fetch_surf_fsaverage, i.e. keys should be 'infl_left',
        'pial_left', 'sulc_left', 'infl_right', 'pial_right', and 'sulc_right',
        containing inflated and pial meshes, and sulcal depth values for left
        and right hemispheres. Default='fsaverage5'.

    threshold : str, number or None, optional
        If None, no thresholding.
        If it is a number only values of amplitude greater
        than threshold will be shown.
        If it is a string it must finish with a percent sign,
        e.g. "25.3%", and only values of amplitude above the
        given percentile will be shown.

    cmap : str or matplotlib colormap, optional
        Colormap to use. Default=cm.cold_hot.

    black_bg : bool, optional
        If True, image is plotted on a black background. Otherwise on a
        white background. Default=False.

    vmax : float or None, optional
        upper bound for the colorbar. if None, use the absolute max of the
        brain map.

    vmin : float or None, optional
        min value for mapping colors.
        If `symmetric_cmap` is `True`, `vmin` is always equal to `-vmax` and
        cannot be chosen.
        If `symmetric_cmap` is `False`, `vmin` defaults to the min of the
        image, or 0 when a threshold is used.

    symmetric_cmap : bool, optional
        Make colormap symmetric (ranging from -vmax to vmax).
        You can set it to False if you are plotting only positive values.
        Default=True.

    colorbar : bool, optional
        Add a colorbar or not. Default=True.

    colorbar_height : float, optional
        Height of the colorbar, relative to the figure height. Default=0.5.

    colorbar_fontsize : int, optional
        Fontsize of the colorbar tick labels. Default=25.

    title : str, optional
        Title for the plot.

    title_fontsize : int, optional
        Fontsize of the title. Default=25.

    vol_to_surf_kwargs : dict, optional
        Dictionary of keyword arguments that are passed on to
        :func:`nilearn.surface.vol_to_surf` when extracting a surface from
        the input image. See the function documentation for details.This
        parameter is especially useful when plotting an atlas. See
        https://nilearn.github.io/auto_examples/01_plotting/plot_3d_map_to_surface_projection.html

    Returns
    -------
    SurfaceView : plot of the stat map.
        It can be saved as an html page or rendered (transparently) by the
        Jupyter notebook. Useful methods are :

        - 'resize' to resize the plot displayed in a Jupyter notebook
        - 'save_as_html' to save the plot to a file
        - 'open_in_browser' to save the plot and open it in a web browser.

    See Also
    --------
    nilearn.plotting.view_surf: plot from a surface map on a cortical mesh.

    """
    stat_map_img = check_niimg_3d(stat_map_img)
    info = full_brain_info(volume_img=stat_map_img,
                           mesh=surf_mesh,
                           threshold=threshold,
                           cmap=cmap,
                           black_bg=black_bg,
                           vmax=vmax,
                           vmin=vmin,
                           symmetric_cmap=symmetric_cmap,
                           vol_to_surf_kwargs=vol_to_surf_kwargs)
    info['colorbar'] = colorbar
    info['cbar_height'] = colorbar_height
    info['cbar_fontsize'] = colorbar_fontsize
    info['title'] = title
    info['title_fontsize'] = title_fontsize
    return _fill_html_template(info, embed_js=True)
Ejemplo n.º 4
0
    def _apply_mask_and_get_affinity(seeds,
                                     niimg,
                                     radius,
                                     allow_overlap,
                                     mask_img=None):
        seeds = list(seeds)
        aff = niimg.get_affine()

        # Compute world coordinates of all in-mask voxels.
        if mask_img is not None:
            mask_img = check_niimg_3d(mask_img)
            mask_img = image.resample_img(mask_img,
                                          target_affine=aff,
                                          target_shape=niimg.shape[:3],
                                          interpolation='nearest')
            mask, _ = masking._load_mask_img(mask_img)
            mask_coords = list(zip(*np.where(mask != 0)))

            # X = masking._apply_mask_fmri(niimg, mask_img)
        else:
            mask_coords = list(np.ndindex(niimg.shape[:3]))

        # For each seed, get coordinates of nearest voxel
        nearests = []
        for sx, sy, sz in seeds:
            nearest = np.round(coord_transform(sx, sy, sz, np.linalg.inv(aff)))
            nearest = nearest.astype(int)
            nearest = (nearest[0], nearest[1], nearest[2])
            try:
                nearests.append(mask_coords.index(nearest))
            except ValueError:
                nearests.append(None)

        mask_coords = np.asarray(list(zip(*mask_coords)))
        mask_coords = coord_transform(mask_coords[0], mask_coords[1],
                                      mask_coords[2], aff)
        mask_coords = np.asarray(mask_coords).T

        if (radius is not None
                and LooseVersion(sklearn.__version__) < LooseVersion('0.16')):
            # Fix for scikit learn versions below 0.16. See
            # https://github.com/scikit-learn/scikit-learn/issues/4072
            radius += 1e-6

        clf = neighbors.NearestNeighbors(radius=radius)
        A = clf.fit(mask_coords).radius_neighbors_graph(seeds)
        A = A.tolil()

        for i, nearest in enumerate(nearests):
            if nearest is None:
                continue
            A[i, nearest] = True

        # Include the voxel containing the seed itself if not masked
        mask_coords = mask_coords.astype(int).tolist()
        for i, seed in enumerate(seeds):
            try:
                A[i, mask_coords.index(seed)] = True
            except ValueError:
                # seed is not in the mask
                pass

        if not allow_overlap:
            if np.any(A.sum(axis=0) >= 2):
                raise ValueError('Overlap detected between spheres')

        return A
Ejemplo n.º 5
0
def create_spherical_vois(ref_img, seeds, radius=1):
    """ 
    Utility to create spherical masks for voi extraction.
    Careful, differing from NiftiSpheresMasker this function
    does not check whether vois are overlapping. The function
    puts out single masks for each coordinate. These can then
    be used with e.g. the NiftiMasker. Importantly note, that 
    this function is just a "remix" of nilearn's
    NiftiSpheresMasker! So check it out!
    Parameters
    ----------
    ref_img : 3D nifti image, which serves as the reference
        for VOI creation. Output masks will have the same 
        dimensions and affine as ref_img.
    seeds : a list of lists or tuples of size 3, defining
        the seed coordinates in MNI-space around which the 
        vois will be centered.
    radius : the radius of the VOI in mm, defaults to 1.
    Returns
    -------
    voi_masks : A list of length(seeds), containing
        a spherical mask for each seed in the dimensions
        of the ref_img.
    """

    niimg = check_niimg_3d(ref_img)
    affine = niimg.affine
    img_shape = niimg.shape

    X = niimg.get_data().reshape([-1, 1]).T

    mask_coords = list(np.ndindex(img_shape[:3]))

    voi_masks = []
    nearests = []

    for sx, sy, sz in seeds:
        nearest = np.round(coord_transform(sx, sy, sz, np.linalg.inv(affine)))
        nearest = nearest.astype(int)
        nearest = (nearest[0], nearest[1], nearest[2])
        try:
            nearests.append(mask_coords.index(nearest))
        except ValueError:
            nearests.append(None)

    mask_coords = np.asarray(list(zip(*mask_coords)))
    mask_coords = coord_transform(mask_coords[0], mask_coords[1],
                                  mask_coords[2], affine)
    mask_coords = np.asarray(mask_coords).T

    clf = neighbors.NearestNeighbors(radius=radius)
    A = clf.fit(mask_coords).radius_neighbors_graph(seeds)
    A = A.tolil()

    clf.fit(mask_coords)

    for i, nearest in enumerate(nearests):
        if nearest is None:
            continue
        A[i, nearest] = True

        voi_mask = new_img_like(niimg, A[i].toarray().reshape(img_shape[:3]))

        voi_masks.append(voi_mask)

    return voi_masks
def _apply_mask_and_get_affinity(seeds,
                                 niimg,
                                 radius,
                                 allow_overlap,
                                 mask_img=None):
    seeds = list(seeds)
    affine = niimg.affine

    # Compute world coordinates of all in-mask voxels.

    if mask_img is not None:
        mask_img = check_niimg_3d(mask_img)
        mask_img = image.resample_img(mask_img,
                                      target_affine=affine,
                                      target_shape=niimg.shape[:3],
                                      interpolation='nearest')
        mask, _ = masking._load_mask_img(mask_img)
        mask_coords = list(zip(*np.where(mask != 0)))

        X = masking._apply_mask_fmri(niimg, mask_img)
    else:
        if np.isnan(np.sum(_safe_get_data(niimg))):
            warnings.warn('The imgs you have fed into fit_transform() contains'
                          ' NaN values which will be converted to zeroes ')
            X = _safe_get_data(niimg, True).reshape([-1, niimg.shape[3]]).T
        else:
            X = _safe_get_data(niimg).reshape([-1, niimg.shape[3]]).T
        mask_coords = list(np.ndindex(niimg.shape[:3]))

    # For each seed, get coordinates of nearest voxel
    nearests = []
    for sx, sy, sz in seeds:
        nearest = np.round(coord_transform(sx, sy, sz, np.linalg.inv(affine)))
        nearest = nearest.astype(int)
        nearest = (nearest[0], nearest[1], nearest[2])
        try:
            nearests.append(mask_coords.index(nearest))
        except ValueError:
            nearests.append(None)

    mask_coords = np.asarray(list(zip(*mask_coords)))
    mask_coords = coord_transform(mask_coords[0], mask_coords[1],
                                  mask_coords[2], affine)
    mask_coords = np.asarray(mask_coords).T

    clf = neighbors.NearestNeighbors(radius=radius)
    A = clf.fit(mask_coords).radius_neighbors_graph(seeds)
    A = A.tolil()
    for i, nearest in enumerate(nearests):
        if nearest is None:
            continue
        A[i, nearest] = True

    # Include the voxel containing the seed itself if not masked
    mask_coords = mask_coords.astype(int).tolist()
    for i, seed in enumerate(seeds):
        try:
            A[i, mask_coords.index(seed)] = True
        except ValueError:
            # seed is not in the mask
            pass

    if not allow_overlap:
        if np.any(A.sum(axis=0) >= 2):
            raise ValueError('Overlap detected between spheres')

    return X, A