Ejemplo 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
Ejemplo n.º 2
0
def get_response_change(unit_name,
                        rec1,
                        unit1,
                        din1,
                        rec2,
                        unit2,
                        din2,
                        bin_size=250,
                        bin_step=25,
                        norm_func=None):
    '''Uses the spike arrays to compute the change in
    firing rate of the response to the tastant.

    Parameters
    ----------
    unit_name : str, name of held unit
    rec1 : str, path to recording directory 1
    unit1: str, name of unit in rec1
    din1 : int, number of din to use from rec1
    rec2 : str, path to recording directory 2
    unit2: str, name of unit in rec2
    din2 : int, number of din to use from rec2
    bin_size : int, default=250
        width of bins in units of time vector saved in hf5 spike_trains
        usually ms
    bin_step : int, default=25
        step size to take from one bin to the next in same units (usually ms)
    norm_func: function (optional)
        function with which to normalize the firing rates before getting difference
        must take inputs (time_vector, firing_rate_array) where time_vector is
        1D numpy.array and firing_rate_array is a Trial x Time numpy.array
        Must return a numpy.array with same size as firing rate array

    Returns
    -------
    difference_of_means : numpy.array
    SEM : numpy.array, standard error of the mean difference
    '''
    # Get metadata
    dat1 = load_dataset(rec1)
    dat2 = load_dataset(rec2)

    # Get data from hf5 files
    time1, spikes1 = dio.h5io.get_spike_data(rec1, unit1, din1)
    time2, spikes2 = dio.h5io.get_spike_data(rec2, unit2, din2)

    # Get Firing Rates
    bin_time1, fr1 = sas.get_binned_firing_rate(time1, spikes1, bin_size,
                                                bin_step)
    bin_time2, fr2 = sas.get_binned_firing_rate(time2, spike2, bin_size,
                                                bin_step)

    if not np.array_equal(bin_time1, bin_time2):
        raise ValueError('Time of spike trains is not aligned')

    # Normalize firing rates
    if norm_func:
        fr1 = norm_func(bin_time1, fr1)
        fr2 = norm_fun(bin_time2, fr2)

    difference_of_mean, SEM = sas.get_mean_difference(fr1, fr2, axis=0)

    return difference_of_mean, SEM, bin_time1
Ejemplo n.º 3
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
Ejemplo n.º 4
0
def plot_overlay_psth(rec_dir,
                      unit,
                      din_map,
                      plot_window=[-1500, 2500],
                      bin_size=250,
                      bin_step=25,
                      dig_ins=None,
                      smoothing_width=3,
                      save_file=None):
    '''
    Plots overlayed PSTHs for all tastants or a specified subset

    Parameters
    ----------
    rec_dir: str
    unit: int
    plot_window: list of int, time window for plotting in ms
    bin_size: int, window size for binning spikes in ms
    bin_step: int, step size for binning spikes in ms
    dig_ins: list of int (optional)
        which digital inputs to plot PSTHs for, None (default) plots all
    save_file: str (optional), full path to save file, if None, saves in Overlay_PSTHs subfolder
    '''
    if isinstance(unit, str):
        unit = dio.h5io.parse_unit_number(unit)

    if dig_ins is None:
        dig_ins = din_map.query('spike_array==True').channel.values

    if save_file is None:
        save_dir = os.path.join(rec_dir, 'Overlay_PSTHs')
        save_file = os.path.join(save_dir, 'Overlay_PSTH_unit%03d' % unit)
        if not os.path.isdir(save_dir):
            os.mkdir(save_dir)

    fig, ax = plt.subplots(figsize=(20, 15))
    for din in dig_ins:
        name = din_map.query('channel==@din').name.values[0]
        time, spike_train = dio.h5io.get_spike_data(rec_dir, unit, din)
        psth_time, fr = sas.get_binned_firing_rate(time, spike_train, bin_size,
                                                   bin_step)

        mean_fr = np.mean(fr, axis=0)
        sem_fr = sem(fr, axis=0)

        t_idx = np.where((psth_time >= plot_window[0])
                         & (psth_time <= plot_window[1]))[0]
        psth_time = psth_time[t_idx]
        mean_fr = mean_fr[t_idx]
        sem_fr = sem_fr[t_idx]
        mean_fr = gaussian_filter1d(mean_fr, smoothing_width)

        ax.fill_between(psth_time,
                        mean_fr - sem_fr,
                        mean_fr + sem_fr,
                        alpha=0.3)
        ax.plot(psth_time, mean_fr, linewidth=3, label=name)

    ax.set_title('Peri-stimulus Firing Rate Plot\nUnit %i' % unit, fontsize=34)
    ax.set_xlabel('Time (ms)', fontsize=28)
    ax.set_ylabel('Firing Rate (Hz)', fontsize=28)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    ax.autoscale(enable=True, axis='x', tight=True)
    ax.legend(loc='best')
    ax.axvline(0, color='red', linestyle='--')
    fig.savefig(save_file)
    plt.close('all')
Ejemplo 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)