示例#1
0
def _format_for_gam2(count, time, pos):
    assert np.rank(count) == np.rank(time) == (np.rank(pos) - 1)
    assert count.shape[0] == time.shape[0] == pos.shape[0]
    assert (count.shape[1] + 1) == time.shape[1] == pos.shape[1]

    y = count.flatten()[:,None]
    npt = y.size
    tax, spax = 1, -1
    
    # don't use real time as won't compare equivalent portions of trials
    # t  = edge2cen(time, axis=tax) # (ntrial, nbin)
    # subtract offset to get all relative times
    #t = (t - t[:,:1]).flatten()[:,None]
    
    # instead use bin numbers
    ntrial, nbin = count.shape
    t = np.tile(np.arange(nbin, dtype=float)[None], (ntrial, 1))
    t = t.flatten()[:,None]

    # also create trial numbers for pulling out appropriate later on
    # these don't correspond to original trial numbers because original trials
    # have been permuted before getting here
    tr = np.tile(np.arange(ntrial), (nbin, 1)).T.flatten()
    
    d  = kin.get_dir(pos, tax=tax, spax=spax).reshape(npt, 3)
    p  = edge2cen(pos, axis=tax).reshape(npt, 3)
    v  = kin.get_vel(pos, time, tax=tax, spax=spax).reshape(npt, 3)
    sp = kin.get_speed(pos, time, tax=tax, spax=spax).flatten()[:,None]

    # q is a second direction set-of-columns for deviance calculation
    q  = kin.get_dir(pos, tax=tax, spax=spax).reshape(npt, 3)
    return np.concatenate([y,t,d,p,v,sp,q], axis=1), tr
    def encode(self, bnd):
        '''
        Return spike counts corresponding to given direction and encoding model.

        Parameters
        ----------
        bnd :BinnedData
          uses bnd.pos, bnd.bin_edges
        '''
        pos = bnd.pos
        time = bnd.bin_edges
        ntask, nrep, nedge, ndim = pos.shape
        model = self.model

        assert(ndim == 3)
        nbin = nedge - 1
        lshape = ntask, nrep, nbin
        rate = np.zeros(lshape, dtype=float)
        assert(model == 'kd') # only model currently implemented 
        
        rate += self.B['k']                           # baseline
        dr    = get_dir(pos)
        rate += np.dot(dr, self.B['D'])               # direction
        rate += np.dot(pos[...,:-1,:], self.B['P'])   # position
        speed = get_speed(pos, time, tax=2, spax=-1)
        rate += self.B['s'] * speed
        return np.exp(rate)
    def encode(self, bnd):
        '''
        Return spike counts corresponding to given direction and encoding model.

        Parameters
        ----------
        bnd :BinnedData
          uses bnd.pos, bnd.bin_edges
        '''
        pos = bnd.pos
        time = bnd.bin_edges
        ntask, nrep, nedge, ndim = pos.shape
        model = self.model

        assert (ndim == 3)
        nbin = nedge - 1
        lshape = ntask, nrep, nbin
        rate = np.zeros(lshape, dtype=float)
        assert (model == 'kd')  # only model currently implemented

        rate += self.B['k']  # baseline
        dr = get_dir(pos)
        rate += np.dot(dr, self.B['D'])  # direction
        rate += np.dot(pos[..., :-1, :], self.B['P'])  # position
        speed = get_speed(pos, time, tax=2, spax=-1)
        rate += self.B['s'] * speed
        return np.exp(rate)
示例#4
0
def _format_for_gam(count, time, pos):
    '''
    Format data for gam_predict_cv, i.e. an (n, 12) array
    
    Parameters
    ----------
    count : ndarray
      spike counts, shape (ntrial, nbin)
    time : ndarray
      bin_edges, shape (ntrial, nbin + 1)
    pos : ndarray
      positions at `bin_edges`, shape (ntrial, nbin + 1, 3)
    
    Returns
    -------
    formatted_data : ndarray
      shape (ntrial * nbin, 12)
      dimension 1 is [count, t, dx, dy, dz, px, py, pz, vx, vy, vz, sp]
    '''        
    assert np.rank(count) == np.rank(time) == (np.rank(pos) - 1)
    assert count.shape[0] == time.shape[0] == pos.shape[0]
    assert (count.shape[1] + 1) == time.shape[1] == pos.shape[1]

    y  = count.flatten()[:,None]
    npt = y.size
    tax, spax = 1, -1
    
    # don't use real time as won't compare equivalent portions of trials
    # t  = edge2cen(time, axis=tax) # (ntrial, nbin)
    # subtract offset to get all relative times
    #t = (t - t[:,:1]).flatten()[:,None]
    
    # instead use bin numbers
    ntrial, nbin = count.shape
    t = np.tile(np.arange(nbin, dtype=float)[None], (ntrial, 1))
    t = t.flatten()[:,None]
    
    d  = kin.get_dir(pos, tax=tax, spax=spax).reshape(npt, 3)
    p  = edge2cen(pos, axis=tax).reshape(npt, 3)
    v  = kin.get_vel(pos, time, tax=tax, spax=spax).reshape(npt, 3)
    sp = kin.get_speed(pos, time, tax=tax, spax=spax).flatten()[:,None]

    # q is a second direction set-of-columns for deviance calculation
    q  = kin.get_dir(pos, tax=tax, spax=spax).reshape(npt, 3)
    return np.concatenate([y,t,d,p,v,sp,q], axis=1)
示例#5
0
def make_inst_dir_rate(time, pos, pd, kd, sqp={}):
    '''
    Create directional firing components from instantaneous direction,
    preferred direction, and modulation depth.

    Parameters
    ----------
    time : ndarray
      times for pos samples, shape (??)
    pos : ndarray
      positional data, shape (ntrial, nbin, 3)
    pd : array_like
      pds for a number of cells, shape (nunit, 3)
    kd : array_like
      modulation depth, shape (nunit)
    sqp : dict, optional
      parameter values for squashing function
    '''
    drn = get_dir(pos, tax=1, spax=-1)
    rate = np.dot(drn, pd.T) * kd
    set_squash_defaults(sqp, rate)
    return squash(rate, sqp)
示例#6
0
文件: fit.py 项目: amcmorl/motorlab
def prepare_regressors(count, pos, time, model=''):
    '''
    Parameters
    ----------
    count : array_like
      firing rates, shape (ntrial, nbin)
    pos : array_like
      positional data, shape (ntrial, nbin + 1, ndim)
      these are positions at bin edges
    time : array_like
      bin edge times, shape (ntrial, nbin + 1)
    model : string
      model

    Returns
    -------
    reg_vars : ndarray

    reg_frs : ndarray
    '''
    count = np.asarray(count)
    assert(np.rank(count) == 2)
    ntrial, nbin = count.shape
    assert(not np.any(np.isnan(count)))
    pos = np.asarray(pos)
    assert(np.rank(pos) == 3)
    assert(pos.shape[0:2] == (ntrial, nbin + 1))
    time = np.asarray(time)
    assert(np.rank(time) == 2)
    assert(time.shape == (ntrial, nbin + 1))
    assert(type(model) == str)
                      
    #ntrial, nbin = count.shape
    ndim = pos.shape[-1]
    nvar = ntrial * nbin
    endog = count.reshape(nvar) # should be equivalent to flatten
    vels = None
    exog = None

    # add the time-invariant variables
    if 'p' in model:
        pos_flat = pos[:,1:,:].reshape(nvar, ndim)
        exog = add_column(exog, pos_flat)
    if 's' in model:
        if vels == None:
            vels = get_vel(pos, time, tax=1, spax=2)
        spds = np.sqrt(np.sum(vels**2, axis=2))
        spds_flat = spds.reshape(nvar)
        exog = add_column(exog, spds_flat)

    # do the potentially time-variant variables
    if ('d' in model or 'v' in model):
        if 'd' in model:
            var = get_dir(pos, tax=1, spax=2)
        elif 'v' in model:
            if vels == None:
                vels = get_vel(pos, time, tax=1, spax=2)
            var = vels
        if not 'X' in model: # time-static variable
            var_flat = np.reshape(var, (nvar, ndim))
        else: # time-dynamic variable
            mask = np.eye(nbin)
            var_flat = np.reshape(mask[None,...,None] * var[...,None,:],
                                  (nvar, nbin * ndim))
        exog = add_column(exog, var_flat)

    # do the constant + dynamic direction model
    if 'q' in model:
        assert ('X' in model)
        # for simplicity's sake, let us call this model 'kqX'
        assert ('d' not in model)
        assert ('v' not in model)

    if 'k' in model:
        exog = sm.tools.add_constant(exog, prepend=False)

    offset = np.log(np.diff(time, axis=-1).reshape(nvar))

    return endog, exog, offset
示例#7
0
def test_gam_predict_cv():
    dsname = 'frank-osmd'
    align = 'hold'
    lag = 0.1 # s
    b0 = 20 # Hz
    noise_sd = 1. # Hz
    b_scale = 10.
    nbin = 10

    ds = datasets[dsname]
    dc = DataCollection(ds.get_files()[:5])
    unit = ds.get_units()[0]
    dc.add_unit(unit, lag)
    bnd = dc.make_binned(nbin=nbin, align=align, do_count=True)
    ntask, nrep, nedge, ndim = bnd.pos.shape
    
    pos = bnd.pos.reshape(ntask * nrep, nedge, -1)
    drn = kin.get_dir(pos)
    
    # simplest model
    # y = b0 + Bd.D
    B = np.array([.2, .6, .4]) * b_scale
    y = b0 + np.dot(drn, B)
    
    noise = np.random.normal(0, noise_sd, size=y.shape)
    y += noise
    
    bnd.set_count_from_flat(y[:,None])
    out = gam_predict_cv(bnd, ['kd'], [dsname, unit, lag, align], \
        family='gaussian')
    
    have = np.mean(out.coef[0], axis=0)[:4]
    want = np.array([b0, B[0], B[1], B[2]])

    np.testing.assert_array_almost_equal(have, want, decimal=1)

    # changing Bdt model, gaussian noise model
    # y = b0 + Bdt.D
    gc_type = [('A', float), ('fwhm', float), ('c', float)]
    gcoeff = np.array([[(1., 1.5, 3.), (.75, 2.5, 6.)],
                       [(.4, 4.,  2.), (.1,  2.,  5.)],
                       [(.8, 3.,  5.), (.6, 4.5, 6.5)]], dtype=gc_type)
    gcoeff = gcoeff.view(np.recarray)

    x  = np.linspace(0, 10, nbin)
    Bt = np.zeros((3, nbin))

    for Bkt, gc in zip(Bt, gcoeff):
        g0 = gauss1d(x, gc.A[0], gc.fwhm[0], gc.c[0])
        g1 = gauss1d(x, gc.A[1], gc.fwhm[1], gc.c[1])
        Bkt[:] = g0 + g1
        
    Bt *= b_scale
    y = b0 + np.sum(Bt.T[None] * drn, axis=-1)
    y = np.random.normal(y, noise_sd)
    bnd.set_count_from_flat(y[:,None])
    out = gam_predict_cv(bnd, ['kdX'], [dsname, unit, lag, align], \
        family='gaussian')
        
    # check that actual and predicted are correlated
    x = out.actual.flatten()
    y = out.pred[8].flatten()
    mc, rp = pearsonr(x,y)
    np.testing.assert_approx_equal(mc, 1, significant=1)