def test_make_regressor_3(): """ test the generated regressor """ condition = ([1, 20, 36.5], [2, 2, 2], [1, 1, 1]) frame_times = np.linspace(0, 138, 70) hrf_model = 'fir' reg, reg_names = compute_regressor(condition, hrf_model, frame_times, fir_delays=np.arange(4)) assert_array_equal(np.sum(reg, 0), np.array([3, 3, 3, 3])) assert len(reg_names) == 4 reg_, reg_names_ = compute_regressor(condition, hrf_model, frame_times, fir_delays=np.arange(4), oversampling=50.) assert_array_equal(reg, reg_)
def test_design_warnings(): """ test that warnings are correctly raised upon weird design specification """ condition = ([-25, 20, 36.5], [0, 0, 0], [1, 1, 1]) frame_times = np.linspace(0, 69, 70) hrf_model = 'spm' with warnings.catch_warnings(record=True): warnings.simplefilter("always") with pytest.warns(UserWarning): compute_regressor(condition, hrf_model, frame_times) condition = ([-25, -25, 36.5], [0, 0, 0], [1, 1, 1]) with warnings.catch_warnings(record=True): warnings.simplefilter("always") with pytest.warns(UserWarning): compute_regressor(condition, hrf_model, frame_times)
def convolveevents(evtable, epi, *, hrf_model='spm', target_col='stim_id', regressors=None, **kwarg): """return a convolved design matrix for the design in pd.DataFrame-like evtable, using the meta data in nibabel.Nifti1Image-like epi to deduce tr and nvol.""" if not "amplitude" in evtable: LOGGER.info("no amplitude field in evtable, creating") evtable = evtable.assign(amplitude=1) if regressors is None: LOGGER.info("no regressors input, using unique entries in target_col") regressors = evtable[target_col].unique() regressors = np.sort(regressors[np.isnan(regressors) == False]) tr = epi.header.get_zooms()[-1] nvol = epi.shape[-1] frametimes = np.arange(0, nvol * tr, tr) convolved = [] for thisreg in regressors: regtable = evtable.loc[evtable[target_col] == thisreg] vals = regtable[['onset', 'duration', 'amplitude']].values.T convolved.append( hrf.compute_regressor(vals, hrf_model, frametimes, **kwarg)[0]) return np.concatenate(convolved, axis=1)
def get_bold_signal(self, exp, amplitudes, hrf_model, fmri_gain=1): '''To get the response vector''' # # To get the stimuli signal within the frame_times framework # stim = np.zeros_like(self.frame_times) # Contains amplitude of the stimulus in the frame_times space # for k, idx in idx_stimuli_within_frames: # stim[idx] = amplitudes[k] # Build experimental condition vector exp_condition = np.array((exp.stimulus_onsets, exp.stimulus_durations, amplitudes[:exp.n_stimuli]))\ .reshape(3, exp.n_stimuli) signal, name = hemodynamic_models.compute_regressor(exp_condition, hrf_model, self.frame_times, con_id='main', oversampling=1) # Amplify the signal signal = fmri_gain * signal # Take the signal only at the scan values scan_signal = np.zeros_like(self.scan_times) for k, idx in enumerate(self.idx_scans_within_frames): scan_signal[k] = signal[idx, 0] return signal, scan_signal, name
def test_make_regressor_1(): """ test the generated regressor """ condition = ([1, 20, 36.5], [2, 2, 2], [1, 1, 1]) frame_times = np.linspace(0, 69, 70) hrf_model = "spm" reg, reg_names = compute_regressor(condition, hrf_model, frame_times) assert_almost_equal(reg.sum(), 6, 1) assert_equal(reg_names[0], "cond")
def test_make_regressor_2(): """ test the generated regressor """ condition = ([1, 20, 36.5], [0, 0, 0], [1, 1, 1]) frame_times = np.linspace(0, 69, 70) hrf_model = 'spm' reg, reg_names = compute_regressor(condition, hrf_model, frame_times) assert_almost_equal(reg.sum() * 50, 3, 1) assert_equal(reg_names[0], 'cond')
def test_make_regressor_3(): """ test the generated regressor """ condition = ([1, 20, 36.5], [0, 0, 0], [1, 1, 1]) frame_times = np.linspace(0, 138, 70) hrf_model = "fir" reg, reg_names = compute_regressor(condition, hrf_model, frame_times, fir_delays=np.arange(4)) assert_array_equal(np.unique(reg), np.array([0, 1])) assert_array_equal(np.sum(reg, 0), np.array([3, 3, 3, 3])) assert_equal(len(reg_names), 4)
def test_make_regressor_3(): """ test the generated regressor """ condition = ([1, 20, 36.5], [0, 0, 0], [1, 1, 1]) frame_times = np.linspace(0, 138, 70) hrf_model = 'fir' reg, reg_names = compute_regressor(condition, hrf_model, frame_times, fir_delays=np.arange(4)) assert_array_equal(np.unique(reg), np.array([0, 1])) assert_array_equal(np.sum(reg, 0), np.array([3, 3, 3, 3])) assert_equal(len(reg_names), 4)
def process_raw_features(run, tr, nscans): # compute convolution of raw_features with hrf kernel df = pd.read_csv(run) result = [] count = 0 raw_features_columns = [ col for col in df.columns if col not in ['offsets', 'duration'] ] for col in raw_features_columns: conditions = np.vstack((df.offsets, df.duration, df[col])) tmp = compute_regressor(exp_condition=conditions, hrf_model='spm', frame_times=np.arange(0.0, nscans * tr, tr), oversampling=10) result.append(pd.DataFrame(tmp[0], columns=[col])) count += 1 return pd.concat(result, axis=1)
def onset2reg(df, nscans, tr): """ df : pandas dataframe with columnes onset and amplitude, and, optionnaly, duration nscans: number of scans tr : sampling period of scanning""" n_events = len(df) onsets = df.onset amplitudes = df.amplitude if 'duration' in df.columns: # optionaly, use "duration" durations = df.duration else: durations = np.zeros(n_events) conditions = np.vstack((onsets, durations, amplitudes)) x = compute_regressor(exp_condition=conditions, hrf_model="spm", frame_times=np.arange(0.0, nscans * tr, tr), oversampling=10) return pd.DataFrame(x[0], columns=['hrf'])
def __init__(self, name, frame_times, onset, *, duration=None, modulation=None): ''' Args: name (str): Name of the regressor. frame_times (np.ndarray of shape (n_frames,)): The timing of acquisition of the scans in seconds. onset (array-like): Specifies the start time of each event in seconds. duration (array-like, optional): Duration of each event in seconds. Defaults duration is set to 0 (impulse function). modulation (array-like, optional): Parametric modulation of event amplitude. Before convolution regressor is demeaned. ''' if not isinstance(frame_times, np.ndarray) or frame_times.ndim != 1: msg = 'frame_times should be np.ndarray of shape (n_frames, )' raise TypeError(msg) self._name = name self._frame_times = frame_times n_events = len(onset) if duration is None: duration = np.zeros(n_events) if modulation is None or (len(modulation) > 1 and np.all(np.array(modulation) == modulation[0])): modulation = np.ones(n_events) elif len(modulation) > 1: modulation = np.array(modulation) modulation = modulation - np.mean(modulation) self._values, _ = hemodynamic_models.compute_regressor( exp_condition=np.vstack((onset, duration, modulation)), hrf_model='spm', frame_times=frame_times )
def convolve(signal, t_r=2, oversampling=50, hrf_model='spm'): '''Convolve signal with hemodynamic response function. Performs signal convolution with requested hrf model. This function wraps around nistats compute_regressor function usually used for creating task-based regressors. The trick is to define neural regressor as a sequence of equally spaced (with the gap of 1TR) and modulated 'task events'. Event amplitude modulation corresponds to neural signal amplitude at a given timepoint. Args: signal (iterable): Neural signal. t_r (float): Repetition time in seconds. oversampling (int, optional): Convolution upsampling rate. hrf_model (str, optional): Hemodynamic response function type. See the documentation of compute regressor function from nistats.hemodynamic_models for more details. Returns: Convolved neural signal in BOLD space. ''' n_volumes = len(signal) frame_times = np.arange(0, n_volumes * t_r, t_r) onsets = np.zeros((3, n_volumes)) for vol, amplitude in enumerate(signal): onsets[:, vol] = (vol * t_r, 0, amplitude) signal_bold = hemodynamic_models.compute_regressor( onsets, hrf_model=hrf_model, frame_times=frame_times, oversampling=oversampling, fir_delays=None)[0].ravel() return signal_bold
def compute_regressor(self, dataframe, offset_type, duration_type, run_index): """ Compute the convolution with an hrf for each column of the dataframe. Arguments: - dataframes: pd.DataFrame - offset_type: str - duration_type: str - run_index: str Returns: - matrix: np.array """ regressors = [] dataframe = dataframe.dropna(axis=0) representations = [col for col in dataframe.columns] offsets = fetch_offsets(offset_type, run_index, self.offset_path, self.language) duration = fetch_duration(duration_type, run_index, self.duration_path, default_size=len(dataframe)) offsets += self.temporal_shifting # shift offsets by 'temporal_shifting' seconds for col in representations: conditions = np.vstack((offsets, duration, dataframe[col])) signal, name = compute_regressor( exp_condition=conditions, hrf_model=self.hrf, frame_times=np.arange(0.0, self.nscans[run_index] * self.tr, self.tr), oversampling=self.oversampling) col = str(col) regressors.append( pd.DataFrame(signal, columns=[col] + [col + '_' + item for item in name[1:]])) matrix = pd.concat(regressors, axis=1).values return matrix
stim = np.zeros_like(frame_times) for k in range(n_events): stim[(frame_times > onset[k]) * (frame_times <= onset[k] + duration[k])] = amplitude[k] exp_condition = np.array((onset, duration, amplitude)).reshape(3, n_events) hrf_models = [None, 'spm', 'glover + derivative'] ######################################################################### # sample the hrf fig = plt.figure(figsize=(9, 4)) for i, hrf_model in enumerate(hrf_models): signal, name = hemodynamic_models.compute_regressor(exp_condition, hrf_model, frame_times, con_id='main', oversampling=16, fir_delays=np.array( [1., 2.])) plt.subplot(1, 3, i + 1) # plt.fill(frame_times, stim, 'k', alpha=.5, label='stimulus') for j in range(signal.shape[1]): plt.plot(frame_times, signal.T[j], label=name[j]) plt.xlabel('time (s)') #plt.legend(loc=1) plt.title(hrf_model) plt.subplots_adjust(bottom=.12) plt.savefig('output/figures/example_hrf.png', bbox_inches='tight')
# ---------------------------------- # # Let's quickly plot this file: frame_times = np.linspace(0, 30, 61) onset, amplitude, duration = 0., 1., 1. stim = np.zeros_like(frame_times) stim[(frame_times > onset) * (frame_times <= onset + duration)] = amplitude exp_condition = np.array((onset, duration, amplitude)).reshape(3, 1) hrf_models = [None, 'glover + derivative', 'glover + derivative + dispersion'] ######################################################################### # sample the hrf fig = plt.figure(figsize=(9, 4)) for i, hrf_model in enumerate(hrf_models): signal, name = hemodynamic_models.compute_regressor(exp_condition, hrf_model, frame_times, con_id='main', oversampling=16) plt.subplot(1, 3, i + 1) plt.fill(frame_times, stim, 'k', alpha=.5, label='stimulus') for j in range(signal.shape[1]): plt.plot(frame_times, signal.T[j], label=name[j]) plt.xlabel('time (s)') plt.legend(loc=1) plt.title(hrf_model) plt.subplots_adjust(bottom=.12) plt.show()
import matplotlib.pyplot as plt from nistats import hemodynamic_models # parameters frame_times = np.linspace(0, 30, 61) onset, amplitude, duration = 0., 1., 1. stim = np.zeros_like(frame_times) stim[(frame_times > onset) * (frame_times <= onset + duration)] = amplitude exp_condition = np.array((onset, duration, amplitude)).reshape(3, 1) hrf_models = ['glover + derivative', 'glover + derivative + dispersion'] fig = plt.figure(figsize=(9, 4)) # sample the hrf for i, hrf_model in enumerate(hrf_models): signal, name = hemodynamic_models.compute_regressor( exp_condition, hrf_model, frame_times, con_id='main', oversampling=16) plt.subplot(1, 2, i + 1) plt.fill(frame_times, stim, 'k', alpha=.5, label='stimulus') for j in range(signal.shape[1]): plt.plot(frame_times, signal.T[j], label=name[j]) plt.xlabel('time (s)') plt.legend(loc=1) plt.title(hrf_model) plt.subplots_adjust(bottom=.12) fig.show()