def estimate_voxel_params(subj, data, model, runs, conditions): """Fit a univariate model in each voxel of a ROI data array.""" # Load the task design design_file = design_temp.format(subj, model) design = pd.read_csv(design_file) # Precompute the highpass filter kernel and HRF ntp = data.shape[1] hpf_kernel = glm.fsl_highpass_matrix(ntp, 128) hrf = glm.GammaDifferenceHRF() # Build a design matrix for each run separately and then combine Xs = [] for run in runs: run_design = design.query("run == @run") X = glm.DesignMatrix(run_design, hrf, ntp, hpf_kernel=hpf_kernel, condition_names=conditions) Xs.append(X.design_matrix) X = pd.concat(Xs).reset_index(drop=True) # Rotate the data around to stack runs together np.testing.assert_equal(len(data), len(runs)) data = data.reshape(-1, data.shape[-1]) # Fit the model model = sm.OLS(data, X).fit() # Return the params return model.params
def regress_task(exp, subj, data): """Fit a model of the task and return the residuals.""" if exp == "dots": ntp = 459 design, _ = dots_design(subj) design.loc[:, "duration"] = 0 hpf_kernel = glm.fsl_highpass_matrix(ntp, 128, 1) elif exp == "sticks": ntp = 515 design, _ = sticks_design(subj) design.loc[:, "duration"] = 0 design.loc[:, "onset"] = (design["onset"] / .72).round() hpf_kernel = glm.fsl_highpass_matrix(ntp, 178, 1) conditions = design["condition"].unique() # Upsample the dots data to match the design resolution if exp == "dots": run_data = np.split(data, 12) data = np.concatenate([moss.upsample(d, 2) for d in run_data]) # Make a design matrix for each run and then concatenate Xs = [] for run, run_df in design.groupby("run"): Xrun = glm.DesignMatrix(run_df, glm.FIR(tr=1, nbasis=24, offset=-2), condition_names=conditions, hpf_kernel=hpf_kernel, ntp=ntp, tr=1, oversampling=1).design_matrix # Regress confounds out of the design matrix confounds = confound_design(exp, subj, run, hpf_kernel) assert len(confounds) == len(Xrun) confounds.index = Xrun.index Xrun = OLS(Xrun, confounds).fit().resid Xs.append(Xrun) X = pd.concat(Xs) resid = OLS(data, X).fit().resid.values return resid
def estimate_subject_roi_fir(subj, mask, model, conditions=None): # Load the cached ROI dataset data = load_cached_roi_data(subj, mask) # Average the data over voxels data = data.mean(axis=-1) # Upsample the data to 1s resolution data = moss.upsample(data.T, 2).T # Convert the data to percent signal change over runs data = percent_change(data, 1) # Count the number of timepoints ntp = data.shape[1] # Concatenate the data into one long vector data = np.concatenate(data) # Load the design, make events impulses, get a list of conditions design = pd.read_csv(design_temp.format(subj, model)) design["duration"] = 0 if conditions is None: conditions = design["condition"].unique() # Precache the hpf kernel hpf_kernel = glm.fsl_highpass_matrix(ntp, 128) # Make a design matrix for each run and then concatenate Xs = [] for run, run_df in design.groupby("run"): X = glm.DesignMatrix(run_df, glm.FIR(tr=1, nbasis=24, offset=-2), condition_names=conditions, hpf_cutoff=None, hpf_kernel=hpf_kernel, ntp=ntp, tr=1, oversampling=1) Xs.append(X.design_matrix) X = pd.concat(Xs) # Fit the model model = sm.OLS(data, X).fit() # Add metadata about the beta for each timepoint and condition params = model.params.reset_index(name="coef") params["timepoint"] = params["index"].str[-2:].astype(int) params["timepoint"] -= 1 params["condition"] = params["index"].str[:-3] params["subj"] = subj params["roi"] = mask # Return the model parameters return params
def residualize_roi_data(subj, mask, model, conditions=None): """Residualize cached ROI data against task model.""" orig_data = load_cached_roi_data(subj, mask) # De-mean the data by run and voxel orig_data = signal.detrend(orig_data, axis=1, type="constant") # Precompute the highpass filter kernel and HRF ntp = orig_data.shape[1] hpf_kernel = glm.fsl_highpass_matrix(ntp, 128) hrf = glm.GammaDifferenceHRF(temporal_deriv=True) # Load the task design design_file = op.join(data_dir, subj, "design", model + ".csv") design = pd.read_csv(design_file) if conditions is None: conditions = sorted(design["condition"].unique()) # Set up the output data structure out_data = np.empty_like(orig_data) # Loop over the runs and get the residual data for each for run_i, run_data in enumerate(orig_data): # Generate the design matrix run_design = design.query("run == (@run_i + 1)") X = glm.DesignMatrix(run_design, hrf, ntp, condition_names=conditions, hpf_kernel=hpf_kernel) # Fit the model ols = sm.OLS(run_data, X.design_matrix).fit() # Save the residuals out_data[run_i] = ols.resid # Z-score the residuals by run and voxel out_data = stats.zscore(out_data, axis=1) assert not np.any(np.isnan(out_data)) return out_data
def _get_hpf_kernel(self): """Cache the highpass filter matrix, which is expensive to build.""" if self.exp == "dots": return glm.fsl_highpass_matrix(230, 128, 2) elif self.exp == "sticks": return glm.fsl_highpass_matrix(515, 128, .72)