Ejemplo n.º 1
0
def test_high_level_glm_different_design_matrices():
    # test that one can estimate a contrast when design matrices are different
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    # add a column to the second design matrix
    design_matrices[1]['new'] = np.ones((19, 1))

    # Fit a glm with two sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)
    z_joint = multi_session_model.compute_contrast(
        [np.eye(rk)[:1], np.eye(rk + 1)[:1]], output_type='effect_size')
    assert z_joint.shape == (7, 8, 7)

    # compare the estimated effects to seprarately-fitted models
    model1 = FirstLevelModel(mask_img=mask).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = model1.compute_contrast(np.eye(rk)[:1], output_type='effect_size')
    model2 = FirstLevelModel(mask_img=mask).fit(
        fmri_data[1], design_matrices=design_matrices[1])
    z2 = model2.compute_contrast(np.eye(rk + 1)[:1],
                                 output_type='effect_size')
    assert_almost_equal(get_data(z1) + get_data(z2),
                        2 * get_data(z_joint))
Ejemplo n.º 2
0
def test_z_score_opposite_contrast():
    fmri, mask = generate_fake_fmri(shape=(50, 20, 50),
                                    length=96,
                                    rand_gen=np.random.RandomState(42))

    nifti_masker = NiftiMasker(mask_img=mask)
    data = nifti_masker.fit_transform(fmri)

    frametimes = np.linspace(0, (96 - 1) * 2, 96)

    for i in [0, 20]:
        design_matrix = make_first_level_design_matrix(
            frametimes,
            hrf_model='spm',
            add_regs=np.array(data[:, i]).reshape(-1, 1))
        c1 = np.array([1] + [0] * (design_matrix.shape[1] - 1))
        c2 = np.array([0] + [1] + [0] * (design_matrix.shape[1] - 2))
        contrasts = {'seed1 - seed2': c1 - c2, 'seed2 - seed1': c2 - c1}
        fmri_glm = FirstLevelModel(t_r=2.,
                                   noise_model='ar1',
                                   standardize=False,
                                   hrf_model='spm',
                                   drift_model='cosine')
        fmri_glm.fit(fmri, design_matrices=design_matrix)
        z_map_seed1_vs_seed2 = fmri_glm.compute_contrast(
            contrasts['seed1 - seed2'], output_type='z_score')
        z_map_seed2_vs_seed1 = fmri_glm.compute_contrast(
            contrasts['seed2 - seed1'], output_type='z_score')
        assert_almost_equal(z_map_seed1_vs_seed2.get_data().min(),
                            -z_map_seed2_vs_seed1.get_data().max(),
                            decimal=10)
        assert_almost_equal(z_map_seed1_vs_seed2.get_data().max(),
                            -z_map_seed2_vs_seed1.get_data().min(),
                            decimal=10)
Ejemplo n.º 3
0
def test_explicit_fixed_effects():
    """ tests the fixed effects performed manually/explicitly"""
    with InTemporaryDirectory():
        shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3
        mask, fmri_data, design_matrices =\
            write_fake_fmri_data_and_design(shapes, rk)
        contrast = np.eye(rk)[1]
        # session 1
        multi_session_model = FirstLevelModel(mask_img=mask).fit(
            fmri_data[0], design_matrices=design_matrices[:1])
        dic1 = multi_session_model.compute_contrast(contrast,
                                                    output_type='all')

        # session 2
        multi_session_model.fit(fmri_data[1],
                                design_matrices=design_matrices[1:])
        dic2 = multi_session_model.compute_contrast(contrast,
                                                    output_type='all')

        # fixed effects model
        multi_session_model.fit(fmri_data, design_matrices=design_matrices)
        fixed_fx_dic = multi_session_model.compute_contrast(contrast,
                                                            output_type='all')

        # manual version
        contrasts = [dic1['effect_size'], dic2['effect_size']]
        variance = [dic1['effect_variance'], dic2['effect_variance']]
        (
            fixed_fx_contrast,
            fixed_fx_variance,
            fixed_fx_stat,
        ) = compute_fixed_effects(contrasts, variance, mask)

        assert_almost_equal(get_data(fixed_fx_contrast),
                            get_data(fixed_fx_dic['effect_size']))
        assert_almost_equal(get_data(fixed_fx_variance),
                            get_data(fixed_fx_dic['effect_variance']))
        assert_almost_equal(get_data(fixed_fx_stat),
                            get_data(fixed_fx_dic['stat']))

        # test without mask variable
        (
            fixed_fx_contrast,
            fixed_fx_variance,
            fixed_fx_stat,
        ) = compute_fixed_effects(contrasts, variance)
        assert_almost_equal(get_data(fixed_fx_contrast),
                            get_data(fixed_fx_dic['effect_size']))
        assert_almost_equal(get_data(fixed_fx_variance),
                            get_data(fixed_fx_dic['effect_variance']))
        assert_almost_equal(get_data(fixed_fx_stat),
                            get_data(fixed_fx_dic['stat']))

        # ensure that using unbalanced effects size and variance images
        # raises an error
        with pytest.raises(ValueError):
            compute_fixed_effects(contrasts * 2, variance, mask)
        del mask, multi_session_model
Ejemplo n.º 4
0
def test_high_level_glm_null_contrasts():
    # test that contrast computation is resilient to 0 values.
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3
    mask, fmri_data, design_matrices = \
        generate_fake_fmri_data_and_design(shapes, rk)

    multi_session_model = FirstLevelModel(mask_img=None).fit(
        fmri_data, design_matrices=design_matrices)
    single_session_model = FirstLevelModel(mask_img=None).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = multi_session_model.compute_contrast(
        [np.eye(rk)[:1], np.zeros((1, rk))], output_type='stat')
    z2 = single_session_model.compute_contrast(np.eye(rk)[:1],
                                               output_type='stat')
    np.testing.assert_almost_equal(get_data(z1), get_data(z2))
Ejemplo n.º 5
0
def run_glm(dmtx,
            contrasts,
            fmri_data,
            mask_img,
            subject_dic,
            subject_session_output_dir,
            tr,
            slice_time_ref,
            smoothing_fwhm=False):
    """ Run the GLM on a given session and compute contrasts

    Parameters
    ----------
    dmtx : array-like
        the design matrix for the model
    contrasts : dict
        holding the numerical specification of contrasts
    fmri_data : Nifti1Image
        the fMRI data fir by the model
    mask_img : Nifti1Image
        the mask used for the fMRI data
    """
    from nilearn.glm.first_level import FirstLevelModel
    fmri_4d = nib.load(fmri_data)

    # GLM analysis
    print('Fitting a GLM (this takes time)...')
    fmri_glm = FirstLevelModel(mask_img=mask_img,
                               t_r=tr,
                               slice_time_ref=slice_time_ref,
                               smoothing_fwhm=smoothing_fwhm).fit(
                                   fmri_4d, design_matrices=dmtx)

    # compute contrasts
    z_maps = {}
    for contrast_id, contrast_val in contrasts.items():
        print("\tcontrast id: %s" % contrast_id)

        # store stat maps to disk
        for map_type in ['z_score', 'stat', 'effect_size', 'effect_variance']:
            stat_map = fmri_glm.compute_contrast(contrast_val,
                                                 output_type=map_type)
            map_dir = os.path.join(subject_session_output_dir,
                                   '%s_maps' % map_type)
            if not os.path.exists(map_dir):
                os.makedirs(map_dir)
            map_path = os.path.join(map_dir, '%s.nii.gz' % contrast_id)
            print("\t\tWriting %s ..." % map_path)
            stat_map.to_filename(map_path)

            # collect zmaps for contrasts we're interested in
            if map_type == 'z_score':
                z_maps[contrast_id] = map_path
    return z_maps, fmri_glm
Ejemplo n.º 6
0
def test_first_level_hrf_model(hrf_model, spaces):
    """
    Ensure that FirstLevelModel runs without raising errors
    for different values of hrf_model. In particular, one checks that it runs
    without raising errors when given a custom response function.
    Also ensure that it computes contrasts without raising errors,
    even when event (ie condition) names have spaces.
    """
    shapes, rk = [(10, 10, 10, 25)], 3
    mask, fmri_data, _ =\
        generate_fake_fmri_data_and_design(shapes, rk)

    events = basic_paradigm(condition_names_have_spaces=spaces)

    model = FirstLevelModel(t_r=2.0, mask_img=mask, hrf_model=hrf_model)

    model.fit(fmri_data, events)

    columns = model.design_matrices_[0].columns
    model.compute_contrast(f"{columns[0]}-{columns[1]}")
Ejemplo n.º 7
0
def test_high_level_glm_with_paths():
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 14)), 3
    with InTemporaryDirectory():
        mask_file, fmri_files, design_files = write_fake_fmri_data_and_design(shapes, rk)
        multi_session_model = FirstLevelModel(mask_img=None).fit(
            fmri_files, design_matrices=design_files)
        z_image = multi_session_model.compute_contrast(np.eye(rk)[1])
        assert_array_equal(z_image.affine, load(mask_file).affine)
        assert get_data(z_image).std() < 3.
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del z_image, fmri_files, multi_session_model
Ejemplo n.º 8
0
def test_high_level_glm_one_session():
    shapes, rk = [(7, 8, 9, 15)], 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    single_session_model = FirstLevelModel(mask_img=None).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    assert isinstance(single_session_model.masker_.mask_img_,
                      Nifti1Image)

    single_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = single_session_model.compute_contrast(np.eye(rk)[:1])
    assert isinstance(z1, Nifti1Image)
Ejemplo n.º 9
0
def test_high_level_glm_different_design_matrices_formulas():
    # test that one can estimate a contrast when design matrices are different
    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3
    mask, fmri_data, design_matrices =\
        generate_fake_fmri_data_and_design(shapes, rk)

    # make column names identical
    design_matrices[1].columns = design_matrices[0].columns
    # add a column to the second design matrix
    design_matrices[1]['new'] = np.ones((19, 1))

    # Fit a glm with two sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)

    # Compute contrast with formulas
    cols_formula = tuple(design_matrices[0].columns[:2])
    formula = "%s-%s" % cols_formula
    with pytest.warns(UserWarning,
                      match='One contrast given, '
                      'assuming it for all 2 runs'):
        multi_session_model.compute_contrast(formula,
                                             output_type='effect_size')
Ejemplo n.º 10
0
def test_high_level_glm_with_data():
    with InTemporaryDirectory():
        shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3
        mask, fmri_data, design_matrices = write_fake_fmri_data_and_design(shapes, rk)
        multi_session_model = FirstLevelModel(mask_img=None).fit(
            fmri_data, design_matrices=design_matrices)
        n_voxels = get_data(multi_session_model.masker_.mask_img_).sum()
        z_image = multi_session_model.compute_contrast(np.eye(rk)[1])
        assert np.sum(get_data(z_image) != 0) == n_voxels
        assert get_data(z_image).std() < 3.
        # with mask
        multi_session_model = FirstLevelModel(mask_img=mask).fit(
            fmri_data, design_matrices=design_matrices)
        z_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='z_score')
        p_value = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='p_value')
        stat_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='stat')
        effect_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='effect_size')
        variance_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='effect_variance')
        assert_array_equal(get_data(z_image) == 0., get_data(load(mask)) == 0.)
        assert (get_data(variance_image)[get_data(load(mask)) > 0] > .001
                ).all()
        all_images = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='all')
        assert_array_equal(get_data(all_images['z_score']), get_data(z_image))
        assert_array_equal(get_data(all_images['p_value']), get_data(p_value))
        assert_array_equal(get_data(all_images['stat']), get_data(stat_image))
        assert_array_equal(get_data(all_images['effect_size']),
                           get_data(effect_image))
        assert_array_equal(get_data(all_images['effect_variance']),
                           get_data(variance_image))
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del (all_images,
             design_matrices,
             effect_image,
             fmri_data,
             mask,
             multi_session_model,
             n_voxels,
             p_value,
             rk,
             shapes,
             stat_image,
             variance_image,
             z_image)
Ejemplo n.º 11
0
def test_high_level_glm_one_session():
    shapes, rk = [(7, 8, 9, 15)], 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    # Give an unfitted NiftiMasker as mask_img and check that we get an error
    masker = NiftiMasker(mask)
    with pytest.raises(ValueError,
                       match="It seems that NiftiMasker has not been fitted."):
        single_session_model = FirstLevelModel(mask_img=masker).fit(
                fmri_data[0], design_matrices=design_matrices[0])

    # Give a fitted NiftiMasker with a None mask_img_ attribute
    # and check that the masker parameters are overriden by the
    # FirstLevelModel parameters
    masker.fit()
    masker.mask_img_ = None
    with pytest.warns(UserWarning,
                      match="Parameter memory of the masker overriden"):
        single_session_model = FirstLevelModel(mask_img=masker).fit(
                fmri_data[0], design_matrices=design_matrices[0])

    # Give a fitted NiftiMasker
    masker = NiftiMasker(mask)
    masker.fit()
    single_session_model = FirstLevelModel(mask_img=masker).fit(
                    fmri_data[0], design_matrices=design_matrices[0])
    assert single_session_model.masker_ == masker

    # Call with verbose (improve coverage)
    single_session_model = FirstLevelModel(mask_img=None,
                                           verbose=1).fit(
        fmri_data[0], design_matrices=design_matrices[0])

    single_session_model = FirstLevelModel(mask_img=None).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    assert isinstance(single_session_model.masker_.mask_img_,
                      Nifti1Image)

    single_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data[0], design_matrices=design_matrices[0])
    z1 = single_session_model.compute_contrast(np.eye(rk)[:1])
    assert isinstance(z1, Nifti1Image)
Ejemplo n.º 12
0
def test_compute_contrast_num_contrasts():

    shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19), (7, 8, 7, 13)), 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    # Fit a glm with 3 sessions and design matrices
    multi_session_model = FirstLevelModel(mask_img=mask).fit(
        fmri_data, design_matrices=design_matrices)

    # raise when n_contrast != n_runs | 1
    with pytest.raises(ValueError):
        multi_session_model.compute_contrast([np.eye(rk)[1]]*2)

    multi_session_model.compute_contrast([np.eye(rk)[1]]*3)
    with pytest.warns(UserWarning, match='One contrast given, assuming it for all 3 runs'):
        multi_session_model.compute_contrast([np.eye(rk)[1]])
Ejemplo n.º 13
0
def test_first_level_contrast_computation():
    with InTemporaryDirectory():
        shapes = ((7, 8, 9, 10), )
        mask, FUNCFILE, _ = write_fake_fmri_data_and_design(shapes)
        FUNCFILE = FUNCFILE[0]
        func_img = load(FUNCFILE)
        # basic test based on basic_paradigm and glover hrf
        t_r = 10.0
        slice_time_ref = 0.
        events = basic_paradigm()
        # Ordinary Least Squares case
        model = FirstLevelModel(t_r,
                                slice_time_ref,
                                mask_img=mask,
                                drift_model='polynomial',
                                drift_order=3,
                                minimize_memory=False)
        c1, c2, cnull = np.eye(7)[0], np.eye(7)[1], np.zeros(7)
        # asking for contrast before model fit gives error
        with pytest.raises(ValueError):
            model.compute_contrast(c1)
        # fit model
        model = model.fit([func_img, func_img], [events, events])
        # Check that an error is raised for invalid contrast_def
        with pytest.raises(ValueError,
                           match="contrast_def must be an "
                           "array or str or list"):
            model.compute_contrast(37)
        # smoke test for different contrasts in fixed effects
        model.compute_contrast([c1, c2])
        # smoke test for same contrast in fixed effects
        model.compute_contrast([c2, c2])
        # smoke test for contrast that will be repeated
        model.compute_contrast(c2)
        model.compute_contrast(c2, 'F')
        model.compute_contrast(c2, 't', 'z_score')
        model.compute_contrast(c2, 't', 'stat')
        model.compute_contrast(c2, 't', 'p_value')
        model.compute_contrast(c2, None, 'effect_size')
        model.compute_contrast(c2, None, 'effect_variance')
        # formula should work (passing variable name directly)
        model.compute_contrast('c0')
        model.compute_contrast('c1')
        model.compute_contrast('c2')
        # smoke test for one null contrast in group
        model.compute_contrast([c2, cnull])
        # only passing null contrasts should give back a value error
        with pytest.raises(ValueError):
            model.compute_contrast(cnull)
        with pytest.raises(ValueError):
            model.compute_contrast([cnull, cnull])
        # passing wrong parameters
        with pytest.raises(ValueError):
            model.compute_contrast([])
        with pytest.raises(ValueError):
            model.compute_contrast([c1, []])
        with pytest.raises(ValueError):
            model.compute_contrast(c1, '', '')
        with pytest.raises(ValueError):
            model.compute_contrast(c1, '', [])
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del func_img, FUNCFILE, model
Ejemplo n.º 14
0
                           minimize_memory=True)

#########################################################################
# Compute fixed effects of the two runs and compute related images
# For this, we first define the contrasts as we would do for a single session
n_columns = design_matrices[0].shape[1]
contrast_val = np.hstack(([-1, -1, 1, 1], np.zeros(n_columns - 4)))

#########################################################################
# Statistics for the first session
from nilearn import plotting
cut_coords = [-129, -126, 49]
contrast_id = 'DSt_minus_SSt'

fmri_glm = fmri_glm.fit(fmri_img[0], design_matrices=design_matrices[0])
summary_statistics_session1 = fmri_glm.compute_contrast(contrast_val,
                                                        output_type='all')
plotting.plot_stat_map(summary_statistics_session1['z_score'],
                       bg_img=mean_img_,
                       threshold=3.0,
                       cut_coords=cut_coords,
                       title='{0}, first session'.format(contrast_id))

#########################################################################
# Statistics for the second session

fmri_glm = fmri_glm.fit(fmri_img[1], design_matrices=design_matrices[1])
summary_statistics_session2 = fmri_glm.compute_contrast(contrast_val,
                                                        output_type='all')
plotting.plot_stat_map(summary_statistics_session2['z_score'],
                       bg_img=mean_img_,
                       threshold=3.0,
Ejemplo n.º 15
0
def main(subject, session, sourcedata):
    runs = range(1, 9)
    behavior = []

    for run in runs:
        behavior.append(pd.read_table(op.join(
            sourcedata, f'sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task-{run}_events.tsv')))

    behavior = pd.concat(behavior, keys=runs, names=['run'])
    behavior['subject'] = subject
    behavior = behavior.reset_index().set_index(
        ['subject', 'run', 'trial_type'])

    ims = [
        op.join(sourcedata, f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_space-T1w_desc-preproc_bold.nii.gz') for run in runs]

    mask_img = op.join(sourcedata, f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-1_space-T1w_desc-brain_mask.nii.gz')

    fmriprep_confounds_include = ['global_signal', 'dvars', 'framewise_displacement', 'trans_x',
                                  'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z',
                                  'a_comp_cor_00', 'a_comp_cor_01', 'a_comp_cor_02', 'a_comp_cor_03', 'cosine00', 'cosine01', 'cosine02', 
                                  'cosine03',
                                  'non_steady_state_outlier00', 'non_steady_state_outlier01', 'non_steady_state_outlier02']
    fmriprep_confounds = [
        op.join(sourcedata, f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_desc-confounds_timeseries.tsv') for run in runs]
    fmriprep_confounds = [pd.read_table(
        cf)[fmriprep_confounds_include] for cf in fmriprep_confounds]

    retroicor_confounds = [
        op.join(sourcedata, f'derivatives/physiotoolbox/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_desc-retroicor_timeseries.tsv') for run in runs]
    retroicor_confounds = [pd.read_table(
        cf, header=None, usecols=range(18)) for cf in retroicor_confounds]

    confounds = [pd.concat((rcf, fcf), axis=1) for rcf, fcf in zip(retroicor_confounds, fmriprep_confounds)]
    confounds = [c.fillna(method='bfill') for c in confounds]

    print(behavior)

    print(confounds)
    model = FirstLevelModel(t_r=2.3, slice_time_ref=.5, signal_scaling=False, drift_model=None, 
            mask_img=mask_img,
                        smoothing_fwhm=0.0)

    stimulus1 = behavior.xs('stimulus 1', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type']]
    stimulus1['duration'] = 0.6
    stimulus2 = behavior.xs('stimulus 2', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type']]
    stimulus2['duration'] = 0.6

    n1 = behavior.xs('stimulus 1', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type', 'n1']]
    n1['duration'] = 0.6
    def zscore(n):
        return (n - n.mean()) / n.std()
    n1['modulation'] = zscore(n1['n1'])
    n1['trial_type'] = 'n_dots1'

    n2 = behavior.xs('stimulus 2', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type', 'n2']]
    n2['duration'] = 0.6
    def zscore(n):
        return (n - n.mean()) / n.std()
    n2['modulation'] = zscore(n2['n2'])
    n2['trial_type'] = 'n_dots2'

    p1 = behavior.xs('stimulus 1', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type', 'prob1']]
    p1 = p1[p1.prob1 == 1.0]
    p1['duration'] = 0.6
    p1['trial_type'] = 'certain1'

    p2 = behavior.xs('stimulus 2', 0, 'trial_type', drop_level=False).reset_index('trial_type')[['onset', 'trial_type', 'prob2']]
    p2 = p2[p2.prob2 == 1.0]
    p2['duration'] = 0.6
    p2['trial_type'] = 'certain2'

    events = pd.concat((stimulus1, stimulus2, n1, n2, p1, p2)).sort_values('onset')
    events['modulation'].fillna(1.0, inplace=True)
    print(events)


    model.fit(ims, [r for _, r in events.groupby(['run'])], confounds)

    zmaps = {}

    results_dir = op.join(sourcedata, 'derivatives', 'glm', 'simple_task', f'sub-{subject}', f'ses-{session}')

    if not op.exists(results_dir):
        os.makedirs(results_dir)

    for key in ['stimulus 1', 'stimulus 2', 'n_dots1', 'n_dots2', 'certain1', 'certain2']:
        zmaps[key] = model.compute_contrast(key)
    
        zmaps[key].to_filename(op.join(results_dir, f'sub-{subject}_ses-{session}_zmap_{key}.nii.gz'))
active_minus_rest = conditions['active'] - conditions['rest']

###############################################################################
# Let's look at it: plot the coefficients of the contrast, indexed by
# the names of the columns of the design matrix.

from nilearn.reporting import plot_contrast_matrix
plot_contrast_matrix(active_minus_rest, design_matrix=design_matrix)

###############################################################################
# Below, we compute the estimated effect. It is in BOLD signal unit,
# but has no statistical guarantees, because it does not take into
# account the associated variance.

eff_map = fmri_glm.compute_contrast(active_minus_rest,
                                    output_type='effect_size')

###############################################################################
# In order to get statistical significance, we form a t-statistic, and
# directly convert it into z-scale. The z-scale means that the values
# are scaled to match a standard Gaussian distribution (mean=0,
# variance=1), across voxels, if there were no effects in the data.

z_map = fmri_glm.compute_contrast(active_minus_rest, output_type='z_score')

###############################################################################
# Plot thresholded z scores map
# ------------------------------
#
# We display it on top of the average
# functional image of the series (could be the anatomical image of the
Ejemplo n.º 17
0
def main(subject,
         session,
         bids_folder,
         smoothed=False,
         pca_confounds=False,
         space='fsnative',
         n_jobs=14):

    derivatives = op.join(bids_folder, 'derivatives')

    runs = range(1, 9)

    ims = [
        op.join(
            derivatives,
            f'fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_space-T1w_desc-preproc_bold.nii.gz'
        ) for run in runs
    ]

    mask = op.join(
        derivatives,
        f'fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-1_space-T1w_desc-brain_mask.nii.gz'
    )

    base_dir = 'glm_stim1'

    if smoothed:
        base_dir += '.smoothed'

    if pca_confounds:
        base_dir += '.pca_confounds'

    base_dir = op.join(derivatives, base_dir, f'sub-{subject}',
                       f'ses-{session}', 'func')

    if not op.exists(base_dir):
        os.makedirs(base_dir)

    behavior = []
    for run in runs:
        behavior.append(
            pd.read_table(
                op.join(
                    bids_folder,
                    f'sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_events.tsv'
                )))

    behavior = pd.concat(behavior, keys=runs, names=['run'])
    behavior = behavior.reset_index().set_index(['run', 'trial_type'])

    stimulus1 = behavior.xs(
        'stimulus 1', 0, 'trial_type',
        drop_level=False).reset_index('trial_type')[['onset', 'trial_type']]
    stimulus1['duration'] = 0.6

    stimulus2 = behavior.xs('stimulus 2', 0, 'trial_type',
                            drop_level=False).reset_index('trial_type')[[
                                'onset', 'trial_type', 'trial_nr'
                            ]]
    stimulus2['duration'] = 0.6
    stimulus2['trial_type'] = stimulus2.trial_nr.map(
        lambda trial: f'trial_{trial}')
    print(stimulus2)

    n1 = behavior.xs('stimulus 1', 0, 'trial_type',
                     drop_level=False).reset_index('trial_type')[[
                         'onset', 'trial_type', 'n1'
                     ]]
    n1['duration'] = 0.6

    def zscore(n):
        return (n - n.mean()) / n.std()

    n1['modulation'] = zscore(n1['n1'])
    n1['trial_type'] = 'n_dots1'

    p1 = behavior.xs('stimulus 1', 0, 'trial_type',
                     drop_level=False).reset_index('trial_type')[[
                         'onset', 'trial_type', 'prob1'
                     ]]
    p1 = p1[p1.prob1 == 1.0]
    p1['duration'] = 0.6
    p1['trial_type'] = 'certain1'

    events = pd.concat(
        (stimulus1, stimulus2, n1, p1)).set_index('trial_nr',
                                                  append=True).sort_index()
    events['modulation'].fillna(1.0, inplace=True)
    print(events)

    fmriprep_confounds_include = [
        'global_signal', 'dvars', 'framewise_displacement', 'trans_x',
        'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z', 'a_comp_cor_00',
        'a_comp_cor_01', 'a_comp_cor_02', 'a_comp_cor_03', 'cosine00',
        'cosine01', 'cosine02', 'cosine03', 'non_steady_state_outlier00',
        'non_steady_state_outlier01', 'non_steady_state_outlier02'
    ]
    fmriprep_confounds = [
        op.join(
            bids_folder,
            f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_desc-confounds_timeseries.tsv'
        ) for run in runs
    ]
    fmriprep_confounds = [
        pd.read_table(cf)[fmriprep_confounds_include]
        for cf in fmriprep_confounds
    ]

    retroicor_confounds = [
        op.join(
            bids_folder,
            f'derivatives/physiotoolbox/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-task_run-{run}_desc-retroicor_timeseries.tsv'
        ) for run in runs
    ]
    retroicor_confounds = [
        pd.read_table(cf, header=None, usecols=range(18))
        if op.exists(cf) else pd.DataFrame(np.zeros((160, 0)))
        for cf in retroicor_confounds
    ]

    confounds = [
        pd.concat((rcf, fcf), axis=1)
        for rcf, fcf in zip(retroicor_confounds, fmriprep_confounds)
    ]
    confounds = [c.fillna(method='bfill') for c in confounds]

    t_r, n_scans = 2.3, 160
    frame_times = t_r * (np.arange(n_scans) + .5)

    model = FirstLevelModel(t_r=2.3,
                            slice_time_ref=.5,
                            signal_scaling=False,
                            drift_model=None,
                            mask_img=mask,
                            smoothing_fwhm=0.0)

    single_trial_betas = []

    for run in runs:
        im = image.math_img('(im / im.mean(-1)[..., np.newaxis]) * 100 - 100',
                            im=ims[run - 1])
        model.fit(im, events.loc[run], confounds[run - 1])

        for trial in range(1 + (run - 1) * 24, 1 + run * 24):
            print(trial)
            single_trial_betas.append(
                model.compute_contrast(f'trial_{trial}',
                                       output_type='effect_size'))

    single_trial_betas = image.concat_imgs(single_trial_betas)
    single_trial_betas.to_filename(
        op.join(
            base_dir,
            f'sub-{subject}_ses-{session}_task-task_space-T1w_desc-stims2_pe.nii.gz'
        ))
Ejemplo n.º 18
0
def get_contrasts(fmri_img: Union[str, PathLike,
                                  PosixPath, Nifti1Image],
                  events: Union[str, PathLike,
                                PosixPath, pd.DataFrame],
                  desc: str = 'effect_size',
                  design_kws: Union[dict, Bunch] = None,
                  glm_kws: Union[dict, Bunch] = None,
                  masker_kws: Union[dict, Bunch] = None,
                  standardize: bool = True,
                  scale: bool = False,
                  scale_between: tuple = (0, 1),
                  maximize: bool = False,
                  masker: [MultiNiftiMasker, NiftiLabelsMasker,
                           NiftiMapsMasker, NiftiMasker] = None,
                  feature_labels: Union[Sequence, pd.Index] = None,
                  session=None,
                  **kwargs
                  ) -> Bunch:
    """
    Return dict-like structure containing experimental contrasts.


    Using ``nilearn.glm.first_level.FirstLevel`` object,
    contrasts are first computed trial-wise. Then, the same is done
    for each experimental condition in ``trial_type_cols`` if a
    list of string is provided.

    Args:
        fmri_img: str, PathLike, PosixPath or Nifti1Image
            In-memory or path pointing to a ``nibabel.nifti1.Nifti1Image``.

        events: : str, PathLike, PosixPath or DataFrame
            In-memory or path pointing to a ``pandas.DataFrame``.

        desc: str (Default = 'effect_size')
            String passed to
            ``nilearn.glm.first_level.FirstLevel.compute_contrast``
            ``desc`` parameter.

        design_kws: dict or Bunch (Deault = None)
            Dict-like mapping of keyword arguments passed to
            ``nilearn.glm.first_level.make_first_level_design_matrix``.
            If a ``session`` object is passed in the parameters,
            the value under the corresponding key is used.

        glm_kws: dict or Bunch (Deault = None)
            Dict-like mapping of keyword arguments passed to
            ``nilearn.glm.first_level.FirstLevel.__init__``.
            If a ``session`` object is passed in the parameters,
            the value under the corresponding key is used.

        masker_kws: dict or Bunch (Deault = None)
            Dict-like mapping of keyword arguments passed to
            ``masker.__init__``.
            If a ``session`` object is passed in the parameters,
            the value under the corresponding key is used.

        standardize: bool (Default = True)
            If true (by default), the extracted brain signals are
            standardized using a ``sklearn.preprocessing.StandardScaler``
            object (demeaning ans scaling to variance). It is generally
            advised to standardize data for machine-learning operations.
            See notes for documentation, tutorials and more.

        scale: bool (Default = False)
            If true, the extracted brain signals are
            scaled (between 0 and 1 by default) using a
            ``sklearn.preprocessing.MinMaxScaler`` object. It is generally
            advised to standardize data for machine-learning operations.
            See notes for documentation, tutorials and more.

        scale_between: tuple (Default = (0, 1)
            Values between which the signal should be scaled.
            Default is (0, 1) - left = min, right = max.
            Only used if ``scale`` parameter is True.

        maximize: bool (Default = False)
            If true, scale each feature by its maximum absolute value.
            From the docs of ``sklearn.preprocessing.MaxAbsScaler``:
                '[...] Scales and translates each feature individually
                such that the maximal absolute value of each feature in
                training set is 1.0. Does not shift/center the data,
                and thus does not destroy any sparsity.'

        masker: MultiNiftiMasker, NiftiLabelsMasker,
                NiftiMapsMasker or NiftiMasker (Default = None)
            Masker object from the ``nilearn.input_data`` module meant
            to perform brain signal extraction (conversion from 4D or 3D
            image to 2D data).
            If omitted, a NiftiMasker with default parameters is used.

        feature_labels: List or pd.Index (Default = None)
            List of feature names used as columns for the brain signal matrix.
            Number of labels and number of features must match.
            An error is raised otherwise.

        session: dict or Bunch (Default = None)
            Dict-like structure containing all required and/or optional
            parameters. The functions ``fetch_fmriprep_session`` and
            ``get_fmri_session`` from ``cimaq_decoding_utils``
            return a ``session`` object. It is similar to the return
            values of ``nilearn.datasets.fetch{dataset_name}`` functions.

    Returns: ``sklearn.utils.Bunch``
        Dict-like structure with the following keys:
        ['model', 'contrast_img', 'signals',
         'feature_labels', 'condition_labels']

    Notes:
        https://scikit-learn.org/stable/modules/preprocessing.html#preprocessing
    """

    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import MaxAbsScaler, MinMaxScaler
    from sklearn.preprocessing import StandardScaler
    from cimaq_decoding_utils import get_frame_times, get_t_r

    # Parameter initialization
    design_defs, glm_defs = {}, {}
    fmri_img = nimage.image.load_img(fmri_img)
    events = [events if isinstance(events, pd.DataFrame)
              else pd.read_csv(events,
                               sep=['\t' if splitext(events)[1][1] == 't'
                                    else ','][0])][0]
    if session is not None:
        design_defs.update(session.design_defs)
        glm_defs.update(session.glm_defs)

    t_r, frame_times = get_t_r(fmri_img), get_frame_times(fmri_img)

    if design_kws is not None:
        design_defs.update(design_kws)
    if glm_kws is not None:
        glm_defs.update(glm_kws)

    # GLM initialization and contrast computation
    design = make_first_level_design_matrix(frame_times, events=events.iloc[1:, :],
                                            **design_defs)

    model = FirstLevelModel(**glm_defs).fit(run_imgs=fmri_img,
                                            design_matrices=design.iloc[:, 1:])
    contrasts = nimage.concat_imgs([model.compute_contrast(
                    trial, desc=desc) for trial in
                    tqdm_(design.columns[:-1].astype(str),
                          ncols=100,
                          desc='Computing Contrasts')])

    # Brain signals extraction
    pipe_components = ((standardize, 'standardize', StandardScaler()),
                       (maximize, 'maximize', MaxAbsScaler()),
                       (scale, 'scale', MinMaxScaler(scale_between)))

    pipe_components = [item[1:] for item in
                       list(filter(lambda x: x[0], pipe_components))]
    signals = masker.transform_single_imgs(contrasts)
    if pipe_components != []:
        pipeline = Pipeline(pipe_components)
        signals = pipeline.fit_transform(signals)
    signals = pd.DataFrame(signals,
                           index=design.iloc[:, :-1].columns)

    if feature_labels is not None:
        signals.set_axis(feature_labels, axis=1, inplace=True)

    return Bunch(model=model, contrast_img=contrasts,
                 signals=signals, feature_labels=feature_labels)
Ejemplo n.º 19
0
def main(subject, session, sourcedata):
    runs = range(1, 5)
    behavior = []

    for run in runs:
        behavior.append(
            pd.read_table(
                op.join(
                    sourcedata,
                    f'sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-mapper_run-{run}_events.tsv'
                )))

    behavior = pd.concat(behavior, keys=runs, names=['run'])
    behavior['subject'] = subject
    behavior = behavior.reset_index().set_index(
        ['subject', 'run', 'trial_type'])

    ims = [
        op.join(
            sourcedata,
            f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-mapper_run-{run}_space-T1w_desc-preproc_bold.nii.gz'
        ) for run in runs
    ]

    fmriprep_confounds_include = [
        'global_signal', 'dvars', 'framewise_displacement', 'trans_x',
        'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z', 'a_comp_cor_00',
        'a_comp_cor_01', 'a_comp_cor_02', 'a_comp_cor_03', 'cosine00',
        'cosine01', 'cosine02', 'non_steady_state_outlier00',
        'non_steady_state_outlier01', 'non_steady_state_outlier02'
    ]
    fmriprep_confounds = [
        op.join(
            sourcedata,
            f'derivatives/fmriprep/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-mapper_run-{run}_desc-confounds_timeseries.tsv'
        ) for run in runs
    ]
    fmriprep_confounds = [
        pd.read_table(cf)[fmriprep_confounds_include]
        for cf in fmriprep_confounds
    ]

    retroicor_confounds = [
        op.join(
            sourcedata,
            f'derivatives/physiotoolbox/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-mapper_run-{run}_desc-retroicor_timeseries.tsv'
        ) for run in runs
    ]
    retroicor_confounds = [
        pd.read_table(cf, header=None, usecols=range(18))
        for cf in retroicor_confounds
    ]

    confounds = [
        pd.concat((rcf, fcf), axis=1)
        for rcf, fcf in zip(retroicor_confounds, fmriprep_confounds)
    ]
    confounds = [c.fillna(method='bfill') for c in confounds]
    model = FirstLevelModel(t_r=2.3,
                            slice_time_ref=.5,
                            signal_scaling=False,
                            drift_model=None,
                            smoothing_fwhm=0.0)
    responses = behavior.xs(
        'response', 0, 'trial_type',
        drop_level=False).reset_index('trial_type')[['onset', 'trial_type']]
    responses['duration'] = 0.0
    responses = responses[responses.onset > 0]
    stimulation = behavior.xs('stimulation', 0, 'trial_type',
                              drop_level=False).reset_index('trial_type')[[
                                  'onset', 'duration', 'n_dots', 'trial_type'
                              ]]
    stimulation_mod = stimulation.copy()
    stimulation_mod['modulation'] = np.log(stimulation_mod['n_dots'])
    stimulation_mod['modulation'] = (stimulation_mod['modulation'] -
                                     stimulation_mod['modulation'].mean(0)
                                     ) / stimulation_mod['modulation'].std()
    stimulation_mod['trial_type'] = 'stimulation*n_dots'

    targets = behavior.xs('targets', 0, 'trial_type')
    hazard_regressor = targets[~targets.hazard1.isnull()].copy()
    hazard_regressor['modulation'] = hazard_regressor['hazard1']
    hazard_regressor['modulation'] = (hazard_regressor['modulation'] -
                                      hazard_regressor['modulation'].mean()
                                      ) / hazard_regressor['modulation'].std()
    hazard_regressor['trial_type'] = 'hazard1'
    hazard_regressor['duration'] = 0.0

    hazard_regressor = hazard_regressor[[
        'trial_type', 'duration', 'modulation', 'onset'
    ]]

    events = pd.concat(
        (responses, stimulation, stimulation_mod, hazard_regressor))
    events['modulation'].fillna(1.0, inplace=True)
    model.fit(ims, [r for _, r in events.groupby(['run'])], confounds)

    zmaps = {}

    results_dir = op.join(sourcedata, 'derivatives', 'glm', 'simple_mapper',
                          f'sub-{subject}', f'ses-{session}')

    if not op.exists(results_dir):
        os.makedirs(results_dir)

    for key in ['response', 'stimulation', 'stimulation*n_dots', 'hazard1']:
        zmaps[key] = model.compute_contrast(key)

        zmaps[key].to_filename(
            op.join(results_dir,
                    f'sub-{subject}_ses-{session}_zmap_{key}.nii.gz'))
Ejemplo n.º 20
0
                                               add_reg_names=["pcc_seed"])
dmn_contrast = np.array([1] + [0] * (design_matrix.shape[1] - 1))
contrasts = {'seed_based_glm': dmn_contrast}

#########################################################################
# Perform first level analysis
# ----------------------------
# Setup and fit GLM.
first_level_model = FirstLevelModel(t_r=t_r, slice_time_ref=slice_time_ref)
first_level_model = first_level_model.fit(run_imgs=adhd_dataset.func[0],
                                          design_matrices=design_matrix)

#########################################################################
# Estimate the contrast.
print('Contrast seed_based_glm computed.')
z_map = first_level_model.compute_contrast(contrasts['seed_based_glm'],
                                           output_type='z_score')

# Saving snapshots of the contrasts
filename = 'dmn_z_map.png'
display = plotting.plot_stat_map(z_map,
                                 threshold=3.0,
                                 title='Seed based GLM',
                                 cut_coords=pcc_coords)
display.add_markers(marker_coords=[pcc_coords],
                    marker_color='g',
                    marker_size=300)
display.savefig(filename)
print("Save z-map in '{0}'.".format(filename))

###########################################################################
# Generating a report
Ejemplo n.º 21
0
def run_subject(sub, out_dir):
    """ Runs pattern estimation for a single subject. """
    print(f"INFO: Processing {sub}")

    # Define in- and output directories
    bids_dir = op.join(f'../{sub}')
    fprep_dir = op.join(f'../derivatives/fmriprep/{sub}')
    out_dir = op.join(out_dir, sub)

    funcs = sorted(
        glob(fprep_dir +
             '/ses-?/func/*task-face*space-MNI*desc-preproc_bold.nii.gz'))
    for func in funcs:
        t_r = nib.load(func).header['pixdim'][4]
        conf = func.split('_space')[0] + '_desc-confounds_timeseries.tsv'
        mask = func.replace('preproc_bold', 'brain_mask')
        events = bids_dir + func.split(fprep_dir)[1].split(
            '_space')[0] + '_events.tsv'

        flm = FirstLevelModel(t_r=t_r,
                              slice_time_ref=0.5,
                              hrf_model='glover',
                              drift_model='cosine',
                              high_pass=0.01,
                              mask_img=mask,
                              smoothing_fwhm=None,
                              noise_model='ols',
                              n_jobs=1,
                              minimize_memory=False)

        # Select confounds
        conf = pd.read_csv(conf, sep='\t').loc[:, [
            'trans_x', 'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z', 'csf',
            'white_matter'
        ]]

        # Redefine output dir
        this_out_dir = op.join(out_dir, func.split(fprep_dir)[1].split('/')[1])
        for d in ['patterns', 'model', 'figures']:
            if not op.isdir(op.join(this_out_dir, d)):
                os.makedirs(op.join(this_out_dir, d), exist_ok=True)

        # Fit model
        flm.fit(run_imgs=func, events=events, confounds=conf)

        # Save some stuff!
        f_base = op.basename(func).split('preproc')[0]
        rsq_out = op.join(this_out_dir, 'model', f_base + 'model_r2.nii.gz')
        flm.r_square[0].to_filename(rsq_out)

        dm = flm.design_matrices_[0]
        dm_out = op.join(this_out_dir, 'model', f_base + 'design_matrix.tsv')
        dm.to_csv(dm_out, sep='\t', index=False)

        dmfig_out = op.join(this_out_dir, 'figures',
                            f_base + 'design_matrix.png')
        plot_design_matrix(dm, output_file=dmfig_out)

        dmcorrfig_out = op.join(this_out_dir, 'figures',
                                f_base + 'design_corr.png')
        labels = dm.columns.tolist()[:-1]
        ax = plot_design_matrix(dm.drop('constant', axis=1).corr())
        ax.set_yticks(range(len(labels)))
        ax.set_yticklabels(labels)
        plt.savefig(dmcorrfig_out)
        plt.close()

        resids_out = op.join(this_out_dir, 'model',
                             f_base + 'model_residuals.nii.gz')
        flm.residuals[0].to_filename(resids_out)

        trials = [l for l in labels if 'STIM' in l]
        b, vb = [], []
        for trial in trials:
            dat = flm.compute_contrast(trial, stat_type='t', output_type='all')
            b.append(dat['effect_size'])
            vb.append(dat['effect_variance'])

        beta_out = op.join(this_out_dir, 'patterns',
                           f_base + 'trial_beta.nii.gz')
        image.concat_imgs(b).to_filename(beta_out)
        varbeta_out = op.join(this_out_dir, 'patterns',
                              f_base + 'trial_varbeta.nii.gz')
        image.concat_imgs(vb).to_filename(varbeta_out)
Ejemplo n.º 22
0
def sub_tcontrasts3(session:Union[dict,Bunch]=None,
                    sub_id:str=None,
                    tr:float=None,
                    frame_times:list=None,
                    hrf_model:str=None,
                    events:pd.DataFrame=None,
                    fmri_img:Nifti1Image=None,
                    sub_outdir:Union[str,os.PathLike]=None):
    """
    Create beta values maps using nilearn first-level model.

    The beta values correspond to the following contrasts between conditions:
    correctsource (cs), wrongsource (ws), cs_minus_ws, cs_minus_miss,
    ws_minus_miss, cs_minus_ctl, ws_minus_ctl
    hit, miss, hit_minus_miss, hit_minus_ctl and miss_minus_ctl

    Parameters:
    ----------
    sub_id: string (subject's dccsub_id)
    tr: float (length of time to repetition, in seconds)
    frames_times: list of float (onsets of fMRI frames, in seconds)
    hrf_model: string (type of HRF model)
    confounds: pandas dataframe (motion and other noise regressors)
    all_events: string (task information: trials' onset time, duration and label)
    fmrsub_idir: string (path to directory with fMRI data)
    outdir: string (path to subject's image output directory)

    Return:
    ----------
    None (beta maps are exported in sub_outdir)
    """
    if isinstance(session, dict):
        session = Bunch(**session)    
    # Model 1: encoding vs control conditions
    events3 = session.events.copy(deep = True)
    cols = ['onset', 'duration', 'ctl_miss_ws_cs']
    events3 = events3[cols]
    events3.rename(columns={'ctl_miss_ws_cs':'trial_type'}, inplace=True)

    # create the model - Should data be standardized?
    model3 = FirstLevelModel(**session.glm_defs)

    # create the design matrices
    design3 = make_first_level_design_matrix(events=events3, **session.design_defs)

    # fit model with design matrix
    model3 = model3.fit(session.cleaned_fmri, design_matrices = design3)

    # Condition order: control, correct source, missed, wrong source (alphabetical)
    #contrast 3.1: wrong source
    ws_vec = np.repeat(0, design3.shape[1])
    ws_vec[3] = 1
    b31_map = model3.compute_contrast(ws_vec, output_type='effect_size') #"effect_size" for betas
    b31_name = f'betas_{session.sub_id}_ws.nii'

    #contrast 3.2: correct source
    cs_vec = np.repeat(0, design3.shape[1])
    cs_vec[1] = 1
    b32_map = model3.compute_contrast(cs_vec, output_type='effect_size') #"effect_size" for betas
    b32_name = f'betas_{session.sub_id}_cs.nii'

    #contrast 3.3: correct source minus wrong source
    cs_minus_ws_vec = np.repeat(0, design3.shape[1])
    cs_minus_ws_vec[1] = 1
    cs_minus_ws_vec[3] = -1
    b33_map = model3.compute_contrast(cs_minus_ws_vec, output_type='effect_size') #"effect_size" for betas
    b33_name = f'betas_{session.sub_id}_cs_minus_ws.nii'

    #contrast 3.4: correct source minus miss
    cs_minus_miss_vec = np.repeat(0, design3.shape[1])
    cs_minus_miss_vec[1] = 1
    cs_minus_miss_vec[2] = -1
    b34_map = model3.compute_contrast(cs_minus_miss_vec, output_type='effect_size') #"effect_size" for betas
    b34_name = f'betas_{session.sub_id}_cs_minus_miss.nii'

    #contrast 3.5: wrong source minus miss
    ws_minus_miss_vec = np.repeat(0, design3.shape[1])
    ws_minus_miss_vec[3] = 1
    ws_minus_miss_vec[2] = -1
    b35_map = model3.compute_contrast(ws_minus_miss_vec, output_type='effect_size') #"effect_size" for betas
    b35_name = f'betas_{session.sub_id}_ws_minus_miss.nii'

    #contrast 3.6: correct source minus control
    cs_minus_ctl_vec = np.repeat(0, design3.shape[1])
    cs_minus_ctl_vec[1] = 1
    cs_minus_ctl_vec[0] = -1
    b36_map = model3.compute_contrast(cs_minus_ctl_vec, output_type='effect_size') #"effect_size" for betas
    b36_name = f'betas_{session.sub_id}_cs_minus_ctl.nii'

    #contrast 3.7: wrong source minus control
    ws_minus_ctl_vec = np.repeat(0, design3.shape[1])
    ws_minus_ctl_vec[3] = 1
    ws_minus_ctl_vec[0] = -1
    b37_map = model3.compute_contrast(ws_minus_ctl_vec, output_type='effect_size') #"effect_size" for betas
    b37_name = f'betas_{session.sub_id}_ws_minus_ctl.nii'

    contrasts = ((b31_map, b31_name), (b32_map, b32_name), (b33_map, b33_name),
                 (b34_map, b34_name), (b35_map, b35_name), (b36_map, b36_name),
                 (b37_map, b37_name))
    if sub_outdir is not None:
        savedir = os.path.join(sub_outdir, session.sub_id, session.ses_id)
        os.makedirs(savedir, exist_ok=True)
        [nibabel.save(*contrast) for contrast in contrasts]

    return contrasts
Ejemplo n.º 23
0
#########################################################################
# Take a look at the contrasts.
plot_contrast_matrix(contrasts['left-right'], design_matrix)

#########################################################################
# Take a breath.
#
# We can now  proceed by estimating the contrasts and displaying them.

import matplotlib.pyplot as plt
from nilearn.plotting import plot_stat_map

fig = plt.figure(figsize=(11, 3))
for index, (contrast_id, contrast_val) in enumerate(contrasts.items()):
    ax = plt.subplot(1, len(contrasts), 1 + index)
    z_map = first_level_model.compute_contrast(contrast_val,
                                               output_type='z_score')
    plot_stat_map(z_map,
                  display_mode='z',
                  threshold=3.0,
                  title=contrast_id,
                  axes=ax,
                  cut_coords=1)
    plt.show()

#########################################################################
# The result is acceptable. Note that we're asking a lot of questions
# to a small dataset, yet with a relatively large number of experimental
# conditions.
#
Ejemplo n.º 24
0
lsa_glm = FirstLevelModel(**glm_parameters)
lsa_glm.fit(fmri_file, lsa_events_df)

fig, ax = plt.subplots(figsize=(10, 10))
plotting.plot_design_matrix(lsa_glm.design_matrices_[0], ax=ax)
fig.show()

##############################################################################
# Aggregate beta maps from the LSA model based on condition
# `````````````````````````````````````````````````````````
# Collect the parameter estimate maps
lsa_beta_maps = {cond: [] for cond in events_df['trial_type'].unique()}
trialwise_conditions = lsa_events_df['trial_type'].unique()
for condition in trialwise_conditions:
    beta_map = lsa_glm.compute_contrast(condition, output_type='effect_size')
    # Drop the trial number from the condition name to get the original name
    condition_name = condition.split('__')[0]
    lsa_beta_maps[condition_name].append(beta_map)

# We can concatenate the lists of 3D maps into a single 4D beta series for
# each condition, if we want
lsa_beta_maps = {
    name: image.concat_imgs(maps)
    for name, maps in lsa_beta_maps.items()
}

##############################################################################
# Define the LSS models
# ---------------------
# We will now create a separate LSS model for each trial of interest.
contrast_matrix = np.eye(len(names))
for i in range(len(names)):
    contrasts[names[i]] = contrast_matrix[i]

# more interesting contrasts"""
contrasts = {'active-rest': contrasts['active'] - contrasts['rest']}

# fit GLM
print('\r\nFitting a GLM (this takes time) ..')
fmri_glm = FirstLevelModel(noise_model='ar1', standardize=False, t_r=tr).fit(
    [nibabel.concat_images(subject_data.func[0])],
    design_matrices=design_matrix)

# save computed mask
mask_path = os.path.join(subject_data.output_dir, "mask.nii.gz")
print("Saving mask image %s" % mask_path)
nibabel.save(fmri_glm.masker_.mask_img_, mask_path)

# compute bg unto which activation will be projected
anat_img = nibabel.load(subject_data.anat)

print("Computing contrasts ..")
z_maps = {}
effects_maps = {}
for contrast_id, contrast_val in contrasts.items():
    print("\tcontrast id: %s" % contrast_id)
    z_map = fmri_glm.compute_contrast(contrasts[contrast_id],
                                      output_type='z_score')

    z_maps[contrast_id] = z_map
Ejemplo n.º 26
0
def sub_tcontrasts1(session:Union[dict,Bunch]=None,
                    sub_id:str=None,
                    tr:float=None,
                    frame_times:list=None,
                    hrf_model:str=None,
                    events:pd.DataFrame=None,
                    fmri_img:Nifti1Image=None,
                    sub_outdir:Union[str,os.PathLike]=None):
    """
    Create beta values maps using nilearn first-level model.

    The beta values correspond to the following contrasts between conditions:
    control, encoding, and encoding_minus_control

    Parameters:
    ----------
    sub_id: string (subject's dccsub_id)
    tr: float (length of time to repetition, in seconds)
    frames_times: list of float (onsets of fMRI frames, in seconds)
    hrf_model: string (type of HRF model)
    confounds: pandas dataframe (motion and other noise regressors)
    all_events: string (task information: trials' onset time, duration and label)
    fmrsub_idir: string (path to directory with fMRI data)
    outdir: string (path to subject's image output directory)

    Return:
    ----------
    None (beta maps are exported in sub_outdir)
    """

    if isinstance(session, dict):
        session = Bunch(**session)
    # Model 1: encoding vs control conditions
    events1 = session.events.copy(deep = True)
    cols = ['onset', 'duration', 'trial_type']
    events1 = events1[cols]

    # create the model - Should data be standardized?
    model1 = FirstLevelModel(**session.glm_defs)

    # create the design matrices
    design1 = make_first_level_design_matrix(events=events1, **session.design_defs)

    # fit model with design matrix
    model1 = model1.fit(session.cleaned_fmri, design_matrices = design1)

    # Condition order: control, encoding (alphabetical)
    # contrast 1.1: control condition
    ctl_vec = np.repeat(0, design1.shape[1])
    ctl_vec[0] = 1
    b11_map = model1.compute_contrast(ctl_vec, output_type='effect_size') #"effect_size" for betas
    b11_name = f'betas_{session.sub_id}_ctl.nii'

    #contrast 1.2: encoding condition
    enc_vec = np.repeat(0, design1.shape[1])
    enc_vec[1] = 1
    b12_map = model1.compute_contrast(enc_vec, output_type='effect_size') #"effect_size" for betas
    b12_name = f'betas_{session.sub_id}_enc.nii'

    #contrast 1.3: encoding minus control
    encMinCtl_vec = np.repeat(0, design1.shape[1])
    encMinCtl_vec[1] = 1
    encMinCtl_vec[0] = -1
    b13_map = model1.compute_contrast(encMinCtl_vec, output_type='effect_size') #"effect_size" for betas
    b13_name = f'betas_{session.sub_id}_enc_minus_ctl.nii'
    contrasts = ((b11_map, b11_name), (b12_map, b12_name), (b13_map, b13_name))
    if sub_outdir is not None:
        savedir = os.path.join(sub_outdir, session.sub_id, session.ses_id)
        os.makedirs(savedir, exist_ok=True)
        [nibabel.save(*contrast) for contrast in contrasts]
    return contrasts
from nilearn.glm.first_level import FirstLevelModel

fmri_glm = FirstLevelModel(t_r=7,
                           drift_model='cosine',
                           signal_scaling=False,
                           mask_img=mask,
                           minimize_memory=False)

fmri_glm = fmri_glm.fit(fmri_img, events)

#########################################################################
# Calculate and plot contrast
# ---------------------------
from nilearn import plotting

z_map = fmri_glm.compute_contrast('active - rest')

plotting.plot_stat_map(z_map, bg_img=mean_img, threshold=3.1)

#########################################################################
# Extract the largest clusters
# ----------------------------
from nilearn.reporting import get_clusters_table
from nilearn.maskers import NiftiSpheresMasker

table = get_clusters_table(z_map, stat_threshold=3.1,
                           cluster_threshold=20).set_index('Cluster ID',
                                                           drop=True)
table.head()

# get the 6 largest clusters' max x, y, and z coordinates
                      memory='nilearn_cache')

##############################################################################
# Run the glm on data from each session
# -------------------------------------
for session in unique_sessions:
    # grab the fmri data for that particular session
    fmri_session = index_img(func_filename, sessions == session)

    # fit the glm
    glm.fit(fmri_session, events=events[session])

    # set up contrasts: one per condition
    conditions = events[session].trial_type.unique()
    for condition_ in conditions:
        z_maps.append(glm.compute_contrast(condition_))
        condition_idx.append(condition_)
        session_idx.append(session)

#########################################################################
# Generating a report
# -------------------
# Since we have already computed the FirstLevelModel
# and have the contrast, we can quickly create a summary report.
from nilearn.image import mean_img
from nilearn.reporting import make_glm_report

mean_img_ = mean_img(func_filename)
report = make_glm_report(glm,
                         contrasts=conditions,
                         bg_img=mean_img_,
Ejemplo n.º 29
0
from nilearn.glm.first_level import FirstLevelModel
print('Fitting a GLM')
fmri_glm = FirstLevelModel()
fmri_glm = fmri_glm.fit(fmri_img, design_matrices=design_matrices)

#########################################################################
# Now we can compute contrast-related statistical maps (in z-scale), and plot
# them.
print('Computing contrasts')
from nilearn import plotting

# Iterate on contrasts
for contrast_id, contrast_val in contrasts.items():
    print("\tcontrast id: %s" % contrast_id)
    # compute the contrasts
    z_map = fmri_glm.compute_contrast(
        contrast_val, output_type='z_score')
    # plot the contrasts as soon as they're generated
    # the display is overlaid on the mean fMRI image
    # a threshold of 3.0 is used, more sophisticated choices are possible
    plotting.plot_stat_map(
        z_map, bg_img=mean_image, threshold=3.0, display_mode='z',
        cut_coords=3, black_bg=True, title=contrast_id)
    plotting.show()

#########################################################################
# Based on the resulting maps we observe that the analysis results in
# wide activity for the 'effects of interest' contrast, showing the
# implications of large portions of the visual cortex in the
# conditions. By contrast, the differential effect between "faces" and
# "scrambled" involves sparser, more anterior and lateral regions. It
# also displays some responses in the frontal lobe.
Ejemplo n.º 30
0
def sub_tcontrasts2(session:Union[dict,Bunch]=None,
                    sub_id:str=None,
                    tr:float=None,
                    frame_times:list=None,
                    hrf_model:str=None,
                    events:pd.DataFrame=None,
                    fmri_img:Nifti1Image=None,
                    sub_outdir:Union[str,os.PathLike]=None):
    """
    Create beta values maps using nilearn first-level model.

    The beta values correspond to the following contrasts between conditions:
    hit, miss, hit_minus_miss, hit_minus_ctl and miss_minus_ctl

    Parameters:
    ----------
    sub_id: string (subject's dccsub_id)
    tr: float (length of time to repetition, in seconds)
    frames_times: list of float (onsets of fMRI frames, in seconds)
    hrf_model: string (type of HRF model)
    confounds: pandas dataframe (motion and other noise regressors)
    all_events: string (task information: trials' onset time, duration and label)
    fmrsub_idir: string (path to directory with fMRI data)
    outdir: string (path to subject's image output directory)

    Return:
    ----------
    None (beta maps are exported in sub_outdir)
    """
    if isinstance(session, dict):
        session = Bunch(**session)
    # Model 1: encoding vs control conditions
    events2 = session.events.copy(deep = True)
    cols = ['onset', 'duration', 'recognition_performance']
    events2 = events2[cols]
    events2.rename(columns={'recognition_performance':'trial_type'},
                   inplace=True)

    # create the model - Should data be standardized?
    model2 = FirstLevelModel(**session.glm_defs)

    # create the design matrices
    design2 = make_first_level_design_matrix(events=events2,**session.design_defs)

    # fit model with design matrix
    model2 = model2.fit(session.cleaned_fmri, design_matrices = design2)

    # Condition order: control, hit, missed (alphabetical)
    #contrast 2.1: miss
    miss_vec = np.repeat(0, design2.shape[1])
    miss_vec[2] = 1
    b21_map = model2.compute_contrast(miss_vec, output_type='effect_size') #"effect_size" for betas
    b21_name = f'betas_{session.sub_id}_miss.nii'
#     b21_name = os.path.join(sub_outdir, 'betas_sub'+str(sub_id)+'_miss.nii')
#     nibabel.save(b21_map, b21_name)

    #contrast 2.2: hit
    hit_vec = np.repeat(0, design2.shape[1])
    hit_vec[1] = 1
    b22_map = model2.compute_contrast(hit_vec, output_type='effect_size') #"effect_size" for betas
    b22_name = f'betas_{session.sub_id}_hit.nii'

    #contrast 2.3: hit minus miss
    hit_min_miss_vec = np.repeat(0, design2.shape[1])
    hit_min_miss_vec[1] = 1
    hit_min_miss_vec[2] = -1
    b23_map = model2.compute_contrast(hit_min_miss_vec, output_type='effect_size') #"effect_size" for betas
    b23_name = f'betas_{session.sub_id}_hit_minus_miss.nii'

    #contrast 2.4: hit minus control
    hit_min_ctl_vec = np.repeat(0, design2.shape[1])
    hit_min_ctl_vec[1] = 1
    hit_min_ctl_vec[0] = -1
    b24_map = model2.compute_contrast(hit_min_ctl_vec, output_type='effect_size') #"effect_size" for betas
    b24_name = f'betas_{session.sub_id}_hit_minus_ctl.nii'

    #contrast 2.5: miss minus control
    miss_min_ctl_vec = np.repeat(0, design2.shape[1])
    miss_min_ctl_vec[2] = 1
    miss_min_ctl_vec[0] = -1
    b25_map = model2.compute_contrast(miss_min_ctl_vec, output_type='effect_size') #"effect_size" for betas
    b25_name = f'betas_{session.sub_id}_miss_minus_ctl.nii'
    
    contrasts = ((b21_map, b21_name), (b22_map, b22_name), (b23_map, b23_name),
                 (b24_map, b24_name), (b25_map, b25_name))

    if sub_outdir is not None:
        savedir = os.path.join(sub_outdir, session.sub_id, session.ses_id)
        os.makedirs(savedir, exist_ok=True)
        [nibabel.save(*contrast) for contrast in contrasts]
    return contrasts