Exemple #1
0
def test_define():
    expr = sympy.exp(3*t)
    yield assert_equal(str(expr), 'exp(3*t)')
    newf = define('f', expr)
    yield assert_equal(str(newf), 'f(t)')
    f = lambdify_t(newf)
    tval = np.random.standard_normal((3,))
    yield assert_almost_equal(np.exp(3*tval), f(tval))
Exemple #2
0
def _blankdrift():
    """ Create the blank drift formula

    Returns
    -------
    df  a formula that contains a constant regressor
    """
    t = formula.Term('t')
    pt = [utils.define('constant', 1.0 + 0 * t)]
    df = formula.Formula(pt)
    return df
Exemple #3
0
def _polydrift(order, tmax):
    """
    Create a polynomial drift formula
    
    Parameters
    ----------
    order, int, number of polynomials in the drift model
    tmax, float maximal time value used in the sequence
          this is used to normalize porperly the columns
    
    Returns
    -------
    pol a formula that contains all the polynomial drift 
    plus a constant regressor
    """
    t = formula.Term("t")
    pt = []
    # fixme : ideally  this should be orthonormalized
    for k in range(order):
        pt.append(utils.define("poly_drift_%d" % (k + 1), t ** (k + 1) / tmax ** (k + 1)))
    pt.append(utils.define("constant", 1.0 + 0 * t))
    pol = formula.Formula(pt)
    return pol
Exemple #4
0
def _cosinedrift(hfcut, tmax, tsteps):
    """
    Create a cosine drift formula

    Parameters
    ----------
    hfcut, float , cut frequency of the low-pass filter
    tmax, float  maximal time value used in the sequence
    tsteps, int,  number of TRs in the sequence
    
    Returns
    -------
    cos  a formula that contains all the polynomial drift 
    plus a constant regressor
    """
    t = formula.Term("t")
    pt = []
    order = int(np.floor(2 * float(tmax) / float(hfcut)) + 1)
    for k in range(1, order):
        u = np.sqrt(2.0 / tmax) * sympy.cos(np.pi * (t / tmax + 0.5 / tsteps) * k)
        pt.append(utils.define("cosine_drift_%d" % (k + 1), u))
    pt.append(utils.define("constant", 1.0 + 0 * t))
    cos = formula.Formula(pt)
    return cos
"""

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])
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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