Beispiel #1
0
def plot_binaural_psths(df, cellid, bg, fg, batch, save=False, close=False):
    '''Takes input of a data fram from ohel.calc_psth_metrics along with a cellid and pair of
    sounds and will plot all the spatial psth combos with spectrogram of sound. Can save.'''
    manager = BAPHYExperiment(cellid=cellid, batch=batch)
    options = ohel.get_load_options(batch)
    rec = manager.get_recording(**options)

    rec['resp'] = rec['resp'].extract_channels([cellid])
    resp = copy.copy(rec['resp'].rasterize())

    expt_params = manager.get_baphy_exptparams()  # Using Charlie's manager
    if len(expt_params) == 1:
        ref_handle = expt_params[0]['TrialObject'][1]['ReferenceHandle'][1]
    if len(expt_params) > 1:
        ref_handle = expt_params[-1]['TrialObject'][1]['ReferenceHandle'][1]
    BG_folder, FG_folder = ref_handle['BG_Folder'], ref_handle['FG_Folder']

    ## I could make this not dependent on DF if I add some code that loads the epochs of the cell
    ## that you inputted and applies that type label function, that's really all I'm using from df

    df_filtered = df[(df.BG == bg) & (df.FG == fg) & (df.cellid == cellid)]
    if len(df_filtered) == 0:
        pairs = get_pair_names(cellid, df, show=False)
        raise ValueError(f"The inputted BG: {bg} and FG: {fg} are not in {cellid}.\n"
                         f"Maybe try one of these:\n{pairs}")

    epochs = []
    name = df_filtered.epoch.loc[df_filtered.kind == '11'].values[0]
    bb, ff = name.split('_')[1], name.split('_')[2]
    bb1, ff1 = name.replace(ff, 'null'), name.replace(bb, 'null')
    epochs.append(bb1), epochs.append(ff1)

    name = df_filtered.epoch.loc[df_filtered.kind == '22'].values[0]
    bb, ff = name.split('_')[1], name.split('_')[2]
    bb2, ff2 = name.replace(ff, 'null'), name.replace(bb, 'null')
    epochs.append(bb2), epochs.append(ff2)
    epochs.extend(df_filtered.epoch.values)

    r = resp.extract_epochs(epochs)
    SR = df_filtered['SR'].values[0]

    f = plt.figure(figsize=(18, 9))
    psth11 = plt.subplot2grid((9, 8), (0, 0), rowspan=3, colspan=3)
    psth12 = plt.subplot2grid((9, 8), (0, 3), rowspan=3, colspan=3, sharey=psth11)
    psth21 = plt.subplot2grid((9, 8), (3, 0), rowspan=3, colspan=3, sharey=psth11)
    psth22 = plt.subplot2grid((9, 8), (3, 3), rowspan=3, colspan=3, sharey=psth11)
    specA1 = plt.subplot2grid((9, 8), (7, 0), rowspan=1, colspan=3)
    specB1 = plt.subplot2grid((9, 8), (8, 0), rowspan=1, colspan=3)
    specA2 = plt.subplot2grid((9, 8), (7, 3), rowspan=1, colspan=3)
    specB2 = plt.subplot2grid((9, 8), (8, 3), rowspan=1, colspan=3)
    psthbb = plt.subplot2grid((9, 8), (0, 6), rowspan=3, colspan=2, sharey=psth11)
    psthff = plt.subplot2grid((9, 8), (3, 6), rowspan=3, colspan=2, sharey=psth11)
    ax = [psth11, psth12, psth21, psth22, specA1, specB1, specA2, specB2, psthbb, psthff]

    prestim = resp.epochs[resp.epochs['name'] == 'PreStimSilence'].copy().iloc[0]['end']
    time = (np.arange(0, r[epochs[0]].shape[-1]) / options['rasterfs']) - prestim

    # r_mean = {e: np.squeeze(np.nanmean(r[e], axis=0)) for e in epochs}
    r_mean = {e: np.squeeze(np.nanmean(r[e], axis=0)) - SR for e in epochs}

    epochs.extend(['lin11', 'lin12', 'lin21', 'lin22'])
    bg1, fg1, bg2, fg2 = epochs[0], epochs[1], epochs[2], epochs[3]
    r_mean['lin11'], r_mean['lin12'] = r_mean[bg1]+r_mean[fg1], r_mean[bg1]+r_mean[fg2]
    r_mean['lin21'], r_mean['lin22'] = r_mean[bg2]+r_mean[fg1], r_mean[bg2]+r_mean[fg2]

    colors = ['deepskyblue'] *3 + ['violet'] *3 + ['yellowgreen'] *3 + ['darksalmon'] *3 \
             + ['dimgray'] *4 + ['black'] *4
    styles = ['-'] *16 + [':'] *4
    ax_num = [0, 1, 8, 2, 3, 8, 0, 2, 9, 1, 3, 9, 0, 1, 2, 3, 0, 1, 2, 3]
    ep_num = [0, 0, 0, 2, 2, 2, 1, 1, 1, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    labels = ['BG1'] *3 + ['BG2'] *3 + ['FG1'] *3 + ['FG2'] *3 \
             + ['BG1+FG1'] + ['BG1+FG2'] + ['BG2+FG1'] + ['BG2+FG2'] + ['LS'] *4

    for e, a, c, s, l in zip(ep_num, ax_num, colors, styles, labels):
        ax[a].plot(time, sf.gaussian_filter1d(r_mean[epochs[e]], sigma=2)
                   * options['rasterfs'], color=c, linestyle=s, label=l)

    ymin, ymax = ax[0].get_ylim()
    AXS = [0, 1, 2, 3, 8, 9]
    for AX, tt, aab, bab, ali, bli, prf in zip(range(4), df_filtered.kind, df_filtered.AcorAB,
                                          df_filtered.BcorAB, df_filtered.AcorLin,
                                               df_filtered.BcorLin, df_filtered.pref):
        ax[AX].legend((f'BG{tt[0]}, corr={np.around(aab, 3)}',
                       f'FG{tt[1]}, corr={np.around(bab, 3)}',
                       f'BG{tt[0]}+FG{tt[1]}',
                       f'LS, Acorr={np.around(ali, 3)}\nBcorr={np.around(bli, 3)}\npref={np.around(prf, 3)}'))
    for AX in AXS:
        ax[AX].vlines([0, 1.0], ymin, ymax, color='black', lw=0.75, ls='--')
        ax[AX].vlines(0.5, ymax * 0.9, ymax, color='black', lw=0.75, ls=':')
        ax[AX].spines['right'].set_visible(True), ax[AX].spines['top'].set_visible(True)
        if AX !=8 and AX !=9:
            ax[AX].set_xlim((-prestim * 0.5), (1 + (prestim * 0.75)))
        else:
            ax[AX].set_xlim((-prestim * 0.15), (1 + (prestim * 0.25)))

        if AX == 0 or AX == 1 or AX == 8:
            plt.setp(ax[AX].get_xticklabels(), visible=False)
        if AX == 1 or AX == 3 or AX == 8 or AX == 9:
            plt.setp(ax[AX].get_yticklabels(), visible=False)
        if AX == 2 or AX == 3 or AX == 9:
            ax[AX].set_xlabel('Time(s)', fontweight='bold', fontsize=10)
        if AX == 0 or AX == 2:
            ax[AX].set_ylabel('Spikes', fontweight='bold', fontsize=10)

    ax[0].set_title(f"{cellid} - BG: {bg} - FG: {fg}", fontweight='bold', fontsize=12)

    bbn, ffn = bb[:2], ff[:2]
    bg_path = glob.glob((f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/'
                        f'{BG_folder}/{bbn}*.wav'))[0]
    fg_path = glob.glob((f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/'
                        f'{FG_folder}/{ffn}*.wav'))[0]

    xf = 100
    low, high = ax[0].get_xlim()
    low, high = low * xf, high * xf

    for AX in range(4,8):
        if AX == 4 or AX == 6:
            sfs, W = wavfile.read(bg_path)
        elif AX == 5 or AX == 7:
            sfs, W = wavfile.read(fg_path)
        spec = gtgram(W, sfs, 0.02, 0.01, 48, 100, 24000)
        ax[AX].imshow(spec, aspect='auto', origin='lower', extent=[0, spec.shape[1], 0, spec.shape[0]])
        ax[AX].set_xlim(low, high)
        ax[AX].set_xticks([]), ax[AX].set_yticks([])
        ax[AX].set_xticklabels([]), ax[AX].set_yticklabels([])
        ax[AX].spines['top'].set_visible(False), ax[AX].spines['bottom'].set_visible(False)
        ax[AX].spines['left'].set_visible(False), ax[AX].spines['right'].set_visible(False)
    ax[4].set_ylabel(f"{bb.split('-')[0]}", fontweight='bold')
    ax[5].set_ylabel(f"{ff.split('-')[0]}", fontweight='bold')

    if save:
        site, animal, area, unit = cellid.split('-')[0], cellid[:3], df.area.loc[df.cellid == cellid].unique()[0], cellid[8:]
        path = f"/home/hamersky/OLP Binaural/{animal}/{area}/{site}/{unit}/"
        Path(path).mkdir(parents=True, exist_ok=True)
        print(f"Saving to {path + f'{cellid}-{bg}-{fg}.png'}")
        plt.savefig(path + f"{cellid}-{bg}-{fg}.png")
        if close:
            plt.close()
Beispiel #2
0
p2ax.plot((spk_times2[1] / rasterfs) - 2,
          lim + (spk_times2[0] / 1),
          '|',
          color='k',
          markersize=0.75,
          alpha=0.5)

spec_offset = lim + ((spk_times1[0] / 1)).max() + 2
# spectrogram
fs, data = wavfile.read(soundfile)
# pad / crop data
data = data[:int(3 * fs)]
spbins = int(2 * fs)
postbins = int(0.5 * fs)
data = np.concatenate((np.zeros(spbins), data, np.zeros(postbins)))
spec = gt.gtgram(data, fs, 0.01, 0.002, 100, 0)
p1ax.imshow(np.sqrt(spec),
            cmap='Greys',
            origin='lower',
            aspect='auto',
            extent=[-2, 3.5, spec_offset, spec_offset + 20])
p1ax.axvline(0, linestyle='--', lw=1, color='lime')
p1ax.axvline(3, linestyle='--', lw=1, color='lime')
p1ax.set_ylabel("Spk / s")
p1ax.set_title(r"$\bar p_{k} = %s$" % np.round(mean_pupil1, 2))
p1ax.set_xlabel('Time (s)')
p1ax.set_xlim((-2, 3.5))
p1ax.set_ylim((0, spec_offset + 20))

p2ax.imshow(np.sqrt(spec),
            cmap='Greys',
Beispiel #3
0
def get_sound_statistics(weight_df, plot=True):
    '''5/12/22 Takes a cellid and batch and figures out all the sounds that were played
    in that experiment and calculates some stastistics it plots side by side. Also outputs
    those numbers in a cumbersome dataframe'''
    lfreq, hfreq, bins = 100, 24000, 48
    cid, btch = weight_df.cellid.iloc[0], weight_df.batch.iloc[0]
    manager = BAPHYExperiment(cellid=cid, batch=btch)
    expt_params = manager.get_baphy_exptparams()  # Using Charlie's manager
    ref_handle = expt_params[-1]['TrialObject'][1]['ReferenceHandle'][1]
    BG_folder, FG_folder = ref_handle['BG_Folder'], ref_handle['FG_Folder']

    bbs = list(set([bb.split('_')[1][:2] for bb in weight_df.epoch]))
    ffs = list(set([ff.split('_')[2][:2] for ff in weight_df.epoch]))
    bbs.sort(key=int), ffs.sort(key=int)

    bg_paths = [glob.glob((f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/'
                           f'{BG_folder}/{bb}*.wav'))[0] for bb in bbs]
    fg_paths = [glob.glob((f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/'
                           f'{FG_folder}/{ff}*.wav'))[0] for ff in ffs]
    paths = bg_paths + fg_paths
    bgname = [bb.split('/')[-1].split('.')[0] for bb in bg_paths]
    fgname = [ff.split('/')[-1].split('.')[0] for ff in fg_paths]
    names = bgname + fgname

    Bs, Fs = ['BG'] * len(bgname), ['FG'] * len(fgname)
    labels = Bs + Fs

    sounds = []
    means = np.empty((bins, len(names)))
    means[:] = np.NaN
    for cnt, sn, pth, ll in zip(range(len(labels)), names, paths, labels):
        sfs, W = wavfile.read(pth)
        spec = gtgram(W, sfs, 0.02, 0.01, bins, lfreq, hfreq)

        dev = np.std(spec, axis=1)

        freq_mean = np.nanmean(spec, axis=1)
        x_freq = np.logspace(np.log2(lfreq), np.log2(hfreq), num=bins, base=2)
        csm = np.cumsum(freq_mean)
        big = np.max(csm)

        freq75 = x_freq[np.abs(csm - (big * 0.75)).argmin()]
        freq25 = x_freq[np.abs(csm - (big * 0.25)).argmin()]
        freq50 = x_freq[np.abs(csm - (big * 0.5)).argmin()]
        bandw = np.log2(freq75 / freq25)

        means[:, cnt] = freq_mean

        sounds.append({'name': sn,
                       'type': ll,
                       'std': dev,
                       'bandwidth': bandw,
                       '75th': freq75,
                       '25th': freq25,
                       'center': freq50,
                       'spec': spec,
                       'mean_freq': freq_mean,
                       'freq_stationary': np.std(freq_mean)})

    sound_df = pd.DataFrame(sounds)

    # allmean = np.nanmean(means, axis=1, keepdims=True)
    # norm_mean = [aa / allmean for aa in sound_df.mean_freq]
    # freq_stationarity = [np.std(aa) for aa in allmean]
    # sound_df['norm_mean'],  = norm_mean
    # sound_df['freq_stationary'] = freq_stationarity

    ss = sound_df.explode('std')
    # frs = sound_df.explode('norm_mean')
    # frs = sound_df.explode('mean_freq')
    snames = [dd[2:] for dd in sound_df.name]

    if plot:
        fig, ax = plt.subplots(1, 3, figsize=(18, 8))

        sb.barplot(x='name', y='std', palette=["lightskyblue" if x == 'BG' else 'yellowgreen' for x in sound_df.type],
                   data=ss, ci=68, ax=ax[0], errwidth=1)
        ax[0].set_xticklabels(snames, rotation=90, fontweight='bold', fontsize=7)
        ax[0].set_ylabel('Non-stationariness', fontweight='bold', fontsize=12)
        ax[0].spines['top'].set_visible(True), ax[0].spines['right'].set_visible(True)
        ax[0].set(xlabel=None)

        sb.barplot(x='name', y='bandwidth',
                   palette=["lightskyblue" if x == 'BG' else 'yellowgreen' for x in sound_df.type],
                   data=sound_df, ax=ax[1])
        ax[1].set_xticklabels(snames, rotation=90, fontweight='bold', fontsize=7)
        ax[1].set_ylabel('Bandwidth (octaves)', fontweight='bold', fontsize=12)
        ax[1].spines['top'].set_visible(True), ax[1].spines['right'].set_visible(True)
        ax[1].set(xlabel=None)

        sb.barplot(x='name', y='freq_stationary',
                   palette=["lightskyblue" if x == 'BG' else 'yellowgreen' for x in sound_df.type],
                   data=sound_df, ax=ax[2])
        ax[2].set_xticklabels(snames, rotation=90, fontweight='bold', fontsize=7)
        ax[2].set_ylabel('Frequency Non-stationariness', fontweight='bold', fontsize=12)
        ax[2].spines['top'].set_visible(True), ax[2].spines['right'].set_visible(True)
        ax[2].set(xlabel=None)

        fig.tight_layout()

    return sound_df
Beispiel #4
0
                    f'Background2/*.wav'))
fg_dir = glob.glob((f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/'
                    f'Foreground3/*.wav'))
fgs= fg_dir[:5] #ferrets

fgs = fg_dir[5:15] # marms
names = [aa.split('/')[-1] for aa in fgs]

pl = 0

fig, axes = plt.subplots(5,1, sharey=True)
ax = axes.ravel()
for pl in range(len(fgs)):
    path = fgs[pl]
    sfs, W = wavfile.read(path)
    spec = gtgram(W, sfs, 0.02, 0.01, 48, 100, 32000)

    # ax[pl].plot(W)
    ax[pl].set_title(f"{names[pl]}")
    ax[pl].imshow(np.log(spec), aspect='auto', origin='lower', extent=[0, spec.shape[1], 0, spec.shape[0]])

fig.tight_layout()

pl = 0

fig, axes = plt.subplots(5,1, sharey=True)
ax = axes.ravel()

for pl in range(len(fgs)):
    path = fgs[pl]
    sfs, W = wavfile.read(path)
Beispiel #5
0
def NAT_stim(exptevents,
             exptparams,
             stimfmt='gtgram',
             separate_files_only=False,
             channels=18,
             rasterfs=100,
             f_min=200,
             f_max=20000,
             mono=False,
             binaural=False,
             **options):
    """
    :param exptevents: from baphy
    :param exptparams: from baphy
    :param stimfmt: string, currently must be 'wav' or 'gtgram'
    :param separate_files_only: boolean [=False]
        if True, just return each individual sound file rather than combinations
        (eg, as specified for binaural stim)
    :param channels: int
        number of gtgram channels
    :param rasterfs: int
        gtgram sampling rate
    :param f_min: float
        gtgram min frequency
    :param f_max: float
        gtgram max frequency
    :param mono: boolean [False]
        if True, collapse wavs to single channel (dumb control for binaural)
    :param binaural:
        if True, apply model to simulate sound at each ear. Currently, a very dumb HRTF
    :param options: dict
        extra stuff to pass through
    :return:
        stim, tags, stimparam
    """
    ReferenceClass = exptparams['TrialObject'][1]['ReferenceClass']
    ReferenceHandle = exptparams['TrialObject'][1]['ReferenceHandle'][1]
    OveralldB = exptparams['TrialObject'][1]['OveralldB']

    if exptparams['TrialObject'][1]['ReferenceClass'] == 'BigNat':
        sound_root = Path(exptparams['TrialObject'][1]['ReferenceHandle'][1]
                          ['SoundPath'].replace("H:/", "/auto/data/"))

        #stim_epochs = exptevents.loc[exptevents.name.str.startswith("Stim"),'name'].tolist()
        #print(exptevents.loc[exptevents.name.str.startswith("Stim"),'name'].tolist()[:10])
        #wav1=[e.split(' , ')[1].split("+")[0].split(":")[0].replace("STIM_","") for e in stim_epochs]
        #wav2=[e.split(' , ')[1].split("+")[0].split(":")[0].replace("STIM_","") for e in stim_epochs]

        stim_epochs = exptparams['TrialObject'][1]['ReferenceHandle'][1][
            'Names']
        #print(exptparams['TrialObject'][1]['ReferenceHandle'][1]['Names'][:10])
        wav1 = [e.split("+")[0].split(":")[0] for e in stim_epochs]
        wav2 = [e.split("+")[1].split(":")[0] for e in stim_epochs]
        chan1 = [int(e.split("+")[0].split(":")[1]) - 1 for e in stim_epochs]
        chan2 = [int(e.split("+")[1].split(":")[1]) - 1 for e in stim_epochs]
        #log.info(wav1[0],chan1[0],wav2[0],chan2[0])
        file_unique = wav1.copy()
        file_unique.extend(wav2)
        file_unique = list(set(file_unique))
        if 'NULL' in file_unique:
            file_unique.remove('NULL')

    elif ReferenceClass == 'NaturalSounds':
        subset = ReferenceHandle['Subsets']
        if subset == 1:
            sound_root = Path(
                f'/auto/users/svd/code/baphy/Config/lbhb/SoundObjects/@NaturalSounds/sounds'
            )
        else:
            sound_root = Path(
                f'/auto/users/svd/code/baphy/Config/lbhb/SoundObjects/@NaturalSounds/sounds_set{subset}'
            )
        stim_epochs = ReferenceHandle['Names']
        file_unique = [f.replace('.wav', '') for f in stim_epochs]

        wav1 = file_unique.copy()
        chan1 = [0] * len(wav1)
        wav2 = ["NULL"] * len(wav1)
        chan2 = [0] * len(wav1)

    elif ReferenceClass == 'OverlappingPairs':
        bg_folder = ReferenceHandle['BG_Folder']
        fg_folder = ReferenceHandle['FG_Folder']

        bg_root = Path(
            f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/{bg_folder}'
        )
        fg_root = Path(
            f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/{fg_folder}'
        )

        stim_epochs = ReferenceHandle['Names']
        #print(exptparams['TrialObject'][1]['ReferenceHandle'][1]['Names'][:10])
        wav1 = [e.split("_")[0].split("-")[0] for e in stim_epochs]
        wav2 = [e.split("_")[1].split("-")[0] for e in stim_epochs]
        chan1 = [
            int(e.split("_")[0].split("-")[3]) -
            1 if e.split("_")[0] != 'null' else 0 for e in stim_epochs
        ]
        chan2 = [
            int(e.split("_")[1].split("-")[3]) -
            1 if e.split("_")[1] != 'null' else 0 for e in stim_epochs
        ]
        #log.info(wav1[0],chan1[0],wav2[0],chan2[0])
        #wav1 = [wav for wav in wav1 if wav != 'null']
        #wav2 = [wav for wav in wav2 if wav != 'null']

        file_unique = wav1.copy()
        file_unique.extend(wav2)
        file_unique = list(set(file_unique))
        file_unique = [f for f in file_unique if f != 'null']

        log.info(
            'NOTE: Stripping spaces from epoch names in OverlappingPairs files'
        )
        stim_epochs = [s.replace(" ", "") for s in stim_epochs]
    else:
        raise ValueError(
            f"ReferenceClass {ReferenceClass} gtgram not supported.")

    max_chans = np.max(np.concatenate([np.array(chan1), np.array(chan2)])) + 1
    max_chans_was = max_chans
    if mono:
        log.info("Forcing mono stimulus, averaging across space")
        chan1 = [0] * len(wav1)
        chan2 = [0] * len(wav2)
        max_chans = 1

    PreStimSilence = ReferenceHandle['PreStimSilence']
    Duration = ReferenceHandle['Duration']
    PostStimSilence = ReferenceHandle['PostStimSilence']
    log.info(f"Pre/Dur/Pos: {PreStimSilence}/{Duration}/{PostStimSilence}")

    wav_unique = {}
    fs0 = None
    for filename in file_unique:
        if ReferenceClass == "OverlappingPairs":
            try:
                fs, w = wavfile.read(Path(bg_root) / (filename + '.wav'))
            except:
                fs, w = wavfile.read(Path(fg_root) / (filename + '.wav'))
        else:
            fs, w = wavfile.read(sound_root / (filename + '.wav'))
        if fs0 is None:
            fs0 = fs
        elif fs != fs0:
            raise ValueError(
                "fs mismatch between wav files. Need to implement resampling!")

        #print(f"{filename} fs={fs} len={w.shape}")
        duration_samples = int(np.floor(Duration * fs))

        # 10ms ramp at onset:
        w = w[:duration_samples].astype(float)
        ramp = np.hanning(.01 * fs * 2)
        ramp = ramp[:int(np.floor(len(ramp) / 2))]
        w[:len(ramp)] *= ramp
        w[-len(ramp):] = w[-len(ramp):] * np.flipud(ramp)

        # scale peak-to-peak amplitude to OveralldB
        w = w / np.max(np.abs(w)) * 5
        sf = 10**((80 - OveralldB) / 20)
        w /= sf

        wav_unique[filename] = w[:, np.newaxis]

    if separate_files_only:
        # combine into pairs that were actually presented
        wav_all = wav_unique
    else:
        wav_all = {}
        fs_all = {}
        for (f1, c1, f2, c2, n) in zip(wav1, chan1, wav2, chan2, stim_epochs):
            #print(f1,f2)
            if f1.upper() != "NULL":
                w1 = wav_unique[f1]
                if f2.upper() != "NULL":
                    w2 = wav_unique[f2]
                else:
                    w2 = np.zeros(w1.shape)
            else:
                w2 = wav_unique[f2]
                w1 = np.zeros(w2.shape)
            w = np.zeros((w1.shape[0], max_chans))
            if (binaural is None) | (binaural == False):
                #log.info(f'binaural model: None')
                w[:, [c1]] = w1
                w[:, [c2]] += w2
            else:
                #log.info(f'binaural model: {binaural}')
                #import pdb; pdb.set_trace()
                db_atten = 10
                factor = 10**(-db_atten / 20)
                w[:, [c1]] = w1 * 1 / (1 + factor) + w2 * factor / (1 + factor)
                w[:,
                  [c2]] += w2 * 1 / (1 + factor) + w1 * factor / (1 + factor)

            wav_all[n] = w

    if stimfmt == 'wav':
        for f, w in wav_all.items():
            wav_all[f] = np.concatenate([
                np.zeros((int(np.floor(fs * PreStimSilence)), max_chans)), w,
                np.zeros((int(np.floor(fs * PostStimSilence)), max_chans))
            ],
                                        axis=0)
        return wav_all

    if stimfmt == 'gtgram':
        window_time = 1 / rasterfs
        hop_time = 1 / rasterfs

        duration_bins = int(np.floor(rasterfs * Duration))
        sg_pre = np.zeros((channels, int(np.floor(rasterfs * PreStimSilence))))
        sg_null = np.zeros((channels, duration_bins))
        sg_post = np.zeros(
            (channels, int(np.floor(rasterfs * PostStimSilence))))

        sg_unique = {}
        stimparam = {'f_min': f_min, 'f_max': f_max, 'rasterfs': rasterfs}
        padbins = int(np.ceil((window_time - hop_time) / 2 * fs))

        for (f, w) in wav_all.items():
            if len(sg_unique) % 100 == 99:
                log.info(f"i={len(sg_unique)+1} {f} {w.std(axis=0)}")
            sg = [
                gtgram(np.pad(w[:, i], [padbins, padbins]), fs, window_time,
                       hop_time, channels, f_min, f_max)
                if w[:, i].var() > 0 else sg_null for i in range(w.shape[1])
            ]

            sg = [
                np.concatenate(
                    [sg_pre,
                     np.abs(s[:, :duration_bins])**0.5, sg_post],
                    axis=1) for s in sg
            ]

            if mono & (max_chans_was > 1):
                sgshuff = np.random.permutation(sg[0].flatten())
                sgshuff = np.reshape(sgshuff, sg[0].shape)
                sg.append(sgshuff)
            sg_unique[f] = np.concatenate(sg, axis=0)

        return sg_unique, list(sg_unique.keys()), stimparam
Beispiel #6
0
def psth_responses(parm, pair_idx, cell, sigma=2, save=False, rasterfs=100):
    expt = BAPHYExperiment(parm)
    rec = expt.get_recording(rasterfs=rasterfs, resp=True, stim=False)
    resp = rec['resp'].rasterize()

    site, unit = expt.siteid[:-1], resp.chans[cell]
    if len(resp.chans) <= cell:
        raise ValueError(f"Cell {cell} is out of range for site with {len(resp.chans) - 1} units")

    expt_params = expt.get_baphy_exptparams()  # Using Charlie's manager
    ref_handle = expt_params[0]['TrialObject'][1]['ReferenceHandle'][1]
    soundies = list(ref_handle['SoundPairs'].values())
    pairs = [tuple([j for j in (soundies[s]['bg_sound_name'].split('.')[0],
                                soundies[s]['fg_sound_name'].split('.')[0])])
             for s in range(len(soundies))]

    if len(pairs) <= pair_idx:
        raise ValueError(f"Pair_idx {pair_idx} is out of range for unit with {len(pairs) - 1} sound pairs")

    BG, FG = pairs[pair_idx]
    colors = ['deepskyblue', 'yellowgreen', 'grey', 'silver']
    bg_path = f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/Background2/{BG}.wav'
    fg_path = f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/Foreground3/{FG}.wav'

    #turn pairs into format for epochs, not file getting
    for c, t in enumerate(pairs):
        pairs[c] = tuple([ss.replace(' ', '') for ss in t])
    BG, FG = pairs[pair_idx]
    epochs = [f'STIM_{BG}-0-1_null', f'STIM_null_{FG}-0-1', f'STIM_{BG}-0-1_{FG}-0-1',
              f'STIM_{BG}-0.5-1_{FG}-0-1']

    prestim = ref_handle['PreStimSilence']

    f = plt.figure(figsize=(15,9))
    psth = plt.subplot2grid((4, 5), (0, 0), rowspan=2, colspan=5)
    specBG = plt.subplot2grid((4, 5), (2, 0), rowspan=1, colspan=5)
    specFG = plt.subplot2grid((4, 5), (3, 0), rowspan=1, colspan=5)

    ax = [psth, specBG, specFG]

    r = resp.extract_epochs(epochs)

    time = (np.arange(0, r[epochs[0]].shape[-1]) / rasterfs ) - prestim

    for e, c in zip(epochs, colors):
        ax[0].plot(time, sf.gaussian_filter1d(np.nanmean(r[e][:,cell,:], axis=0), sigma=sigma)
             * rasterfs, color=c, label=e)
    ax[0].legend()
    ax[0].set_title(f"{resp.chans[cell]} - Pair {pair_idx} - BG: {BG} - FG: {FG} - sigma={sigma}", weight='bold')
    # ax[0].set_xlim([0-(prestim/2), time[-1]])
    ymin, ymax = ax[0].get_ylim()
    ax[0].vlines([0,1.0], ymin, ymax, color='black', lw=0.75, ls='--')
    ax[0].vlines(0.5, ymin, ymax, color='black', lw=0.75, ls=':')

    xf = 100
    low, high = ax[0].get_xlim()
    low, high = low * xf, high * xf

    sfs, W = wavfile.read(bg_path)
    spec = gtgram(W, sfs, 0.02, 0.01, 48, 100, 24000)
    ax[1].imshow(spec, aspect='auto', origin='lower', extent=[0, spec.shape[1], 0, spec.shape[0]])
    ax[1].set_xlim(low, high)
    ax[1].set_xticks([0, 20, 40, 60, 80]), ax[1].set_yticks([])
    ax[1].set_xticklabels([0, 0.2, 0.4, 0.6, 0.8]), ax[1].set_yticklabels([])
    ax[1].spines['top'].set_visible(False), ax[1].spines['bottom'].set_visible(False)
    ax[1].spines['left'].set_visible(False), ax[1].spines['right'].set_visible(False)
    ymin2, ymax2 = ax[1].get_ylim()
    ax[1].vlines((spec.shape[-1]+1)/2, ymin2, ymax2, color='white', lw=0.75, ls=':')

    sfs, W = wavfile.read(fg_path)
    spec = gtgram(W, sfs, 0.02, 0.01, 48, 100, 24000)
    ax[2].imshow(spec, aspect='auto', origin='lower', extent=[0, spec.shape[1], 0, spec.shape[0]])
    ax[2].set_xlim(low, high)
    ax[2].set_xticks([0, 20, 40, 60, 80]), ax[2].set_yticks([])
    ax[2].set_xticklabels([0, 0.2, 0.4, 0.6, 0.8]), ax[2].set_yticklabels([])
    ax[2].spines['top'].set_visible(False), ax[2].spines['bottom'].set_visible(False)
    ax[2].spines['left'].set_visible(False), ax[2].spines['right'].set_visible(False)
    ymin3, ymax3 = ax[2].get_ylim()
    ax[2].vlines((spec.shape[-1]+1)/2, ymin3, ymax3, color='white', lw=0.75, ls=':')

    ax[2].set_xlabel('Seconds', weight='bold')
    ax[1].set_ylabel(f"Background:\n{BG}", weight='bold', labelpad=-80, rotation=0)
    ax[2].set_ylabel(f"Foreground:\n{FG}", weight='bold', labelpad=-80, rotation=0)

    if save:
        path = f"/home/hamersky/Tabor PSTHs/{site}/"
        # if os.path.isfile(path):
        Path(path).mkdir(parents=True, exist_ok=True)

        plt.savefig(path + f"{unit} - Pair {pair_idx} - {BG} - {FG} - sigma{sigma}.png")
        plt.close()



# parm = '/auto/data/daq/Tabor/TBR011/TBR011a17_p_OLP.m'
# # parm = '/auto/data/daq/Tabor/TBR007/TBR007a10_p_OLP.m'
# expt = BAPHYExperiment(parm)
# rec = expt.get_recording(rasterfs=rasterfs, resp=True, stim=False)
# resp = rec['resp'].rasterize()
#
# expt_params = expt.get_baphy_exptparams()  # Using Charlie's manager
# ref_handle = expt_params[0]['TrialObject'][1]['ReferenceHandle'][1]
# soundies = list(ref_handle['SoundPairs'].values())
# pairs = [tuple([j for j in (soundies[s]['bg_sound_name'].split('.')[0],
#                             soundies[s]['fg_sound_name'].split('.')[0])])
#          for s in range(len(soundies))]
# #TBR011a-58-1 = -3
# cell = -3  #TBR011a-58-1
# cell = 2  #
# cell = 3 #large effect
#
# epochs = ['STIM_17Tuning-0-1_13Tsik-0-1', 'STIM_17Tuning-0-1_null', 'STIM_null_13Tsik-0-1',
#           'STIM_17Tuning-0.5-1_13Tsik-0-1', 'STIM_17Tuning-0-1_13Tsik-0.5-1']
# epochs = ['STIM_17Tuning-0-1_13Tsik-0-1', 'STIM_null_13Tsik-0-1',
#           'STIM_17Tuning-0.5-1_13Tsik-0-1']
# epochs = ['STIM_17Tuning-0-1_13Tsik-0-1', 'STIM_17Tuning-0-1_null',
#           'STIM_17Tuning-0-1_13Tsik-0.5-1']
#
# epochs = ['STIM_17Tuning-0-1_13Tsik-0-1', 'STIM_null_13Tsik-0-1',
#           'STIM_17Tuning-0.5-1_13Tsik-0-1', 'STIM_17Tuning-0-1_null']
# colors = ['black', 'yellowgreen', 'lightgrey', 'blue']
#
# #final colors for better plot
# epochs = ['STIM_17Tuning-0-1_null', 'STIM_null_13Tsik-0-1', 'STIM_17Tuning-0-1_13Tsik-0-1',
#           'STIM_17Tuning-0.5-1_13Tsik-0-1']
# colors = ['deepskyblue', 'yellowgreen', 'grey', 'rosybrown']
#
#
# epochs = [f'STIM_17Tuning-0-1_null', 'STIM_null_13Tsik-0-1', 'STIM_17Tuning-0-1_13Tsik-0-1',
#           'STIM_17Tuning-0.5-1_13Tsik-0-1']
# colors = ['deepskyblue', 'yellowgreen', 'grey', 'rosybrown']
#
# bg_path = f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/Background1/{AA}.wav'
# fg_path = f'/auto/users/hamersky/baphy/Config/lbhb/SoundObjects/@OverlappingPairs/Foreground2/{BB}.wav'
#
# smooval = 6
#
# f = plt.figure(figsize=(15, 9))
# psth = plt.subplot2grid((4, 6), (0, 0), rowspan=2, colspan=6)
# specBG = plt.subplot2grid((4, 6), (2, 0), rowspan=1, colspan=6)
# specFG = plt.subplot2grid((4, 6), (3, 0), rowspan=1, colspan=6)
#
# ax = [psth, specBG, specFG]
#
# time = np.arange(0, r[epochs[0]].shape[-1] / rasterfs)
#
# for e, c in zip(epochs, colors):
#     mean = r[e][:,cell,:].mean(axis=0)
#     mean = smooth(mean, smooval)
#     ax[0].plot(mean, label=e, color=c)
# ax[0].legend()
# ax[0].set_title(f"{resp.chans[cell]}")
#
#
#
# r = resp.extract_epochs(epochs)
# fig, ax = plt.subplots()
# for e, c in zip(epochs,colors):
#     mean = r[e][:,cell,:].mean(axis=0)
#     mean = smooth(mean, 7)
#     ax.plot(mean, label=e, color=c)
# ax.legend()
# ax.set_title(f"{resp.chans[cell]}")
# ymin,ymax = ax.get_ylim()
# ax.vlines([50, 100, 150], ymin, ymax, color = 'black', ls=':')
Beispiel #7
0
            f'{FG_folder}/{ff}*.wav'))[0] for ff in idxstr
    ]
    fgname = [
        ff.split('/')[-1].split('.')[0].replace(' ', '') for ff in fg_paths
    ]
    ep_fg = [f"STIM_null_{ff}" for ff in fgname]

    prebins = int(ref_handle['PreStimSilence'] * options['rasterfs'])
    postbins = int(ref_handle['PostStimSilence'] * options['rasterfs'])
    durbins = int(ref_handle['Duration'] * options['rasterfs'])
    trialbins = durbins + postbins

    env_cuts = {}
    for nm, pth in zip(fgname, fg_paths):
        sfs, W = wavfile.read(pth)
        spec = gtgram(W, sfs, 0.02, 0.01, bins, lfreq, hfreq)

        env = np.nanmean(spec, axis=0)
        cutoff = np.max(env) * threshold

        # aboves = np.squeeze(np.argwhere(env >= cutoff))
        # belows = np.squeeze(np.argwhere(env < cutoff))

        highs, lows, whole_thing = env >= cutoff, env < cutoff, env > 0
        prestimFalse = np.full((prebins, ), False)
        poststimTrue = np.full((trialbins - len(env), ), True)
        poststimFalse = np.full((trialbins - len(env), ), False)

        full = np.concatenate((prestimFalse, np.full((trialbins, ), True)))
        aboves = np.concatenate((prestimFalse, highs, poststimFalse))
        belows = np.concatenate((prestimFalse, lows, poststimFalse))