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 fourier_basis(freq): """ sin and cos Formula for Fourier drift The Fourier basis consists of sine and cosine waves of given frequencies. Parameters ---------- freq : sequence of float Frequencies for the terms in the Fourier basis. Returns ------- f : Formula Examples -------- >>> f=fourier_basis([1,2,3]) >>> f.terms array([cos(2*pi*t), sin(2*pi*t), cos(4*pi*t), sin(4*pi*t), cos(6*pi*t), sin(6*pi*t)], dtype=object) >>> f.mean _b0*cos(2*pi*t) + _b1*sin(2*pi*t) + _b2*cos(4*pi*t) + _b3*sin(4*pi*t) + _b4*cos(6*pi*t) + _b5*sin(6*pi*t) """ r = [] for f in freq: r += [ sympy.cos((2 * sympy.pi * f * T)), sympy.sin((2 * sympy.pi * f * T)) ] return Formula(r)
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
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