Esempio n. 1
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)
Esempio n. 2
0
def test_first_level_residuals():
    shapes, rk = [(10, 10, 10, 100)], 3
    mask, fmri_data, design_matrices =\
        generate_fake_fmri_data_and_design(shapes, rk)

    for i in range(len(design_matrices)):
        design_matrices[i].iloc[:, 0] = 1

    # Check that voxelwise model attributes cannot be
    # accessed if minimize_memory is set to True
    model = FirstLevelModel(mask_img=mask,
                            minimize_memory=True,
                            noise_model='ols')
    model.fit(fmri_data, design_matrices=design_matrices)

    with pytest.raises(ValueError, match="To access voxelwise attributes"):
        residuals = model.residuals[0]

    model = FirstLevelModel(mask_img=mask,
                            minimize_memory=False,
                            noise_model='ols')

    # Check that trying to access residuals without fitting
    # raises an error
    with pytest.raises(ValueError, match="The model has not been fit yet"):
        residuals = model.residuals[0]

    model.fit(fmri_data, design_matrices=design_matrices)

    # For coverage
    with pytest.raises(ValueError, match="attribute must be one of"):
        model._get_voxelwise_model_attribute("foo", True)
    residuals = model.residuals[0]
    mean_residuals = model.masker_.transform(residuals).mean(0)
    assert_array_almost_equal(mean_residuals, 0)
Esempio n. 3
0
def test_first_level_with_no_signal_scaling():
    """
    test to ensure that the FirstLevelModel works correctly with a
    signal_scaling==False. In particular, that derived theta are correct for a
    constant design matrix with a single valued fmri image
    """
    shapes, rk = [(3, 1, 1, 2)], 1
    fmri_data = list()
    design_matrices = list()
    design_matrices.append(
        pd.DataFrame(np.ones((shapes[0][-1], rk)),
                     columns=list('abcdefghijklmnopqrstuvwxyz')[:rk]))
    # Check error with invalid signal_scaling values
    with pytest.raises(ValueError, match="signal_scaling must be"):
        FirstLevelModel(mask_img=False,
                        noise_model='ols',
                        signal_scaling="foo")

    first_level = FirstLevelModel(mask_img=False,
                                  noise_model='ols',
                                  signal_scaling=False)
    fmri_data.append(Nifti1Image(np.zeros((1, 1, 1, 2)) + 6, np.eye(4)))

    first_level.fit(fmri_data, design_matrices=design_matrices)
    # trivial test of signal_scaling value
    assert first_level.signal_scaling is False
    # assert that our design matrix has one constant
    assert first_level.design_matrices_[0].equals(
        pd.DataFrame([1.0, 1.0], columns=['a']))
    # assert that we only have one theta as there is only on voxel in our image
    assert first_level.results_[0][0].theta.shape == (1, 1)
    # assert that the theta is equal to the one voxel value
    assert_almost_equal(first_level.results_[0][0].theta[0, 0], 6.0, 2)
Esempio n. 4
0
def test_first_level_predictions_r_square():
    shapes, rk = [(10, 10, 10, 25)], 3
    mask, fmri_data, design_matrices =\
        generate_fake_fmri_data_and_design(shapes, rk)

    for i in range(len(design_matrices)):
        design_matrices[i].iloc[:, 0] = 1

    model = FirstLevelModel(mask_img=mask,
                            signal_scaling=False,
                            minimize_memory=False,
                            noise_model='ols')
    model.fit(fmri_data, design_matrices=design_matrices)

    pred = model.predicted[0]
    data = fmri_data[0]
    r_square_3d = model.r_square[0]

    y_predicted = model.masker_.transform(pred)
    y_measured = model.masker_.transform(data)

    assert_almost_equal(np.mean(y_predicted - y_measured), 0)

    r_square_2d = model.masker_.transform(r_square_3d)
    assert_array_less(0., r_square_2d)
Esempio n. 5
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
Esempio n. 6
0
def test_glm_sample_mask():
    """Ensure the sample mask is performing correctly in GLM."""
    shapes, rk = [(10, 10, 10, 25)], 3
    mask, fmri_data, design_matrix =\
        generate_fake_fmri_data_and_design(shapes, rk)
    model = FirstLevelModel(t_r=2.0, mask_img=mask, minimize_memory=False)
    sample_mask = np.arange(25)[3:]  # censor the first three volumes
    model.fit(fmri_data,
              design_matrices=design_matrix,
              sample_masks=sample_mask)
    assert model.design_matrices_[0].shape[0] == 22
    assert model.predicted[0].shape[-1] == 22
def test_first_level_residuals():
    shapes, rk = [(10, 10, 10, 100)], 3
    mask, fmri_data, design_matrices = generate_fake_fmri_data_and_design(shapes, rk)

    for i in range(len(design_matrices)):
        design_matrices[i].iloc[:, 0] = 1

    model = FirstLevelModel(mask_img=mask, minimize_memory=False,
                            noise_model='ols')
    model.fit(fmri_data, design_matrices=design_matrices)

    residuals = model.residuals[0]
    mean_residuals = model.masker_.transform(residuals).mean(0)
    assert_array_almost_equal(mean_residuals, 0)
Esempio n. 8
0
def test_first_level_design_creation():
    # Test processing of FMRI inputs
    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()
        model = FirstLevelModel(t_r,
                                slice_time_ref,
                                mask_img=mask,
                                drift_model='polynomial',
                                drift_order=3)
        model = model.fit(func_img, events)
        frame1, X1, names1 = check_design_matrix(model.design_matrices_[0])
        # check design computation is identical
        n_scans = get_data(func_img).shape[3]
        start_time = slice_time_ref * t_r
        end_time = (n_scans - 1 + slice_time_ref) * t_r
        frame_times = np.linspace(start_time, end_time, n_scans)
        design = make_first_level_design_matrix(frame_times,
                                                events,
                                                drift_model='polynomial',
                                                drift_order=3)
        frame2, X2, names2 = check_design_matrix(design)
        assert_array_equal(frame1, frame2)
        assert_array_equal(X1, X2)
        assert_array_equal(names1, names2)
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del FUNCFILE, mask, model, func_img
Esempio n. 9
0
def test_get_voxelwise_attributes_should_return_as_many_as_design_matrices(
        shapes):
    mask, fmri_data, design_matrices =\
        generate_fake_fmri_data_and_design(shapes)

    for i in range(len(design_matrices)):
        design_matrices[i].iloc[:, 0] = 1

    model = FirstLevelModel(mask_img=mask,
                            minimize_memory=False,
                            noise_model='ols')
    model.fit(fmri_data, design_matrices=design_matrices)

    # Check that length of outputs is the same as the number of design matrices
    assert len(model._get_voxelwise_model_attribute("resid", True)) == \
           len(shapes)
def report_flm_fiac():  # pragma: no cover
    data = datasets.func.fetch_fiac_first_level()
    fmri_img = [data['func1'], data['func2']]

    from nilearn.image import mean_img
    mean_img_ = mean_img(fmri_img[0])

    design_files = [data['design_matrix1'], data['design_matrix2']]
    design_matrices = [pd.DataFrame(np.load(df)['X']) for df in design_files]

    fmri_glm = FirstLevelModel(mask_img=data['mask'], minimize_memory=True)
    fmri_glm = fmri_glm.fit(fmri_img, design_matrices=design_matrices)

    n_columns = design_matrices[0].shape[1]

    contrasts = {
        'SStSSp_minus_DStDSp': _pad_vector([1, 0, 0, -1], n_columns),
        'DStDSp_minus_SStSSp': _pad_vector([-1, 0, 0, 1], n_columns),
        'DSt_minus_SSt': _pad_vector([-1, -1, 1, 1], n_columns),
        'DSp_minus_SSp': _pad_vector([-1, 1, -1, 1], n_columns),
        'DSt_minus_SSt_for_DSp': _pad_vector([0, -1, 0, 1], n_columns),
        'DSp_minus_SSp_for_DSt': _pad_vector([0, 0, -1, 1], n_columns),
        'Deactivation': _pad_vector([-1, -1, -1, -1, 4], n_columns),
        'Effects_of_interest': np.eye(n_columns)[:5]
    }
    report = make_glm_report(
        fmri_glm,
        contrasts,
        bg_img=mean_img_,
        height_control='fdr',
    )
    output_filename = 'generated_report_flm_fiac.html'
    output_filepath = os.path.join(REPORTS_DIR, output_filename)
    report.save_as_html(output_filepath)
    report.get_iframe()
Esempio n. 11
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 varible 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
Esempio n. 12
0
def test_first_level_glm_computation_with_memory_caching():
    with InTemporaryDirectory():
        shapes = ((7, 8, 9, 10),)
        mask, FUNCFILE, _ = write_fake_fmri_data_and_design(shapes)
        FUNCFILE = FUNCFILE[0]
        func_img = load(FUNCFILE)
        # initialize FirstLevelModel with memory option enabled
        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,
                                memory='nilearn_cache', memory_level=1,
                                minimize_memory=False)
        model.fit(func_img, events)
        # Delete objects attached to files to avoid WindowsError when deleting
        # temporary directory (in Windows)
        del mask, func_img, FUNCFILE, model
Esempio n. 13
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]}")
Esempio n. 14
0
def test_first_level_with_scaling():
    shapes, rk = [(3, 1, 1, 2)], 1
    fmri_data = list()
    fmri_data.append(Nifti1Image(np.zeros((1, 1, 1, 2)) + 6, np.eye(4)))
    design_matrices = list()
    design_matrices.append(
        pd.DataFrame(np.ones((shapes[0][-1], rk)),
                     columns=list('abcdefghijklmnopqrstuvwxyz')[:rk]))
    fmri_glm = FirstLevelModel(mask_img=False,
                               noise_model='ols',
                               signal_scaling=0,
                               minimize_memory=True)
    assert fmri_glm.signal_scaling == 0
    assert not fmri_glm.standardize
    with pytest.warns(DeprecationWarning,
                      match="Deprecated. `scaling_axis` will be removed"):
        assert fmri_glm.scaling_axis == 0
    glm_parameters = fmri_glm.get_params()
    test_glm = FirstLevelModel(**glm_parameters)
    fmri_glm = fmri_glm.fit(fmri_data, design_matrices=design_matrices)
    test_glm = test_glm.fit(fmri_data, design_matrices=design_matrices)
    assert glm_parameters['signal_scaling'] == 0
def report_flm_adhd_dmn():  # pragma: no cover
    t_r = 2.
    slice_time_ref = 0.
    n_scans = 176
    pcc_coords = (0, -53, 26)
    adhd_dataset = nilearn.datasets.fetch_adhd(n_subjects=1)
    seed_masker = NiftiSpheresMasker([pcc_coords],
                                     radius=10,
                                     detrend=True,
                                     standardize=True,
                                     low_pass=0.1,
                                     high_pass=0.01,
                                     t_r=2.,
                                     memory='nilearn_cache',
                                     memory_level=1,
                                     verbose=0)
    seed_time_series = seed_masker.fit_transform(adhd_dataset.func[0])
    frametimes = np.linspace(0, (n_scans - 1) * t_r, n_scans)
    design_matrix = make_first_level_design_matrix(frametimes,
                                                   hrf_model='spm',
                                                   add_regs=seed_time_series,
                                                   add_reg_names=["pcc_seed"])
    dmn_contrast = np.array([1] + [0] * (design_matrix.shape[1] - 1))
    contrasts = {'seed_based_glm': dmn_contrast}

    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)

    report = make_glm_report(
        first_level_model,
        contrasts=contrasts,
        title='ADHD DMN Report',
        cluster_threshold=15,
        height_control='bonferroni',
        min_distance=8.,
        plot_type='glass',
        report_dims=(1200, 'a'),
    )
    output_filename = 'generated_report_flm_adhd_dmn.html'
    output_filepath = os.path.join(REPORTS_DIR, output_filename)
    report.save_as_html(output_filepath)
    report.get_iframe()
Esempio n. 16
0
################################
from nilearn.glm.first_level import FirstLevelModel
from nilearn.glm.first_level import make_first_level_design_matrix
import nibabel as ni

bids_dir = os.path.join(path_bids, "derivatives", "pipeline-fidl")
subjects = os.listdir(bids_dir)

for subj in subjects:

    p = os.path.join(bids_dir, subj)

    files = os.listdir(os.path.join(bids_dir, subj))
    files = [f for f in files if f.find("delayed") != -1]

    nii = [f for f in files if f.find('.nii') != -1]
    tsv = [f for f in files if f.find('.tsv') != -1][0]
    events = pd.read_csv(os.path.join(bids_dir, subj, tsv), delimiter="\t")
    events['trial_type'] = events['image']

    first_level_model = FirstLevelModel(1.71, hrf_model='glover')

    nii.sort()

    fmri_list = [ni.load(os.path.join(p, f)).get_data() for f in nii]
    fmri_list = np.concatenate(fmri_list, 3)
    image = ni.Nifti1Image(fmri_list, np.eye(4))

    first_level_model = first_level_model.fit(image, events=events)

Esempio n. 17
0
events_file = data['events']
import pandas as pd
events = pd.read_table(events_file)
events

###############################################################################
# Running a basic model
# ---------------------
#
# First we specify a linear model.
# The .fit() functionality of FirstLevelModel function creates the design
# matrix and the beta maps.
#
from nilearn.glm.first_level import FirstLevelModel
first_level_model = FirstLevelModel(t_r)
first_level_model = first_level_model.fit(fmri_img, events=events)
design_matrix = first_level_model.design_matrices_[0]

#########################################################################
# Let us take a look at the design matrix: it has 10 main columns corresponding
# to 10 experimental conditions, followed by 3 columns describing low-frequency
# signals (drifts) and a constant regressor.
from nilearn.plotting import plot_design_matrix
plot_design_matrix(design_matrix)
import matplotlib.pyplot as plt
plt.show()

#########################################################################
# Specification of the contrasts.
#
# For this, let's create a function that, given the design matrix, generates
Esempio n. 18
0
                                 verbose=0)
seed_time_series = seed_masker.fit_transform(adhd_dataset.func[0])
frametimes = np.linspace(0, (n_scans - 1) * t_r, n_scans)
design_matrix = make_first_level_design_matrix(frametimes,
                                               hrf_model='spm',
                                               add_regs=seed_time_series,
                                               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',
anat_file = results[0]['anat']
"""specify contrasts"""
_, matrix, names = check_design_matrix(design_matrix)
contrasts = {}
n_columns = len(names)
I = np.eye(len(names))
for i in range(2):
    contrasts['%s' % names[2 * i]] = I[2 * i]
"""more interesting contrasts"""
contrasts['EV1>EV2'] = contrasts['EV1'] - contrasts['EV2']
contrasts['EV2>EV1'] = contrasts['EV2'] - contrasts['EV1']
contrasts['effects_of_interest'] = contrasts['EV1'] + contrasts['EV2']
"""fit GLM"""
print('\r\nFitting a GLM (this takes time) ..')
fmri_glm = FirstLevelModel()
fmri_glm.fit(fmri_files, 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
mean_fmri_files = compute_mean_3D_image(fmri_files)
print("Computing contrasts ..")
z_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
Esempio n. 20
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)
# Instantiate the glm
glm = FirstLevelModel(t_r=TR,
                      mask_img=haxby_dataset.mask,
                      high_pass=.008,
                      smoothing_fwhm=4,
                      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
# * t_r=7(s) is the time of repetition of acquisitions
# * noise_model='ar1' specifies the noise covariance model: a lag-1 dependence
# * standardize=False means that we do not want to rescale the time series to mean 0, variance 1
# * hrf_model='spm' means that we rely on the SPM "canonical hrf" model (without time or dispersion derivatives)
# * drift_model='cosine' means that we model the signal drifts as slow oscillating time functions
# * high_pass=0.01(Hz) defines the cutoff frequency (inverse of the time period).
fmri_glm = FirstLevelModel(t_r=7,
                           noise_model='ar1',
                           standardize=False,
                           hrf_model='spm',
                           drift_model='cosine',
                           high_pass=.01)

###############################################################################
# Now that we have specified the model, we can run it on the fMRI image
fmri_glm = fmri_glm.fit(fmri_img, events)

###############################################################################
# One can inspect the design matrix (rows represent time, and
# columns contain the predictors).
design_matrix = fmri_glm.design_matrices_[0]

###############################################################################
# Formally, we have taken the first design matrix, because the model is
# implictily meant to for multiple runs.
from nilearn.reporting import plot_design_matrix
plot_design_matrix(design_matrix)
import matplotlib.pyplot as plt
plt.show()

###############################################################################
Esempio n. 23
0
design_files = [data['design_matrix1'], data['design_matrix2']]
import pandas as pd
import numpy as np
design_matrices = [pd.DataFrame(np.load(df)['X']) for df in design_files]

#########################################################################
# GLM estimation
# ----------------------------------
# GLM specification. Note that the mask was provided in the dataset. So we use it.

from nilearn.glm.first_level import FirstLevelModel
fmri_glm = FirstLevelModel(mask_img=data['mask'], minimize_memory=True)

#########################################################################
# Let's fit the GLM.
fmri_glm = fmri_glm.fit(fmri_img, design_matrices=design_matrices)

#########################################################################
# 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]

def pad_vector(contrast_, n_columns):
    """A small routine to append zeros in contrast vectors"""
    return np.hstack((contrast_, np.zeros(n_columns - len(contrast_))))

#########################################################################
# Contrast specification

contrasts = {'SStSSp_minus_DStDSp': pad_vector([1, 0, 0, -1], n_columns),
             'DStDSp_minus_SStSSp': pad_vector([-1, 0, 0, 1], n_columns),
Esempio n. 24
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'))
Esempio n. 25
0
events_file = data['events']
import pandas as pd
events = pd.read_table(events_file)
events

###############################################################################
# Running a basic model
# ---------------------
#
# First we specify a linear model.
# The .fit() functionality of FirstLevelModel function creates the design
# matrix and the beta maps.
#
from nilearn.glm.first_level import FirstLevelModel
first_level_model = FirstLevelModel(t_r)
first_level_model = first_level_model.fit(fmri_img, events=events)
design_matrix = first_level_model.design_matrices_[0]

#########################################################################
# Let us take a look at the design matrix: it has 10 main columns corresponding
# to 10 experimental conditions, followed by 3 columns describing low-frequency
# signals (drifts) and a constant regressor.
from nilearn.plotting import plot_design_matrix
plot_design_matrix(design_matrix)
import matplotlib.pyplot as plt
plt.show()

#########################################################################
# Specification of the contrasts.
#
# For this, let's create a function that, given the design matrix, generates
Esempio n. 26
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'
        ))
Esempio n. 27
0
#########################################################################
# Next solution is to try Finite Impulse Reponse (FIR) models: we just
# say that the hrf is an arbitrary function that lags behind the
# stimulus onset.  In the present case, given that the numbers of
# conditions is high, we should use a simple FIR model.
#
# Concretely, we set `hrf_model` to 'fir' and `fir_delays` to [1, 2,
# 3] (scans) corresponding to a 3-step functions on the [1 * t_r, 4 *
# t_r] seconds interval.
#

from nilearn.glm.first_level import FirstLevelModel
from nilearn.reporting import plot_design_matrix, plot_contrast_matrix

first_level_model = FirstLevelModel(t_r, hrf_model='fir', fir_delays=[1, 2, 3])
first_level_model = first_level_model.fit(fmri_img, events=events)
design_matrix = first_level_model.design_matrices_[0]
plot_design_matrix(design_matrix)

#########################################################################
# We have to adapt contrast specification. We characterize the BOLD
# response by the sum across the three time lags. It's a bit hairy,
# sorry, but this is the price to pay for flexibility...

import numpy as np

contrast_matrix = np.eye(design_matrix.shape[1])
contrasts = dict([(column, contrast_matrix[i])
                  for i, column in enumerate(design_matrix.columns)])
conditions = events.trial_type.unique()
for condition in conditions:
# beta maps into condition-wise beta series.

# Transform the DataFrame for LSA
lsa_events_df = events_df.copy()
conditions = lsa_events_df['trial_type'].unique()
condition_counter = {c: 0 for c in conditions}
for i_trial, trial in lsa_events_df.iterrows():
    trial_condition = trial['trial_type']
    condition_counter[trial_condition] += 1
    # We use a unique delimiter here (``__``) that shouldn't be in the
    # original condition names
    trial_name = f'{trial_condition}__{condition_counter[trial_condition]:03d}'
    lsa_events_df.loc[i_trial, 'trial_type'] = trial_name

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]
# spanning the two conditions.

contrasts = {
    'faces-scrambled': basic_contrasts['faces'] - basic_contrasts['scrambled'],
    'scrambled-faces': -basic_contrasts['faces'] + basic_contrasts['scrambled'],
    'effects_of_interest': np.vstack((basic_contrasts['faces'],
                                      basic_contrasts['scrambled']))
    }

#########################################################################
# Fit the GLM for the 2 sessions by specifying a FirstLevelModel and then
# fitting it.
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
Esempio n. 30
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'))