def test_events(): # test events utility function h = Function('hrf') evs = events([3,6,9]) yield assert_equal(DiracDelta(-9 + t) + DiracDelta(-6 + t) + DiracDelta(-3 + t), evs) evs = events([3,6,9], f=h) yield assert_equal(h(-3 + t) + h(-6 + t) + h(-9 + t), evs) # make some beta symbols b = [Symbol('b%d' % i, dummy=True) for i in range(3)] a = Symbol('a') p = b[0] + b[1]*a + b[2]*a**2 evs = events([3,6,9], amplitudes=[2,1,-1], g=p) yield assert_equal((2*b[1] + 4*b[2] + b[0])*DiracDelta(-3 + t) + (-b[1] + b[0] + b[2])*DiracDelta(-9 + t) + (b[0] + b[1] + b[2])*DiracDelta(-6 + t), evs) evs = events([3,6,9], amplitudes=[2,1,-1], g=p, f=h) yield assert_equal((2*b[1] + 4*b[2] + b[0])*h(-3 + t) + (-b[1] + b[0] + b[2])*h(-9 + t) + (b[0] + b[1] + b[2])*h(-6 + t), evs) # test no error for numpy int arrays onsets = np.array([30, 70, 100], dtype=np.int64) evs = events(onsets, f=mfhrf.glover)
def test_events(): # test events utility function h = Function('hrf') t = Term('t') evs = events([3,6,9]) yield assert_equal(DiracDelta(-9 + t) + DiracDelta(-6 + t) + DiracDelta(-3 + t), evs) evs = events([3,6,9], f=h) yield assert_equal(h(-3 + t) + h(-6 + t) + h(-9 + t), evs) # test no error for numpy int arrays onsets = np.array([30, 70, 100], dtype=np.int64) evs = events(onsets, f=mfhrf.glover)
def convolve_regressors(paradigm, hrf_model, names=None, fir_delays=[0], fir_duration=1.0): """ Creation of a formula that represents the convolution of the conditions onset witha certain hrf model Parameters ---------- paradigm: paradigm instance hrf_model, string that can be 'Canonical', 'Canonical With Derivative' or 'FIR' that specifies the hemodynamic reponse function names=None, list of strings corresponding to the condition names if names==None, these are create as 'c1',..,'cn' meaning 'condition 1'.. 'condition n' fir_delays=[0], optional, array of shape(nb_onsets) or list in case of FIR design, yields the array of delays used in the FIR model fir_duration=1., float, duration of the FIR block; in general it should eb equal to the tr Returns ------- f a formula object that contains the convolved regressors as functions of time names list of strings corresponding to the condition names the output names depend on teh hrf model used if 'Canonical' then this is identical to the input names if 'Canonical With Derivative', then two names are produced for input name 'name': 'name' and 'name_derivative' fixme: normalization of the columns of the design matrix ? """ ncond = int(paradigm.index.max() + 1) if names == None: names = ["c%d" % k for k in range(ncond)] else: if len(names) < ncond: raise ValueError, "the number of names is less than the \ number of conditions" else: ncond = len(names) listc = [] hnames = [] typep = paradigm.type for nc in range(ncond): onsets = paradigm.onset[paradigm.index == nc] nos = np.size(onsets) if paradigm.amplitude is not None: values = paradigm.amplitude[paradigm.index == nc] else: values = np.ones(nos) if nos > 0: if typep == "event": if hrf_model == "Canonical": c = utils.define(names[nc], utils.events(onsets, values, f=hrf.glover)) listc.append(c) hnames.append(names[nc]) elif hrf_model == "Canonical With Derivative": c1 = utils.define(names[nc], utils.events(onsets, values, f=hrf.glover)) c2 = utils.define(names[nc] + "_derivative", utils.events(onsets, values, f=hrf.dglover)) listc.append(c1) listc.append(c2) hnames.append(names[nc]) hnames.append(names[nc] + "_derivative") elif hrf_model == "FIR": for i, ft in enumerate(fir_delays): lnames = names[nc] + "_delay_%d" % i changes = np.hstack((onsets + ft, onsets + ft + fir_duration)) ochanges = np.argsort(changes) lvalues = np.hstack((values, np.zeros(nos))) changes = changes[ochanges] lvalues = lvalues[ochanges] c = utils.define(lnames, utils.step_function(changes, lvalues)) listc.append(c) hnames.append(lnames) else: raise NotImplementedError, "unknown hrf model" elif typep == "block": offsets = onsets + paradigm.duration[paradigm.type == nc] changes = np.hstack((onsets, offsets)) values = np.hstack((values, -values)) if hrf_model == "Canonical": c = utils.events(changes, values, f=hrf.iglover) listc.append(c) hnames.append(names[nc]) elif hrf_model == "Canonical With Derivative": c1 = utils.events(changes, values, f=hrf.iglover) c2 = utils.events(changes, values, f=hrf.glover) listc.append(c1) listc.append(c2) hnames.append(names[nc]) hnames.append(names[nc] + "_derivative") elif hrf_model == "FIR": raise NotImplementedError, "block design are not compatible with FIR at the moment" else: raise NotImplementedError, "unknown hrf model" # create the formula p = formula.Formula(listc) return p, hnames
from nipy.modalities.fmri.utils import events, Symbol, lambdify_t from nipy.modalities.fmri.hrf import glover # Symbol for amplitude a = Symbol('a') # Some event onsets regularly spaced onsets = np.linspace(0,50,6) # Make amplitudes from onset times (greater as function of time) amplitudes = onsets[:] # Flip even numbered amplitudes amplitudes = amplitudes * ([-1, 1] * 3) # Make event functions evs = events(onsets, amplitudes=amplitudes, g=a + 0.5 * a**2, f=glover) # Real valued function for symbolic events real_evs = lambdify_t(evs) # Time points at which to sample t_samples = np.linspace(0,60,601) pylab.plot(t_samples, real_evs(t_samples), c='r') for onset, amplitude in zip(onsets, amplitudes): pylab.plot([onset, onset],[0, 25 * amplitude], c='b') pylab.show()
def protocol(recarr, design_type, *hrfs): """ Create an object that can evaluate the FIAC Subclass of formula.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 group. The 'begin' events are convolved with hrf.glover. hrfs: symoblic HRFs Each event type ('SSt_SSp','SSt_DSp','DSt_SSp','DSt_DSp') is convolved with each of these HRFs in order. Returns ------- f: Formula Formula for constructing design matrices. contrasts : dict Dictionary of the contrasts of the experiment. """ event_types = np.unique(recarr['event']) N = recarr.size if design_type == 'block': keep = np.not_equal((np.arange(N)) % 6, 0) else: keep = np.greater(np.arange(N), 0) # This first frame was used to model out a potentially # 'bad' first frame.... _begin = recarr['time'][~keep] termdict = {} termdict['begin'] = utils.define('begin', utils.events(_begin, f=hrf.glover)) drift = formula.natural_spline(utils.T, knots=[N_ROWS/2.+1.25], intercept=True) for i, t in enumerate(drift.terms): termdict['drift%d' % i] = t # After removing the first frame, keep the remaining # events and times times = recarr['time'][keep] events = recarr['event'][keep] # Now, specify the experimental conditions # This creates expressions # named SSt_SSp0, SSt_SSp1, etc. # with one expression for each (eventtype, hrf) pair for v in event_types: for l, h in enumerate(hrfs): k = np.array([events[i] == v for i in range(times.shape[0])]) termdict['%s%d' % (v,l)] = utils.define("%s%d" % (v, l), utils.events(times[k], f=h)) f = formula.Formula(termdict.values()) Tcontrasts = {} Tcontrasts['average'] = (termdict['SSt_SSp0'] + termdict['SSt_DSp0'] + termdict['DSt_SSp0'] + termdict['DSt_DSp0']) / 4. Tcontrasts['speaker'] = (termdict['SSt_DSp0'] - termdict['SSt_SSp0'] + termdict['DSt_DSp0'] - termdict['DSt_SSp0']) * 0.5 Tcontrasts['sentence'] = (termdict['DSt_DSp0'] + termdict['DSt_SSp0'] - termdict['SSt_DSp0'] - termdict['SSt_SSp0']) * 0.5 Tcontrasts['interaction'] = (termdict['SSt_SSp0'] - termdict['SSt_DSp0'] - termdict['DSt_SSp0'] + termdict['DSt_DSp0']) # Ftest Fcontrasts = {} Fcontrasts['overall1'] = formula.Formula(Tcontrasts.values()) return f, Tcontrasts, Fcontrasts
#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ A simple contrast for an FMRI HRF model """ from __future__ import print_function # Python 2/3 compatibility import numpy as np from nipy.algorithms.statistics.api import Formula, make_recarray from nipy.modalities.fmri import utils, hrf from nipy.modalities.fmri.fmristat import hrf as delay # We take event onsets, and a specified HRF model, and make symbolic functions # of time c1 = utils.events([3, 7, 10], f=hrf.glover) # Symbolic function of time c2 = utils.events([1, 3, 9], f=hrf.glover) # Symbolic function of time c3 = utils.events([3, 4, 6], f=delay.spectral[0]) # Symbolic function of time # We can also use a Fourier basis for some other onsets - again making symbolic # functions of time d = utils.fourier_basis([3, 5, 7]) # Formula # Make a formula for all four sets of onsets f = Formula([c1, c2, c3]) + d # A contrast is a formula expressed on the elements of the design formula contrast = Formula([c1 - c2, c1 - c3]) # Instantiate actual values of time at which to create the design matrix rows t = make_recarray(np.linspace(0, 20, 50), 't')
""" import numpy as np import sympy from nipy.algorithms.statistics.api import Formula, make_recarray from nipy.modalities.fmri import utils, hrf # Inter-stimulus intervals (time between events) dt = np.random.uniform(low=0, high=2.5, size=(50,)) # Onset times from the ISIs t = np.cumsum(dt) # We're going to model the amplitudes ('a') by dt (the time between events) a = sympy.Symbol('a') linear = utils.define('linear', utils.events(t, dt, f=hrf.glover)) quadratic = utils.define('quad', utils.events(t, dt, f=hrf.glover, g=a**2)) cubic = utils.define('cubic', utils.events(t, dt, f=hrf.glover, g=a**3)) f1 = Formula([linear, quadratic, cubic]) # Evaluate this time-based formula at specific times to make the design matrix tval = make_recarray(np.linspace(0,100, 1001), 't') X1 = f1.design(tval, return_float=True) # Now we make a model where the relationship of time between events and signal # is an exponential with a time constant tau l = sympy.Symbol('l') exponential = utils.events(t, dt, f=hrf.glover, g=sympy.exp(-l*a)) f3 = Formula([exponential])
import numpy as np import nipy.testing as niptest import sympy from nipy.modalities.fmri import formula, utils, hrf from nipy.modalities.fmri.fmristat import hrf as delay c1 = utils.events([3,7,10], f=hrf.glover) # Symbolic function of time c2 = utils.events([1,3,9], f=hrf.glover) # Symbolic function of time c3 = utils.events([3,4,6], f=delay.spectral[0]) d = utils.fourier_basis([3,5,7]) # Formula f = formula.Formula([c1,c2,c3]) + d contrast = formula.Formula([c1-c2, c1-c3]) t = formula.make_recarray(np.linspace(0,20,50), 't') X, c = f.design(t, return_float=True, contrasts={'C':contrast}) preC = contrast.design(t, return_float=True) C = np.dot(np.linalg.pinv(X), preC).T niptest.assert_almost_equal(C, c['C']) print C
k1, k2, k3 = knots[i:i+3] d1 = k2-k1 def anon(x,k1=k1,k2=k2,k3=k3): return ((x-k1) / d1 * np.greater(x, k1) * np.less_equal(x, k2) + (k3-x) / d1 * np.greater(x, k2) * np.less(x, k3)) fns.append(implemented_function(name, anon)) return fns # The splines are functions of t (time) bsp_fns = linBspline(np.arange(0,10,2)) # We're going to evaluate at these specific values of time tt = np.linspace(0,50,101) tvals= tt.view(np.dtype([('t', np.float)])) # Some interstimulus intervals isis = np.random.uniform(low=0, high=3, size=(4,)) + 10. # Made into event onset times e = np.cumsum(isis) f = Formula([utils.events(e, f=fn) for fn in bsp_fns]) # The design matrix X = f.design(tvals, return_float=True) plt.plot(X[:,0]) plt.plot(X[:,1]) plt.plot(X[:,2]) plt.show()
def convolve_regressors(paradigm, hrf_model, end_time, fir_delays=[0], fir_duration=1.): """ Creation of a formula that represents the convolution of the conditions onset with a certain hrf model Parameters ---------- paradigm: paradigm instance hrf_model: string that can be 'Canonical', 'Canonical With Derivative' or 'FIR' that specifies the hemodynamic reponse function end_time: float, end time of the paradigm (needed only for block designs) fir_delays=[0], optional, array of shape(nb_onsets) or list in case of FIR design, yields the array of delays used in the FIR model fir_duration=1., float, duration of the FIR block in general it should eb equal to the tr Returns ------- f: formula instance, contains the convolved regressors as functions of time names: list of strings, the condition names, that depend on the hrf model used if 'Canonical' then this is identical to the input names if 'Canonical With Derivative', then two names are produced for input name 'name': 'name' and 'name_derivative' fixme ----- normalization of the columns of the design matrix ? """ listc = [] hnames = [] typep = paradigm.type for nc in np.unique(paradigm.con_id): onsets = paradigm.onset[paradigm.con_id == nc] nos = np.size(onsets) if paradigm.amplitude is not None: values = paradigm.amplitude[paradigm.con_id == nc] else: values = np.ones(nos) if nos < 1: continue if typep == 'event': if hrf_model == "Canonical": c = utils.define( nc, utils.events(onsets, values, f=hrf.glover)) listc.append(c) hnames.append(nc) elif hrf_model == "Canonical With Derivative": c1 = utils.define( nc, utils.events(onsets, values, f=hrf.glover)) c2 = utils.define(nc + "_derivative", utils.events(onsets, values, f=hrf.dglover)) listc.append(c1) listc.append(c2) hnames.append(nc) hnames.append(nc + "_derivative") elif hrf_model == "FIR": for i, ft in enumerate(fir_delays): lnames = nc + "_delay_%d" % i changes = np.hstack((onsets + ft, onsets + ft + fir_duration)) ochanges = np.argsort(changes) lvalues = np.hstack((values, np.zeros(nos))) changes = changes[ochanges] lvalues = lvalues[ochanges] c = utils.define(lnames, utils.step_function(changes, lvalues)) listc.append(c) hnames.append(lnames) else: raise NotImplementedError('unknown hrf model') elif typep == 'block': offsets = onsets + paradigm.duration[paradigm.con_id == nc] intervals = [[on, off] for (on, off) in zip(onsets, offsets)] blks = utils.blocks(intervals, values) changes = np.hstack((onsets, offsets)) cvalues = np.hstack((values, - values)) if hrf_model == "Canonical": c = utils.convolve_functions(blks, hrf.glover(hrf.T), [0, end_time], 0.001) listc.append(c) hnames.append(nc) elif hrf_model == "Canonical With Derivative": c1 = utils.convolve_functions(blks, hrf.glover(hrf.T), [0, end_time], 0.001) c2 = utils.events(changes, cvalues, f=hrf.glover) listc.append(c1) listc.append(c2) hnames.append(nc) hnames.append(nc + "_derivative") elif hrf_model == "FIR": raise NotImplementedError( 'block design are not compatible with FIR') else: raise NotImplementedError('unknown hrf model') # create the formula p = formula.Formula(listc) return p, hnames
from nipy.modalities.fmri.utils import events, Symbol, lambdify_t from nipy.modalities.fmri.hrf import glover # Symbol for amplitude a = Symbol('a') # Some event onsets regularly spaced onsets = np.linspace(0, 50, 6) # Make amplitudes from onset times (greater as function of time) amplitudes = onsets[:] # Flip even numbered amplitudes amplitudes = amplitudes * ([-1, 1] * 3) # Make event functions evs = events(onsets, amplitudes=amplitudes, g=a + 0.5 * a**2, f=glover) # Real valued function for symbolic events real_evs = lambdify_t(evs) # Time points at which to sample t_samples = np.linspace(0, 60, 601) pylab.plot(t_samples, real_evs(t_samples), c='r') for onset, amplitude in zip(onsets, amplitudes): pylab.plot([onset, onset], [0, 25 * amplitude], c='b') pylab.show()
def protocol(fh, design_type, *hrfs): """ Create an object that can evaluate the FIAC. Subclass of formula.Formula, but not necessary. Parameters: ----------- fh : file handler File-like object that reads in the FIAC design, i.e. like file('subj1_evt_fonc3.txt') design_type : str in ['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 group. The 'begin' events are convolved with hrf.glover. hrfs: symoblic HRFs Each event type ('SSt_SSp','SSt_DSp','DSt_SSp','DSt_DSp') is convolved with each of these HRFs in order. Outputs: -------- f: Formula Formula for constructing design matrices. contrasts : dict Dictionary of the contrasts of the experiment. """ eventdict = {1: "SSt_SSp", 2: "SSt_DSp", 3: "DSt_SSp", 4: "DSt_DSp"} fh = fh.read().strip().splitlines() times = [] events = [] for row in fh: time, eventtype = map(float, row.split()) times.append(time) events.append(eventdict[eventtype]) if design_type == "block": keep = np.not_equal((np.arange(len(times))) % 6, 0) else: keep = np.greater(np.arange(len(times)), 0) # This first frame was used to model out a potentially # 'bad' first frame.... _begin = np.array(times)[~keep] termdict = {} termdict["begin"] = formula.define("begin", utils.events(_begin, f=hrf.glover)) drift = formula.natural_spline(hrf.t, knots=[191 / 2.0 + 1.25], intercept=True) for i, t in enumerate(drift.terms): termdict["drift%d" % i] = t # After removing the first frame, keep the remaining # events and times times = np.array(times)[keep] events = np.array(events)[keep] # Now, specify the experimental conditions # This creates expressions # named SSt_SSp0, SSt_SSp1, etc. # with one expression for each (eventtype, hrf) pair for v in eventdict.values(): for l, h in enumerate(hrfs): k = np.array([events[i] == v for i in range(times.shape[0])]) termdict["%s%d" % (v, l)] = formula.define("%s%d" % (v, l), utils.events(times[k], f=h)) f = formula.Formula(termdict.values()) Tcontrasts = {} Tcontrasts["average"] = ( termdict["SSt_SSp0"] + termdict["SSt_DSp0"] + termdict["DSt_SSp0"] + termdict["DSt_DSp0"] ) / 4.0 Tcontrasts["speaker"] = ( termdict["SSt_DSp0"] - termdict["SSt_SSp0"] + termdict["DSt_DSp0"] - termdict["DSt_SSp0"] ) * 0.5 Tcontrasts["sentence"] = ( termdict["DSt_DSp0"] + termdict["DSt_SSp0"] - termdict["SSt_DSp0"] - termdict["SSt_SSp0"] ) * 0.5 Tcontrasts["interaction"] = ( termdict["SSt_SSp0"] - termdict["SSt_DSp0"] - termdict["DSt_SSp0"] + termdict["DSt_DSp0"] ) # Ftest Fcontrasts = {} Fcontrasts["overall1"] = formula.Formula(Tcontrasts.values()) return f, Tcontrasts, Fcontrasts
def altprotocol(fh, design_type, *hrfs): """ Create an object that can evaluate the FIAC. Subclass of formula.Formula, but not necessary. Parameters: ----------- fh : file handler File-like object that reads in the FIAC design, but has a different format (test_FIACdata.altdescr) design_type : str in ['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 group. The 'begin' events are convolved with hrf.glover. hrfs: symoblic HRFs Each event type ('SSt_SSp','SSt_DSp','DSt_SSp','DSt_DSp') is convolved with each of these HRFs in order. """ d = csv2rec(fh) if design_type == "block": keep = np.not_equal((np.arange(d.time.shape[0])) % 6, 0) else: keep = np.greater(np.arange(d.time.shape[0]), 0) # This first frame was used to model out a potentially # 'bad' first frame.... _begin = d.time[~keep] d = d[keep] termdict = {} termdict["begin"] = formula.define("begin", utils.events(_begin, f=hrf.glover)) drift = formula.natural_spline(hrf.t, knots=[191 / 2.0 + 1.25], intercept=True) for i, t in enumerate(drift.terms): termdict["drift%d" % i] = t # Now, specify the experimental conditions # The elements of termdict are DiracDeltas, rather than HRFs st = formula.Factor("sentence", ["DSt", "SSt"]) sp = formula.Factor("speaker", ["DSp", "SSp"]) indic = {} indic["sentence"] = st.main_effect indic["speaker"] = sp.main_effect indic["interaction"] = st.main_effect * sp.main_effect indic["average"] = formula.I for key in indic.keys(): # The matrix signs will be populated with +- 1's # d is the recarray having fields ('time', 'sentence', 'speaker') signs = indic[key].design(d, return_float=True) for l, h in enumerate(hrfs): # symb is a sympy expression representing a sum # of [h(t-_t) for _t in d.time] symb = utils.events(d.time, amplitudes=signs, f=h) # the values of termdict will have keys like # 'average0', 'speaker1' # and values that are sympy expressions like average0(t), # speaker1(t) termdict["%s%d" % (key, l)] = formula.define("%s%d" % (key, l), symb) f = formula.Formula(termdict.values()) Tcontrasts = {} Tcontrasts["average"] = termdict["average0"] Tcontrasts["speaker"] = termdict["speaker0"] Tcontrasts["sentence"] = termdict["sentence0"] Tcontrasts["interaction"] = termdict["interaction0"] # F tests Fcontrasts = {} Fcontrasts["overall1"] = formula.Formula(Tcontrasts.values()) nhrf = len(hrfs) Fcontrasts["averageF"] = formula.Formula([termdict["average%d" % j] for j in range(nhrf)]) Fcontrasts["speakerF"] = formula.Formula([termdict["speaker%d" % j] for j in range(nhrf)]) Fcontrasts["sentenceF"] = formula.Formula([termdict["sentence%d" % j] for j in range(nhrf)]) Fcontrasts["interactionF"] = formula.Formula([termdict["interaction%d" % j] for j in range(nhrf)]) Fcontrasts["overall2"] = ( Fcontrasts["averageF"] + Fcontrasts["speakerF"] + Fcontrasts["sentenceF"] + Fcontrasts["interactionF"] ) return f, Tcontrasts, Fcontrasts
from nipy.algorithms.statistics.api import Term, Formula, Factor from nipy.modalities.fmri import utils, hrf # HRF models we will use for each run. Just to show it can be done, use a # different HRF model for each run h1 = hrf.glover h2 = hrf.afni # Symbol for time in general. The 'events' function below will return models in # terms of 't', but we'll want models in terms of 't1' and 't2'. We need 't' # here so we can substitute. t = Term('t') # run 1 t1 = Term('t1') # Time within run 1 c11 = utils.events([3, 7, 10], f=h1) # Condition 1, run 1 # The events utility returns a formula in terms of 't' - general time c11 = c11.subs(t, t1) # Now make it in terms of time in run 1 # Same for conditions 2 and 3 c21 = utils.events([1, 3, 9], f=h1) c21 = c21.subs(t, t1) c31 = utils.events([2, 4, 8], f=h1) c31 = c31.subs(t, t1) # Add also a Fourier basis set for drift with frequencies 0.3, 0.5, 0.7 d1 = utils.fourier_basis([0.3, 0.5, 0.7]) d1 = d1.subs(t, t1) # Here's our formula for run 1 signal terms of time in run 1 (t1) f1 = Formula([c11, c21, c31]) + d1 # run 2
import numpy as np import sympy from nipy.modalities.fmri import formula, utils, hrf # hrf h1 = sympy.Function("hrf1") h2 = sympy.Function("hrf2") t = formula.Term("t") # Session 1 t1 = formula.Term("t1") c11 = utils.events([3, 7, 10], f=h1) c11 = c11.subs(t, t1) c21 = utils.events([1, 3, 9], f=h1) c21 = c21.subs(t, t1) c31 = utils.events([2, 4, 8], f=h1) c31 = c31.subs(t, t1) d1 = utils.fourier_basis([0.3, 0.5, 0.7]) d1 = d1.subs(t, t1) tval1 = np.linspace(0, 20, 101) f1 = formula.Formula([c11, c21, c31]) + d1 f1 = f1.subs("hrf1", hrf.glover) # Session 2 t2 = formula.Term("t2") c12 = utils.events([3.3, 7, 10], f=h2) c12 = c12.subs(t, t2)
# The splines are functions of t (time) bsp_fns = linBspline(np.arange(0,10,2)) # We're going to evaluate at these specific values of time tt = np.linspace(0,50,101) tvals= tt.view(np.dtype([('t', np.float)])) # Some interstimulus intervals isis = np.random.uniform(low=0, high=3, size=(4,)) + 10. # Made into event onset times e = np.cumsum(isis) # Make event onsets into functions of time convolved with the spline functions. event_funcs = [utils.events(e, f=fn) for fn in bsp_fns] # Put into a formula. f = Formula(event_funcs) # The design matrix X = f.design(tvals, return_float=True) # Show the design matrix as line plots plt.plot(X[:,0]) plt.plot(X[:,1]) plt.plot(X[:,2]) plt.xlabel('time (s)') plt.title('B spline used as bases for an FIR response model') plt.show()
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import numpy as np import sympy from nipy.modalities.fmri import formula, utils, hrf # hrf h1 = sympy.Function('hrf1') h2 = sympy.Function('hrf2') t = formula.Term('t') # Session 1 t1 = formula.Term('t1') c11 = utils.events([3,7,10], f=h1); c11 = c11.subs(t, t1) c21 = utils.events([1,3,9], f=h1); c21 = c21.subs(t, t1) c31 = utils.events([2,4,8], f=h1); c31 = c31.subs(t, t1) d1 = utils.fourier_basis([0.3,0.5,0.7]); d1 = d1.subs(t, t1) tval1 = np.linspace(0,20,101) f1 = formula.Formula([c11,c21,c31]) + d1 f1 = f1.subs('hrf1', hrf.glover) # Session 2 t2 = formula.Term('t2') c12 = utils.events([3.3,7,10], f=h2); c12 = c12.subs(t, t2) c22 = utils.events([1,3.2,9], f=h2); c22 = c22.subs(t, t2) c32 = utils.events([2,4.2,8], f=h2); c32 = c32.subs(t, t2) d2 = utils.fourier_basis([0.3,0.5,0.7]); d2 = d2.subs(t, t2)
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import numpy as np import pylab from nipy.modalities.fmri.utils import events, Symbol, Vectorize from nipy.modalities.fmri.hrf import glover_sympy a = Symbol('a') b = np.linspace(0,50,6) ba = b*([-1,1]*3) d = events(b, amplitudes=ba, g=a+0.5*a**2, f=glover_sympy) dt = Vectorize(d) tt = np.linspace(0,60,601) pylab.plot(tt, dt(tt), c='r') for bb, aa in zip(b,ba): pylab.plot([bb,bb],[0,25*aa], c='b') pylab.show()
def convolve_regressors(paradigm, hrf_model, names=None, fir_delays=[0], fir_duration = 1.): """ Creation of a formula that represents the convolution of the conditions onset witha certain hrf model Parameters ---------- paradigm array of shape (nevents,2) if the type is event-related design or (nenvets,3) for a block design that contains (condition id, onset) or (condition id, onset, duration) hrf_model, string that can be 'Canonical', 'Canonical With Derivative' or 'FIR' that specifies the hemodynamic reponse function names=None, list of strings corresponding to the condition names if names==None, these are create as 'c1',..,'cn' meaning 'condition 1'.. 'condition n' fir_delays=[0], optional, array of shape(nb_onsets) or list in case of FIR design, yields the array of delays used in the FIR model fir_duration=1., float, duration of the FIR block; in general it should eb equal to the tr Returns ------- f a formula object that contains the convolved regressors as functions of time names list of strings corresponding to the condition names the output names depend on teh hrf model used if 'Canonical' then this is identical to the input names if 'Canonical With Derivative', then two names are produced for input name 'name': 'name' and 'name_derivative' fixme: normalization of the columns of the design matrix ? """ paradigm = np.asarray(paradigm) if paradigm.ndim !=2: raise ValueError('Paradigm should have 2 dimensions') ncond = int(paradigm[:,0].max()+1) if names==None: names=["c%d" % k for k in range(ncond)] else: if len(names)<ncond: raise ValueError, 'the number of names is less than the \ number of conditions' else: ncond = len(names) listc = [] hnames = [] if paradigm.shape[1]>2: typep = 'block' else: typep='event' for nc in range(ncond): onsets = paradigm[paradigm[:,0]==nc,1] nos = np.size(onsets) if nos>0: if typep=='event': if hrf_model=="Canonical": c = formula.define(names[nc], utils.events(onsets, f=hrf.glover)) listc.append(c) hnames.append(names[nc]) elif hrf_model=="Canonical With Derivative": c1 = formula.define(names[nc], utils.events(onsets, f=hrf.glover)) c2 = formula.define(names[nc]+"_derivative", utils.events(onsets, f=hrf.dglover)) listc.append(c1) listc.append(c2) hnames.append(names[nc]) hnames.append(names[nc]+"_derivative") elif hrf_model=="FIR": for i,ft in enumerate(fir_delays): lnames = names[nc]+"_delay_%d"%i changes = np.hstack((onsets+ft,onsets+ft+fir_duration)) ochanges = np.argsort(changes) values = np.hstack((np.ones(nos), np.zeros(nos))) changes = changes[ochanges] values = values[ochanges] c = formula.define(lnames, utils.step_function(changes,values)) listc.append(c) hnames.append(lnames) else: raise NotImplementedError,'unknown hrf model' elif typep=='block': offsets = onsets+paradigm[paradigm[:,0]==nc,2] changes = np.hstack((onsets,offsets)) values = np.hstack((np.ones(nos), -np.ones(nos))) if hrf_model=="Canonical": c = utils.events(changes,values, f=hrf.iglover) listc.append(c) hnames.append(names[nc]) elif hrf_model=="Canonical With Derivative": c1 = utils.events(changes,values, f=hrf.iglover) c2 = utils.events(changes,values, f=hrf.glover) listc.append(c1) listc.append(c2) hnames.append(names[nc]) hnames.append(names[nc]+"_derivative") elif hrf_model=="FIR": raise NotImplementedError,\ 'block design are not compatible with FIR at the moment' else: raise NotImplementedError,'unknown hrf model' else: raise NotImplementedError,'unknown type of paradigm' # create the formula p = formula.Formula(listc) return p, hnames
the amount of time since the last stimulus T[i-1] """ import numpy as np import nipy.testing as niptest import sympy from nipy.modalities.fmri import utils, formula, hrf dt = np.random.uniform(low=0, high=2.5, size=(50,)) t = np.cumsum(dt) a = sympy.Symbol("a") linear = formula.define("linear", utils.events(t, dt, f=hrf.glover)) quadratic = formula.define("quad", utils.events(t, dt, f=hrf.glover, g=a ** 2)) cubic = formula.define("cubic", utils.events(t, dt, f=hrf.glover, g=a ** 3)) f1 = formula.Formula([linear, quadratic, cubic]) # Evaluate them tval = formula.make_recarray(np.linspace(0, 100, 1001), "t") X1 = f1.design(tval, return_float=True) # Let's make it exponential with a time constant tau l = sympy.Symbol("l") exponential = utils.events(t, dt, f=hrf.glover, g=sympy.exp(-l * a)) f3 = formula.Formula([exponential])
def altprotocol(d, design_type, *hrfs): """ Create an object that can evaluate the FIAC. Subclass of formula.Formula, but not necessary. Parameters ---------- d : np.recarray recarray defining design in terms of time, sentence speaker design_type : str in ['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 group. The 'begin' events are convolved with hrf.glover. hrfs: symoblic HRFs Each event type ('SSt_SSp','SSt_DSp','DSt_SSp','DSt_DSp') is convolved with each of these HRFs in order. """ if design_type == 'block': keep = np.not_equal((np.arange(d.time.shape[0])) % 6, 0) else: keep = np.greater(np.arange(d.time.shape[0]), 0) # This first frame was used to model out a potentially # 'bad' first frame.... _begin = d.time[~keep] d = d[keep] termdict = {} termdict['begin'] = utils.define('begin', utils.events(_begin, f=hrf.glover)) drift = formula.natural_spline(utils.T, knots=[N_ROWS/2.+1.25], intercept=True) for i, t in enumerate(drift.terms): termdict['drift%d' % i] = t # Now, specify the experimental conditions # The elements of termdict are DiracDeltas, rather than HRFs st = formula.Factor('sentence', ['DSt', 'SSt']) sp = formula.Factor('speaker', ['DSp', 'SSp']) indic = {} indic['sentence'] = st.main_effect indic['speaker'] = sp.main_effect indic['interaction'] = st.main_effect * sp.main_effect indic['average'] = formula.I for key in indic.keys(): # The matrix signs will be populated with +- 1's # d is the recarray having fields ('time', 'sentence', 'speaker') signs = indic[key].design(d, return_float=True) for l, h in enumerate(hrfs): # symb is a sympy expression representing a sum # of [h(t-_t) for _t in d.time] symb = utils.events(d.time, amplitudes=signs, f=h) # the values of termdict will have keys like # 'average0', 'speaker1' # and values that are sympy expressions like average0(t), # speaker1(t) termdict['%s%d' % (key, l)] = utils.define("%s%d" % (key, l), symb) f = formula.Formula(termdict.values()) Tcontrasts = {} Tcontrasts['average'] = termdict['average0'] Tcontrasts['speaker'] = termdict['speaker0'] Tcontrasts['sentence'] = termdict['sentence0'] Tcontrasts['interaction'] = termdict['interaction0'] # F tests Fcontrasts = {} Fcontrasts['overall1'] = formula.Formula(Tcontrasts.values()) nhrf = len(hrfs) Fcontrasts['averageF'] = formula.Formula([termdict['average%d' % j] for j in range(nhrf)]) Fcontrasts['speakerF'] = formula.Formula([termdict['speaker%d' % j] for j in range(nhrf)]) Fcontrasts['sentenceF'] = formula.Formula([termdict['sentence%d' % j] for j in range(nhrf)]) Fcontrasts['interactionF'] = formula.Formula([termdict['interaction%d' % j] for j in range(nhrf)]) Fcontrasts['overall2'] = Fcontrasts['averageF'] + Fcontrasts['speakerF'] + Fcontrasts['sentenceF'] + Fcontrasts['interactionF'] return f, Tcontrasts, Fcontrasts
# The splines are functions of t (time) bsp_fns = linBspline(np.arange(0, 10, 2)) # We're going to evaluate at these specific values of time tt = np.linspace(0, 50, 101) tvals = tt.view(np.dtype([('t', np.float)])) # Some inter-stimulus intervals isis = np.random.uniform(low=0, high=3, size=(4, )) + 10. # Made into event onset times e = np.cumsum(isis) # Make event onsets into functions of time convolved with the spline functions. event_funcs = [utils.events(e, f=fn) for fn in bsp_fns] # Put into a formula. f = Formula(event_funcs) # The design matrix X = f.design(tvals, return_float=True) # Show the design matrix as line plots plt.plot(X[:, 0]) plt.plot(X[:, 1]) plt.plot(X[:, 2]) plt.xlabel('time (s)') plt.title('B spline used as bases for an FIR response model') plt.show()
d2 = k3-k2 def anon(x,k1=k1,k2=k2,k3=k3): return ((x-k1) / d1 * np.greater(x, k1) * np.less_equal(x, k2) + (k3-x) / d1 * np.greater(x, k2) * np.less(x, k3)) fns.append((n, anon)) symbols.append(s(t)) ff = formula.Formula(symbols) for n, l in fns: ff.aliases[n] = l return ff t = formula.Term('t') bsp = linBspline(t, np.arange(0,10,2)) tt = np.linspace(0,50,101) tval = tt.view(np.dtype([('t', np.float)])) e = np.random.uniform(low=0, high=3, size=(20,)) + 20. e = np.cumsum(e) f = formula.Formula([utils.events(e, f=hrf.symbolic(term)) for term in bsp.design]) for k, v in bsp.aliases.items(): f.aliases[k] = v d = formula.Design(f, return_float=True) X = d(tval) pylab.plot(X[:,0]) pylab.plot(X[:,1]) pylab.plot(X[:,2]) pylab.show()