def process_subject(inputpath, subjid, dtx_mat, outputpath): subjglm = op.join(outputpath, "cache", "glm_{}".format(subjid)) subjid = str(subjid) if op.isfile(subjglm): print('Loading already saved model {}'.format(subjglm)) fmri_glm = load(subjglm) # the model has already been estimated else: # else, we create and estimate it print('Creating model for subject %s' % subjid) imgs = sorted( glob.glob(op.join(inputpath, subjid, "func", "res*_medn_afw.nii"))) if len(imgs) != 9: print("WARNING: %s does not have 9 sessions. We skip it." % subjid) return fmri_glm = FirstLevelModel( t_r=2.0, hrf_model='spm', # mask='mask_ICV.nii', noise_model='ar1', period_cut=128.0, smoothing_fwhm=0, minimize_memory=True, # memory='/mnt/ephemeral/cache', memory=None, verbose=2, n_jobs=1) # creating and estimating the model fmri_glm = fmri_glm.fit(imgs, design_matrices=dtx_mat) # saving it as a pickle object dump(fmri_glm, subjglm) # creating the maps for each individual predictor # this assumes the same predictors for each session print('Computing contrasts for subject %s', subjid) contrasts = {} con_names = [i for i in dtx_mat[0].columns] ncon = len(con_names) con = np.eye(ncon) for i, name in enumerate(con_names): contrasts[name] = con[i, :] for name, val in contrasts.items(): z_map = fmri_glm.compute_contrast(val, output_type='z_score') eff_map = fmri_glm.compute_contrast(val, output_type='effect_size') #std_map = fmri_glm.compute_contrast(val, output_type='stddev') nib.save(z_map, op.join(outputpath, '%s_%s_zmap.nii.gz' % (name, subjid))) nib.save(eff_map, op.join(outputpath, '%s_%s_effsize.nii.gz' % (name, subjid))) display = None display = plot_glass_brain(z_map, display_mode='lzry', threshold=3.1, colorbar=True, title=name) display.savefig( op.join(outputpath, '%s_%s_glassbrain.png' % (name, subjid))) display.close()
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(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(fixed_fx_contrast.get_data(), fixed_fx_dic['effect_size'].get_data()) assert_almost_equal(fixed_fx_variance.get_data(), fixed_fx_dic['effect_variance'].get_data()) assert_almost_equal(fixed_fx_stat.get_data(), fixed_fx_dic['stat'].get_data()) # test without mask variable ( fixed_fx_contrast, fixed_fx_variance, fixed_fx_stat, ) = compute_fixed_effects(contrasts, variance) assert_almost_equal(fixed_fx_contrast.get_data(), fixed_fx_dic['effect_size'].get_data()) assert_almost_equal(fixed_fx_variance.get_data(), fixed_fx_dic['effect_variance'].get_data()) assert_almost_equal(fixed_fx_stat.get_data(), fixed_fx_dic['stat'].get_data()) # 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
def main(sourcedata, derivatives, subject, session, tmp_dir): sourcedata_layout = BIDSLayout(sourcedata) sourcedata_df = sourcedata_layout.as_data_frame() events = sourcedata_df[(sourcedata_df['type'] == 'events') & (sourcedata_df['subject'] == subject) & (sourcedata_df['session'] == session)] derivatives_layout = BIDSLayout(os.path.join(derivatives, 'spynoza')) derivatives_df = derivatives_layout.as_data_frame() bold = derivatives_df[(derivatives_df['type'] == 'preproc') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] mask = derivatives_layout.get(subject=subject, session=session, type='mask', return_type='file')[0] mask = image.math_img('(im > .5).astype(int)', im=mask) print(mask) row = bold.iloc[0] results_dir = os.path.join(derivatives, 'modelfitting_av', 'glm2', 'sub-{}'.format(row['subject'])) os.makedirs(results_dir, exist_ok=True) av_bold_fn = os.path.join( results_dir, 'sub-{}_ses-{}_bold_average.nii.gz'.format(row['subject'], row['session'])) av_bold = average_over_runs(bold.path.tolist(), output_filename=av_bold_fn) av_bold = image.math_img('(av_bold / av_bold.mean(-1)[..., np.newaxis])', av_bold=av_bold) av_bold.to_filename(av_bold_fn) model = FirstLevelModel(t_r=4, mask=mask, drift_model=None) paradigm = pd.read_table(events.iloc[0]['path']) model.fit(av_bold, paradigm) left_right = model.compute_contrast('eye_L - eye_R', output_type='z_score') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session'], ))) left_right = model.compute_contrast('eye_L - eye_R', output_type='effect_size') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_psc.nii.gz'.format( row['subject'], row['session'])))
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(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))
def test_high_level_glm_null_contrasts(): # test that contrast computation is resilient to 0 values. # new API shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 19)), 3 mask, fmri_data, design_matrices = _generate_fake_fmri_data(shapes, rk) multi_session_model = FirstLevelModel(mask=None).fit( fmri_data, design_matrices=design_matrices) single_session_model = FirstLevelModel(mask=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(z1.get_data(), z2.get_data())
def test_high_level_glm_with_data(): # New API with InTemporaryDirectory(): shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3 mask, fmri_data, design_matrices = _write_fake_fmri_data(shapes, rk) multi_session_model = FirstLevelModel(mask=None).fit( fmri_data, design_matrices=design_matrices) n_voxels = multi_session_model.masker_.mask_img_.get_data().sum() z_image = multi_session_model.compute_contrast(np.eye(rk)[1]) assert_equal(np.sum(z_image.get_data() != 0), n_voxels) assert_true(z_image.get_data().std() < 3.) # with mask multi_session_model = FirstLevelModel(mask=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(z_image.get_data() == 0., load(mask).get_data() == 0.) assert_true((variance_image.get_data()[load(mask).get_data() > 0] > .001).all()) all_images = multi_session_model.compute_contrast(np.eye(rk)[:2], output_type='all') assert_array_equal(all_images['z_score'].get_data(), z_image.get_data()) assert_array_equal(all_images['p_value'].get_data(), p_value.get_data()) assert_array_equal(all_images['stat'].get_data(), stat_image.get_data()) assert_array_equal(all_images['effect_size'].get_data(), effect_image.get_data()) assert_array_equal(all_images['effect_variance'].get_data(), variance_image.get_data()) # 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, )
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(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
def run_glm(dmtx, contrasts, fmri_data, mask_img, subject_dic, subject_session_output_dir, tr, 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 nistats.first_level_model import FirstLevelModel fmri_4d = nib.load(fmri_data) # GLM analysis print('Fitting a GLM (this takes time)...') fmri_glm = FirstLevelModel(mask=mask_img, t_r=tr, slice_time_ref=.5, 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
def test_high_level_glm_one_session(): shapes, rk = [(7, 8, 9, 15)], 3 mask, fmri_data, design_matrices = _generate_fake_fmri_data(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)
def test_high_level_glm_with_data(): # New API shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3 mask, fmri_data, design_matrices = write_fake_fmri_data(shapes, rk) multi_session_model = FirstLevelModel(mask=None).fit( fmri_data, design_matrices=design_matrices) n_voxels = multi_session_model.masker_.mask_img_.get_data().sum() z_image = multi_session_model.compute_contrast(np.eye(rk)[1]) assert_equal(np.sum(z_image.get_data() != 0), n_voxels) assert_true(z_image.get_data().std() < 3.) # with mask multi_session_model = FirstLevelModel(mask=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(z_image.get_data() == 0., load(mask).get_data() == 0.) assert_true( (variance_image.get_data()[load(mask).get_data() > 0] > .001).all())
def test_high_level_glm_with_paths(): # New API shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 14)), 3 with InTemporaryDirectory(): mask_file, fmri_files, design_files = _write_fake_fmri_data(shapes, rk) multi_session_model = FirstLevelModel(mask=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_true(z_image.get_data().std() < 3.) # Delete objects attached to files to avoid WindowsError when deleting # temporary directory (in Windows) del z_image, fmri_files, multi_session_model
def test_high_level_glm_with_data(): # New API with InTemporaryDirectory(): shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3 mask, fmri_data, design_matrices = _write_fake_fmri_data(shapes, rk) multi_session_model = FirstLevelModel(mask=None).fit( fmri_data, design_matrices=design_matrices) n_voxels = multi_session_model.masker_.mask_img_.get_data().sum() z_image = multi_session_model.compute_contrast(np.eye(rk)[1]) assert_equal(np.sum(z_image.get_data() != 0), n_voxels) assert_true(z_image.get_data().std() < 3.) # with mask multi_session_model = FirstLevelModel(mask=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(z_image.get_data() == 0., load(mask).get_data() == 0.) assert_true( (variance_image.get_data()[load(mask).get_data() > 0] > .001).all()) all_images = multi_session_model.compute_contrast( np.eye(rk)[:2], output_type='all') assert_array_equal(all_images['z_score'].get_data(), z_image.get_data()) assert_array_equal(all_images['p_value'].get_data(), p_value.get_data()) assert_array_equal(all_images['stat'].get_data(), stat_image.get_data()) assert_array_equal(all_images['effect_size'].get_data(), effect_image.get_data()) assert_array_equal(all_images['effect_variance'].get_data(), variance_image.get_data()) # 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, )
def test_high_level_glm_one_session(): # New API shapes, rk = [(7, 8, 9, 15)], 3 mask, fmri_data, design_matrices = _generate_fake_fmri_data(shapes, rk) single_session_model = FirstLevelModel(mask=None).fit( fmri_data[0], design_matrices=design_matrices[0]) assert_true(isinstance(single_session_model.masker_.mask_img_, Nifti1Image)) single_session_model = FirstLevelModel(mask=mask).fit( fmri_data[0], design_matrices=design_matrices[0]) z1 = single_session_model.compute_contrast(np.eye(rk)[:1]) assert_true(isinstance(z1, Nifti1Image))
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(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(z1.get_data() + z2.get_data(), 2 * z_joint.get_data())
def fit_subject(sub, space): funcs = sorted( glob( f'../derivatives/fmriprep/{sub}/ses-*/func/*task-flocBLOCKED*space-{space}*desc-preproc_bold.nii.gz' )) masks = [f.replace('preproc_bold', 'brain_mask') for f in funcs] mask = masking.intersect_masks(masks, threshold=0.9) conf_files = [ f.split('space')[0] + 'desc-confounds_regressors.tsv' for f in funcs ] ccols = ['trans_x', 'trans_y', 'trans_z', 'rot_x', 'rot_y', 'rot_z'] confs = [pd.read_csv(c, sep='\t').loc[:, ccols] for c in conf_files] events = [ f"../{sub}/ses{f.split('ses')[1].split('func')[0]}/func/{op.basename(f).split('desc')[0]}events.tsv" for f in conf_files ] flm = FirstLevelModel(t_r=0.7, slice_time_ref=0.5, drift_model='cosine', high_pass=0.01, mask_img=mask, smoothing_fwhm=3.5, noise_model='ols', verbose=True) flm.fit(funcs, events, confs) con_defs = [('face', '4*face - object - character - body - place'), ('place', '4*place - object - face - character - body'), ('body', '4*body - object - face - character - place'), ('character', '4*character - object - face - place - body')] for name, df in con_defs: roi = flm.compute_contrast(df) f_out = f'../derivatives/floc/{sub}/rois/{sub}_task-flocBLOCKED_space-{space}_desc-{name}_zscore.nii.gz' if not op.isdir(op.dirname(f_out)): os.makedirs(op.dirname(f_out)) roi.to_filename(f_out)
def test_first_level_model_contrast_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 10),) mask, FUNCFILE, _ = write_fake_fmri_data(shapes) FUNCFILE = FUNCFILE[0] func_img = load(FUNCFILE) # basic test based on basic_paradigm and glover hrf t_r = 1.0 slice_time_ref = 0. paradigm = basic_paradigm() # ols case model = FirstLevelModel(t_r, slice_time_ref, mask=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 assert_raises(ValueError, model.compute_contrast, c1) # fit model model = model.fit([func_img, func_img], [paradigm, paradigm]) # 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 assert_raises(ValueError, model.compute_contrast, cnull) assert_raises(ValueError, model.compute_contrast, [cnull, cnull]) # passing wrong parameters assert_raises(ValueError, model.compute_contrast, []) assert_raises(ValueError, model.compute_contrast, [c1, []]) assert_raises(ValueError, model.compute_contrast, c1, '', '') assert_raises(ValueError, model.compute_contrast, c1, '', [])
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) ######################################################################### # contrast estimation 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 # ------------------- # It can be useful to quickly generate a # portable, ready-to-view report with most of the pertinent information. # This is easy to do if you have a fitted model and the list of contrasts,
def first_level(subject_dic, mask_img, compcorr=True, smooth=None): """ Run the first-level analysis (GLM fitting + statistical maps) in a given subject Parameters ---------- subject_dic: dict, exhaustive description of an individual acquisition additional_regressors: dict or None, additional regressors provided as an already sampled design_matrix dictionary keys are session_ids compcorr: Bool, optional, whetherconfound estimation and removal should be carried out or not smooth: float or None, optional, how much the data should spatially smoothed during masking """ import nibabel as nib import numpy as np from nistats.design_matrix import make_design_matrix from nilearn.image import high_variance_confounds import pandas as pd from nistats.first_level_model import FirstLevelModel # experimental paradigm meta-params motion_names = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz'] hrf_model = 'spm' hfcut = subject_dic['hfcut'] drift_model = subject_dic['drift_model'] tr = subject_dic['TR'] for session_id, fmri_path, onset, motion_path in zip( subject_dic['session_id'], subject_dic['func'], subject_dic['onset'], subject_dic['realignment_parameters']): n_scans = nib.load(fmri_path).shape[3] # motion parameters motion = np.loadtxt(motion_path) # define the time stamps for different images frametimes = np.linspace(0, (n_scans - 1) * tr, n_scans) confounds = motion confound_names = motion_names if compcorr: confounds = high_variance_confounds(fmri_path, mask_img=mask_img) confounds = np.hstack((confounds, motion)) confound_names = ['conf_%d' % i for i in range(5)] + motion_names paradigm = pd.read_csv(onset, sep='\t') trial_type = paradigm.trial_type.values audio_right_hands = ['audio_right_hand_%d' % i for i in range(5)] audio_left_hands = ['audio_left_hand_%d' % i for i in range(5)] video_right_hands = ['video_right_hand_%d' % i for i in range(5)] video_left_hands = ['video_left_hand_%d' % i for i in range(5)] trial_type[trial_type == 'audio_right_hand'] = audio_right_hands trial_type[trial_type == 'audio_left_hand'] = audio_left_hands trial_type[trial_type == 'video_right_hand'] = video_right_hands trial_type[trial_type == 'video_left_hand'] = video_left_hands # create the design matrix design_matrix = make_design_matrix(frametimes, paradigm, hrf_model=hrf_model, drift_model=drift_model, period_cut=hfcut, add_regs=confounds, add_reg_names=confound_names) # create the relevant contrasts names = design_matrix.columns n_regressors = len(names) interest = audio_right_hands + audio_left_hands + video_right_hands + video_left_hands con = dict([(names[i], np.eye(n_regressors)[i]) for i in range(n_regressors)]) contrasts = dict([(contrast, con[contrast]) for contrast in interest]) subject_session_output_dir = os.path.join(subject_dic['output_dir'], 'res_stats_%s' % session_id) if not os.path.exists(subject_session_output_dir): os.makedirs(subject_session_output_dir) design_matrix.to_csv( os.path.join(subject_session_output_dir, 'design_matrix.npz')) fmri_glm = FirstLevelModel(mask=mask_img, t_r=tr, slice_time_ref=.5, smoothing_fwhm=smooth).fit( fmri_path, design_matrices=design_matrix) # compute contrasts for contrast_id, contrast_val in contrasts.iteritems(): print "\tcontrast id: %s" % contrast_id # store stat maps to disk for map_type in ['z_score']: 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)
contrast_list['con_t_vc_v'] = contrast_vc_v contrast_vi_v = np.zeros(dm_size) contrast_vi_v[4] = 1 contrast_vi_v[5] = -1 contrast_list['con_t_vi_v'] = contrast_vi_v contrast_motion = np.zeros((par_offset, dm_size)) for r in range(par_offset): contrast_motion[r, 6 + r] = 1 contrast_list['con_F_motion'] = contrast_motion # Estimate and plot contrasts for cont in contrast_list: z_map = fmri_glm.compute_contrast(contrast_list[cont], stat_type=cont[4], output_type='z_score') identifier = '%s_sub-%02d_%s' % (cont, sdx, method) out_file = '%s/zmap_%s' % (res_path, identifier) z_map.to_filename('%s.nii.gz' % out_file) # Plot design matrices and contrasts plot_design_matrix(fmri_glm.design_matrices_[0], output_file='%s/design_matrix_01_sub-%02d.svg' % (res_path, sdx)) plot_design_matrix(fmri_glm.design_matrices_[1], output_file='%s/design_matrix_02_sub-%02d.svg' % (res_path, sdx)) plot_design_matrix(fmri_glm.design_matrices_[2],
def main(sourcedata, derivatives, subject, session, tmp_dir): sourcedata_layout = BIDSLayout(sourcedata) sourcedata_df = sourcedata_layout.as_data_frame() events = sourcedata_df[(sourcedata_df['type'] == 'events') & (sourcedata_df['subject'] == subject) & (sourcedata_df['session'] == session)] derivatives_layout = BIDSLayout( os.path.join(derivatives, 'spynoza_mc_mutualinfo')) derivatives_df = derivatives_layout.as_data_frame() bold = derivatives_df[(derivatives_df['type'] == 'preproc') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] confounds = derivatives_df[(derivatives_df['type'] == 'confounds') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] print(derivatives_df.type.unique()) mask = derivatives_layout.get(subject=subject, session=session, type='mask', return_type='file')[0] df = events.merge(bold, on=['subject', 'session', 'run'], suffixes=('_events', '_bold')) confounds = confounds.rename(columns={'path': 'confounds'}) df = df.merge(confounds[['subject', 'session', 'run', 'confounds']]) models = [] for ix, row in df.iterrows(): results_dir = os.path.join(derivatives, 'modelfitting', 'glm4', 'sub-{}'.format(row['subject'])) if 'session' in row: results_dir = os.path.join(results_dir, 'ses-{}'.format(row['session'])) os.makedirs(results_dir, exist_ok=True) confounds = pd.read_table(row.confounds).fillna(method='bfill') print('Fitting {}'.format(row['path_bold'])) model = FirstLevelModel(t_r=4, mask=mask) paradigm = pd.read_table(row['path_events']) model.fit(row['path_bold'], paradigm, confounds=confounds) left_right = model.compute_contrast('eye_L - eye_R', output_type='z_score') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session'], row['run']))) left_right = model.compute_contrast('eye_L - eye_R', output_type='effect_size') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_left_over_right_psc.nii.gz'.format( row['subject'], row['session'], row['run']))) models.append(model) second_level_model = SecondLevelModel(mask=mask) second_level_model.fit(models) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye_L - eye_R', output_type='z_score') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session']))) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye_L - eye_R', output_type='effect_size') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_effect_size.nii.gz'.format( row['subject'], row['session']))) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye_L - eye_R', output_type='z_score') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session'])))
def sub_tcontrasts2(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, sub_outdir): """Uses nistats first-level model to create maps of beta values that correspond to the following contrasts between conditions: hit, miss, hit_minus_miss, hit_minus_ctl and miss_minus_ctl Parameters: ---------- id: string (subject's dccid) 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) fmridir: 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) """ # Model 1: encoding vs control conditions events2 = all_events.copy(deep=True) cols = ['onset', 'duration', 'ctl_miss_hit'] events2 = events2[cols] events2.rename(columns={'ctl_miss_hit': 'trial_type'}, inplace=True) # create the model model2 = FirstLevelModel(t_r=tr, drift_model=None, standardize=True, noise_model='ar1', hrf_model=hrf_model) # Should data be standardized? # create the design matrices design2 = make_first_level_design_matrix(frame_times, events=events2, drift_model=None, add_regs=confounds, hrf_model=hrf_model) # fit model with design matrix model2 = model2.fit(fmri_img, design_matrices=design2) design_matrix2 = model2.design_matrices_[0] # Condition order: control, hit, missed (alphabetical) #contrast 2.1: miss miss_vec = np.repeat(0, design_matrix2.shape[1]) miss_vec[2] = 1 b21_map = model2.compute_contrast( miss_vec, output_type='effect_size') #"effect_size" for betas b21_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_miss.nii') nibabel.save(b21_map, b21_name) #contrast 2.2: hit hit_vec = np.repeat(0, design_matrix2.shape[1]) hit_vec[1] = 1 b22_map = model2.compute_contrast( hit_vec, output_type='effect_size') #"effect_size" for betas b22_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_hit.nii') nibabel.save(b22_map, b22_name) #contrast 2.3: hit minus miss hit_min_miss_vec = np.repeat(0, design_matrix2.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_hit_minus_miss.nii') nibabel.save(b23_map, b23_name) #contrast 2.4: hit minus control hit_min_ctl_vec = np.repeat(0, design_matrix2.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_hit_minus_ctl.nii') nibabel.save(b24_map, b24_name) #contrast 2.5: miss minus control miss_min_ctl_vec = np.repeat(0, design_matrix2.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_miss_minus_ctl.nii') nibabel.save(b25_map, b25_name) return
class Model(object): def __init__(self, img, events, t_r, regressors=None, mask=None, standardize=False, signal_scaling=0, event_index=None, first_level_kws=None): """Class for building a first-level model for the purpose of single- trial modelling. This is intended for single-trial modelling and not as a general purpose GLM class. To prevent unwanted aggregation, it only accepts one image/regressor/event/mask, rather than multiple. This is enforced and will raise a ValueError if inputs are a list of length > 1. Parameters ---------- img : niimg-like One 4D functional image. events : pandas.core.DataFrame DataFrame with 'events', 'onsets' and 'trial_type' columns. Other columns can be included as parametric modulators. regressors : pandas.core.DataFrame DataFrame with shape (number of volumes/timepoints in img, number of regressors). Each column is a separate regressor. mask : niimg-like Mask to restrict analysis, by default None which will compute a whole-brain mask. event_index : int, optional Index of single event in `events`. All other events will be labelled as 'other'. This is to isolate a single event for LSS modelling. """ self.img = img self.mask = mask regressors = _check_file(regressors) if regressors is not None: self.regressors = regressors.values self.reg_names = regressors.columns.values else: self.regressors = regressors self.reg_names = None self.events = _check_file(events) # for LSS modelling self.event_index = event_index if self.event_index is not None: ev = events.copy() idx = ev.index.isin([event_index]) ev.loc[~idx, 'trial_type'] = 'other' # to be used to index contrast during parameter extraction self._event_of_interest = ev.loc[idx, 'trial_type'].values[0] self.events = ev self.t_r = t_r self.frame_times = _compute_frame_times(self.img, self.t_r) if first_level_kws is not None: self.glm = FirstLevelModel(t_r=self.t_r, mask_img=mask, standardize=standardize, signal_scaling=signal_scaling, **first_level_kws) else: self.glm = FirstLevelModel(t_r=self.t_r, mask_img=mask, standardize=standardize, signal_scaling=signal_scaling) self.design = None def add_design_matrix(self, hrf_model, drift_model='cosine', high_pass=.01): self.design = make_first_level_design_matrix( frame_times=self.frame_times, events=self.events, hrf_model=hrf_model, drift_model=drift_model, high_pass=high_pass, add_regs=self.regressors) return self def fit(self): self.glm.fit(self.img, design_matrices=self.design) return self def extract_params(self, param_type, contrast_ix=0): design = self.glm.design_matrices_[0] contrast = np.zeros(design.shape[1]) contrast[contrast_ix] = 1 if param_type == 'beta': param_img = self.glm.compute_contrast(contrast, output_type='effect_size') reg_sd = np.std(design.iloc[:, contrast_ix]) param_img = math_img("img * {}".format(reg_sd), img=param_img) elif param_type == 't': param_img = self.glm.compute_contrast(contrast, stat_type='t', output_type='stat') else: param_img = self.glm.compute_contrast(contrast, output_type=param_type) return param_img
def test_first_level_model_contrast_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 10),) mask, FUNCFILE, _ = _write_fake_fmri_data(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=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 assert_raises(ValueError, model.compute_contrast, c1) # fit model model = model.fit([func_img, func_img], [events, events]) # 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 assert_raises(ValueError, model.compute_contrast, cnull) assert_raises(ValueError, model.compute_contrast, [cnull, cnull]) # passing wrong parameters assert_raises(ValueError, model.compute_contrast, []) assert_raises(ValueError, model.compute_contrast, [c1, []]) assert_raises(ValueError, model.compute_contrast, c1, '', '') assert_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
def sub_tcontrasts3(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, sub_outdir): """Uses nistats first-level model to create maps of beta values that 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: ---------- id: string (subject's dccid) 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) fmridir: 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) """ # Model 1: encoding vs control conditions events3 = all_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 model3 = FirstLevelModel(t_r=tr, drift_model=None, standardize=True, noise_model='ar1', hrf_model=hrf_model) # Should data be standardized? # create the design matrices design3 = make_first_level_design_matrix(frame_times, events=events3, drift_model=None, add_regs=confounds, hrf_model=hrf_model) # fit model with design matrix model3 = model3.fit(fmri_img, design_matrices=design3) design_matrix3 = model3.design_matrices_[0] # Condition order: control, correct source, missed, wrong source (alphabetical) #contrast 3.1: wrong source ws_vec = np.repeat(0, design_matrix3.shape[1]) ws_vec[3] = 1 b31_map = model3.compute_contrast( ws_vec, output_type='effect_size') #"effect_size" for betas b31_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_ws.nii') nibabel.save(b31_map, b31_name) #contrast 3.2: correct source cs_vec = np.repeat(0, design_matrix3.shape[1]) cs_vec[1] = 1 b32_map = model3.compute_contrast( cs_vec, output_type='effect_size') #"effect_size" for betas b32_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_cs.nii') nibabel.save(b32_map, b32_name) #contrast 3.3: correct source minus wrong source cs_minus_ws_vec = np.repeat(0, design_matrix3.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_cs_minus_ws.nii') nibabel.save(b33_map, b33_name) #contrast 3.4: correct source minus miss cs_minus_miss_vec = np.repeat(0, design_matrix3.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_cs_minus_miss.nii') nibabel.save(b34_map, b34_name) #contrast 3.5: wrong source minus miss ws_minus_miss_vec = np.repeat(0, design_matrix3.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_ws_minus_miss.nii') nibabel.save(b35_map, b35_name) #contrast 3.6: correct source minus control cs_minus_ctl_vec = np.repeat(0, design_matrix3.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_cs_minus_ctl.nii') nibabel.save(b36_map, b36_name) #contrast 3.7: wrong source minus control ws_minus_ctl_vec = np.repeat(0, design_matrix3.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_ws_minus_ctl.nii') nibabel.save(b37_map, b37_name) return
def get_subject_betas(id, confounds, all_events, fmridir, outdir): """Uses nistats first-level model to create and export maps of beta values for a single subject, using events and confounds dataframes as parameters. The nistats.first_level_model is an interface to use the glm implemented in nistats.regression Parameters: ---------- id: string (subject's dccid) confounds: pandas dataframe (motion and other noise regressors) all_events: string (task information: trials' onset time, duration and label) fmridir: string (path to directory with fMRI data) outdir: string (path to output directory) Return: ---------- None (beta maps are exported in outdir) """ #Create output directory for subject's images sub_outdir = os.path.join(outdir, str(id)) if not os.path.exists(sub_outdir): os.mkdir(sub_outdir) trial_outdir = os.path.join(sub_outdir, 'TrialContrasts') if not os.path.exists(trial_outdir): os.mkdir(trial_outdir) scanfile = glob.glob(os.path.join(fmridir, 'fmri_sub' + id + '*nii')) if len(scanfile) == 0: print('fMRI data file missing for participant ' + id) return elif len(scanfile) < 0: print('multiple fMRI data files for participant ' + id) return else: # Apply 8mm smoothing since using unsmoothed preprocessed data # (from NIAK's 'resample' output directory) fmri_imgNS = scanfile[0] fmri_img = image.smooth_img(fmri_imgNS, 8) tr = 2.5 # CIMAQ fMRI = 2.5s TRs n_scans = confounds.shape[0] #number of frames frame_times = np.arange(n_scans) * tr # corresponding frame times hrf_model = 'spm' # alternatives: 'glover' or 'spm + derivative' # 117 trials if full scan (no missing frames) numTrials = all_events.shape[0] # Home-made concatenation, as backup # Compile temporally ordered list of betas (per trial) all_betas_filelist = [] # Create a design matrix, first level model and beta map for # each encoding and control trial # Slow drift modelled with NIAK preprocessing pipeline rather than Nistats for i in range(0, numTrials): # copy all_events dataframe to keep the original intact events = all_events.copy(deep=True) # Determine trial number and condition (encoding or control) tnum = events.iloc[i, 6] currentCondi = events.iloc[i, 3] tname = events.iloc[i, 2] #e.g., Enc3, CTL31 # modify trial_type column to model only the trial of interest for j in events.index: if events.loc[j, 'trial_number'] != tnum: events.loc[j, 'trial_type'] = 'X_' + events.loc[j, 'condition'] # X for condition to remain in alphabetical order: trial of interest, X_CTL, X_Enc # design matrix columns that correspond to task conditions are # ordered alphabetically (by name of condition) # remove unecessary columns cols = ['onset', 'duration', 'trial_type'] events = events[cols] # create the model trial_model = FirstLevelModel(t_r=tr, drift_model=None, standardize=True, noise_model='ar1', hrf_model=hrf_model) # Should data be standardized? # create the design matrix design = make_first_level_design_matrix(frame_times, events=events, drift_model=None, add_regs=confounds, hrf_model=hrf_model) # fit model with design matrix trial_model = trial_model.fit(fmri_img, design_matrices=design) design_matrix = trial_model.design_matrices_[0] # Contrast vector: 1 in design matrix column that corresponds to trial of interest, 0s elsewhere contrast_vec = np.repeat(0, design_matrix.shape[1]) contrast_vec[0] = 1 # compute the contrast's beta maps with the model.compute_contrast() method, # based on contrast provided. # https://nistats.github.io/modules/generated/nistats.first_level_model.FirstLevelModel.html b_map = trial_model.compute_contrast( contrast_vec, output_type='effect_size') #"effect_size" for betas b_name = os.path.join( trial_outdir, 'betas_sub' + str(id) + '_Trial' + str(tnum) + '_' + tname + '.nii') #export b_map .nii image in output directory nibabel.save(b_map, b_name) all_betas_filelist.append(b_name) alltrials_betas = nibabel.funcs.concat_images( images=all_betas_filelist, check_affines=True, axis=None) print(alltrials_betas.shape) nibabel.save( alltrials_betas, os.path.join(sub_outdir, 'concat_all_betas_sub' + str(id) + '.nii')) #Create subdirectory to save task contasts tc_outdir = os.path.join(sub_outdir, 'TaskContrasts') if not os.path.exists(tc_outdir): os.mkdir(tc_outdir) #Create beta maps for task contrasts #Encoding & control task sub_tcontrasts1(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, tc_outdir) #Control, hit and miss sub_tcontrasts2(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, tc_outdir) #Control, miss, wrong source and correct source sub_tcontrasts3(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, tc_outdir) return
def sub_tcontrasts1(id, tr, frame_times, hrf_model, confounds, all_events, fmri_img, sub_outdir): """Uses nistats first-level model to create maps of beta values that correspond to the following contrasts between conditions: control, encoding, and encoding_minus_control Parameters: ---------- id: string (subject's dccid) 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) fmridir: 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) """ # Model 1: encoding vs control conditions events1 = all_events.copy(deep=True) cols = ['onset', 'duration', 'condition'] events1 = events1[cols] events1.rename(columns={'condition': 'trial_type'}, inplace=True) # create the model model1 = FirstLevelModel(t_r=tr, drift_model=None, standardize=True, noise_model='ar1', hrf_model=hrf_model) # Should data be standardized? # create the design matrices design1 = make_first_level_design_matrix(frame_times, events=events1, drift_model=None, add_regs=confounds, hrf_model=hrf_model) # fit model with design matrix model1 = model1.fit(fmri_img, design_matrices=design1) design_matrix1 = model1.design_matrices_[0] # Condition order: control, encoding (alphabetical) # contrast 1.1: control condition ctl_vec = np.repeat(0, design_matrix1.shape[1]) ctl_vec[0] = 1 b11_map = model1.compute_contrast( ctl_vec, output_type='effect_size') #"effect_size" for betas b11_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_ctl.nii') nibabel.save(b11_map, b11_name) #contrast 1.2: encoding condition enc_vec = np.repeat(0, design_matrix1.shape[1]) enc_vec[1] = 1 b12_map = model1.compute_contrast( enc_vec, output_type='effect_size') #"effect_size" for betas b12_name = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_enc.nii') nibabel.save(b12_map, b12_name) #contrast 1.3: encoding minus control encMinCtl_vec = np.repeat(0, design_matrix1.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 = os.path.join(sub_outdir, 'betas_sub' + str(id) + '_enc_minus_ctl.nii') nibabel.save(b13_map, b13_name) return
def main(subject, sourcedata, derivatives): source_layout = BIDSLayout(sourcedata, validate=False, derivatives=False) fmriprep_layout = BIDSLayout(op.join(derivatives, 'fmriprep'), validate=False) bold = fmriprep_layout.get( subject=subject, suffix='bold', description='preproc', extension='nii.gz', ) bold = sorted([e for e in bold if 'MNI' in e.filename], key=lambda x: x.run) reg = re.compile('.*_space-(?P<space>.+)_desc.*') fmriprep_layout_df = fmriprep_layout.to_df() fmriprep_layout_df = fmriprep_layout_df[~fmriprep_layout_df.subject.isnull( )] fmriprep_layout_df['subject'] = fmriprep_layout_df.subject.astype(int) fmriprep_layout_df = fmriprep_layout_df[np.in1d( fmriprep_layout_df.suffix, ['bold', 'regressors', 'mask'])] fmriprep_layout_df = fmriprep_layout_df[np.in1d( fmriprep_layout_df.extension, ['nii.gz', 'tsv'])] fmriprep_layout_df['space'] = fmriprep_layout_df.path.apply( lambda path: reg.match(path).group(1) if reg.match(path) else None) fmriprep_layout_df = fmriprep_layout_df.set_index( ['subject', 'run', 'suffix', 'space']) events_df = source_layout.to_df() events_df = events_df[events_df.suffix == 'events'] events_df['subject'] = events_df['subject'].astype(int) events_df = events_df.set_index(['subject', 'run']) tr = source_layout.get_tr(bold[0].path) for b in bold: run = b.entities['run'] print(run) confounds_ = fmriprep_layout_df.loc[(subject, run, 'regressors'), 'path'].iloc[0] confounds_ = pd.read_csv(confounds_, sep='\t') confounds_ = confounds_[to_include].fillna(method='bfill') events_ = events_df.loc[(subject, run), 'path'] events_ = pd.read_csv(events_, sep='\t') events_['trial_type'] = events_['trial_type'].apply( lambda x: 'stim2' if x.startswith('stim2') else x) model = FirstLevelModel(tr, drift_model=None, n_jobs=5, smoothing_fwhm=4.0) pca = PCA(n_components=7) confounds_ -= confounds_.mean(0) confounds_ /= confounds_.std(0) confounds_pca = pca.fit_transform(confounds_[to_include]) events_['onset'] += tr model.fit(b.path, events_, confounds_pca) base_dir = op.join(derivatives, 'glm_stim1', f'sub-{subject}', 'func') if not op.exists(base_dir): os.makedirs(base_dir) # PE ims = [] for stim in 5, 7, 10, 14, 20, 28: im = model.compute_contrast(f'stim1-{stim}', output_type='effect_size') ims.append(im) ims = image.concat_imgs(ims) ims.to_filename( op.join(base_dir, f'sub-{subject}_run-{run}_desc-stims1_pe.nii.gz')) # zmap ims = [] for stim in 5, 7, 10, 14, 20, 28: im = model.compute_contrast(f'stim1-{stim}', output_type='z_score') ims.append(im) ims = image.concat_imgs(ims) ims.to_filename( op.join(base_dir, f'sub-{subject}_run-{run}_desc-stims1_zmap.nii.gz'))
contrasts["calculvideo"] + contrasts["phrasevideo"] contrasts["computation"] = contrasts["calculaudio"] + contrasts["calculvideo"] contrasts["sentences"] = contrasts["phraseaudio"] + contrasts["phrasevideo"] ######################################################################### # Short list of more relevant contrasts contrasts = { "left-right": (contrasts["clicGaudio"] + contrasts["clicGvideo"] - contrasts["clicDaudio"] - contrasts["clicDvideo"]), "H-V": contrasts["damier_H"] - contrasts["damier_V"], "audio-video": contrasts["audio"] - contrasts["video"], "video-audio": -contrasts["audio"] + contrasts["video"], "computation-sentences": (contrasts["computation"] - contrasts["sentences"]), "reading-visual": contrasts["phrasevideo"] - contrasts["damier_H"] } ######################################################################### # contrast estimation for index, (contrast_id, contrast_val) in enumerate(contrasts.items()): print(' Contrast % 2i out of %i: %s' % (index + 1, len(contrasts), contrast_id)) z_map = first_level_model.compute_contrast(contrast_val, output_type='z_score') # Create snapshots of the contrasts display = plotting.plot_stat_map(z_map, display_mode='z', threshold=3.0, title=contrast_id) plotting.show()
add_reg_names=add_reg_names) # define contrast print("Defining the seed contrast") dmn_contrast = np.array([1] + [0]*(design_matrix.shape[1]-1)) contrasts = {'seed_based_glm': dmn_contrast} # fit the GLM print("Fitting the second GLM to extract the network of the seed...") glm = FirstLevelModel(t_r=tr, slice_time_ref=0.5, noise_model='ar1', standardize=False) glm.fit(run_imgs=fmri_img, design_matrices=design_matrix) # compute z_map for the given contrast print("Computing the contrast...") z_map = glm.compute_contrast(contrasts['seed_based_glm'], output_type='z_score') ######################################################################### # Saving output map_path = os.path.join(glm_output_dir, 'seed_based_glm.nii.gz') print("Saving the zmap...") z_map.to_filename(map_path) display = niplt.plot_stat_map(z_map, threshold=3.0, cut_coords=pcc_coords) display.add_markers(marker_coords=[pcc_coords], marker_color='g', marker_size=300) display.savefig(os.path.join(glm_output_dir, 'seed_based_glm.png')) stats_report_filename = os.path.join(subject_data.reports_output_dir, "report_stats.html") print("Creating the subject html report...")
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] } print('Computing contrasts...') for index, (contrast_id, contrast_val) in enumerate(contrasts.items()): print(' Contrast % 2i out of %i: %s' % (index + 1, len(contrasts), contrast_id)) z_image_path = path.join(write_dir, '%s_z_map.nii' % contrast_id) z_map = fmri_glm.compute_contrast(contrast_val, output_type='z_score') nib.save(z_map, z_image_path) # make a snapshot of the contrast activation if contrast_id == 'Effects_of_interest': display = plotting.plot_stat_map(z_map, bg_img=mean_img_, threshold=2.5, title=contrast_id) display.savefig(path.join(write_dir, '%s_z_map.png' % contrast_id)) print('All the results were witten in %s' % write_dir) plotting.show()
masks = [f.replace('preproc_bold', 'brain_mask') for f in funcs] events = sorted(glob(f'../{sub}/ses-*/func/*task-face*events.tsv')) cols = ['rot_x', 'rot_y', 'rot_z', 'trans_x', 'trans_y', 'trans_z'] confs = [pd.read_csv(c, sep='\t').loc[:, cols] for c in confs] events = [pd.read_csv(e, sep='\t').drop('trial_type', axis=1).rename({'expression': 'trial_type'}, axis=1) for e in events] events = [e.loc[~e['trial_type'].isna(), :] for e in events] print(events) mask = masking.intersect_masks(masks, threshold=1) flm = FirstLevelModel( t_r=0.7, slice_time_ref=0.5, hrf_model='glover', drift_model='cosine', high_pass=0.01, noise_model='ols', mask_img=mask, verbose=True, smoothing_fwhm=4, n_jobs=10 ) flm.fit(funcs, confounds=confs, events=events) con = flm.compute_contrast('smiling - neutral') #roi = image.resample_to_img(roi, con, interpolation='nearest') con.to_filename(f'../derivatives/{sub}_smilingGTneutral.nii.gz') #R.append(con) #R = image.concat_imgs(R) #R.to_filename('../derivatives/maleGTfemale.nii.gz')
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} ######################################################################### # 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) ######################################################################### # contrast estimation 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))
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 nistats.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 is 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 now 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 # subject). We use arbitrarily a threshold of 3.0 in z-scale. We'll
def test_first_level_model_contrast_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 10), ) mask, FUNCFILE, _ = _write_fake_fmri_data(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]) # 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
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 nistats.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 is 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 now 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
# Imports for GLM, the sepcify, then fit. from nistats.first_level_model import FirstLevelModel print('Fitting a GLM') fmri_glm = FirstLevelModel() fmri_glm = fmri_glm.fit(fmri_img, design_matrices=design_matrices) ######################################################################### # 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 overlayed 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) ######################################################################### # Show 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 # "scambled" involves sparser, more anterior and lateral regions. It # displays also some responses in the frontal lobe.
def main(sourcedata, derivatives, subject, session, tmp_dir): sourcedata_layout = BIDSLayout(sourcedata) sourcedata_df = sourcedata_layout.as_data_frame() events = sourcedata_df[(sourcedata_df['type'] == 'events') & (sourcedata_df['subject'] == subject) & (sourcedata_df['session'] == session)] derivatives_layout = BIDSLayout(os.path.join(derivatives, 'spynoza')) derivatives_df = derivatives_layout.as_data_frame() bold = derivatives_df[(derivatives_df['type'] == 'preproc') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] mask = derivatives_layout.get(subject=subject, session=session, type='mask', return_type='file')[0] mask = image.math_img('(im > .5).astype(int)', im=mask) print(mask) df = events.merge(bold, on=['subject', 'session', 'run'], suffixes=('_events', '_bold')) models = [] for ix, row in df.iterrows(): results_dir = os.path.join(derivatives, 'modelfitting', 'sub-{}'.format(row['subject'])) if 'session' in row: results_dir = os.path.join(results_dir, 'ses-{}'.format(row['session'])) os.makedirs(results_dir, exist_ok=True) print('Fitting {}'.format(row['path_bold'])) model = FirstLevelModel(t_r=4, mask=mask) paradigm = pd.read_table(row['path_events']) paradigm_short = paradigm.copy() paradigm_short['duration'] = 1 paradigm_short['trial_type'] = paradigm_short['trial_type'].map( lambda x: '{}_instant'.format(x)) paradigm = pd.concat((paradigm, paradigm_short)) model.fit(row['path_bold'], paradigm) left_right = model.compute_contrast('eye_L - eye_R', output_type='z_score') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session'], row['run']))) left_right = model.compute_contrast('eye_L - eye_R', output_type='effect_size') left_right.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_left_over_right_psc.nii.gz'.format( row['subject'], row['session'], row['run']))) eye_l_instant = model.compute_contrast('eye_L_instant', output_type='z_score') eye_l_instant.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_eye_l_instant_zmap.nii.gz'.format( row['subject'], row['session'], row['run']))) eye_l_instant = model.compute_contrast('eye_L_instant', output_type='effect_size') eye_l_instant.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_eye_l_instant_effect_size.nii.gz'.format( row['subject'], row['session'], row['run']))) eye_r_instant = model.compute_contrast('eye_R_instant', output_type='z_score') eye_r_instant.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_eye_r_instant_zmap.nii.gz'.format( row['subject'], row['session'], row['run']))) eye_r_instant = model.compute_contrast('eye_R_instant', output_type='effect_size') eye_r_instant.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_run-{}_eye_R_instant_effect_size.nii.gz'.format( row['subject'], row['session'], row['run']))) models.append(model) second_level_model = SecondLevelModel(mask=mask) second_level_model.fit(models) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye_L - eye_R', output_type='z_score') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session']))) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye_L - eye_R', output_type='effect_size') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_effect_size.nii.gz'.format( row['subject'], row['session'])))
def main(sourcedata, derivatives, subject, session, tmp_dir): sourcedata_layout = BIDSLayout(sourcedata) sourcedata_df = sourcedata_layout.as_data_frame() events = sourcedata_df[(sourcedata_df['suffix'] == 'events') & (sourcedata_df['subject'] == subject) & (sourcedata_df['session'] == session)] derivatives_layout = BIDSLayout(os.path.join(derivatives), validate=False) derivatives_df = derivatives_layout.as_data_frame() bold = derivatives_df[(derivatives_df['suffix'] == 'preproc') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] confounds = derivatives_df[(derivatives_df['suffix'] == 'confounds') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] compcor = derivatives_df[(derivatives_df['suffix'] == 'compcor') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)] mask = derivatives_layout.get(subject=subject, session=session, suffix='mask', return_type='file')[0] df = events.merge(bold, on=['subject', 'session', 'run'], suffixes=('_events', '_bold')) confounds = confounds.rename(columns={'path': 'confounds'}) df = df.merge(confounds[['subject', 'session', 'run', 'confounds']]) compcor = compcor.rename(columns={'path': 'compcor'}) df = df.merge(compcor[['subject', 'session', 'run', 'compcor']]) df.sort_values('run', inplace=True) print(df.iloc[0]) models = [] for ix, row in df.iterrows(): results_dir = os.path.join(derivatives, 'modelfitting', 'glm8', 'sub-{}'.format(row['subject'])) if 'session' in row: results_dir = os.path.join(results_dir, 'ses-{}'.format(row['session'])) results_dir = op.join(results_dir, 'func') os.makedirs(results_dir, exist_ok=True) confounds = pd.read_table(row.confounds).fillna(method='bfill') compcor = pd.read_table(row.compcor).fillna(method='bfill') confounds = pd.concat((confounds, compcor), 1) confounds -= confounds.mean() confounds /= confounds.std() pca = decomposition.PCA(n_components=6) confounds_trans = pd.DataFrame( pca.fit_transform(confounds), columns=['pca_{}'.format(i) for i in range(6)]) print('Fitting {}'.format(row['path_bold'])) model = FirstLevelModel(t_r=4, signal_scaling=False, subject_label=int(row['run']), mask_img=mask) paradigm = pd.read_table(row['path_events']) paradigm_ = paradigm.copy() paradigm['trial_type'] = 'stimulation' paradigm['modulation'] = 1 paradigm_['modulation'] = paradigm_.trial_type.map({ 'eye_L': 1, 'eye_R': -1 }) paradigm_['trial_type'] = 'eye' paradigm = pd.concat((paradigm, paradigm_), ignore_index=True) model.fit(row['path_bold'], paradigm, confounds=confounds_trans) row['run'] = int(row['run']) row = dict(row) left_right = model.compute_contrast('eye', output_type='z_score') left_right.to_filename( os.path.join( results_dir, 'sub-{subject}_ses-{session}_task-{task_events}_run-{run:02d}_left_over_right_zmap.nii.gz' .format(**row))) left_right = model.compute_contrast('eye', output_type='effect_size') left_right.to_filename( os.path.join( results_dir, 'sub-{subject}_ses-{session}_task-{task_events}_run-{run:02d}_left_over_right_psc.nii.gz' .format(**row))) stimulation = model.compute_contrast('stimulation', output_type='effect_size') stimulation.to_filename( os.path.join( results_dir, 'sub-{subject}_ses-{session}_task-{task_events}_run-{run:02d}_stimulation_psc.nii.gz' .format(**row))) stimulation = model.compute_contrast('stimulation', output_type='z_score') stimulation.to_filename( os.path.join( results_dir, 'sub-{subject}_ses-{session}_task-{task_events}_run-{run:02d}_stimulation_zmap.nii.gz' .format(**row))) models.append(model) second_level_model = SecondLevelModel(mask_img=mask) second_level_model.fit(models) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye', output_type='z_score') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_zmap.nii.gz'.format( row['subject'], row['session']))) left_right_group = second_level_model.compute_contrast( first_level_contrast='eye', output_type='effect_size') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_left_over_right_effect_size.nii.gz'.format( row['subject'], row['session']))) stimulation_group = second_level_model.compute_contrast( first_level_contrast='stimulation', output_type='z_score') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_stimulation_zmap.nii.gz'.format( row['subject'], row['session']))) stimulation_group = second_level_model.compute_contrast( first_level_contrast='stimulation', output_type='effect_size') left_right_group.to_filename( os.path.join( results_dir, 'sub-{}_ses-{}_stimulation_effect_size.nii.gz'.format( row['subject'], row['session'])))
plot_contrast(first_level_model) plt.show() ######################################################################### # Not a huge effect, but rather positive overall. We could keep that one. # # Bzw, a benefit of this approach is that we can test which voxels are # well explined by the derivative term, hinting at misfit regions, a # possibly valuable information This is implemented by an F test on # the time derivative regressors. contrast_val = np.eye(design_matrix.shape[1])[1:21:2] plot_contrast_matrix(contrast_val, design_matrix) plt.show() z_map = first_level_model.compute_contrast( contrast_val, output_type='z_score') plotting.plot_stat_map( z_map, display_mode='z', threshold=3.0, title='effect of time derivatives') plt.show() ######################################################################### # Well, there seems to be something here. Maybe we could adjust the # timing, by increasing the slice_time_ref parameter: 0 to 0.5 now the # reference for model sampling is not the beginning of the volume # acquisition, but the middle of it. first_level_model = FirstLevelModel(t_r, hrf_model='spm + derivative', slice_time_ref=0.5) first_level_model = first_level_model.fit(fmri_img, events=events) z_map = first_level_model.compute_contrast( contrast_val, output_type='z_score') plotting.plot_stat_map(