示例#1
0
def bandpass_timefreq(s, frequencies, sample_rate):
    """
        Bandpass filter signal s at the given frequency bands, and then use the Hilber transform
        to produce a complex-valued time-frequency representation of the bandpass filtered signal.
    """

    freqs = sorted(frequencies)
    tf_raw = np.zeros([len(frequencies), len(s)], dtype='float')
    tf_freqs = list()

    for k, f in enumerate(freqs):
        #bandpass filter signal
        if k == 0:
            tf_raw[k, :] = lowpass_filter(s, sample_rate, f)
            tf_freqs.append((0.0, f))
        else:
            tf_raw[k, :] = bandpass_filter(s, sample_rate, freqs[k - 1], f)
            tf_freqs.append((freqs[k - 1], f))

    #compute analytic signal
    tf = hilbert(tf_raw, axis=1)
    #print 'tf_raw.shape=',tf_raw.shape
    #print 'tf.shape=',tf.shape

    return np.array(tf_freqs), tf_raw, tf
示例#2
0
def get_amplitude_envelope(data,
                           fs=30000.0,
                           lowpass=8000.0,
                           highpass=1000.0,
                           rectify_lowpass=600.0,
                           spec_sample_rate=200.0,
                           spec_freq_spacing=200.0,
                           mode="broadband"):
    """Compute an amplitude envelope of a signal

    This can be done in two modes: "broadband" or "max_zscore"

    Broadband mode is the normal amplitude envelope calcualtion. In broadband
    mode, the signal is bandpass filtered, rectified, and then lowpass filtered.

    Max Zscore mode is useful to detect calls which may be more localized in
    the frequency domain from background (white) noise. In max_zscore mode, a
    spectrogram is computed with spec_sample_rate time bins and
    spec_freq_spacing frequency bins. For each time bin, the power in each
    frequency bin is zscored and the max zscored value is assigned to the
    envelope for that bin.
    """
    spectral = True
    filtered = highpass_filter(data.T, fs, highpass, filter_order=10).T
    filtered = lowpass_filter(filtered.T, fs, lowpass, filter_order=10).T

    if mode == "max_zscore":
        t_spec, f_spec, spec, _ = spectrogram(
            filtered,
            fs,
            spec_sample_rate=spec_sample_rate,
            freq_spacing=spec_freq_spacing,
            cmplx=False)
        spec = np.abs(spec)
        std = np.std(spec, axis=0)
        zscored = (spec - np.mean(spec, axis=0)) / std
        filtered = np.max(zscored, axis=0)
        filtered -= np.min(filtered)
        return scipy.signal.resample(filtered, len(data))
    elif mode == "broadband":
        # Rectify and lowpass filter
        filtered = np.abs(filtered)
        filtered = lowpass_filter(filtered.T, fs, rectify_lowpass).T
        return filtered
    else:
        raise ValueError("Invalid amp_env_mode {}".format(amp_env_mode))
# Testing the coherence

import numpy as np
import matplotlib.pyplot as plt

from soundsig.coherence import coherence_jn
from soundsig.signal import lowpass_filter

# Make two gaussian signals
sample_rate = 1000.0
tlen = 2.0  # 2 second signal

# Make space for both signals
s1 = np.random.normal(0, 1, int(tlen * sample_rate))
s2 = lowpass_filter(s1, sample_rate, 250.0) + np.random.normal(
    0, 1, int(tlen * sample_rate))

freq1, c_amp, c_var_amp, c_phase, c_phase_var, cohe_unbiased, cohe_se = coherence_jn(
    s1, s2, sample_rate, 0.1, 0.05)

plt.figure()

plt.plot(freq1, cohe_unbiased, 'k-', linewidth=2.0, alpha=0.9)
plt.plot(freq1, cohe_unbiased + 2 * (cohe_se), 'g-', linewidth=2.0, alpha=0.75)
plt.plot(freq1, cohe_unbiased - 2 * (cohe_se), 'c-', linewidth=2.0, alpha=0.75)

plt.show()
示例#4
0
    def plot_complex(self, **kwargs):

        #set keywords to defaults
        kw_params = {
            'start_time': self.start_time,
            'end_time': self.end_time,
            'output_dir': None,
            'include_spec': False,
            'include_ifreq': False,
            'spikes': False,
            'nbands_to_plot': None,
            'sort_code': '0',
            'demodulate': True,
            'phase_only': False,
            'log_amplitude': False
        }
        for key, val in kw_params.items():
            if key not in kwargs:
                kwargs[key] = val

        nbands, nelectrodes, nt = self.X.shape
        start_time = kwargs['start_time']
        end_time = kwargs['end_time']
        duration = end_time - start_time
        output_dir = kwargs['output_dir']

        sr = self.get_sample_rate()
        t1 = int((start_time - self.start_time) * sr)
        d = int((end_time - start_time) * sr)
        t2 = t1 + d
        t = (np.arange(d) / sr) + kwargs['start_time']

        spike_trains = None
        bin_size = 1e-3
        if kwargs['spikes']:
            if self.spike_rasters is None:
                #load up the spike raster for this time slice
                self.spike_rasters = self.experiment.get_spike_slice(
                    self.segment,
                    0.0,
                    self.segment.annotations['duration'],
                    rcg_names=self.rcg_names,
                    as_matrix=False,
                    sort_code=kwargs['sort_code'],
                    bin_size=bin_size)
            if len(self.spike_rasters) > 1:
                print(
                    "WARNING: plot_complex doesn't work well when more than one electrode array is specified."
                )
            spike_trains_full, spike_train_group = self.spike_rasters[
                self.rcg_names[0]]
            #select out the spikes for the interval to plot
            spike_trains = list()
            for st in spike_trains_full:
                sindex = (st >= start_time) & (st <= end_time)
                spike_trains.append(st[sindex])

        colors = np.array([
            [244.0, 244.0, 244.0],  #white
            [241.0, 37.0, 9.0],  #red
            [238.0, 113.0, 25.0],  #orange
            [255.0, 200.0, 8.0],  #yellow
            [19.0, 166.0, 50.0],  #green
            [1.0, 134.0, 141.0],  #blue
            [244.0, 244.0, 244.0],  #white
        ])
        colors /= 255.0

        #get stimulus spectrogram
        stim_spec_t, stim_spec_freq, stim_spec = self.experiment.get_spectrogram_slice(
            self.segment, kwargs['start_time'], kwargs['end_time'])

        #compute the amplitude, phase, and instantaneous frequency of the complex signal
        amplitude = np.abs(self.Z[:, :, t1:t2])
        phase = np.angle(self.Z[:, :, t1:t2])

        # rescale the amplitude of each electrode so it ranges from 0 to 1
        for k in range(nbands):
            for n in range(nelectrodes):
                amplitude[k, n, :] /= amplitude[k, n].max()

        if kwargs['phase_only']:
            # make sure the amplitude is equal to 1
            nz = amplitude > 0
            amplitude[nz] /= amplitude[nz]

        if kwargs['log_amplitude']:
            nz = amplitude > 0
            amplitude[nz] = np.log10(amplitude[nz])
            amplitude[nz] -= amplitude[nz].min()
            amplitude /= amplitude.max()

        nbands_to_plot = nbands
        if kwargs['nbands_to_plot'] is not None:
            nbands_to_plot = kwargs['nbands_to_plot']

        seg_uname = segment_to_unique_name(self.segment)

        if kwargs['include_ifreq']:
            ##################
            ## make plots of the joint instantaneous frequency per band
            ##################
            rcParams.update({'font.size': 10})
            plt.figure(figsize=(24.0, 13.5))
            plt.subplots_adjust(top=0.98,
                                bottom=0.01,
                                left=0.03,
                                right=0.99,
                                hspace=0.10)
            nsubplots = nbands_to_plot + 2

            #plot the stimulus spectrogram
            ax = plt.subplot(nsubplots, 1, 1)
            plot_spectrogram(stim_spec_t,
                             stim_spec_freq,
                             stim_spec,
                             ax=ax,
                             colormap=cm.afmhot_r,
                             colorbar=False,
                             fmax=8000.0)
            plt.ylabel('')
            plt.yticks([])

            ifreq = np.zeros([nbands, nelectrodes, d])
            sr = self.get_sample_rate()
            for k in range(nbands):
                for j in range(nelectrodes):
                    ifreq[k, j, :] = compute_instantaneous_frequency(
                        self.Z[k, j, t1:t2], sr)
                    ifreq[k, j, :] = lowpass_filter(ifreq[k, j, :],
                                                    sr,
                                                    cutoff_freq=50.0)

            #plot the instantaneous frequency along with it's amplitude
            for k in range(nbands_to_plot):
                img = np.zeros([nelectrodes, d, 4], dtype='float32')

                ifreq_min = np.percentile(ifreq[k, :, :], 5)
                ifreq_max = np.percentile(ifreq[k, :, :], 95)
                ifreq_dist = ifreq_max - ifreq_min
                #print 'ifreq_max=%0.3f, ifreq_min=%0.3f' % (ifreq_max, ifreq_min)

                for j in range(nelectrodes):
                    max_amp = np.percentile(amplitude[k, j, :], 85)

                    #set the alpha and color for the bins
                    alpha = amplitude[k, j, :] / max_amp
                    alpha[alpha > 1.0] = 1.0  #saturate
                    alpha[alpha < 0.05] = 0.0  #nonlinear threshold

                    cnorm = (ifreq[k, j, :] - ifreq_min) / ifreq_dist
                    cnorm[cnorm > 1.0] = 1.0
                    cnorm[cnorm < 0.0] = 0.0
                    img[j, :, 0] = 1.0 - cnorm
                    img[j, :, 1] = 1.0 - cnorm
                    img[j, :, 2] = 1.0 - cnorm
                    #img[j, :, 3] = alpha
                    img[j, :, 3] = 1.0

                ax = plt.subplot(nsubplots, 1, k + 2)
                ax.set_axis_bgcolor('black')
                im = plt.imshow(img,
                                interpolation='nearest',
                                aspect='auto',
                                origin='upper',
                                extent=[t.min(),
                                        t.max(), 1, nelectrodes])
                plt.axis('tight')
                plt.ylabel('Electrode')
                plt.title('band %d' % (k + 1))
            plt.suptitle('Instantaneous Frequency')

            if output_dir is not None:
                fname = 'band_ifreq_%s_%s_start%0.6f_end%0.6f.png' % (
                    seg_uname, ','.join(self.rcg_names), start_time, end_time)
                plt.savefig(os.path.join(output_dir, fname))

        ##################
        ## make plots of the joint phase per band
        ##################

        def compute_envelope(the_matrix, log=False):
            tm_env = np.abs(the_matrix).sum(axis=0)
            tm_env -= tm_env.min()
            tm_env /= tm_env.max()

            if log:
                nz = tm_env > 0.0
                tm_env[nz] = np.log10(tm_env[nz])
                tm_env_thresh = -np.percentile(np.abs(tm_env[nz]), 95)
                tm_env[~nz] = tm_env_thresh
                tm_env[tm_env <= tm_env_thresh] = tm_env_thresh
                tm_env -= tm_env_thresh
                tm_env /= tm_env.max()

            return tm_env

        #compute the amplitude envelope for the spectrogram
        stim_spec_env = compute_envelope(stim_spec)

        rcParams.update({'font.size': 10})
        fig = plt.figure(figsize=(24.0, 13.5), facecolor='gray')
        plt.subplots_adjust(top=0.98,
                            bottom=0.01,
                            left=0.03,
                            right=0.99,
                            hspace=0.10)
        nsubplots = nbands_to_plot + 1 + int(kwargs['spikes'])

        #plot the stimulus spectrogram
        ax = plt.subplot(nsubplots, 1, 1)
        ax.set_axis_bgcolor('black')
        plot_spectrogram(stim_spec_t,
                         stim_spec_freq,
                         stim_spec,
                         ax=ax,
                         colormap=cm.afmhot,
                         colorbar=False,
                         fmax=8000.0)
        plt.plot(stim_spec_t,
                 stim_spec_env * stim_spec_freq.max(),
                 'w-',
                 linewidth=3.0,
                 alpha=0.75)
        plt.axis('tight')
        plt.ylabel('')
        plt.yticks([])

        #plot the spike raster
        if kwargs['spikes']:
            spike_count_env = spike_envelope(spike_trains,
                                             start_time,
                                             duration,
                                             bin_size=bin_size,
                                             win_size=30.0)
            ax = plt.subplot(nsubplots, 1, 2)
            plot_raster(spike_trains,
                        ax=ax,
                        duration=duration,
                        bin_size=bin_size,
                        time_offset=start_time,
                        ylabel='Cell',
                        bgcolor='k',
                        spike_color='#ff0000')
            tenv = np.arange(len(spike_count_env)) * bin_size + start_time
            plt.plot(tenv,
                     spike_count_env * len(spike_trains),
                     'w-',
                     linewidth=1.5,
                     alpha=0.5)
            plt.axis('tight')
            plt.xticks([])
            plt.yticks([])
            plt.ylabel('Spikes')

        #phase_min = phase.min()
        #phase_max = phase.max()
        #print 'phase_max=%0.3f, phase_min=%0.3f' % (phase_max, phase_min)

        for k in range(nbands_to_plot):

            the_phase = phase[k, :, :]
            if kwargs['demodulate']:
                Ztemp = amplitude[k, :, :] * (
                    np.cos(the_phase) + complex(0, 1) * np.sin(the_phase))
                the_phase, complex_pcs = demodulate(Ztemp, depth=1)
                del Ztemp

            img = make_phase_image(amplitude[k, :, :],
                                   the_phase,
                                   normalize=True,
                                   threshold=True,
                                   saturate=True)
            amp_env = compute_envelope(amplitude[k, :, :], log=False)

            ax = plt.subplot(nsubplots, 1, k + 2 + int(kwargs['spikes']))
            ax.set_axis_bgcolor('black')
            im = plt.imshow(img,
                            interpolation='nearest',
                            aspect='auto',
                            origin='upper',
                            extent=[t.min(), t.max(), 1, nelectrodes])
            if not kwargs['phase_only']:
                plt.plot(t,
                         amp_env * nelectrodes,
                         'w-',
                         linewidth=2.0,
                         alpha=0.75)
            plt.axis('tight')
            plt.ylabel('Electrode')
            plt.title('band %d' % (k + 1))

        plt.suptitle('Phase')

        if output_dir is not None:
            fname = 'band_phase_%s_%s_start%0.6f_end%0.6f.png' % (
                seg_uname, ','.join(self.rcg_names), start_time, end_time)
            plt.savefig(os.path.join(output_dir, fname),
                        facecolor=fig.get_facecolor(),
                        edgecolor='none')
            del fig

        if not kwargs['include_spec']:
            return

        ##################
        ## make plots of the band spectrograms
        ##################
        subplot_nrows = 8 + 1
        subplot_ncols = len(self.rcg_names) * 2
        plt.figure()
        plt.subplots_adjust(top=0.95,
                            bottom=0.05,
                            left=0.03,
                            right=0.99,
                            hspace=0.10)

        for k in range(subplot_ncols):
            ax = plt.subplot(subplot_nrows, subplot_ncols, k + 1)
            plot_spectrogram(stim_spec_t,
                             stim_spec_freq,
                             stim_spec,
                             ax=ax,
                             colormap=cm.gist_yarg,
                             colorbar=False)
            plt.ylabel('')
            plt.yticks([])

        for j in range(nelectrodes):

            plt.figure(figsize=(24.0, 13.5))
            plt.subplots_adjust(top=0.95,
                                bottom=0.05,
                                left=0.03,
                                right=0.99,
                                hspace=0.10)

            electrode = self.index2electrode[j]
            rcg, rc = self.experiment.get_channel(self.segment.block,
                                                  electrode)
            row = rc.annotations['row']
            col = rc.annotations['col']
            if len(self.rcg_names) > 1:
                sp = (row + 1) * subplot_ncols + col + 1
            else:
                sp = (row + 1) * subplot_ncols + (col % 2) + 1

            #ax = plt.subplot(subplot_nrows, subplot_ncols, sp)
            gs = GridSpec(100, 1)
            ax = plt.subplot(gs[:20])
            plot_spectrogram(stim_spec_t,
                             stim_spec_freq,
                             stim_spec,
                             ax=ax,
                             colormap=cm.gist_yarg,
                             colorbar=False)
            plt.ylabel('')
            plt.yticks([])

            ax = plt.subplot(gs[20:])
            ax.set_axis_bgcolor('black')

            #get the maximum frequency and set the resolution
            max_freq = ifreq[:, j, :].max()
            nf = 150
            df = max_freq / nf

            #create an image to hold the frequencies
            img = np.zeros([nf, ifreq.shape[-1], 4], dtype='float32')

            #fill in the image for each band
            for k in range(nbands):
                max_amp = np.percentile(amplitude[k, j, :], 85)

                freq_bin = (ifreq[k, j, :] / df).astype('int') - 1
                freq_bin[freq_bin < 0] = 0

                #set the color and alpha for the bins
                alpha = amplitude[k, j, :] / max_amp
                alpha[alpha > 1.0] = 1.0  #saturate
                alpha[alpha < 0.05] = 0.0  #nonlinear threshold

                for m, fbin in enumerate(freq_bin):
                    #print 'm=%d, fbin=%d, colors[k, :].shape=%s' % (m, fbin, str(colors[k, :].shape))
                    img[fbin, m, :3] = colors[k, :]
                    img[fbin, m, 3] = alpha[m]

            #plot the image
            im = plt.imshow(img,
                            interpolation='nearest',
                            aspect='auto',
                            origin='lower',
                            extent=[t.min(), t.max(), 0.0, max_freq])
            plt.ylabel('E%d' % electrode)
            plt.axis('tight')
            plt.ylim(0.0, 140.0)

            if output_dir is not None:
                fname = 'band_spec_e%d_%s_%s_start%0.6f_end%0.6f.png' % (
                    electrode, seg_uname, ','.join(
                        self.rcg_names), start_time, end_time)
                plt.savefig(os.path.join(output_dir, fname))
                plt.close('all')

        if output_dir is None:
            plt.show()
import numpy as np
import matplotlib.pyplot as plt
os.chdir('/Users/Alicia/Desktop/BirdCallProject/Freq_20_10000/filteredCalls')
# Find all the wave files
isound = 250

fs = 44100
for fname in os.listdir('.'):
    if fname.endswith('.npy') and isound < 300:
        isound += 1
        # Read the sound file
        sound = np.load(fname)
        print('Processing sound %d:%s' % (isound, fname))
        soundLen = len(sound)
        sound = sound - sound.mean()
        sound_env = lowpass_filter(np.abs(sound), float(fs), 20.0)
        minimum = argrelextrema(sound_env, np.less, order=2)[0]
        minimum = minimum[np.where(sound_env[minimum] < 0.1 * max(sound_env))]
        minimum = minimum[np.where((1000 < minimum)
                                   & (minimum < soundLen - 1000))]
        print(minimum)
        #       if len(minimum) == 1:
        #           seg1 = sound[:minimum[0]]
        #           seg2 = sound[minimum[0]:]
        #           print(len(seg1) > 1323, len(seg2) > 1323)
        #           if len(seg1) > 1323 and len(seg2) > 1323:
        #               print('true')
        #               np.save("%sSeg1.npy" %fname[:-4], seg1)
        #               np.save("%sSeg2.npy" %fname[:-4], seg2)
        #           else:
        #               print('short seg')