示例#1
0
def test_small_radius_inverse():
    affine = np.eye(4)
    shape = (3, 3, 3)

    data = np.random.RandomState(42).random_sample(shape)
    mask = np.zeros(shape)
    mask[1, 1, 1] = 1
    mask[2, 2, 2] = 1
    affine = np.eye(4) * 1.2
    seed = (1.4, 1.4, 1.4)

    masker = NiftiSpheresMasker([seed],
                                radius=0.1,
                                mask_img=nibabel.Nifti1Image(mask, affine))
    spheres_data = masker.fit_transform(nibabel.Nifti1Image(data, affine))
    masker.inverse_transform(spheres_data)
    # Test if masking is taken into account
    mask[1, 1, 1] = 0
    mask[1, 1, 0] = 1

    masker = NiftiSpheresMasker([seed],
                                radius=0.1,
                                mask_img=nibabel.Nifti1Image(mask, affine))
    masker.fit(nibabel.Nifti1Image(data, affine))

    with pytest.raises(ValueError, match='These spheres are empty'):
        masker.inverse_transform(spheres_data)

    masker = NiftiSpheresMasker([seed],
                                radius=1.6,
                                mask_img=nibabel.Nifti1Image(mask, affine))
    masker.fit(nibabel.Nifti1Image(data, affine))
    masker.inverse_transform(spheres_data)
示例#2
0
def test_nifti_spheres_masker_inverse_transform():
    # Applying the sphere_extraction example from above backwards
    data = np.random.RandomState(42).random_sample((3, 3, 3, 5))
    img = nibabel.Nifti1Image(data, np.eye(4))
    masker = NiftiSpheresMasker([(1, 1, 1)], radius=1)
    # Test the fit
    masker.fit()
    # Transform data
    with pytest.raises(ValueError, match='Please provide mask_img'):
        masker.inverse_transform(data[0, 0, 0, :])

    # Mask describes the extend of the masker's sphere
    mask = np.zeros((3, 3, 3), dtype=np.bool)
    mask[:, 1, 1] = True
    mask[1, :, 1] = True
    mask[1, 1, :] = True

    # Now with a mask
    mask_img = np.zeros((3, 3, 3))
    mask_img[1, :, :] = 1
    mask_img = nibabel.Nifti1Image(mask_img, np.eye(4))
    masker = NiftiSpheresMasker([(1, 1, 1)], radius=1, mask_img=mask_img)
    masker.fit()
    s = masker.transform(img)
    # Create an array mask
    array_mask = np.logical_and(mask, get_data(mask_img))

    inverse_map = masker.inverse_transform(s)

    # Testing whether mask is applied to inverse transform
    assert_array_equal(
        np.mean(get_data(inverse_map), axis=-1) != 0, array_mask)
    # Test whether values are preserved
    assert_array_equal(get_data(inverse_map)[array_mask].mean(0), s[:, 0])

    # Test whether the mask's shape is applied
    assert_array_equal(inverse_map.shape[:3], mask_img.shape)
示例#3
0
def test_nifti_spheres_masker_inverse_overlap():
    rng = np.random.RandomState(42)

    # Test overlapping data in inverse_transform
    affine = np.eye(4)
    shape = (5, 5, 5)

    data = rng.random_sample(shape + (5, ))
    fmri_img = nibabel.Nifti1Image(data, affine)

    # Apply mask image - to allow inversion
    mask_img = new_img_like(fmri_img, np.ones(shape))
    seeds = [(0, 0, 0), (2, 2, 2)]
    # Inverse data
    inv_data = rng.random_sample(len(seeds))

    overlapping_masker = NiftiSpheresMasker(seeds,
                                            radius=1,
                                            allow_overlap=True,
                                            mask_img=mask_img).fit()
    overlapping_masker.inverse_transform(inv_data)

    overlapping_masker = NiftiSpheresMasker(seeds,
                                            radius=2,
                                            allow_overlap=True,
                                            mask_img=mask_img).fit()

    overlap = overlapping_masker.inverse_transform(inv_data)

    # Test whether overlapping data is averaged
    assert_array_almost_equal(get_data(overlap)[1, 1, 1], np.mean(inv_data))

    noverlapping_masker = NiftiSpheresMasker(seeds,
                                             radius=1,
                                             allow_overlap=False,
                                             mask_img=mask_img).fit()

    noverlapping_masker.inverse_transform(inv_data)
    noverlapping_masker = NiftiSpheresMasker(seeds,
                                             radius=2,
                                             allow_overlap=False,
                                             mask_img=mask_img).fit()

    with pytest.raises(ValueError, match='Overlap detected'):
        noverlapping_masker.inverse_transform(inv_data)
示例#4
0
class RsaSearchlight(object):
    def __init__(self,
                 mask_img,
                 seeds_img,
                 radius=10.,
                 distance_method='correlation',
                 memory_params=None):
        # Defs
        self.memory_params = memory_params or dict()
        self.seeds_img = seeds_img
        self.mask_img = mask_img
        self.radius = radius
        self.distance_method = distance_method

    def rsa_on_ball_axis_1(self, sphere_data):
        """
        Data: axis=1: [nvoxels, nslices]
        """

        # sphere_data could be a single voxel; in this case, we'll get
        # nan
        similarity_comparisons = pdist(sphere_data.T, self.distance_method)
        self.similarity_comparisons[self.si, :] = similarity_comparisons
        self.n_voxels[self.si] = sphere_data.shape[0]
        self.si += 1

        if self.memory_params.get('verbose', 0) > 1 and self.si % 100 == 99:
            print 'Processed %s of %s...' % (self.si + 1, self.n_seeds)
        return similarity_comparisons.std()  # output value for all slices

    def fit(self):
        # Create mask
        print("Fit the SphereMasker...")

        self.n_seeds = int(self.seeds_img.get_data().sum())

        # Pass our xform_fn for a callback on each seed.
        self.sphere_masker = NiftiSpheresMasker(
            seeds=self.seeds_img,
            mask_img=self.seeds_img,
            radius=self.radius,
            xform_fn=self.rsa_on_ball_axis_1,
            standardize=False)  # no mem
        self.sphere_masker.fit()

    def transform(self, func_img):
        print("Transforming the image...")

        n_images = func_img.shape[3]
        n_compares = n_images * (n_images - 1) / 2

        # These are computed within the callback.
        self.si = 0
        self.n_voxels = np.empty((self.n_seeds))
        self.similarity_comparisons = np.empty((self.n_seeds, n_compares))

        similarity_std = self.sphere_masker.transform(func_img)

        # Pull the values off of self, set locally.
        n_voxels = self.n_voxels
        similarity_comparisons = self.similarity_comparisons
        delattr(self, 'si')
        delattr(self, 'n_voxels')
        delattr(self, 'similarity_comparisons')

        # Clean up
        good_seeds = np.logical_not(
            np.isnan(similarity_comparisons.mean(axis=1)))
        n_voxels = n_voxels[good_seeds]
        similarity_comparisons = similarity_comparisons[good_seeds]
        similarity_std = similarity_std[:, good_seeds]  # slices x seeds

        return similarity_comparisons, similarity_std, n_voxels

    def visualize(self,
                  similarity_comparisons,
                  similarity_std=None,
                  anat_img=None,
                  labels=None):
        print("Plotting the results...")

        self.visualize_seeds(anat_img=anat_img)
        self.visualize_mask(anat_img=anat_img)
        self.visualize_comparisons(
            similarity_comparisons=similarity_comparisons,
            labels=labels,
            anat_img=anat_img)
        self.visualize_comparisons_std(similarity_std=similarity_std,
                                       anat_img=anat_img)

    def visualize_seeds(self, anat_img=None):
        plot_roi(self.sphere_masker.seeds_img_,
                 bg_img=anat_img,
                 title='seed img')

    def visualize_mask(self, anat_img=None):
        plot_roi(self.sphere_masker.mask_img_,
                 bg_img=anat_img,
                 title='mask img')

    def visualize_comparisons(self,
                              similarity_comparisons,
                              labels=None,
                              anat_img=None):
        # Plot (up to) twenty comparisons.
        plotted_similarity = similarity_comparisons[:, 0]
        plotted_img = self.sphere_masker.inverse_transform(
            plotted_similarity.T)
        plot_stat_map(plotted_img,
                      bg_img=anat_img,
                      title='RSA comparison %s vs. %s' % tuple(labels[:2]))

        # Plot mosaic of up to 20

        # Choose the comparisons
        idx = np.linspace(0, similarity_comparisons.shape[1] - 1, 20)
        idx = np.unique(np.round(idx).astype(int))  # if there's less than 20

        # Make (and filter) titles
        if labels is None:
            titles = None
        else:
            titles = []
            for ai, label1 in enumerate(labels):
                for bi, label2 in enumerate(labels[(ai + 1):]):
                    titles.append('%s vs. %s' % (label1, label2))
            titles = np.asarray(titles)[idx]

        # Create the image
        plotted_similarity = similarity_comparisons[:, idx]
        plotted_img = self.sphere_masker.inverse_transform(
            plotted_similarity.T)

        fh = plt.figure(figsize=(18, 10))
        plot_mosaic_stat_map(plotted_img,
                             colorbar=False,
                             display_mode='z',
                             bg_img=anat_img,
                             cut_coords=1,
                             figure=fh,
                             title=titles)

    def visualize_comparisons_std(self, similarity_std, anat_img=None):
        if similarity_std is not None:
            RSA_std_img = self.sphere_masker.inverse_transform(
                similarity_std[0])
            plot_stat_map(RSA_std_img, bg_img=anat_img, title='RSA std')