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
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()
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')