Exemplo n.º 1
0
def compare_taste_response(rd1,
                           u1,
                           din1,
                           rd2,
                           u2,
                           din2,
                           time_window=[0, 2000],
                           bin_size=250,
                           norm_func=None):
    s_time1, spikes1 = h5io.get_spike_data(rd1, u1, din1)
    s_time2, spikes2 = h5io.get_spike_data(rd2, u2, din2)

    t_idx1 = np.where((s_time1 >= time_window[0])
                      & (s_time1 <= time_window[1]))[0]
    t_idx2 = np.where((s_time2 >= time_window[0])
                      & (s_time2 <= time_window[1]))[0]
    s_time1 = s_time1[t_idx1]
    spikes1 = spikes1[:, t_idx1]
    s_time2 = s_time2[t_idx2]
    spikes2 = spikes2[:, t_idx2]

    time1, fr1 = sas.get_binned_firing_rate(time1, spikes1, bin_size, bin_size)
    time2, fr2 = sas.get_binned_firing_rate(time2, spikes2, bin_size, bin_size)
    if norm_func is not None:
        fr1 = norm_func(time, fr1)
        fr2 = norm_func(time, fr2)

    win_starts = np.arange(time_window[0], time_window[1], bin_size)
    resp_u = np.zeros(win_starts.shape)
    resp_p = np.ones(win_starts.shape)
    for i, ws in enumerate(win_starts):
        rate1 = fr1[:, i]
        rate2 = fr2[:, i]
        try:
            resp_u[i], resp_p[i] = mannwhitneyu(rate1,
                                                rate2,
                                                alternative='two-sided')
        except ValueError:
            resp_u[i] = 0
            resp_p[i] = 1

    # Bonferroni correction
    resp_p = resp_p * len(win_starts)

    return win_starts, resp_u, resp_p
Exemplo n.º 2
0
def compare_baseline(rd1, u1, din1, rd2, u2, din2, win_size=1500):
    time1, spikes1 = h5io.get_spike_data(rd1, u1, din1)
    time2, spikes2 = h5io.get_spike_data(rd2, u2, din2)

    p_idx_1 = np.where((time1 >= -win_size) & (time1 < 0))[0]
    p_idx_2 = np.where((time2 >= -win_size) & (time2 < 0))[0]
    baseline1 = np.sum(spikes1[:, p_idx_1], axis=1) / abs(win_size)
    baseline2 = np.sum(spikes2[:, p_idx_2], axis=1) / abs(win_size)
    baseline1 = baseline1 * 1000  # convert to Hz
    baseline2 = baseline2 * 1000  # convert to Hz

    base_u, base_p = mannwhitneyu(baseline1,
                                  baseline2,
                                  alternative='two-sided')
    stats = {
        'u-stat': base_u,
        'p-val': base_p,
        'baseline1': (np.mean(baseline1), sem(baseline1)),
        'baseline2': (np.mean(baseline2), sem(baseline2))
    }

    return stats, base_p
Exemplo n.º 3
0
def apply_pca_analysis(df, params):
    '''df is held_units dataframe grouped by exp_name, exp_group, time_group
    only contains units held over preCTA or postCTA, no units held from ctaTrain to ctaTest
    
    Parameters
    ----------
    
    
    Returns
    -------
    
    
    Raises
    ------
    
    '''
    bin_size = params['pca']['win_size']
    bin_step = params['pca']['step_size']
    time_start = params['pca']['time_win'][0]
    time_end = params['pca']['time_win'][1]
    smoothing = params['pca']['smoothing_win']
    n_cells = len(df)

    rd1 = df['rec1'].unique()
    rd2 = df['rec2'].unique()
    if len(rd1) > 1 or len(rd2) > 1:
        raise ValueError('Too many recording directories')

    rd1 = rd1[0]
    rd2 = rd2[0]
    units1 = list(df['unit1'].unique())
    units2 = list(df['unit2'].unique())
    dim1 = load_dataset(rd1).dig_in_mapping.set_index('channel')
    dim2 = load_dataset(rd2).dig_in_mapping.set_index('channel')
    if n_cells < 2:
        # No point if only 1 unit
        exp_name = os.path.basename(rd1).split('_')
        print('%s - %s: Not enough units for PCA analysis' %
              (exp_name[0], exp_name[-3]))
        return

    time, sa = h5io.get_spike_data(rd1, units1)
    fr_t, fr, fr_lbls = get_pca_data(rd1,
                                     units1,
                                     bin_size,
                                     step=bin_step,
                                     t_start=time_start,
                                     t_end=time_end)
    rates = fr
    labels = fr_lbls
    time = fr_t
    # Again with rec2
    fr_t, fr, fr_lbls = get_pca_data(rd2,
                                     units2,
                                     bin_size,
                                     step=bin_step,
                                     t_start=time_start,
                                     t_end=time_end)
    rates = np.vstack([rates, fr])
    labels = np.vstack([labels, fr_lbls])
    # So now rates is tastes*trial*times X units

    # Do PCA on all data, put in (trials*time)xcells 2D matrix
    # pca = MDS(n_components=2)
    pca = PCA(n_components=2)
    pc_values = pca.fit_transform(rates)
    mds = MDS(n_components=2)
    md_values = mds.fit_transform(rates)

    out_df = pd.DataFrame(labels, columns=['taste', 'trial', 'time'])
    out_df['n_cells'] = n_cells
    out_df[['PC1', 'PC2']] = pd.DataFrame(pc_values)
    out_df[['MDS1', 'MDS2']] = pd.DataFrame(md_values)

    # Compute the MDS distance metric using the full dimensional solution
    # For each point computes distance to mean Quinine / distance to mean NaCl
    mds = MDS(n_components=rates.shape[1])
    mds_values = mds.fit_transform(rates)
    n_idx = np.where(labels[:, 0] == 'NaCl')[0]
    q_idx = np.where(labels[:, 0] == 'Quinine')[0]
    q_mean = np.mean(mds_values[q_idx, :], axis=0)
    n_mean = np.mean(mds_values[n_idx, :], axis=0)
    dist_metric = [
        euclidean(x, q_mean) / euclidean(x, n_mean) for x in mds_values
    ]
    assert len(
        dist_metric) == rates.shape[0], 'computed distances over wrong axis'
    out_df['dQ_v_dN_fullMDS'] = pd.DataFrame(dist_metric)

    # Do it again with raw rates
    q_mean = np.mean(rates[q_idx, :], axis=0)
    n_mean = np.mean(rates[n_idx, :], axis=0)
    raw_metric = [euclidean(x, q_mean) / euclidean(x, n_mean) for x in rates]
    assert len(
        raw_metric) == rates.shape[0], 'computed distances over wrong axis'
    out_df['dQ_v_dN_rawRates'] = pd.DataFrame(raw_metric)

    return out_df
Exemplo n.º 4
0
def get_pca_data(rec,
                 units,
                 bin_size,
                 step=None,
                 t_start=None,
                 t_end=None,
                 baseline_win=None):
    '''Get spike data, turns it into binned firing rate traces and then
    organizes them into a format for PCA (trials*time X units)
    
    Parameters
    ----------
    
    
    Returns
    -------
    
    
    Raises
    ------
    
    '''
    if step is None:
        step = bin_size

    st, sa = h5io.get_spike_data(rec, units)
    if t_start is None:
        t_start = st[0]

    if t_end is None:
        t_end = st[-1]

    spikes = []
    labels = []
    dim = load_dataset(rec).dig_in_mapping.set_index('channel')
    if isinstance(sa, dict):
        for k, v in sa.items():
            ch = int(k.split('_')[-1])
            tst = dim.loc[ch, 'name']
            l = [(tst, i) for i in range(v.shape[0])]
            if len(v.shape) == 2:
                tmp = np.expand_dims(v, 1)
            else:
                tmp = v

            labels.extend(l)
            spikes.append(tmp)

    else:
        if len(sa.shape) == 2:
            tmp = np.exapnd_dims(sa, 1)
        else:
            tmp = sa

        spikes.append(tmp)
        tst = dim.loc[0, 'name']
        l = [(tst, i) for i in range(sa.shape[0])]
        labels.extend(l)

    spikes = np.vstack(spikes).astype('float64')
    b_idx = np.where(st < 0)[0]
    baseline_fr = np.sum(spikes[:, :, b_idx], axis=-1) / (len(b_idx) / 1000)
    baseline_fr = np.mean(baseline_fr, axis=0)
    t_idx = np.where((st >= t_start) & (st <= t_end))[0]
    spikes = spikes[:, :, t_idx]
    st = st[t_idx]

    fr_lbls = []
    fr_arr = []
    fr_time = None
    for trial_i, (trial, lbl) in enumerate(zip(spikes, labels)):
        fr_t, fr = sas.get_binned_firing_rate(st, trial, bin_size, step)
        # fr is units x time
        fr = fr.T  # now its time x units
        fr = fr - baseline_fr  # subtract baseline firing rate
        l = [(*lbl, t) for t in fr_t]
        fr_arr.append(fr)
        fr_lbls.extend(l)
        if fr_time is None:
            fr_time = fr_t
        elif not np.array_equal(fr_t, fr_time):
            raise ValueError('Time Vectors dont match')

    # So now fr_lbls is [taste, trial, time]
    fr_out = np.vstack(fr_arr)
    fr_lbls = np.array(fr_lbls)
    return fr_time, fr_out, fr_lbls
Exemplo n.º 5
0
def get_firing_rate_trace(rec,
                          unit,
                          ch,
                          bin_size,
                          step_size=None,
                          t_start=None,
                          t_end=None,
                          baseline_win=None,
                          remove_baseline=False):
    '''Gets the spike array for a unit and returns the binned firing rate. If
    t_start and/or t_end are given then the data will be cut accordingly. If
    remove_baseline is true then the baseline firing rate will be
    averaged and subtracted from the firing rate traces.
    If step_size is not given then step_size = bin_size
    All time units in ms.

    Returns
    -------
    time: np.array, time vector in ms, corresponds to bin centers
    firing_rate: np.array
    baseline: tuple
        (mean, sem) of baseline firing rate, if baseline_win is not provided
        then this is computed using all time<0
    '''
    if step_size is None:
        step_size = bin_size

    t, sa = h5io.get_spike_data(rec, unit, ch)

    if baseline_win is None:
        baseline_win = np.min(t)
        baseline_win = np.min(
            (baseline_win, 0))  # in case t doesn't have values less than 0
        baseline_win = np.abs(baseline_win)

    if baseline_win == 0:
        baseline = 0
        baseline_sem = 0
    else:
        idx = np.where((t < 0) & (t >= -baseline_win))[0]
        tmp = np.sum(sa[:, idx], axis=1) / (baseline_win / 1000)
        baseline = np.mean(tmp)
        baseline_sem = sem(tmp)
        del idx, tmp

    # trim arrays
    if t_start is not None:
        idx = np.where((t >= t_start))[0]
        t = t[idx]
        sa = sa[:, idx]
        del idx

    if t_end is not None:
        idx = np.where((t <= t_end))[0]
        t = t[idx]
        sa = sa[:, idx]
        del idx

    bin_time, FR = sas.get_binned_firing_rate(t, sa, bin_size, step_size)
    if remove_baseline:
        FR = FR - baseline

    return bin_time, FR, (baseline, baseline_sem)