def test_unsupported_alignment():
    img1, mask_img = random_niimg((8, 7, 6, 10))
    img2, _ = random_niimg((7, 6, 8, 5))
    args = {'alignment_method': 'scaled_procrustes', 'mask': mask_img}
    algo = PairwiseAlignment(**args)
    with pytest.raises(NotImplementedError):
        algo.fit(img1, img2)
Example #2
0
def _map_template_to_image(imgs, train_index, template, alignment_method,
                           n_pieces, clustering, n_bags, masker, memory,
                           memory_level, n_jobs, verbose):
    '''Learn alignment operator from the template toward new images.

    Parameters
    ----------
    imgs: list of 3D Niimgs
        Target images to learn mapping from the template to a new subject
    train_index: list of int
        Matching index between imgs and the corresponding template images to use
        to learn alignment. len(train_index) must be equal to len(imgs)
    template: list of 3D Niimgs
        Learnt in a first step now used as source image
    All other arguments are the same are passed to PairwiseAlignment


    Returns
    -------
    mapping: instance of PairwiseAlignment class
        Alignment estimator fitted to align the template with the input images
    '''

    mapping_image = index_img(template, train_index)
    mapping = PairwiseAlignment(n_pieces=n_pieces,
                                alignment_method=alignment_method,
                                clustering=clustering,
                                n_bags=n_bags,
                                mask=masker,
                                memory=memory,
                                memory_level=memory_level,
                                n_jobs=n_jobs,
                                verbose=verbose)
    mapping.fit(mapping_image, imgs)
    return mapping
def test_pairwise_identity():
    img1, mask_img = random_niimg((8, 7, 6, 10))

    args_list = [{
        'alignment_method': 'identity',
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'n_bags': 4,
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'n_bags': 3,
        'mask': mask_img,
        'n_jobs': 2
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'n_bags': 2,
        'mask': mask_img,
        'n_jobs': 2,
        'parallel_backend': 'multiprocessing'
    }]
    for args in args_list:
        algo = PairwiseAlignment(**args)
        assert_algo_transform_almost_exactly(algo, img1, img1, mask=mask_img)
Example #4
0
def _align_images_to_template(imgs, template, alignment_method, n_pieces,
                              clustering, n_bags, masker, memory, memory_level,
                              n_jobs, verbose):
    '''Convenience function : for a list of images, return the list
    of estimators (PairwiseAlignment instances) aligning each of them to a
    common target, the template. All arguments are used in PairwiseAlignment
    '''
    aligned_imgs = []
    for img in imgs:
        piecewise_estimator = \
            PairwiseAlignment(n_pieces=n_pieces,
                              alignment_method=alignment_method,
                              clustering=clustering, n_bags=n_bags,
                              mask=masker, memory=memory,
                              memory_level=memory_level,
                              n_jobs=n_jobs,
                              verbose=verbose)
        piecewise_estimator.fit(img, template)
        aligned_imgs.append(piecewise_estimator.transform(img))
    return aligned_imgs
def test_pairwise_identity():
    img1, mask_img = random_niimg((8, 7, 6, 10))

    args_list = [{
        'alignment_method': 'identity',
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'n_bags': 4,
        'mask': mask_img
    }, {
        'alignment_method': 'identity',
        'n_pieces': 3,
        'n_bags': 3,
        'mask': mask_img,
        'n_jobs': 2
    }]
    for args in args_list:
        algo = PairwiseAlignment(**args)
        assert_algo_transform_almost_exactly(algo, img1, img1, mask=mask_img)

    # test intersection of clustering and mask
    data_mask = copy.deepcopy(mask_img.get_fdata())
    data_mask[0] = 0
    # create ground truth
    clustering_mask = new_img_like(mask_img, data_mask)
    data_clust = copy.deepcopy(data_mask)
    data_clust[1] = 3
    # create 2-parcels clustering, smaller than background
    clustering = new_img_like(mask_img, data_clust)

    # clustering is smaller than mask
    assert (mask_img.get_fdata() > 0).sum() > (clustering.get_data() > 0).sum()
    algo = PairwiseAlignment(alignment_method='identity',
                             mask=mask_img,
                             clustering=clustering)
    with pytest.warns(UserWarning):
        algo.fit(img1, img1)
    assert (algo.mask.get_fdata() > 0).sum() == (clustering.get_fdata() >
                                                 0).sum()

    # test warning raised if parcel is 0 :
    null_im = new_img_like(img1, np.zeros_like(img1.get_fdata()))
    with pytest.warns(UserWarning):
        algo.fit(null_im, null_im)
def test_models_against_identity():
    img1, mask_img = random_niimg((7, 6, 8, 5))
    img2, _ = random_niimg((7, 6, 8, 5))
    masker = NiftiMasker(mask_img=mask_img)
    masker.fit()
    ground_truth = masker.transform(img2)
    identity_baseline_score = zero_mean_coefficient_determination(
        ground_truth, masker.transform(img1))
    for alignment_method in [
            'permutation', 'ridge_cv', 'scaled_orthogonal',
            'optimal_transport', 'diagonal'
    ]:
        algo = PairwiseAlignment(alignment_method=alignment_method,
                                 mask=mask_img,
                                 n_pieces=2,
                                 n_bags=1,
                                 n_jobs=1)
        algo.fit(img1, img2)
        im_test = algo.transform(img1)
        algo_score = zero_mean_coefficient_determination(
            ground_truth, masker.transform(im_test))
        assert_greater(algo_score, identity_baseline_score)
Example #7
0
target_test = df[df.subject == 'sub-02'][df.acquisition == 'pa'].path.values

#############################################################################
# Define the estimator used to align subjects, fit it and use it to predict
# -------------------------------------------------------------------------
# To proceed with alignment we use PairwiseAlignment class.
# We will use the common model proposed in the literature:
# * we will align the whole brain through multiple local alignments.
# * these alignments are calculated on a parcellation of the brain in 150
#   pieces, this parcellation creates group of functionnally similar voxels.
#

from fmralign.pairwise_alignment import PairwiseAlignment

alignement_estimator = PairwiseAlignment(alignment_method='scaled_orthogonal',
                                         n_pieces=150,
                                         mask=masker)
# Learn alignment operator from subject 1 to subject 2 on training data
alignement_estimator.fit(source_train, target_train)
# Predict test data for subject 2 from subject 1
target_pred = alignement_estimator.transform(source_test)

#############################################################################
# Score the prediction of test data with and without alignment
# ---------------------------------------------------
#  To score the quality of prediction we use r2 score on each voxel
# activation profile across contrasts. This score is 1 for a perfect prediction
# and can get arbitrarly bad (here we clip it to -1 for bad predictions)

from sklearn.metrics import r2_score
import numpy as np
def align_one_target(sources_train,
                     sources_test,
                     target_train,
                     target_test,
                     method,
                     masker,
                     pairwise_method,
                     clustering,
                     n_pieces,
                     n_jobs,
                     decoding_dir=None,
                     srm_atlas=None,
                     srm_components=40,
                     ha_radius=5,
                     ha_sparse_radius=3,
                     smoothing_fwhm=6,
                     surface=False):
    overhead_time = 0
    aligned_sources_test = []

    if surface == "rh":

        clustering = clustering.replace("lh", "rh")
        # clustering = load_surf_data(
        #    "/storage/store2/tbazeill/schaeffer/FreeSurfer5.3/fsaverage/label/rh.Schaefer2018_700Parcels_17Networks_order.annot")
        sources_train = np.asarray(
            [t.replace("lh", "rh") for t in sources_train])
        sources_test = np.asarray(
            [t.replace("lh", "rh") for t in sources_test])
        target_train.replace("lh", "rh")
        target_test.replace("lh", "rh")
    if surface in ["rh", "lh"]:
        from nilearn.surface import load_surf_data
        clustering = load_surf_data(clustering)
    if method == "anat_inter_subject":
        fit_start = time.process_time()
        if surface in ["lh", "rh"]:
            aligned_sources_test = load_clean(sources_test, masker)
            aligned_target_test = load_clean(target_test, masker)
        else:
            aligned_sources_test = np.vstack(
                [masker.transform(s) for s in sources_test])
            aligned_target_test = masker.transform(target_test)

    elif method == "smoothing":
        fit_start = time.process_time()
        smoothing_masker = NiftiMasker(mask_img=masker.mask_img_,
                                       smoothing_fwhm=smoothing_fwhm).fit()
        aligned_sources_test = np.vstack(
            [smoothing_masker.transform(s) for s in sources_test])
        aligned_target_test = smoothing_masker.transform(target_test)
    elif method in ["pairwise", "intra_subject"]:
        fit_start = time.process_time()
        for source_train, source_test in zip(sources_train, sources_test):
            if method == "pairwise":
                if surface in ["lh", "rh"]:
                    source_align = SurfacePairwiseAlignment(
                        alignment_method=pairwise_method,
                        clustering=clustering,
                        n_jobs=n_jobs)
                else:
                    source_align = PairwiseAlignment(
                        alignment_method=pairwise_method,
                        clustering=clustering,
                        n_pieces=n_pieces,
                        mask=masker,
                        n_jobs=n_jobs)
                source_align.fit(source_train, target_train)
                aligned_sources_test.append(
                    source_align.transform(source_test))
            elif method == "intra_subject":
                source_align = IntraSubjectAlignment(
                    alignment_method="ridge_cv",
                    clustering=clustering,
                    n_pieces=n_pieces,
                    mask=masker,
                    n_jobs=n_jobs)
                source_align.fit(source_train, source_test)
                aligned_sources_test.append(
                    source_align.transform(target_train))

        if surface in ["lh", "rh"]:
            aligned_sources_test = np.vstack(aligned_sources_test)
            aligned_target_test = load_clean(target_test, masker)
        else:
            aligned_target_test = masker.transform(target_test)
            aligned_sources_test = np.vstack(
                [masker.transform(t) for t in aligned_sources_test])
    elif method == "srm":
        common_time = time.process_time()
        fastsrm = FastSRM(atlas=srm_atlas,
                          n_components=srm_components,
                          n_iter=1000,
                          n_jobs=n_jobs,
                          aggregate="mean",
                          temp_dir=decoding_dir)

        reduced_SR = fastsrm.fit_transform(
            [masker.transform(t).T for t in sources_train])
        overhead_time = time.process_time() - common_time

        fit_start = time.process_time()
        fastsrm.aggregate = None

        fastsrm.add_subjects([masker.transform(t).T for t in [target_train]],
                             reduced_SR)
        aligned_test = fastsrm.transform([
            masker.transform(t).T
            for t in np.hstack([sources_test, [target_test]])
        ])
        aligned_sources_test = np.hstack(aligned_test[:-1]).T
        aligned_target_test = aligned_test[-1].T
    elif method == "HA":
        overhead_time = 0
        fit_start = time.process_time()

        from mvpa2.algorithms.searchlight_hyperalignment import SearchlightHyperalignment
        from mvpa2.datasets.base import Dataset
        pymvpa_datasets = []

        flat_mask = load_img(masker.mask_img_).get_fdata().flatten()
        n_voxels = flat_mask.sum()
        flat_coord_grid = make_coordinates_grid(
            masker.mask_img_.shape).reshape((-1, 3))
        masked_coord_grid = flat_coord_grid[flat_mask != 0]
        for sub, sub_data in enumerate(
                np.hstack([[target_train], sources_train])):
            d = Dataset(masker.transform(sub_data))
            d.fa['voxel_indices'] = masked_coord_grid
            pymvpa_datasets.append(d)
        ha = SearchlightHyperalignment(radius=ha_radius,
                                       nproc=1,
                                       sparse_radius=ha_sparse_radius)
        ha.__call__(pymvpa_datasets)
        aligned_sources_test = []
        for j, source_test in enumerate(sources_test):
            if surface in ["lh", "rh"]:
                array_source = load_clean(source_test, masker)
            else:
                array_source = masker.transform(source_test)
            aligned_sources_test.append(
                array_source.dot(ha.projections[j + 1].proj.toarray()))
        aligned_sources_test = np.vstack(aligned_sources_test)
        aligned_target_test = masker.transform(target_test).dot(
            ha.projections[0].proj.toarray())

    fit_time = time.process_time() - fit_start

    return aligned_sources_test, aligned_target_test, fit_time, overhead_time
Example #9
0
#      on the norm of R.
#   *  the optimal transport plan, which yields the minimal transport cost
#       while respecting the mass conservation constraints. Calculated with
#       entropic regularization.
#   *  we also include identity (no alignment) as a baseline.
# Then for each method we define the estimator fit it, predict the new image and plot
# its correlation with the real signal.
#

from fmralign.pairwise_alignment import PairwiseAlignment
from fmralign.metrics import score_voxelwise
methods = ['identity', 'scaled_orthogonal', 'ridge_cv', 'optimal_transport']

for method in methods:
    alignment_estimator = PairwiseAlignment(alignment_method=method,
                                            n_pieces=n_pieces,
                                            mask=roi_masker)
    alignment_estimator.fit(source_train, target_train)
    target_pred = alignment_estimator.transform(source_test)

    # derive correlation between prediction, test
    method_error = score_voxelwise(target_test,
                                   target_pred,
                                   masker=roi_masker,
                                   loss='corr')

    # plot correlation for each method
    aligned_score = roi_masker.inverse_transform(method_error)
    title = "Correlation of prediction after {} alignment".format(method)
    display = plotting.plot_stat_map(aligned_score,
                                     display_mode="z",
Example #10
0
target_test = df[df.subject == 'sub-02'][df.acquisition == 'pa'].path.values

#############################################################################
# Define the estimator used to align subjects, fit it and use it to predict
# -------------------------------------------------------------------------
# To proceed with alignment we use the class PairwiseAlignment with the \
# visual mask we created before. \
# We use the scaled orthogonal method, common in the literature under the \
# name hyperalignment. As we work on a single ROI, we will search correspondence \
# between the full data of each subject and so we set the number of cluster \
# n_pieces to 1. We learn alignment estimator on train data and use it \
# to predict target test data
#

from fmralign.pairwise_alignment import PairwiseAlignment
alignment_estimator = PairwiseAlignment(
    alignment_method='scaled_orthogonal', n_pieces=1, mask=roi_masker)
alignment_estimator.fit(source_train, target_train)
predicted_img = alignment_estimator.transform(source_test)

#############################################################################
# Score the prediction of test data with and without alignment
# ---------------------------------------------------
# To score the quality of prediction we use r2 score \
#   on each voxel activation profile across contrasts
# This score is 1 for a perfect prediction and can get \
#   arbitrarly bad (here we clip it to -1 for bad predictions)

import numpy as np
from sklearn.metrics import r2_score
# Mask the real test data for subject 2 to get a ground truth vector
ground_truth = roi_masker.transform(target_test)