def test_get_contrasts(): # preamble borrowed from the previous test skip_if_no_external('nibabel') skip_if_no_external('nipy') # ATM relies on NiPy's GLM implementation # taking subset of the dataset to speed testing up ds = load_example_fmri_dataset('25mm', literal=True)[{ 'chunks': [0, 1] }, :3] # TODO: simulate short dataset with known properties and use it # for testing events = find_events(targets=ds.sa.targets, chunks=ds.sa.chunks) tr = ds.a.imghdr['pixdim'][4] for ev in events: for a in ('onset', 'duration'): ev[a] = ev[a] * tr evds = fit_event_hrf_model( ds, events=events, time_attr='time_coords', condition_attr='targets', design_kwargs=dict(drift_model='blank'), glmfit_kwargs=dict(model='ols'), return_model=True, ) # Simple one -- stat per each condition cons = get_contrasts(evds) # and let's get p-values cons_p = get_contrasts(evds, fxname='p_value') # Without contrasts explicitly prescribed -- there will be one per each # condition assert_array_equal(cons.UT, evds.UT) # and per each feature assert_equal(cons.shape, (len(evds.UT), evds.nfeatures)) assert_array_less(cons_p, 1) assert_array_less(0, cons_p) cons_fh = get_contrasts( evds, contrasts={ 'face-house': { 'face': 1, 'house': -1 }, 'betterface': { 'face': 1, 'house': -0.5, 'scrambledpix': -0.5 } }, ) # print(cons_fh.samples) assert_array_equal(cons_fh.UT, ['betterface', 'face-house']) # and nipy does one tailed test so all p-values should correspond to z-s skip_if_no_external('scipy') import scipy.stats.distributions as ssd assert_array_almost_equal(ssd.norm().isf(cons_p), cons)
def create_betas_per_trial_with_pymvpa_roni(study_path, subj, conf, mask_name, flavor, TR): dhandle = OpenFMRIDataset(study_path) model = 1 task = 1 # Do this for other tasks as well. not only the first mask_fname = _opj(study_path, "sub{:0>3d}".format(subj), "masks", conf.mvpa_tasks[0], "{}.nii.gz".format(mask_name)) print mask_fname run_datasets = [] for run_id in dhandle.get_task_bold_run_ids(task)[subj]: if type(run_id) == str: continue # all_events = dhandle.get_bold_run_model(model, subj, run_id) all_events = get_bold_run_model(dhandle, 2, subj, run_id) run_events = [] i = 0 for event in all_events: if event["task"] == task: event["condition"] = "{}-{}".format(event["condition"], event["id"]) run_events.append(event) i += 1 # load BOLD data for this run (with masking); add 0-based chunk ID run_ds = dhandle.get_bold_run_dataset(subj, task, run_id, flavor=flavor, chunks=run_id - 1, mask=mask_fname) # convert event info into a sample attribute and assign as 'targets' run_ds.sa.time_coords = run_ds.sa.time_indices * TR run_ds.sa["targets"] = events2sample_attr(run_events, run_ds.sa.time_coords, noinfolabel="rest") # additional time series preprocessing can go here poly_detrend(run_ds, polyord=1, chunks_attr="chunks") zscore(run_ds, chunks_attr="chunks", param_est=("targets", ["rest"]), dtype="float32") glm_dataset = fit_event_hrf_model(run_ds, run_events, time_attr="time_coords", condition_attr="condition") glm_dataset.sa["targets"] = [x[: x.find("-")] for x in glm_dataset.sa.condition] glm_dataset.sa["id"] = [x[x.find("-") + 1 :] for x in glm_dataset.sa.condition] glm_dataset.sa.condition = glm_dataset.sa["targets"] glm_dataset.sa["chunks"] = [run_id - 1] * len(glm_dataset.samples) # If a trial was dropped (the subject pressed on a button) than the counter trial from the # other condition should also be dropped for pair in conf.conditions_to_compare: cond_bool = np.array([c in pair for c in glm_dataset.sa["condition"]]) sub_dataset = glm_dataset[cond_bool] c = Counter(sub_dataset.sa.id) for value in c: if c[value] < 2: id_bool = np.array([value in cond_id for cond_id in glm_dataset.sa["id"]]) glm_dataset = glm_dataset[np.bitwise_not(np.logical_and(id_bool, cond_bool))] run_datasets.append(glm_dataset) return vstack(run_datasets, 0)
def create_betas_per_trial_with_pymvpa(study_path, subj, conf, mask_name, flavor, TR): dhandle = OpenFMRIDataset(study_path) model = 1 task = 1 # Do this for other tasks as well. not only the first mask_fname = _opj(study_path, "sub{:0>3d}".format(subj), "masks", conf.mvpa_tasks[0], "{}.nii.gz".format(mask_name)) print mask_fname run_datasets = [] for run_id in dhandle.get_task_bold_run_ids(task)[subj]: if type(run_id) == str: continue all_events = dhandle.get_bold_run_model(model, subj, run_id) run_events = [] i = 0 for event in all_events: if event["task"] == task: event["condition"] = "{}-{}".format(event["condition"], i) run_events.append(event) i += 1 # load BOLD data for this run (with masking); add 0-based chunk ID run_ds = dhandle.get_bold_run_dataset(subj, task, run_id, flavor=flavor, chunks=run_id - 1, mask=mask_fname) # convert event info into a sample attribute and assign as 'targets' run_ds.sa.time_coords = run_ds.sa.time_indices * TR print run_id run_ds.sa["targets"] = events2sample_attr(run_events, run_ds.sa.time_coords, noinfolabel="rest") # additional time series preprocessing can go here poly_detrend(run_ds, polyord=1, chunks_attr="chunks") zscore(run_ds, chunks_attr="chunks", param_est=("targets", ["rest"]), dtype="float32") glm_dataset = fit_event_hrf_model(run_ds, run_events, time_attr="time_coords", condition_attr="condition") glm_dataset.sa["targets"] = [x[: x.find("-")] for x in glm_dataset.sa.condition] glm_dataset.sa.condition = glm_dataset.sa["targets"] glm_dataset.sa["chunks"] = [run_id - 1] * len(glm_dataset.samples) run_datasets.append(glm_dataset) return vstack(run_datasets, 0)
def runsub(sub, thisContrast, r, dstype='raw', roi='grayMatter', filterLen=49, filterOrd=3, write=False): if dstype == 'raw': outdir='PyMVPA' print "working with raw data" thisSub = {sub: subList[sub]} dsdict = lmvpa.loadsubdata(paths, thisSub, m=roi) thisDS = dsdict[sub] mc_params = lmvpa.loadmotionparams(paths, thisSub) beta_events = lmvpa.loadevents(paths, thisSub) # savitsky golay filtering sg.sg_filter(thisDS, filterLen, filterOrd) # gallant group zscores before regression. # zscore w.r.t. rest trials # zscore(thisDS, param_est=('targets', ['rest']), chunks_attr='chunks') # zscore entire set. if done chunk-wise, there is no double-dipping (since we leave a chunk out at a time). zscore(thisDS, chunks_attr='chunks') print "beta extraction" ## BETA EXTRACTION ## rds, events = lmvpa.amendtimings(thisDS.copy(), beta_events[sub]) evds = er.fit_event_hrf_model(rds, events, time_attr='time_coords', condition_attr=('trial_type', 'chunks'), design_kwargs={'add_regs': mc_params[sub], 'hrf_model': 'canonical'}, return_model=True) fds = lmvpa.replacetargets(evds, contrasts, thisContrast) fds = fds[fds.targets != '0'] else: outdir=os.path.join('LSS', dstype) print "loading betas" fds = lmvpa.loadsubbetas(paths, sub, btype=dstype, m=roi) fds.sa['targets'] = fds.sa[thisContrast] zscore(fds, chunks_attr='chunks') fds = lmvpa.sortds(fds) print "searchlights" ## initialize classifier clf = svm.LinearNuSVMC() cv = CrossValidation(clf, NFoldPartitioner()) from mvpa2.measures.searchlight import sphere_searchlight cvSL = sphere_searchlight(cv, radius=r) # now I have betas per chunk. could just correlate the betas, or correlate the predictions for corresponding runs lidx = fds.chunks < fds.sa['chunks'].unique[len(fds.sa['chunks'].unique)/2] pidx = fds.chunks >= fds.sa['chunks'].unique[len(fds.sa['chunks'].unique) / 2] lres = sl.run_cv_sl(cvSL, fds[lidx].copy(deep=False)) pres = sl.run_cv_sl(cvSL, fds[pidx].copy(deep=False)) if write: from mvpa2.base import dataset map2nifti(fds, dataset.vstack([lres, pres])).\ to_filename(os.path.join( paths[0], 'Maps', outdir, sub + '_' + roi + '_' + thisContrast + '_cvsl.nii.gz')) del lres, pres, cvSL cvSL = sphere_searchlight(cv, radius=r) crossSet = fds.copy() crossSet.chunks[lidx] = 1 crossSet.chunks[pidx] = 2 cres = sl.run_cv_sl(cvSL, crossSet.copy(deep=False)) if write: map2nifti(fds, cres[0]).to_filename( os.path.join(paths[0], 'Maps', outdir, sub + '_' + roi + '_' + (thisContrast) + '_P2L.nii.gz')) map2nifti(fds, cres[1]).to_filename( os.path.join(paths[0], 'Maps', outdir, sub + '_' + roi + '_' + (thisContrast) + '_L2P.nii.gz'))
# zscore(thisDS, param_est=('targets', ['rest']), chunks_attr='chunks') # zscore entire set. if done chunk-wise, there is no double-dipping (since we leave a chunk out at a time). zscore(thisDS, chunks_attr='chunks') # kay method: leave out a model run, use it to fit an HRF for each voxel # huth method: essentially use FIR # mumford method: deconvolution with canonical HRF # refit events and regress... # get timing data from timing files rds, events = lmvpa.amendtimings(thisDS.copy(), beta_events[sub]) #OLS beta extraction betas = 'LSA' evds = er.fit_event_hrf_model(rds, events, time_attr='time_coords', condition_attr=('trial_type', 'chunks'), design_kwargs={'add_regs': mc_params[sub], 'hrf_model': 'canonical'}, return_model=True) fds = lmvpa.replacetargets(evds, contrasts, thisContrast) fds = fds[fds.targets != '0'] fds = fds[fds.targets != 'rest'] rsaresults.append(dsm(fds)) lidx = fds.chunks < fds.sa['chunks'].unique[len(fds.sa['chunks'].unique)/2] pidx = fds.chunks >= fds.sa['chunks'].unique[len(fds.sa['chunks'].unique) / 2] lfds = fds[lidx] pfds = fds[pidx] lres = cv(lfds) lresults.append(lres)
data = np.concatenate(data) labels = np.concatenate(labels) return data, labels.astype(np.int) rois = ['aSTG', 'HG', 'pSTG'] for sub_id in range(1, 21): data = [] for roi in rois: data_path = os.path.join(data_dir, roi) tmp_data, label = load_data(data_path, sub_id) data.append(tmp_data) data = np.concatenate(data, axis=1) data = np.concatenate([data[i,:,:].T for i in range(len(data))]) ds = Dataset(data) ds.sa['time_coords'] = np.linspace(0, len(ds)-1, len(ds)) events = [{'onset': i*5, 'duration': 5, 'targets':label[i], 'chunks':i+1} for i in range(int(len(ds)/5))] hrf_estimates = fit_event_hrf_model(ds, events, time_attr='time_coords', condition_attr=('targets', 'chunks'), design_kwargs=dict(drift_model='blank'), glmfit_kwargs=dict(model='ols'), return_model=True) fsel = SensitivityBasedFeatureSelection(OneWayAnova(), FixedNElementTailSelector(5000, mode='select', tail='upper')) fsel.train(hrf_estimates) ds_p = fsel(hrf_estimates) np.save('feat_sub{:03d}'.format(sub_id), ds_p.samples)
def runsub(sub, thisContrast, r, dstype="raw", roi="grayMatter", filterLen=49, filterOrd=3, write=False): if dstype == "raw": outdir = "PyMVPA" print "working with raw data" thisSub = {sub: subList[sub]} dsdict = lmvpa.loadsubdata(paths, thisSub, m=roi) thisDS = dsdict[sub] mc_params = lmvpa.loadmotionparams(paths, thisSub) beta_events = lmvpa.loadevents(paths, thisSub) # savitsky golay filtering sg.sg_filter(thisDS, filterLen, filterOrd) # gallant group zscores before regression. # zscore w.r.t. rest trials # zscore(thisDS, param_est=('targets', ['rest']), chunks_attr='chunks') # zscore entire set. if done chunk-wise, there is no double-dipping (since we leave a chunk out at a time). zscore(thisDS, chunks_attr="chunks") print "beta extraction" ## BETA EXTRACTION ## rds, events = lmvpa.amendtimings(thisDS.copy(), beta_events[sub]) evds = er.fit_event_hrf_model( rds, events, time_attr="time_coords", condition_attr=("trial_type", "chunks"), design_kwargs={"add_regs": mc_params[sub], "hrf_model": "canonical"}, return_model=True, ) fds = lmvpa.replacetargets(evds, contrasts, thisContrast) fds = fds[fds.targets != "0"] else: outdir = os.path.join("LSS", dstype) print "loading betas" fds = lmvpa.loadsubbetas(paths, sub, btype=dstype, m=roi) fds.sa["targets"] = fds.sa[thisContrast] zscore(fds, chunks_attr="chunks") fds = lmvpa.sortds(fds) print "searchlights" ## initialize classifier clf = svm.LinearNuSVMC() cv = CrossValidation(clf, NFoldPartitioner()) from mvpa2.measures.searchlight import sphere_searchlight cvSL = sphere_searchlight(cv, radius=r) # now I have betas per chunk. could just correlate the betas, or correlate the predictions for corresponding runs lidx = fds.chunks < fds.sa["chunks"].unique[len(fds.sa["chunks"].unique) / 2] pidx = fds.chunks >= fds.sa["chunks"].unique[len(fds.sa["chunks"].unique) / 2] lres = sl.run_cv_sl(cvSL, fds[lidx].copy(deep=False)) pres = sl.run_cv_sl(cvSL, fds[pidx].copy(deep=False)) if write: from mvpa2.base import dataset map2nifti(fds, dataset.vstack([lres, pres])).to_filename( os.path.join(paths[0], "Maps", outdir, sub + "_" + roi + "_" + thisContrast + "_cvsl.nii.gz") ) del lres, pres, cvSL cvSL = sphere_searchlight(cv, radius=r) crossSet = fds.copy() crossSet.chunks[lidx] = 1 crossSet.chunks[pidx] = 2 cres = sl.run_cv_sl(cvSL, crossSet.copy(deep=False)) if write: map2nifti(fds, cres[0]).to_filename( os.path.join(paths[0], "Maps", outdir, sub + "_" + roi + "_" + (thisContrast) + "_P2L.nii.gz") ) map2nifti(fds, cres[1]).to_filename( os.path.join(paths[0], "Maps", outdir, sub + "_" + roi + "_" + (thisContrast) + "_L2P.nii.gz") )
# kay method: leave out a model run, use it to fit an HRF for each voxel # huth method: essentially use FIR # mumford method: deconvolution with canonical HRF # refit events and regress... # get timing data from timing files rds, events = lmvpa.amendtimings(thisDS.copy(), beta_events[sub]) #OLS beta extraction betas = 'LSA' evds = er.fit_event_hrf_model(rds, events, time_attr='time_coords', condition_attr=('trial_type', 'chunks'), design_kwargs={ 'add_regs': mc_params[sub], 'hrf_model': 'canonical' }, return_model=True) fds = lmvpa.replacetargets(evds, contrasts, thisContrast) fds = fds[fds.targets != '0'] fds = fds[fds.targets != 'rest'] rsaresults.append(dsm(fds)) lidx = fds.chunks < fds.sa['chunks'].unique[len(fds.sa['chunks'].unique) / 2] pidx = fds.chunks >= fds.sa['chunks'].unique[len(fds.sa['chunks'].unique) / 2]