def fourier_basis(t, freq): """ Create a design matrix with columns given by the Fourier basis with a given set of frequencies. Parameters ---------- t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. freq : sequence of float Frequencies for the terms in the Fourier basis. Returns ------- X : np.ndarray Examples -------- >>> t = np.linspace(0,50,101) >>> drift = fourier_basis(t, np.array([4,6,8])) >>> drift.shape (101, 6) """ tval = make_recarray(t, ['t']) f = fourier_basis_sym(freq) return f.design(tval, return_float=True)
def natural_spline(tvals, knots=None, order=3, intercept=True): """ Create a design matrix with columns given by a natural spline of a given order and a specified set of knots. Parameters ---------- tvals : np.array Time values knots : None or sequence, optional Sequence of float. Default None (same as empty list) order : int, optional Order of the spline. Defaults to a cubic (==3) intercept : bool, optional If True, include a constant function in the natural spline. Default is False Returns ------- X : np.ndarray Examples -------- >>> tvals = np.linspace(0,50,101) >>> drift = natural_spline(tvals, knots=[10,20,30,40]) >>> drift.shape (101, 8) """ tvals = make_recarray(tvals, ['t']) t = Term('t') f = formulae.natural_spline(t, knots=knots, order=order, intercept=intercept) return f.design(tvals, return_float=True)
def test_run(): ar1_fname = 'ar1_out.nii' funcim = load_image(funcfile) fmriims = FmriImageList.from_image(funcim, volume_start_times=2.) one_vol = fmriims[0] # Formula - with an intercept t = Term('t') f = Formula([t, t**2, t**3, 1]) # Design matrix and contrasts time_vector = make_recarray(fmriims.volume_start_times, 't') con_defs = dict(c=t, c2=t+t**2) desmtx, cmatrices = f.design(time_vector, contrasts=con_defs) # Run with Image and ImageList for inp_img in (img_rollaxis(funcim, 't'), fmriims): with InTemporaryDirectory(): # Run OLS model outputs = [] outputs.append(model.output_AR1(ar1_fname, fmriims)) outputs.append(model.output_resid('resid_OLS_out.nii', fmriims)) ols = model.OLS(fmriims, f, outputs) ols.execute() # Run AR1 model outputs = [] outputs.append( model.output_T('T_out.nii', cmatrices['c'], fmriims)) outputs.append( model.output_F('F_out.nii', cmatrices['c2'], fmriims)) outputs.append( model.output_resid('resid_AR_out.nii', fmriims)) rho = load_image(ar1_fname) ar = model.AR1(fmriims, f, rho, outputs) ar.execute() f_img = load_image('F_out.nii') assert_equal(f_img.shape, one_vol.shape) f_data = f_img.get_data() assert_true(np.all((f_data>=0) & (f_data<30))) resid_img = load_image('resid_AR_out.nii') assert_equal(resid_img.shape, funcim.shape[3:] + one_vol.shape) assert_array_almost_equal(np.mean(resid_img.get_data()), 0, 3) e_img = load_image('T_out_effect.nii') sd_img = load_image('T_out_sd.nii') t_img = load_image('T_out_t.nii') t_data = t_img.get_data() assert_array_almost_equal(t_data, e_img.get_data() / sd_img.get_data()) assert_true(np.all(np.abs(t_data) < 6)) # Need to delete to help windows delete temporary files del rho, resid_img, f_img, e_img, sd_img, t_img, f_data, t_data
def test_run(): ar1_fname = 'ar1_out.nii' funcim = load_image(funcfile) fmriims = FmriImageList.from_image(funcim, volume_start_times=2.) one_vol = fmriims[0] # Formula - with an intercept t = Term('t') f = Formula([t, t**2, t**3, 1]) # Design matrix and contrasts time_vector = make_recarray(fmriims.volume_start_times, 't') con_defs = dict(c=t, c2=t + t**2) desmtx, cmatrices = f.design(time_vector, contrasts=con_defs) # Run with Image and ImageList for inp_img in (rollimg(funcim, 't'), fmriims): with InTemporaryDirectory(): # Run OLS model outputs = [] outputs.append(model.output_AR1(ar1_fname, fmriims)) outputs.append(model.output_resid('resid_OLS_out.nii', fmriims)) ols = model.OLS(fmriims, f, outputs) ols.execute() # Run AR1 model outputs = [] outputs.append(model.output_T('T_out.nii', cmatrices['c'], fmriims)) outputs.append( model.output_F('F_out.nii', cmatrices['c2'], fmriims)) outputs.append(model.output_resid('resid_AR_out.nii', fmriims)) rho = load_image(ar1_fname) ar = model.AR1(fmriims, f, rho, outputs) ar.execute() f_img = load_image('F_out.nii') assert_equal(f_img.shape, one_vol.shape) f_data = f_img.get_data() assert_true(np.all((f_data >= 0) & (f_data < 30))) resid_img = load_image('resid_AR_out.nii') assert_equal(resid_img.shape, funcim.shape) assert_array_almost_equal(np.mean(resid_img.get_data()), 0, 3) e_img = load_image('T_out_effect.nii') sd_img = load_image('T_out_sd.nii') t_img = load_image('T_out_t.nii') t_data = t_img.get_data() assert_array_almost_equal(t_data, e_img.get_data() / sd_img.get_data()) assert_true(np.all(np.abs(t_data) < 6)) # Need to delete to help windows delete temporary files del rho, resid_img, f_img, e_img, sd_img, t_img, f_data, t_data
def openfmri2nipy(ons_dur_amp): """ Contents of OpenFMRI condition file `ons_dur_map` as nipy recarray Parameters ---------- ons_dur_amp : str or array Path to OpenFMRI stimulus file or 2D array containing three columns corresponding to onset, duration, amplitude. Returns ------- block_spec : array Structured array with fields "start" (corresponding to onset time), "end" (onset time plus duration), "amplitude". """ if not isinstance(ons_dur_amp, np.ndarray): ons_dur_amp = np.loadtxt(ons_dur_amp) onsets, durations, amplitudes = ons_dur_amp.T return make_recarray(np.column_stack( (onsets, onsets + durations, amplitudes)), names=['start', 'end', 'amplitude'], drop_name_dim=True)
def openfmri2nipy(ons_dur_amp): """ Contents of OpenFMRI condition file `ons_dur_map` as nipy recarray Parameters ---------- ons_dur_amp : str or array Path to OpenFMRI stimulus file or 2D array containing three columns corresponding to onset, duration, amplitude. Returns ------- block_spec : array Structured array with fields "start" (corresponding to onset time), "end" (onset time plus duration), "amplitude". """ if not isinstance(ons_dur_amp, np.ndarray): ons_dur_amp = np.loadtxt(ons_dur_amp) onsets, durations, amplitudes = ons_dur_amp.T return make_recarray( np.column_stack((onsets, onsets + durations, amplitudes)), names=['start', 'end', 'amplitude'], drop_name_dim=True)
def event_design(event_spec, t, order=2, hrfs=(glover, ), level_contrasts=False): """ Create design matrix from event specification `event_spec` Create a design matrix for linear model based on an event specification `event_spec`, evaluating the design rows at a sequence of time values `t`. Each column in the design matrix will be convolved with each HRF in `hrfs`. Parameters ---------- event_spec : np.recarray A recarray having at least a field named 'time' signifying the event time, and all other fields will be treated as factors in an ANOVA-type model. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. order : int, optional The highest order interaction to be considered in constructing the contrast matrices. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each event. Default is ``(glover,)``. level_contrasts : bool, optional If True, generate contrasts for each individual level of each factor. Returns ------- X : np.ndarray The design matrix with ``X.shape[0] == t.shape[0]``. The number of columns will depend on the other fields of `event_spec`. contrasts : dict Dictionary of contrasts that is expected to be of interest from the event specification. Each interaction / effect up to a given order will be returned. Also, a contrast is generated for each interaction / effect for each HRF specified in hrfs. """ fields = list(event_spec.dtype.names) if 'time' not in fields: raise ValueError('expecting a field called "time"') fields.pop(fields.index('time')) e_factors = [Factor(n, np.unique(event_spec[n])) for n in fields] e_formula = np.product(e_factors) e_contrasts = {} if len(e_factors) > 1: for i in range(1, order + 1): for comb in combinations(zip(fields, e_factors), i): names = [c[0] for c in comb] fs = [c[1].main_effect for c in comb] e_contrasts[":".join(names)] = np.product(fs).design( event_spec) e_contrasts['constant'] = formulae.I.design(event_spec) # Design and contrasts in event space # TODO: make it so I don't have to call design twice here # to get both the contrasts and the e_X matrix as a recarray e_X = e_formula.design(event_spec) e_dtype = e_formula.dtype # Now construct the design in time space t_terms = [] t_contrasts = {} for l, h in enumerate(hrfs): for n in e_dtype.names: term = events(event_spec['time'], amplitudes=e_X[n], f=h) t_terms += [term] if level_contrasts: t_contrasts['%s_%d' % (n, l)] = Formula([term]) for n, c in e_contrasts.items(): t_contrasts["%s_%d" % (n, l)] = Formula([ \ events(event_spec['time'], amplitudes=c[nn], f=h) for i, nn in enumerate(c.dtype.names)]) t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t, c_t = t_formula.design(tval, contrasts=t_contrasts) return X_t, c_t
def block_design(block_spec, t, order=2, hrfs=(glover, ), convolution_padding=5., convolution_dt=0.02, hrf_interval=(0., 30.), level_contrasts=False): """ Create a design matrix from specification of blocks `block_spec` Create design matrix for linear model from a block specification `block_spec`, evaluating design rows at a sequence of time values `t`. Each column in the design matrix will be convolved with each HRF in `hrfs`. Parameters ---------- block_spec : np.recarray A recarray having at least a field named 'start' and a field named 'end' signifying the block time, and all other fields will be treated as factors in an ANOVA-type model. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. order : int, optional The highest order interaction to be considered in constructing the contrast matrices. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each block. Default is ``(glover,)``. convolution_padding : float, optional A padding for the convolution with the HRF. The intervals used for the convolution are the smallest 'start' minus this padding to the largest 'end' plus this padding. convolution_dt : float, optional Time step for high-resolution time course for use in convolving the blocks with each HRF. hrf_interval: length 2 sequence of floats, optional Interval over which the HRF is assumed supported, used in the convolution. level_contrasts : bool, optional If true, generate contrasts for each individual level of each factor. Returns ------- X : np.ndarray The design matrix with X.shape[0] == t.shape[0]. The number of columns will depend on the other fields of block_spec. contrasts : dict Dictionary of contrasts that is expected to be of interest from the block specification. For each interaction / effect up to a given order will be returned. Also, a contrast is generated for each interaction / effect for each HRF specified in hrfs. """ fields = list(block_spec.dtype.names) if 'start' not in fields or 'end' not in fields: raise ValueError('expecting fields called "start" and "end"') fields.pop(fields.index('start')) fields.pop(fields.index('end')) e_factors = [Factor(n, np.unique(block_spec[n])) for n in fields] e_formula = np.product(e_factors) e_contrasts = {} if len(e_factors) > 1: for i in range(1, order + 1): for comb in combinations(zip(fields, e_factors), i): names = [c[0] for c in comb] fs = [c[1].main_effect for c in comb] e_contrasts[":".join(names)] = np.product(fs).design( block_spec) e_contrasts['constant'] = formulae.I.design(block_spec) # Design and contrasts in block space # TODO: make it so I don't have to call design twice here # to get both the contrasts and the e_X matrix as a recarray e_X = e_formula.design(block_spec) e_dtype = e_formula.dtype # Now construct the design in time space block_times = np.array([ (s, e) for s, e in zip(block_spec['start'], block_spec['end']) ]) convolution_interval = (block_times.min() - convolution_padding, block_times.max() + convolution_padding) t_terms = [] t_names = [] t_contrasts = {} for l, h in enumerate(hrfs): for n in e_dtype.names: B = blocks(block_times, amplitudes=e_X[n]) term = convolve_functions(B, h(T), convolution_interval, hrf_interval, convolution_dt) t_terms += [term] if level_contrasts: t_contrasts['%s_%d' % (n, l)] = Formula([term]) for n, c in e_contrasts.items(): F = [] for i, nn in enumerate(c.dtype.names): B = blocks(block_times, amplitudes=c[nn]) F.append( convolve_functions(B, h(T), convolution_interval, hrf_interval, convolution_dt)) t_contrasts["%s_%d" % (n, l)] = Formula(F) t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t, c_t = t_formula.design(tval, contrasts=t_contrasts) return X_t, c_t
from ... import utils, hrf, design from .. import hrf as delay from nipy.algorithms.statistics.models.regression import OLSModel from nipy.algorithms.statistics.formula import formulae from nipy.utils.compat3 import to_str # testing imports from nipy.testing import (dec, assert_true, assert_almost_equal) # Local imports from .FIACdesigns import (descriptions, fmristat, altdescr, N_ROWS, time_vector) t = formulae.make_recarray(time_vector, 't') def protocol(recarr, design_type, *hrfs): """ Create an object that can evaluate the FIAC Subclass of formulae.Formula, but not necessary. Parameters ---------- recarr : (N,) structured array with fields 'time' and 'event' design_type : str one of ['event', 'block']. Handles how the 'begin' term is handled. For 'block', the first event of each block is put in this group. For the 'event', only the first event is put in this
def block_amplitudes(name, block_spec, t, hrfs=(glover, ), convolution_padding=5., convolution_dt=0.02, hrf_interval=(0., 30.)): """ Design matrix at times `t` for blocks specification `block_spec` Create design matrix for linear model from a block specification `block_spec`, evaluating design rows at a sequence of time values `t`. `block_spec` may specify amplitude of response for each event, if different (see description of `block_spec` parameter below). The on-off step function implied by `block_spec` will be convolved with each HRF in `hrfs` to form a design matrix shape ``(len(t), len(hrfs))``. Parameters ---------- name : str Name of condition block_spec : np.recarray or array-like A recarray having fields ``start, end, amplitude``, or a 2D ndarray / array-like with three columns corresponding to start, end, amplitude. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each block. Default is ``(glover,)``. convolution_padding : float, optional A padding for the convolution with the HRF. The intervals used for the convolution are the smallest 'start' minus this padding to the largest 'end' plus this padding. convolution_dt : float, optional Time step for high-resolution time course for use in convolving the blocks with each HRF. hrf_interval: length 2 sequence of floats, optional Interval over which the HRF is assumed supported, used in the convolution. Returns ------- X : np.ndarray The design matrix with ``X.shape[0] == t.shape[0]``. The number of columns will be ``len(hrfs)``. contrasts : dict A contrast is generated for each HRF specified in `hrfs`. """ block_spec = np.asarray(block_spec) if block_spec.dtype.names is not None: if block_spec.dtype.names not in (('start', 'end'), ('start', 'end', 'amplitude')): raise ValueError('expecting fields called "start", "end" and ' '(optionally) "amplitude"') block_spec = np.array(block_spec.tolist()) block_times = block_spec[:, :2] amplitudes = block_spec[:, 2] if block_spec.shape[1] == 3 else None # Now construct the design in time space convolution_interval = (block_times.min() - convolution_padding, block_times.max() + convolution_padding) B = blocks(block_times, amplitudes=amplitudes) t_terms = [] c_t = {} n_hrfs = len(hrfs) for hrf_no in range(n_hrfs): t_terms.append( convolve_functions(B, hrfs[hrf_no](T), convolution_interval, hrf_interval, convolution_dt)) contrast = np.zeros(n_hrfs) contrast[hrf_no] = 1 c_t['{0}_{1:d}'.format(name, hrf_no)] = contrast t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t = t_formula.design(tval, return_float=True) return X_t, c_t
def event_design(event_spec, t, order=2, hrfs=(glover,), level_contrasts=False): """ Create design matrix from event specification `event_spec` Create a design matrix for linear model based on an event specification `event_spec`, evaluating the design rows at a sequence of time values `t`. Each column in the design matrix will be convolved with each HRF in `hrfs`. Parameters ---------- event_spec : np.recarray A recarray having at least a field named 'time' signifying the event time, and all other fields will be treated as factors in an ANOVA-type model. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. order : int, optional The highest order interaction to be considered in constructing the contrast matrices. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each event. Default is ``(glover,)``. level_contrasts : bool, optional If True, generate contrasts for each individual level of each factor. Returns ------- X : np.ndarray The design matrix with ``X.shape[0] == t.shape[0]``. The number of columns will depend on the other fields of `event_spec`. contrasts : dict Dictionary of contrasts that is expected to be of interest from the event specification. Each interaction / effect up to a given order will be returned. Also, a contrast is generated for each interaction / effect for each HRF specified in hrfs. """ fields = list(event_spec.dtype.names) if 'time' not in fields: raise ValueError('expecting a field called "time"') fields.pop(fields.index('time')) e_factors = [Factor(n, np.unique(event_spec[n])) for n in fields] e_formula = np.product(e_factors) e_contrasts = {} if len(e_factors) > 1: for i in range(1, order+1): for comb in combinations(zip(fields, e_factors), i): names = [c[0] for c in comb] fs = [c[1].main_effect for c in comb] e_contrasts[":".join(names)] = np.product(fs).design(event_spec) e_contrasts['constant'] = formulae.I.design(event_spec) # Design and contrasts in event space # TODO: make it so I don't have to call design twice here # to get both the contrasts and the e_X matrix as a recarray e_X = e_formula.design(event_spec) e_dtype = e_formula.dtype # Now construct the design in time space t_terms = [] t_contrasts = {} for l, h in enumerate(hrfs): for n in e_dtype.names: term = events(event_spec['time'], amplitudes=e_X[n], f=h) t_terms += [term] if level_contrasts: t_contrasts['%s_%d' % (n, l)] = Formula([term]) for n, c in e_contrasts.items(): t_contrasts["%s_%d" % (n, l)] = Formula([ \ events(event_spec['time'], amplitudes=c[nn], f=h) for i, nn in enumerate(c.dtype.names)]) t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t, c_t = t_formula.design(tval, contrasts=t_contrasts) return X_t, c_t
def block_design(block_spec, t, order=2, hrfs=(glover,), convolution_padding=5., convolution_dt=0.02, hrf_interval=(0.,30.), level_contrasts=False): """ Create a design matrix from specification of blocks `block_spec` Create design matrix for linear model from a block specification `block_spec`, evaluating design rows at a sequence of time values `t`. Each column in the design matrix will be convolved with each HRF in `hrfs`. Parameters ---------- block_spec : np.recarray A recarray having at least a field named 'start' and a field named 'end' signifying the block time, and all other fields will be treated as factors in an ANOVA-type model. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. order : int, optional The highest order interaction to be considered in constructing the contrast matrices. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each block. Default is ``(glover,)``. convolution_padding : float, optional A padding for the convolution with the HRF. The intervals used for the convolution are the smallest 'start' minus this padding to the largest 'end' plus this padding. convolution_dt : float, optional Time step for high-resolution time course for use in convolving the blocks with each HRF. hrf_interval: length 2 sequence of floats, optional Interval over which the HRF is assumed supported, used in the convolution. level_contrasts : bool, optional If true, generate contrasts for each individual level of each factor. Returns ------- X : np.ndarray The design matrix with X.shape[0] == t.shape[0]. The number of columns will depend on the other fields of block_spec. contrasts : dict Dictionary of contrasts that is expected to be of interest from the block specification. For each interaction / effect up to a given order will be returned. Also, a contrast is generated for each interaction / effect for each HRF specified in hrfs. """ fields = list(block_spec.dtype.names) if 'start' not in fields or 'end' not in fields: raise ValueError('expecting fields called "start" and "end"') fields.pop(fields.index('start')) fields.pop(fields.index('end')) e_factors = [Factor(n, np.unique(block_spec[n])) for n in fields] e_formula = np.product(e_factors) e_contrasts = {} if len(e_factors) > 1: for i in range(1, order+1): for comb in combinations(zip(fields, e_factors), i): names = [c[0] for c in comb] fs = [c[1].main_effect for c in comb] e_contrasts[":".join(names)] = np.product(fs).design(block_spec) e_contrasts['constant'] = formulae.I.design(block_spec) # Design and contrasts in block space # TODO: make it so I don't have to call design twice here # to get both the contrasts and the e_X matrix as a recarray e_X = e_formula.design(block_spec) e_dtype = e_formula.dtype # Now construct the design in time space block_times = np.array([(s,e) for s, e in zip(block_spec['start'], block_spec['end'])]) convolution_interval = (block_times.min() - convolution_padding, block_times.max() + convolution_padding) t_terms = [] t_names = [] t_contrasts = {} for l, h in enumerate(hrfs): for n in e_dtype.names: B = blocks(block_times, amplitudes=e_X[n]) term = convolve_functions(B, h(T), convolution_interval, hrf_interval, convolution_dt) t_terms += [term] if level_contrasts: t_contrasts['%s_%d' % (n, l)] = Formula([term]) for n, c in e_contrasts.items(): F = [] for i, nn in enumerate(c.dtype.names): B = blocks(block_times, amplitudes=c[nn]) F.append(convolve_functions(B, h(T), convolution_interval, hrf_interval, convolution_dt)) t_contrasts["%s_%d" % (n, l)] = Formula(F) t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t, c_t = t_formula.design(tval, contrasts=t_contrasts) return X_t, c_t
def block_amplitudes(name, block_spec, t, hrfs=(glover,), convolution_padding=5., convolution_dt=0.02, hrf_interval=(0.,30.)): """ Design matrix at times `t` for blocks specification `block_spec` Create design matrix for linear model from a block specification `block_spec`, evaluating design rows at a sequence of time values `t`. `block_spec` may specify amplitude of response for each event, if different (see description of `block_spec` parameter below). The on-off step function implied by `block_spec` will be convolved with each HRF in `hrfs` to form a design matrix shape ``(len(t), len(hrfs))``. Parameters ---------- name : str Name of condition block_spec : np.recarray or array-like A recarray having fields ``start, end, amplitude``, or a 2D ndarray / array-like with three columns corresponding to start, end, amplitude. t : np.ndarray An array of np.float values at which to evaluate the design. Common examples would be the acquisition times of an fMRI image. hrfs : sequence, optional A sequence of (symbolic) HRFs that will be convolved with each block. Default is ``(glover,)``. convolution_padding : float, optional A padding for the convolution with the HRF. The intervals used for the convolution are the smallest 'start' minus this padding to the largest 'end' plus this padding. convolution_dt : float, optional Time step for high-resolution time course for use in convolving the blocks with each HRF. hrf_interval: length 2 sequence of floats, optional Interval over which the HRF is assumed supported, used in the convolution. Returns ------- X : np.ndarray The design matrix with ``X.shape[0] == t.shape[0]``. The number of columns will be ``len(hrfs)``. contrasts : dict A contrast is generated for each HRF specified in `hrfs`. """ block_spec = np.asarray(block_spec) if block_spec.dtype.names is not None: if block_spec.dtype.names not in (('start', 'end'), ('start', 'end', 'amplitude')): raise ValueError('expecting fields called "start", "end" and ' '(optionally) "amplitude"') block_spec = np.array(block_spec.tolist()) block_times = block_spec[:, :2] amplitudes = block_spec[:, 2] if block_spec.shape[1] == 3 else None # Now construct the design in time space convolution_interval = (block_times.min() - convolution_padding, block_times.max() + convolution_padding) B = blocks(block_times, amplitudes=amplitudes) t_terms = [] c_t = {} n_hrfs = len(hrfs) for hrf_no in range(n_hrfs): t_terms.append(convolve_functions(B, hrfs[hrf_no](T), convolution_interval, hrf_interval, convolution_dt)) contrast = np.zeros(n_hrfs) contrast[hrf_no] = 1 c_t['{0}_{1:d}'.format(name, hrf_no)] = contrast t_formula = Formula(t_terms) tval = make_recarray(t, ['t']) X_t = t_formula.design(tval, return_float=True) return X_t, c_t