def run_surface_glm(dmtx, contrasts, fmri_path, subject_session_output_dir): """ """ from nibabel.gifti import read, write, GiftiDataArray, GiftiImage from nistats.first_level_model import run_glm from nistats.contrasts import compute_contrast Y = np.array([darrays.data for darrays in read(fmri_path).darrays]) labels, res = run_glm(Y, dmtx) # Estimate the contrasts print('Computing contrasts...') side = fmri_path[-6:-4] for index, contrast_id in enumerate(contrasts): print(' Contrast % i out of %i: %s' % (index + 1, len(contrasts), contrast_id)) # compute contrasts con_ = contrasts[contrast_id] contrast_ = compute_contrast(labels, res, con_) stats = [ contrast_.z_score(), contrast_.stat_, contrast_.effect, contrast_.variance ] for map_type, out_map in zip(['z', 't', 'effects', 'variance'], stats): map_dir = os.path.join(subject_session_output_dir, '%s_surf' % map_type) if not os.path.exists(map_dir): os.makedirs(map_dir) map_path = os.path.join(map_dir, '%s_%s.gii' % (contrast_id, side)) print("\t\tWriting %s ..." % map_path) tex = GiftiImage(darrays=[ GiftiDataArray().from_array(out_map, intent='t test') ]) write(tex, map_path)
def compute_rfx_contrast(imgs, design_matrix, contrast_def, mask=None, noise_model='ols', stat_type='t', output_type='z_score'): design_info = DesignInfo(design_matrix.columns.tolist()) if isinstance(imgs, list): Y = np.stack([i.get_data() for i in imgs]).reshape(len(imgs), -1) elif isinstance(imgs, np.ndarray): Y = imgs else: raise ValueError(f"Unknown format for Y ({type(imgs)}).") X = design_matrix.values labels, results = run_glm(Y, X, noise_model=noise_model) if isinstance(contrast_def, (np.ndarray, str)): con_vals = [contrast_def] elif isinstance(contrast_def, (list, tuple)): con_vals = contrast_def else: raise ValueError('contrast_def must be an array or str or list of' ' (array or str)') for cidx, con in enumerate(con_vals): if not isinstance(con, np.ndarray): con_vals[cidx] = design_info.linear_constraint(con).coefs contrast = compute_contrast(labels, results, con_vals, stat_type) values = getattr(contrast, output_type)() if isinstance(imgs, list): values = nib.Nifti1Image(values.reshape(imgs[0].shape), affine=imgs[0].affine) return values
def test_Tcontrast(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) labels, results = run_glm(Y, X, 'ar1') con_val = np.eye(q)[0] z_vals = compute_contrast(labels, results, con_val).z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_fixed_effect_contrast(): n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ols') c1, c2 = np.eye(q)[0], np.eye(q)[1] con = _compute_fixed_effect_contrast([lab, lab], [res, res], [c1, c2]) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_fixed_effect_contrast(): n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ols') c1, c2 = np.eye(q)[0], np.eye(q)[1] con = _fixed_effect_contrast([lab, lab], [res, res], [c1, c2]) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_Tcontrast(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) labels, results = run_glm(Y, X, 'ar1') con_val = np.eye(q)[0] z_vals = compute_contrast(labels, results, con_val).z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_t_contrast_add(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ols') c1, c2 = np.eye(q)[0], np.eye(q)[1] con = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c2) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_t_contrast_add(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ols') c1, c2 = np.eye(q)[0], np.eye(q)[1] con = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c2) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_Fcontrast(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) for model in ['ols', 'ar1']: labels, results = run_glm(Y, X, model) for con_val in [np.eye(q)[0], np.eye(q)[:3]]: z_vals = compute_contrast( labels, results, con_val, contrast_type='F').z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_Fcontrast(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) for model in ['ols', 'ar1']: labels, results = run_glm(Y, X, model) for con_val in [np.eye(q)[0], np.eye(q)[:3]]: z_vals = compute_contrast( labels, results, con_val, contrast_type='F').z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0)
def test_contrast_mul(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1') for c1 in [np.eye(q)[0], np.eye(q)[:3]]: con1 = compute_contrast(lab, res, c1) con2 = con1 * 2 assert_almost_equal(con1.effect * 2, con2.effect) # assert_almost_equal(con1.variance * 2, con2.variance) FIXME # assert_almost_equal(con1.stat() * 2, con2.stat()) FIXME assert_almost_equal(con1.z_score(), con2.z_score())
def test_contrast_mul(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1') for c1 in [np.eye(q)[0], np.eye(q)[:3]]: con1 = compute_contrast(lab, res, c1) con2 = con1 * 2 assert_almost_equal(con1.effect * 2, con2.effect) # assert_almost_equal(con1.variance * 2, con2.variance) FIXME # assert_almost_equal(con1.stat() * 2, con2.stat()) FIXME assert_almost_equal(con1.z_score(), con2.z_score())
def test_fixed_effect_contrast_nonzero_effect(): X, y = make_regression(n_features=5, n_samples=20, random_state=0) y = y[:, None] labels, results = run_glm(y, X, 'ols') coef = LinearRegression(fit_intercept=False).fit(X, y).coef_ for i in range(X.shape[1]): contrast = np.zeros(X.shape[1]) contrast[i] = 1. fixed_effect = _compute_fixed_effect_contrast([labels], [results], [contrast]) assert_almost_equal(fixed_effect.effect_size(), coef.ravel()[i]) fixed_effect = _compute_fixed_effect_contrast( [labels] * 3, [results] * 3, [contrast] * 3) assert_almost_equal(fixed_effect.effect_size(), coef.ravel()[i])
def test_run_glm(): # New API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) # Ordinary Least Squares case labels, results = run_glm(Y, X, 'ols') assert_array_equal(labels, np.zeros(n)) assert_equal(list(results.keys()), [0.0]) assert_equal(results[0.0].theta.shape, (q, n)) assert_almost_equal(results[0.0].theta.mean(), 0, 1) assert_almost_equal(results[0.0].theta.var(), 1. / p, 1) # ar(1) case labels, results = run_glm(Y, X, 'ar1') assert_equal(len(labels), n) assert_true(len(results.keys()) > 1) tmp = sum([val.theta.shape[1] for val in results.values()]) assert_equal(tmp, n) # non-existant case assert_raises(ValueError, run_glm, Y, X, 'ar2') assert_raises(ValueError, run_glm, Y, X.T)
def test_run_glm(): # New API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) # ols case labels, results = run_glm(Y, X, 'ols') assert_array_equal(labels, np.zeros(n)) assert_equal(list(results.keys()), [0.0]) assert_equal(results[0.0].theta.shape, (q, n)) assert_almost_equal(results[0.0].theta.mean(), 0, 1) assert_almost_equal(results[0.0].theta.var(), 1. / p, 1) # ar(1) case labels, results = run_glm(Y, X, 'ar1') assert_equal(len(labels), n) assert_true(len(results.keys()) > 1) tmp = sum([val.theta.shape[1] for val in results.values()]) assert_equal(tmp, n) # non-existant case assert_raises(ValueError, run_glm, Y, X, 'ar2') assert_raises(ValueError, run_glm, Y, X.T)
def preprocess_varpar(num, subj, subj_dir, **kwargs): from nistats.design_matrix import make_design_matrix from nistats.first_level_model import run_glm bold_path = 'BOLD/task001_run00%i/bold_dico_bold7Tp1_to_subjbold7Tp1.nii.gz' % (num+1) bold_path = os.path.join(DATA_DIR, subj, bold_path) mask = os.path.join(DATA_DIR, subj, 'templates', 'bold7Tp1', 'brain_mask.nii.gz') bold = load(bold_path) masker = NiftiMasker(mask) data = masker.fit_transform(bold) dmat = make_design_matrix(np.arange(data.shape[0])*TR, hrf_model='fir', drift_order=5, **kwargs) labels, results = run_glm(data, dmat, noise_model='ols', verbose=1) img = masker.inverse_transform(StandardScaler().fit_transform(results[0.0].resid)) # return StandardScaler().fit_transform(results[0.0].resid) save(img, os.path.join(subj_dir, 'run00%i.nii.gz' % num))
def test_second_level_model_glm_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 1),) mask, FUNCFILE, _ = write_fake_fmri_data(shapes) FUNCFILE = FUNCFILE[0] func_img = load(FUNCFILE) # ols case model = SecondLevelModel(mask=mask) Y = [func_img] * 4 X = pd.DataFrame([[1]] * 4) model = model.fit(Y, design_matrix=X) labels1 = model.labels_ results1 = model.results_ labels2, results2 = run_glm(model.masker_.transform(Y), X, 'ols') assert_almost_equal(labels1, labels2, decimal=1) assert_equal(len(results1), len(results2))
def test_F_contrast_add(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1') c1, c2 = np.eye(q)[:2], np.eye(q)[2:4] con = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c2) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0) # first test with dependent contrast con1 = compute_contrast(lab, res, c1) con2 = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c1) assert_almost_equal(con1.effect * 2, con2.effect) assert_almost_equal(con1.variance * 2, con2.variance) assert_almost_equal(con1.stat() * 2, con2.stat())
def test_F_contrast_add(): # new API n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1') c1, c2 = np.eye(q)[:2], np.eye(q)[2:4] con = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c2) z_vals = con.z_score() assert_almost_equal(z_vals.mean(), 0, 0) assert_almost_equal(z_vals.std(), 1, 0) # first test with dependent contrast con1 = compute_contrast(lab, res, c1) con2 = compute_contrast(lab, res, c1) + compute_contrast(lab, res, c1) assert_almost_equal(con1.effect * 2, con2.effect) assert_almost_equal(con1.variance * 2, con2.variance) assert_almost_equal(con1.stat() * 2, con2.stat())
def test_contrast_values(): # new API # but this test is circular and should be removed n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1', bins=1) # t test cval = np.eye(q)[0] con = compute_contrast(lab, res, cval) t_ref = list(res.values())[0].Tcontrast(cval).t assert_almost_equal(np.ravel(con.stat()), t_ref) # F test cval = np.eye(q)[:3] con = compute_contrast(lab, res, cval) F_ref = list(res.values())[0].Fcontrast(cval).F # Note that the values are not strictly equal, # this seems to be related to a bug in Mahalanobis assert_almost_equal(np.ravel(con.stat()), F_ref, 3)
def test_contrast_values(): # new API # but this test is circular and should be removed n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) lab, res = run_glm(Y, X, 'ar1', bins=1) # t test cval = np.eye(q)[0] con = compute_contrast(lab, res, cval) t_ref = list(res.values())[0].Tcontrast(cval).t assert_almost_equal(np.ravel(con.stat()), t_ref) # F test cval = np.eye(q)[:3] con = compute_contrast(lab, res, cval) F_ref = list(res.values())[0].Fcontrast(cval).F # Note that the values are not strictly equal, # this seems to be related to a bug in Mahalanobis assert_almost_equal(np.ravel(con.stat()), F_ref, 3)
def test_first_level_model_glm_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) model = model.fit(func_img, paradigm) labels1 = model.labels_[0] results1 = model.results_[0] labels2, results2 = run_glm( model.masker_.transform(func_img), model.design_matrices_[0].as_matrix(), 'ar1')
def test_second_level_model_glm_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 1),) mask, FUNCFILE, _ = _write_fake_fmri_data(shapes) FUNCFILE = FUNCFILE[0] func_img = load(FUNCFILE) # Ordinary Least Squares case model = SecondLevelModel(mask_img=mask) Y = [func_img] * 4 X = pd.DataFrame([[1]] * 4, columns=['intercept']) model = model.fit(Y, design_matrix=X) model.compute_contrast() labels1 = model.labels_ results1 = model.results_ labels2, results2 = run_glm( model.masker_.transform(Y), X.values, 'ols') assert_almost_equal(labels1, labels2, decimal=1) assert_equal(len(results1), len(results2)) # Delete objects attached to files to avoid WindowsError when deleting # temporary directory (in Windows) del func_img, FUNCFILE, model, X, Y
def test_second_level_model_glm_computation(): with InTemporaryDirectory(): shapes = ((7, 8, 9, 1), ) mask, FUNCFILE, _ = _write_fake_fmri_data(shapes) FUNCFILE = FUNCFILE[0] func_img = load(FUNCFILE) # Ordinary Least Squares case model = SecondLevelModel(mask_img=mask) Y = [func_img] * 4 X = pd.DataFrame([[1]] * 4, columns=['intercept']) model = model.fit(Y, design_matrix=X) model.compute_contrast() labels1 = model.labels_ results1 = model.results_ labels2, results2 = run_glm(model.masker_.transform(Y), X.values, 'ols') assert_almost_equal(labels1, labels2, decimal=1) assert_equal(len(results1), len(results2)) # Delete objects attached to files to avoid WindowsError when deleting # temporary directory (in Windows) del func_img, FUNCFILE, model, X, Y
def test_run_glm(): n, p, q = 100, 80, 10 X, Y = np.random.randn(p, q), np.random.randn(p, n) # Ordinary Least Squares case labels, results = run_glm(Y, X, 'ols') assert_array_equal(labels, np.zeros(n)) assert list(results.keys()) == [0.0] assert results[0.0].theta.shape == (q, n) assert_almost_equal(results[0.0].theta.mean(), 0, 1) assert_almost_equal(results[0.0].theta.var(), 1. / p, 1) # ar(1) case labels, results = run_glm(Y, X, 'ar1') assert len(labels) == n assert len(results.keys()) > 1 tmp = sum([val.theta.shape[1] for val in results.values()]) assert tmp == n # non-existant case with pytest.raises(ValueError): run_glm(Y, X, 'ar2') with pytest.raises(ValueError): run_glm(Y, X.T)
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, extension='func.gii') bold = sorted([e for e in bold if 'fsaverage6' 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, ['regressors'])] fmriprep_layout_df = fmriprep_layout_df[np.in1d( fmriprep_layout_df.extension, ['tsv'])] fmriprep_layout_df = fmriprep_layout_df.set_index( ['subject', 'run']) 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) base_dir = op.join(derivatives, 'glm_stim1_trialwise_surf', f'sub-{subject}', 'func') if not op.exists(base_dir): os.makedirs(base_dir) for b in bold: run = b.entities['run'] hemi = b.entities['suffix'] # print(run) confounds_ = fmriprep_layout_df.loc[( subject, run), '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) events_['onset'] += tr # Split up over trials stim1_events = events_[events_.trial_type.apply(lambda x: x.startswith('stim1'))] def number_trials(d): return pd.Series(['{}.{}'.format(e, i+1) for i, e in enumerate(d)], index=d.index) stim1_events['trial_type'] = stim1_events.groupby('trial_type').trial_type.apply(number_trials) events_.loc[stim1_events.index, 'trial_type'] = stim1_events['trial_type'] frametimes = np.arange(0, tr*len(confounds_), tr) pca = PCA(n_components=7) confounds_ -= confounds_.mean(0) confounds_ /= confounds_.std(0) confounds_pca = pca.fit_transform(confounds_[to_include]) X = make_first_level_design_matrix(frametimes, events_, add_regs=confounds_pca.values) Y = surface.load_surf_data(b.path).T Y = (Y / Y.mean(0) * 100) Y -= Y.mean(0) fit = run_glm(Y, X, noise_model='ols') r = fit[1][0.0] betas = pd.DataFrame(r.theta, index=X.columns) stim1 = [] for stim in 5, 7, 10, 14, 20, 28: for trial in range(1, 7): stim1.append(betas.loc[f'stim1-{stim}.{trial}']) result = pd.concat(stim1, 1).T pes = nb.gifti.GiftiImage(header=nb.load(b.path).header, darrays=[nb.gifti.GiftiDataArray(result)]) pes.to_filename( op.join(base_dir, f'sub-{subject}_run-{run}_desc-stims1_hemi-{hemi}.pe.gii'))
mask = pybest_dir + '/preproc/sub-02_ses-1_task-face_desc-preproc_mask.nii.gz' trials = sorted(glob(pybest_dir + '/best/*desc-trial*')) for i in range(len(trials)): trials[i] = image.clean_img(trials[i], detrend=False, standardize=True) Y = masking.apply_mask(image.concat_imgs(trials), mask) events = pybest_dir + '/preproc/sub-02_ses-1_task-face_desc-preproc_events.tsv' events = pd.read_csv(events, sep='\t').query("trial_type != 'rating' and trial_type != 'response'") events.loc[:, 'face_eth'] = ['asian' if 'sian' in s else s for s in events['face_eth']] events.loc[:, 'trial_type'] = [s[-7:] for s in events.loc[:, 'trial_type']] X = events.loc[:, ['subject_dominance', 'subject_trustworthiness', 'subject_attractiveness']] X /= X.mean(axis=0) X = pd.concat((X, pd.get_dummies(events.loc[:, 'trial_type'])), axis=1) X = pd.concat((X, pd.get_dummies(events.loc[:, 'face_eth'])), axis=1) labels, results = run_glm(Y, X.to_numpy(), noise_model='ols') for i in range(X.shape[1]): cvec = np.zeros(X.shape[1]) cvec[i] = 1 zscores = compute_contrast(labels, results, con_val=cvec, contrast_type='t').z_score() zscores = masking.unmask(zscores, mask) #zscores = image.smooth_img(zscores, fwhm=4) zscores.to_filename(f"{X.columns[i]}.nii.gz") data = np.zeros_like(labels) for lab in np.unique(labels): data[..., labels == lab] = getattr(results[lab], 'r_square')
def main(sourcedata, derivatives, subject, session): derivatives_layout = BIDSLayout(op.join(derivatives), validate=False) derivatives_df = derivatives_layout.as_data_frame() confounds = derivatives_df[(derivatives_df['suffix'] == 'confounds') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)].set_index(['subject', 'session', 'task', 'run']) compcor = derivatives_df[(derivatives_df['suffix'] == 'compcor') & (derivatives_df['subject'] == subject) & (derivatives_df['session'] == session)].set_index(['subject', 'session', 'task', 'run']) fns = glob.glob(op.join(derivatives, 'sampled_giis/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_*.gii'.format(**locals()))) # Events are the same for all subjects events = pd.read_table(op.join(sourcedata, 'sub-tk/ses-odc2/func/sub-tk_ses-odc2_task-checkerboard_acq-07_run-02_events.tsv')) df = pd.read_pickle(op.join(derivatives, 'depth_sampled_surfaces/sub-{subject}/sub-{subject}_ses-{session}_depth_sampled_data.pkl.gz'.format(**locals()))) print(df.head()) df = df.loc[:, 'psc'] df.index = df.index.droplevel('acq') frametimes = np.linspace(0, 66*4, 66, endpoint=False) X = make_first_level_design_matrix(frametimes, events, drift_order=None, drift_model=None) ts = [] for ix, d in df.loc[:, ['V1l', 'V1r']].groupby(['subject', 'session', 'task', 'run']): print(ix) conf = pd.read_table(confounds.loc[ix].path).fillna(method='bfill') comc = pd.read_table(compcor.loc[ix].path).fillna(method='bfill') conf = pd.concat((conf, comc), 1) conf -= conf.mean() conf /= conf.std() pca = decomposition.PCA(n_components=6) confounds_trans = pd.DataFrame(pca.fit_transform(conf), columns=['pca_{}'.format(i) for i in range(6)]) confounds_trans.index = X.index X_ = pd.concat((X, confounds_trans), axis=1) labels, results = run_glm(d, X, noise_model='ols') results = results[0.0] ts.append(pd.DataFrame([results.theta[0], results.theta[1], results.t(0), results.t(1)], index=pd.MultiIndex.from_product([[e] for e in ix] + [['psc', 't'], ['eye_L', 'eye_R']], names=['subject', 'session', 'task', 'run', 'type', 'contrast']), columns=d.columns)) ts = pd.concat(ts, axis=0) results_dir = op.join(derivatives, 'surfacewise_glms', 'sub-{subject}', 'ses-{session}', 'func').format(**locals()) if not op.exists(results_dir): os.makedirs(results_dir) ts.to_pickle(op.join(results_dir, 'sub-{subject}_ses-{session}_desc-laminarglms.pkl').format(**locals()))
# Specify the contrasts contrasts = make_localizer_contrasts(design_matrix) # plot_contrast_matrix(pd.DataFrame(contrasts), design_matrix) # plt.savefig(os.path.join(write_dir, 'contrasts.png')) for hemisphere in ['left', 'right']: effects = lh_effects if hemisphere == 'right': effects = rh_effects fmri_img = os.path.join( derivative_dir, 'wrr%s_%s_task-%s_bold.ico7.s5.%sh.gii' % (subject, session, task, hemisphere[0])) texture = np.array( [darrays.data for darrays in read(fmri_img).darrays]).T labels, res = run_glm(texture.T, design_matrix.values[:texture.shape[1]]) ####################################################################### # 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)) if subject_idx == 0: effects[contrast_id] = [] contrast_ = compute_contrast(labels, res, contrast_val) z_map = contrast_.z_score() effect = contrast_.effect effects[contrast_id].append(effect) # Create snapshots of the contrasts threshold = fdr_threshold(z_map, alpha=.05) out_file = os.path.join(
# We specify an hrf model containing Glover model and its time derivative # the drift model is implicitly a cosine basis with period cutoff 128s. design_matrix = make_first_level_design_matrix( frame_times, events=events[0], hrf_model='glover + derivative', add_regs=confound[0]) # contrast_specification contrast_values = (design_matrix.columns == 'language') * 1.0 -\ (design_matrix.columns == 'string') # Setup and fit GLM. # Note that the output consists in 2 variables: `labels` and `fit` # `labels` tags voxels according to noise autocorrelation. # `estimates` contains the parameter estimates. # We input them for contrast computation. labels, estimates = run_glm(texture.T, design_matrix.values) contrast = compute_contrast(labels, estimates, contrast_values, contrast_type='t') # we present the Z-transform of the t map z_score = contrast.z_score() z_scores_right.append(z_score) # Do the left hemipshere exactly in the same way texture = surface.vol_to_surf(fmri_img, fsaverage.pial_left) labels, estimates = run_glm(texture.T, design_matrix.values) contrast = compute_contrast(labels, estimates, contrast_values, contrast_type='t') z_scores_left.append(contrast.z_score()) ############################################################################ # Individual activation maps have been accumulated in the z_score_left
def first_level(subject_dic, additional_regressors=None, compcorr=False, smooth=None, surface=False, mask_img=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, whether confound estimation and removal should be done or not smooth: float or None, optional, how much the data should spatially smoothed during masking """ start_time = time.ctime() # experimental paradigm meta-params motion_names = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz'] hrf_model = subject_dic['hrf_model'] hfcut = subject_dic['hfcut'] drift_model = subject_dic['drift_model'] tr = subject_dic['TR'] if not surface and (mask_img is None): mask_img = masking(subject_dic['func'], subject_dic['output_dir']) if additional_regressors is None: additional_regressors = dict([ (session_id, None) for session_id in subject_dic['session_id'] ]) for session_id, fmri_path, onset, motion_path in zip( subject_dic['session_id'], subject_dic['func'], subject_dic['onset'], subject_dic['realignment_parameters']): paradigm_id = _session_id_to_task_id([session_id])[0] if surface: from nibabel.gifti import read n_scans = np.array( [darrays.data for darrays in read(fmri_path).darrays]).shape[0] else: 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) if paradigm_id == 'audio': mask = np.array([1, 0, 1, 1, 0, 1, 1, 0, 1, 1]) n_cycles = 28 cycle_duration = 20 t_r = 2 cycle = np.arange(0, cycle_duration, t_r)[mask > 0] frametimes = np.tile(cycle, n_cycles) +\ np.repeat(np.arange(n_cycles) * cycle_duration, mask.sum()) frametimes = frametimes[:-2] # for some reason... if surface: compcorr = False # XXX Fixme 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 else: confounds = motion confound_names = motion_names if onset is None: warnings.warn('Onset file not provided. Trying to guess it') task = os.path.basename(fmri_path).split('task')[-1][4:] onset = os.path.join( os.path.split(os.path.dirname(fmri_path))[0], 'model001', 'onsets', 'task' + task + '_run001', 'task%s.csv' % task) if not os.path.exists(onset): warnings.warn('non-existant onset file. proceeding without it') paradigm = None else: paradigm = make_paradigm(onset, paradigm_id) # handle manually supplied regressors add_reg_names = [] if additional_regressors[session_id] is None: add_regs = confounds else: df = read_csv(additional_regressors[session_id]) add_regs = [] for regressor in df: add_reg_names.append(regressor) add_regs.append(df[regressor]) add_regs = np.array(add_regs).T add_regs = np.hstack((add_regs, confounds)) add_reg_names += confound_names # create the design matrix design_matrix = make_first_level_design_matrix( frametimes, paradigm, hrf_model=hrf_model, drift_model=drift_model, period_cut=hfcut, add_regs=add_regs, add_reg_names=add_reg_names) _, dmtx, names = check_design_matrix(design_matrix) # create the relevant contrasts contrasts = make_contrasts(paradigm_id, names) if surface: subject_session_output_dir = os.path.join( subject_dic['output_dir'], 'res_surf_%s' % session_id) else: 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) np.savez(os.path.join(subject_session_output_dir, 'design_matrix.npz'), design_matrix=design_matrix) if surface: run_surface_glm(design_matrix, contrasts, fmri_path, subject_session_output_dir) else: z_maps = run_glm(design_matrix, contrasts, fmri_path, mask_img, subject_dic, subject_session_output_dir, tr=tr, smoothing_fwhm=smooth) # do stats report anat_img = nib.load(subject_dic['anat']) stats_report_filename = os.path.join(subject_session_output_dir, 'report_stats.html') generate_subject_stats_report( stats_report_filename, contrasts, z_maps, mask_img, threshold=3., cluster_th=15, anat=anat_img, anat_affine=anat_img.affine, design_matrices=[design_matrix], subject_id=subject_dic['subject_id'], start_time=start_time, title="GLM for subject %s" % session_id, # additional ``kwargs`` for more informative report TR=tr, n_scans=n_scans, hfcut=hfcut, frametimes=frametimes, drift_model=drift_model, hrf_model=hrf_model, ) if not surface: ProgressReport().finish_dir(subject_session_output_dir) print("Statistic report written to %s\r\n" % stats_report_filename)
def _run_interface(self, runtime): import nibabel as nb from nistats import first_level_model as level1 from nistats.contrasts import compute_contrast mat = pd.read_csv(self.inputs.design_matrix, delimiter='\t', index_col=0) img = nb.load(self.inputs.bold_file) is_cifti = isinstance(img, nb.Cifti2Image) if isinstance(img, nb.dataobj_images.DataobjImage): # Ugly hack to ensure that retrieved data isn't cast to float64 unless # necessary to prevent an overflow # For NIfTI-1 files, slope and inter are 32-bit floats, so this is # "safe". For NIfTI-2 (including CIFTI-2), these fields are 64-bit, # so include a check to make sure casting doesn't lose too much. slope32 = np.float32(img.dataobj._slope) inter32 = np.float32(img.dataobj._inter) if max(np.abs(slope32 - img.dataobj._slope), np.abs(inter32 - img.dataobj._inter)) < 1e-7: img.dataobj._slope = slope32 img.dataobj._inter = inter32 mask_file = self.inputs.mask_file if not isdefined(mask_file): mask_file = None smoothing_fwhm = self.inputs.smoothing_fwhm if not isdefined(smoothing_fwhm): smoothing_fwhm = None if is_cifti: fname_fmt = os.path.join(runtime.cwd, '{}_{}.dscalar.nii').format labels, estimates = level1.run_glm(img.get_fdata(dtype='f4'), mat.values) model_attr = { 'r_square': dscalar_from_cifti( img, _get_voxelwise_stat(labels, estimates, 'r_square'), 'r_square'), 'log_likelihood': dscalar_from_cifti( img, _get_voxelwise_stat(labels, estimates, 'logL'), 'log_likelihood') } else: fname_fmt = os.path.join(runtime.cwd, '{}_{}.nii.gz').format flm = level1.FirstLevelModel(minimize_memory=False, mask_img=mask_file, smoothing_fwhm=smoothing_fwhm) flm.fit(img, design_matrices=mat) model_attr = { 'r_square': flm.r_square[0], 'log_likelihood': flm.masker_.inverse_transform( _get_voxelwise_stat(flm.labels_[0], flm.results_[0], 'logL')) } out_ents = self.inputs.contrast_info[0]['entities'] # Save model level images model_maps = [] model_metadata = [] for attr, img in model_attr.items(): model_metadata.append({'stat': attr, **out_ents}) fname = fname_fmt('model', attr) img.to_filename(fname) model_maps.append(fname) effect_maps = [] variance_maps = [] stat_maps = [] zscore_maps = [] pvalue_maps = [] contrast_metadata = [] for name, weights, contrast_type in prepare_contrasts( self.inputs.contrast_info, mat.columns): contrast_metadata.append({ 'contrast': name, 'stat': contrast_type, **out_ents }) if is_cifti: contrast = compute_contrast(labels, estimates, weights, contrast_type=contrast_type) maps = { map_type: dscalar_from_cifti(img, getattr(contrast, map_type)(), map_type) for map_type in [ 'z_score', 'stat', 'p_value', 'effect_size', 'effect_variance' ] } else: maps = flm.compute_contrast(weights, contrast_type, output_type='all') for map_type, map_list in (('effect_size', effect_maps), ('effect_variance', variance_maps), ('z_score', zscore_maps), ('p_value', pvalue_maps), ('stat', stat_maps)): fname = fname_fmt(name, map_type) maps[map_type].to_filename(fname) map_list.append(fname) self._results['effect_maps'] = effect_maps self._results['variance_maps'] = variance_maps self._results['stat_maps'] = stat_maps self._results['zscore_maps'] = zscore_maps self._results['pvalue_maps'] = pvalue_maps self._results['contrast_metadata'] = contrast_metadata self._results['model_maps'] = model_maps self._results['model_metadata'] = model_metadata return runtime
def _run_interface(self, runtime): import nibabel as nb from nistats import second_level_model as level2 from nistats import first_level_model as level1 from nistats.contrasts import (compute_contrast, compute_fixed_effects, _compute_fixed_effects_params) smoothing_fwhm = self.inputs.smoothing_fwhm if not isdefined(smoothing_fwhm): smoothing_fwhm = None effect_maps = [] variance_maps = [] stat_maps = [] zscore_maps = [] pvalue_maps = [] contrast_metadata = [] out_ents = self.inputs.contrast_info[0]['entities'] # Same for all # Only keep files which match all entities for contrast stat_metadata = _flatten(self.inputs.stat_metadata) input_effects = _flatten(self.inputs.effect_maps) input_variances = _flatten(self.inputs.variance_maps) filtered_effects = [] filtered_variances = [] names = [] for m, eff, var in zip(stat_metadata, input_effects, input_variances): if _match(out_ents, m): filtered_effects.append(eff) filtered_variances.append(var) names.append(m['contrast']) mat = pd.get_dummies(names) contrasts = prepare_contrasts(self.inputs.contrast_info, mat.columns) is_cifti = filtered_effects[0].endswith('dscalar.nii') if is_cifti: fname_fmt = os.path.join(runtime.cwd, '{}_{}.dscalar.nii').format else: fname_fmt = os.path.join(runtime.cwd, '{}_{}.nii.gz').format # Only fit model if any non-FEMA contrasts at this level if any(c[2] != 'FEMA' for c in contrasts): if len(filtered_effects) < 2: raise RuntimeError( "At least two inputs are required for a 't' for 'F' " "second level contrast") if is_cifti: effect_data = np.squeeze([ nb.load(effect).get_fdata(dtype='f4') for effect in filtered_effects ]) labels, estimates = level1.run_glm(effect_data, mat.values, noise_model='ols') else: model = level2.SecondLevelModel(smoothing_fwhm=smoothing_fwhm) model.fit(filtered_effects, design_matrix=mat) for name, weights, contrast_type in contrasts: contrast_metadata.append({ 'contrast': name, 'stat': contrast_type, **out_ents }) # Pass-through happens automatically as it can handle 1 input if contrast_type == 'FEMA': # Index design identity matrix on non-zero contrasts weights con_ix = weights[0].astype(bool) # Index of all input files "involved" with that contrast dm_ix = mat.iloc[:, con_ix].any(axis=1) contrast_imgs = np.array(filtered_effects)[dm_ix] variance_imgs = np.array(filtered_variances)[dm_ix] if is_cifti: ffx_cont, ffx_var, ffx_t = _compute_fixed_effects_params( np.squeeze([ nb.load(fname).get_fdata(dtype='f4') for fname in contrast_imgs ]), np.squeeze([ nb.load(fname).get_fdata(dtype='f4') for fname in variance_imgs ]), precision_weighted=False) img = nb.load(filtered_effects[0]) maps = { 'effect_size': dscalar_from_cifti(img, ffx_cont, "effect_size"), 'effect_variance': dscalar_from_cifti(img, ffx_var, "effect_variance"), 'stat': dscalar_from_cifti(img, ffx_t, "stat") } else: ffx_res = compute_fixed_effects(contrast_imgs, variance_imgs) maps = { 'effect_size': ffx_res[0], 'effect_variance': ffx_res[1], 'stat': ffx_res[2] } else: if is_cifti: contrast = compute_contrast(labels, estimates, weights, contrast_type=contrast_type) img = nb.load(filtered_effects[0]) maps = { map_type: dscalar_from_cifti(img, getattr(contrast, map_type)(), map_type) for map_type in [ 'z_score', 'stat', 'p_value', 'effect_size', 'effect_variance' ] } else: maps = model.compute_contrast( second_level_contrast=weights, second_level_stat_type=contrast_type, output_type='all') for map_type, map_list in (('effect_size', effect_maps), ('effect_variance', variance_maps), ('z_score', zscore_maps), ('p_value', pvalue_maps), ('stat', stat_maps)): if map_type in maps: fname = fname_fmt(name, map_type) maps[map_type].to_filename(fname) map_list.append(fname) self._results['effect_maps'] = effect_maps self._results['variance_maps'] = variance_maps self._results['stat_maps'] = stat_maps self._results['contrast_metadata'] = contrast_metadata # These are "optional" as fixed effects do not support these if zscore_maps: self._results['zscore_maps'] = zscore_maps if pvalue_maps: self._results['pvalue_maps'] = pvalue_maps return runtime
def main(subject, sourcedata, derivatives, smoothed, n_jobs=5): os.environ['SUBJECTS_DIR'] = op.join(derivatives, 'freesurfer') source_layout = BIDSLayout(sourcedata, validate=False, derivatives=False) fmriprep_layout = BIDSLayout(op.join(derivatives, 'fmriprep'), validate=False) if smoothed: bold_layout = BIDSLayout(op.join(derivatives, 'smoothed'), validate=False) bold = bold_layout.get(subject=subject, extension='func.gii') else: bold = fmriprep_layout.get(subject=subject, extension='func.gii') bold = sorted([e for e in bold if 'fsaverage6' in e.filename], key=lambda x: x.run) 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, ['regressors'])] fmriprep_layout_df = fmriprep_layout_df[np.in1d( fmriprep_layout_df.extension, ['tsv'])] fmriprep_layout_df = fmriprep_layout_df.set_index(['subject', 'run']) 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) if smoothed: base_dir = op.join(derivatives, 'glm_stim1_surf_smoothed', f'sub-{subject}', 'func') else: base_dir = op.join(derivatives, 'glm_stim1_surf', f'sub-{subject}', 'func') if not op.exists(base_dir): os.makedirs(base_dir) for b in bold: run = b.entities['run'] hemi = b.entities['suffix'] # print(run) confounds_ = fmriprep_layout_df.loc[(subject, run), 'path'].iloc[0] confounds_ = pd.read_csv(confounds_, sep='\t') confounds_ = confounds_[to_include].fillna(method='bfill') pca = PCA(n_components=7) confounds_ -= confounds_.mean(0) confounds_ /= confounds_.std(0) confounds_pca = pca.fit_transform(confounds_[to_include]) 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) frametimes = np.arange(0, tr * len(confounds_), tr) X = make_first_level_design_matrix( frametimes, events_, add_regs=confounds_pca, add_reg_names=[f'confound_pca.{i}' for i in range(1, 8)]) Y = surface.load_surf_data(b.path).T Y = (Y / Y.mean(0) * 100) Y -= Y.mean(0) fit = run_glm(Y, X, noise_model='ols', n_jobs=n_jobs) r = fit[1][0.0] betas = pd.DataFrame(r.theta, index=X.columns) stim1 = [] for stim in 5, 7, 10, 14, 20, 28: stim1.append(betas.loc[f'stim1-{stim}']) result = pd.concat(stim1, 1).T print(result.shape) pes = nb.gifti.GiftiImage(header=nb.load(b.path).header, darrays=[ nb.gifti.GiftiDataArray(row) for ix, row in result.iterrows() ]) fn_template = op.join( base_dir, 'sub-{subject}_run-{run}_space-{space}_desc-stims1_hemi-{hemi}.pe.gii' ) space = 'fsaverage6' pes.to_filename(fn_template.format(**locals())) transformer = SurfaceTransform(source_subject='fsaverage6', target_subject='fsaverage', hemi={ 'L': 'lh', 'R': 'rh' }[hemi]) transformer.inputs.source_file = pes.get_filename() space = 'fsaverage' transformer.inputs.out_file = fn_template.format(**locals()) # Disable on MAC OS X (SIP problem) transformer.run()
def _run_glm_in_parallel(dm, run, event, conf, func, hrf_model, noise_model, tr, osf, slice_time_ref, mask, rf_condition, logger): logger.info(f"Fitting GLM to run {run+1} ...") n_vols = func.shape[0] start_time = slice_time_ref * tr end_time = (n_vols - 1 + slice_time_ref) * tr frame_times = np.linspace(start_time, end_time, n_vols) if mask is not None: func = func[:, mask.ravel()] if dm is not None: logger.info("Design-matrix was supplied, so fitting GLM immediately.") dm.index = frame_times conf.index = dm.index glm_results = run_glm(func, dm.values, noise_model=noise_model) return glm_results[0], glm_results[1], dm if not isinstance(hrf_model, str): # custom HRF! logger.info("Using custom HRF-model.") conds = sorted(event.trial_type.unique()) cols = ['constant'] + conds if isinstance(hrf_model, np.ndarray): # It's a SINGLE HRF (not a voxel-specific) X = np.zeros((n_vols, len(conds) + 1)) X[:, 0] = 1 # intercept for i, con in enumerate(conds): # loop over conditions trials = event.query('trial_type == @con') exp_cond = trials.loc[:, ['onset', 'duration', 'weight']] exp_cond['weight'] = 1 # Upsample x, hr_frame_times = _sample_condition(exp_cond.values.T, frame_times, oversampling=osf) # Convolve predictor xconv = np.convolve(x, hrf_model)[:x.shape[0]] # Downsample f_interp = interp1d(hr_frame_times, xconv) X[:, i+1] = f_interp(frame_times) # Save the design matrix dm = pd.DataFrame(data=X, columns=cols, index=frame_times) elif isinstance(hrf_model, ResponseFitter): # Assuming it's a per-voxel GLM hrf_tc = hrf_model.get_timecourses() if rf_condition is not None: hrf_tc = hrf_tc.loc[hrf_tc.index.get_level_values(0) == rf_condition, :] tlength = hrf_tc.index.get_level_values(-1).values[-1] hrf_values = hrf_tc.values n_vox = func.shape[1] labels, results = [], {} canon = glover_hrf(tr=TR, oversampling=osf, time_length=tlength, onset=0.0) #canon /= canon.max() hrfs = np.zeros((3, canon.size, n_vox)) for vox in range(n_vox): if vox % 1000 == 0: print(f"Voxel {vox} / {n_vox} (run {run + 1})") this_hrf = hrf_values[:, vox] #this_hrf /= this_hrf.max() hrfs[0, :, vox] = this_hrf hrfs[1, :, vox] = canon #hrfs[2, :, vox] = this_hrf X = np.zeros((n_vols, len(conds) + 1)) X[:, 0] = 1 # icept for i, con in enumerate(conds): trials = event.query('trial_type == @con') exp_cond = trials.loc[:, ['onset', 'duration', 'weight']] exp_cond['weight'] = 1 x, hr_frame_times = _sample_condition(exp_cond.values.T, frame_times, oversampling=osf) xconv = np.convolve(x, this_hrf)[:x.shape[0]] #xconv = np.convolve(x, canon)[:x.shape[0]] f_interp = interp1d(hr_frame_times, xconv) X[:, i+1] = f_interp(frame_times) X = pd.DataFrame(data=X, columns=cols, index=frame_times) conf.index = X.index dm = pd.concat((X, conf), axis=1) lab, res = run_glm(func[:, vox, np.newaxis], dm.values, noise_model=noise_model) labels, results = _merge_regression_results(lab[0], res, labels, results, n_vox=n_vox) return np.array(labels), results, dm, hrfs else: raise ValueError("Unknown type for hrf_model; don't know what to do with it!") else: logger.info(f"Using default Nistats HRF model '{hrf_model}'.") dm = make_first_level_design_matrix( frame_times=frame_times, events=event, drift_model=None, hrf_model=hrf_model, fir_delays=None ) conf.index = dm.index dm = pd.concat((dm, conf), axis=1) glm_results = run_glm(func, dm.values, noise_model=noise_model) return glm_results[0], glm_results[1], dm
# We specify an hrf model containing Glover model and its time derivative # the drift model is implicitly a cosine basis with period cutoff 128s. design_matrix = make_first_level_design_matrix( frame_times, events=events[0], hrf_model='glover + derivative', add_regs=confound[0]) # contrast_specification contrast_values = (design_matrix.columns == 'language') * 1.0 -\ (design_matrix.columns == 'string') # Setup and fit GLM. # Note that the output consists in 2 variables: `labels` and `fit` # `labels` tags voxels according to noise autocorrelation. # `estimates` contains the parameter estimates. # We input them for contrast computation. labels, estimates = run_glm(texture.T, design_matrix.values) contrast = compute_contrast(labels, estimates, contrast_values, contrast_type='t') # we present the Z-transform of the t map z_score = contrast.z_score() z_scores_right.append(z_score) # Do the left hemipshere exactly in the same way texture = surface.vol_to_surf(fmri_img, fsaverage.pial_left) labels, estimates = run_glm(texture.T, design_matrix.values) contrast = compute_contrast(labels, estimates, contrast_values, contrast_type='t') z_scores_left.append(contrast.z_score()) ############################################################################ # Individual activation maps have been accumulated in the z_score_left