Exemple #1
0
def test_convolve_functions():
    # replicate convolution
    # This is a square wave on [0,1]
    f1 = (t > 0) * (t < 1)
    # ff1 is the numerical implementation of same
    lam_f1 = lambdify(t, f1)
    ff1 = lambda x : lam_f1(x).astype(np.int)
    # The convolution of ``f1`` with itself is a triangular wave on
    # [0,2], peaking at 1 with height 1
    tri = convolve_functions(f1, f1, [0,2], 1.0e-3, name='conv')
    yield assert_equal(str(tri), 'conv(t)')
    ftri = lambdify(t, tri)
    time, value = numerical_convolve(ff1, ff1, [0, 2], 1.0e-3)
    y = ftri(time)
    # numerical convolve about the same as ours
    yield assert_array_almost_equal(value, y)
    # peak is at 1
    yield assert_array_almost_equal(time[np.argmax(y)], 1)
    # Flip the interval and get the same result
    tri = convolve_functions(f1, f1, [2, 0], 1.0e-3)
    ftri = lambdify(t, tri)
    y = ftri(time)
    yield assert_array_almost_equal(value, y)
    # offset square wave by 1
    f2 = (t > 1) * (t < 2)
    tri = convolve_functions(f1, f2, [0,3], 1.0e-3)
    ftri = lambdify(t, tri)
    y = ftri(time)
    yield assert_array_almost_equal(time[np.argmax(y)], 2)
    # offset both by 1 and start interval at one
    tri = convolve_functions(f2, f2, [1,3], 1.0e-3)
    ftri = lambdify(t, tri)
    # get numerical version
    lam_f2 = lambdify(t, f2)
    ff2 = lambda x : lam_f2(x).astype(np.int)
    time, value = numerical_convolve(ff2, ff2, [1, 3], 1.0e-3)
    # and our version, compare
    y = ftri(time)
    yield assert_array_almost_equal(y, value)
Exemple #2
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