def get_spectral_intensities(data, ranges=FREQ_RANGES): intensities = [] spectral_data = spectrum.pmtm(data, 2.5, show=False) l = len(data) for [min, max] in ranges: intensities.extend(sum(spectral_data[int(min * l / FREQ):int(max * l / FREQ)])/(max-min)) return intensities
def pmtm(self): W = self.W ws = self.ws N = int(len(self.signal)/ws) self.results = np.zeros((W+1,N-8)) for i in range(N-8): data = self.signal[i*ws:i*ws+W] a = spectrum.pmtm(data, 4,NFFT=W*4, show=False) Sk = np.mean(abs(a[0].transpose())**2 * a[1], axis=1) self.results[:,i] = Sk[0:self.W+1] print(i, N)
def pmtm(self): W = self.W ws = self.ws N = int(len(self.signal) / ws) self.results = np.zeros((W + 1, N - 8)) for i in range(N - 8): data = self.signal[i * ws:i * ws + W] a = pmtm(data, 4, NFFT=W * 4, show=False) Sk = np.mean(abs(a[0].transpose())**2 * a[1], axis=1) self.results[:, i] = Sk[0:self.W + 1] print(i, N) print("done")
def compute_spectrum_multitaper(x, dt, max_freq=300, NFFT=None): fs = 1. / (dt / 1000.) fmax = fs / 2. len_x = len(x) if NFFT is None: NFFT = 2**nextpow2(len_x) # fft more efficient if power of 2 freq_vec = np.linspace(0, fmax, NFFT / 2) a = pmtm(x, NFFT=NFFT, NW=2.5, method='eigen', show=False) power_pyr = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / len_x if max_freq is not None: freq_vec = freq_vec[np.where(freq_vec <= max_freq)] power_pyr = power_pyr[np.where(freq_vec <= max_freq)] return freq_vec, power_pyr
def psd(data): N = len(data) NW = 4 #haf bandwidth parameter 2.5, 3, 3.5, 4 # k=4 dt = 1 [tapers, eigen] = dpss(N, NW) Sk_complex, weights, eigenvalues = pmtm(data, e=eigen, v=tapers, NFFT=N, show=False) Sk = abs(Sk_complex)**2 Sk = np.mean(Sk * np.transpose(weights), axis=0) * dt Sk = Sk / np.max(Sk) return Sk
def comp_mtspectrogram(Signal, fs, W, ws=None, NFFT=None, freq_limit=None, normalize=True, NW=2.5, PlotFlag=True): N = int(len(Signal)) T = (N/fs)*1000. if normalize: Signal -= np.mean(Signal) if ws is None: ws = int(np.round(W/10.)) if NFFT is None: NFFT = W*2 fmax = np.round(fs/2.) freq_vect = np.linspace(0, fmax, NFFT/2) if not freq_limit is None: freq_vect = freq_vect[np.where(freq_vect<=freq_limit)] N_segs = int((N-W)/ws+2) result = np.zeros((NFFT/2, N_segs)) for i in range(N_segs): data = Signal[i*ws:i*ws+W] a = pmtm(data, NFFT=NFFT, NW=NW, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) result[:,i] = Sks[:NFFT/2]/W if not freq_limit is None: Signal_MTS = np.squeeze(result[np.where(freq_vect<=freq_limit),:]) else: Signal_MTS = np.squeeze(result) if PlotFlag: plt.figure(figsize=[10,5]) plt.imshow(Signal_MTS, origin="lower", extent=[0, T, freq_vect[0], freq_vect[-1]], aspect="auto", cmap='jet') plt.xlabel('Time (ms)') plt.ylabel('Frequency (Hz)') plt.title('Multitaper Spectrogram') plt.show() return Signal_MTS
def compute_spectrogram_multitaper(x, dt, step_size=1, window_size=2**13, NW=2.5, freq_max=None, freq_min=None): fs = 1. / (dt / 1000.) fmax = fs / 2. len_x = len(x) NFFT = 2**nextpow2(len_x) # fft more efficient if power of 2 if NFFT is None: NFFT = window_size * 2 assert len_x > window_size n_segs = int(np.floor(len_x / float(step_size))) + 1 freq_vec = np.linspace(0, fmax, NFFT / 2) time_vec = np.arange( n_segs) * dt * step_size # midpoint of respective window window_size_half = int(np.floor(window_size / 2.)) x = np.pad(x, window_size_half, mode='reflect') spectrogram = np.zeros((len(freq_vec), n_segs)) for i in range(n_segs): x_window = x[i * step_size:i * step_size + window_size] # symmetric x_window -= np.mean(x_window) a = pmtm(x_window, NFFT=NFFT, NW=NW, method='eigen', show=False) power_window = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / window_size spectrogram[:, i] = power_window if freq_max is not None: spectrogram = spectrogram[np.where(freq_vec <= freq_max)[0], :] freq_vec = freq_vec[np.where(freq_vec <= freq_max)] if freq_min is not None: spectrogram = spectrogram[np.where(freq_vec > freq_min)[0], :] freq_vec = freq_vec[np.where(freq_vec > freq_min)] return spectrogram, freq_vec, time_vec
def get_power_spectra(sample_freq, data): # Get robust power spectra based on multitaper method # Input: # sample_freq: sample frequency of input data # data: Input data from which the power spectrum has to be derived # Output: # freq: frequency array of power spectrum # spec: robust power spectra nfft = 1024 tbw = 3 [tapers, eigen] = spectrum.dpss(nfft, tbw, 1) #res = spectrum.pmtm(data, e=tapers, v=eigen, show=False) amp, weights, _ = spectrum.pmtm(data, NW=3, show=False) freq = np.linspace(0, 1, len(amp[0])) * sample_freq spec = [0. for i in range(len(amp[0]))] for i in range(len(amp[0])): for j in range(len(amp)): spec[i] += amp[j][i] * weights[i][j] return freq, np.abs(spec)
def plot_mts_grid(rawfile, mode, start_time=None, end_time=None, mts_win='whole', W=2**12, ws=None, sim_dt=0.02, out_file=None): sim_dt *= ms if ws is None: ws = W / 10 if mode is 'Homogenous': rawfile = tables.open_file(rawfile, mode='r') PyrInps = (rawfile.root.PyrInps.read() / 1000) * kHz IntInps = (rawfile.root.IntInps.read() / 1000) * kHz PopRateSig_Pyr_list = rawfile.root.PopRateSig_Pyr.read() PopRateSig_Int_list = rawfile.root.PopRateSig_Int.read() rawfile.close() figure(1, figsize=[6 * len(PyrInps), 5 * len(IntInps)]) figure(2, figsize=[6 * len(PyrInps), 5 * len(IntInps)]) fmax = (1 / (sim_dt)) / 2 runtime = len(PopRateSig_Pyr_list[0]) * sim_dt / ms if start_time is None: start_time = 0 if end_time is None: end_time = runtime if start_time > runtime or end_time > runtime: raise ValueError( 'Please provide start time and end time within the simulation time window!' ) for ii in range(len(IntInps)): ii2 = len(IntInps) - ii - 1 for pi in range(len(PyrInps)): idx = pi * len(IntInps) + ii2 sp_idx = ii * len(PyrInps) + pi RateSig_Pyr = PopRateSig_Pyr_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Pyr -= np.mean(RateSig_Pyr) RateSig_Int = PopRateSig_Int_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Int -= np.mean(RateSig_Int) if mts_win is 'whole': N = RateSig_Pyr.shape[0] NFFT = 2**(N - 1).bit_length() freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] a = pmtm(RateSig_Pyr, NFFT=NFFT, NW=2.5, method='eigen', show=False) RateMTS_Pyr = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / N RateMTS_Pyr = RateMTS_Pyr[np.where(freq_vect / Hz <= 300)] a = pmtm(RateSig_Int, NFFT=NFFT, NW=2.5, method='eigen', show=False) RateMTS_Int = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / N RateMTS_Int = RateMTS_Int[np.where(freq_vect / Hz <= 300)] else: NFFT = W * 2 freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] N_segs = int((len(RateSig_Pyr) / ws) - (W - ws) / ws + 1) result = np.zeros((NFFT / 2)) for i in range(N_segs): data = RateSig_Pyr[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) result += Sks[:NFFT / 2] / W RateMTS_Pyr = result[np.where( freq_vect / Hz <= 300)] / N_segs N_segs = int((len(RateSig_Int) / ws) - (W - ws) / ws + 1) result = np.zeros((NFFT / 2)) for i in range(N_segs): data = RateSig_Int[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) result += Sks[:NFFT / 2] / W RateMTS_Int = result[np.where( freq_vect / Hz <= 300)] / N_segs figure(1) subplot(len(IntInps), len(PyrInps), sp_idx + 1) plot(freq_vect, RateMTS_Pyr) xlim(0, 300) xlabel('Frequency (Hz)') ylabel('Power') title('Pyr. Inp.: %s, Int. Inp.:%s' % (PyrInps[pi], IntInps[ii2])) figure(2) subplot(len(IntInps), len(PyrInps), sp_idx + 1) plot(freq_vect, RateMTS_Int) xlim(0, 300) xlabel('Frequency (Hz)') ylabel('Power') title('Pyr. Inp.: %s, Int. Inp.:%s' % (PyrInps[pi], IntInps[ii2])) else: rawfile = tables.open_file(rawfile, mode='r') IPois_As = rawfile.root.IPois_As.read() IPois_fs = (rawfile.root.IPois_fs.read()) * Hz PopRateSig_Pyr_list = rawfile.root.PopRateSig_Pyr.read() PopRateSig_Int_list = rawfile.root.PopRateSig_Int.read() rawfile.close() figure(1, figsize=[6 * len(IPois_fs), 5 * len(IPois_As)]) figure(2, figsize=[6 * len(IPois_fs), 5 * len(IPois_As)]) fmax = (1 / (sim_dt)) / 2 runtime = len(PopRateSig_Pyr_list[0]) * sim_dt / ms if start_time is None: start_time = 0 if end_time is None: end_time = runtime if start_time > runtime or end_time > runtime: raise ValueError( 'Please provide start time and end time within the simulation time window!' ) for pi, IP_A in enumerate(IPois_As): for ii, IP_f in enumerate(IPois_fs): idx = pi * len(IPois_fs) + ii RateSig_Pyr = PopRateSig_Pyr_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Pyr -= np.mean(RateSig_Pyr) RateSig_Int = PopRateSig_Int_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Int -= np.mean(RateSig_Int) if mts_win is 'whole': N = RateSig_Pyr.shape[0] NFFT = 2**(N - 1).bit_length() freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] a = pmtm(RateSig_Pyr, NFFT=NFFT, NW=2.5, method='eigen', show=False) RateMTS_Pyr = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / N RateMTS_Pyr = RateMTS_Pyr[np.where(freq_vect / Hz <= 300)] a = pmtm(RateSig_Int, NFFT=NFFT, NW=2.5, method='eigen', show=False) RateMTS_Int = np.mean(abs(a[0])**2 * a[1], axis=0)[:int(NFFT / 2)] / N RateMTS_Int = RateMTS_Int[np.where(freq_vect / Hz <= 300)] else: NFFT = W * 2 freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] N_segs = int((len(RateSig_Pyr) / ws) - (W - ws) / ws + 1) result = np.zeros((NFFT / 2)) for i in range(N_segs): data = RateSig_Pyr[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) result += Sks[:NFFT / 2] / W RateMTS_Pyr = result[np.where( freq_vect / Hz <= 300)] / N_segs N_segs = int((len(RateSig_Int) / ws) - (W - ws) / ws + 1) result = np.zeros((NFFT / 2)) for i in range(N_segs): data = RateSig_Int[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) result += Sks[:NFFT / 2] / W RateMTS_Int = result[np.where( freq_vect / Hz <= 300)] / N_segs figure(1) subplot(len(IPois_As), len(IPois_fs), idx + 1) plot(freq_vect, RateMTS_Pyr) xlim(0, 300) xlabel('Frequency (Hz)') ylabel('Power') title('IP Amp.: %s, IP Freq.:%s' % (IP_A, IP_f)) figure(2) subplot(len(IPois_As), len(IPois_fs), idx + 1) plot(freq_vect, RateMTS_Int) xlim(0, 300) xlabel('Frequency (Hz)') ylabel('Power') title('IP Amp.: %s, IP Freq.:%s' % (IP_A, IP_f)) if not (out_file is None): figure(1) savefig(out_file + '_Pyr.png') figure(2) savefig(out_file + '_Int.png') show()
def draw_figures(self): ####################################################Get Values dsk_row = self.parent.dsk_row track = self.parent.track ddis = float(self.parent.samp_dis_box.GetValue()) if ddis==0: self.parent.user_warning("Synthetic is required for comparision of phase, start by initalilzing a synthetic"); return synth_dis = self.parent.dis_synth synth_mag = self.parent.synth filter_type = self.filter_type_box.GetValue() lowcut = float(self.lowcut_box.GetValue()) highcut = float(self.highcut_box.GetValue()) order = int(self.order_box.GetValue()) left_bound = float(self.low_bound_box.GetValue()) right_bound = float(self.high_bound_box.GetValue()) aero_diff = float(self.aero_diff_box.GetValue()) left_idx = np.argmin(np.abs(synth_dis-left_bound)) right_idx = np.argmin(np.abs(synth_dis-right_bound)) left_idx,right_idx = min([left_idx,right_idx]),max([left_idx,right_idx]) bin_range,bin_num = (-180,180),120 ###################################################Filter Data data_path = os.path.join(dsk_row["data_dir"],dsk_row["comp_name"]) data_df = utl.open_mag_file(data_path) projected_distances = utl.calc_projected_distance(dsk_row['inter_lon'],dsk_row['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),(180+dsk_row['strike'])%360) shifted_mag = sk.phase_shift_data(data_df["mag"],dsk_row["phase_shift"]) if np.any(np.diff(projected_distances["dist"])<0): itshifted_mag = np.interp(-synth_dis,-projected_distances["dist"],shifted_mag) else: itshifted_mag = np.interp(synth_dis,projected_distances["dist"],shifted_mag) fitshifted_mag = self.filters[filter_type](itshifted_mag,lowcut,highcut,fs=1/ddis,order=order) ###################################################Actual Plotting outer = gridspec.GridSpec(4, 1) ###################################################Axis 0: Magnetic profiles self.ax0 = self.fig.add_subplot(outer[0]) if self.parent.show_other_comp: #Handle Other Aeromag Component if dsk_row["track_type"]=="aero": if "Ed.lp" in track: other_track = track.replace("Ed.lp","Vd.lp") total_track = track.replace("Ed.lp","Td.lp") other_phase = dsk_row["phase_shift"]-90 elif "Hd.lp" in track: other_track = track.replace("Hd.lp","Vd.lp") total_track = track.replace("Hd.lp","Td.lp") other_phase = dsk_row["phase_shift"]-90 elif "Vd.lp" in track: other_track = track.replace("Vd.lp","Ed.lp") total_track = track.replace("Vd.lp","Td.lp") if other_track not in self.parent.deskew_df["comp_name"].tolist(): other_track = track.replace("Vd.lp","Hd.lp") other_phase = dsk_row["phase_shift"]+90 else: self.parent.user_warning("Improperly named component files should have either Ed.lp, Hd.lp, or Vd.lp got: %s"%track); return oth_row = self.parent.deskew_df[self.parent.deskew_df["comp_name"]==other_track].iloc[0] oth_data_path = os.path.join(oth_row["data_dir"],oth_row["comp_name"]) tot_data_path = os.path.join(oth_row["data_dir"],total_track) #Should be in same place oth_data_df = utl.open_mag_file(oth_data_path) oth_shifted_mag = sk.phase_shift_data(oth_data_df["mag"],other_phase) if np.any(np.diff(projected_distances["dist"])<0): oth_itshifted_mag = np.interp(-synth_dis,-projected_distances["dist"],oth_shifted_mag) else: oth_itshifted_mag = np.interp(synth_dis,projected_distances["dist"],oth_data_df) oth_fitshifted_mag = self.filters[filter_type](oth_itshifted_mag,lowcut,highcut,fs=1/ddis,order=order) if filter_type=="None": psk.plot_skewness_data(oth_row,other_phase,self.ax0,xlims=[None,None],color='darkgreen',zorder=2,picker=True,alpha=.7,return_objects=True,flip=True) else: self.ax0.plot(synth_dis,oth_fitshifted_mag,color="#299C29",zorder=3,alpha=.6) tot_data_df = utl.open_mag_file(tot_data_path) if np.any(np.diff(projected_distances["dist"])<0): tot_imag = np.interp(-synth_dis,-projected_distances["dist"],tot_data_df["mag"]) else: tot_imag = np.interp(synth_dis,projected_distances["dist"],tot_data_df["mag"]) tot_fimag = self.filters[filter_type](tot_imag,lowcut,highcut,fs=1/ddis,order=order) if filter_type=="None": psk.plot_skewness_data(dsk_row,dsk_row["phase_shift"],self.ax0,xlims=[None,None],zorder=3,picker=True,return_objects=True,flip=True) else: self.ax0.plot(synth_dis,fitshifted_mag,color="#7F7D7D",zorder=3,alpha=.6) self.ax0.plot(self.parent.dis_synth,self.parent.synth,'r-',alpha=.4,zorder=1) self.ax0.set_ylabel("Magnetic Profiles") # self.ax0.get_xaxis().set_ticklabels([]) ###################################################Axis 1/2: Phase Angles and Differences self.ax1 = self.fig.add_subplot(outer[1], sharex=self.ax0) self.ax2 = self.fig.add_subplot(outer[2], sharex=self.ax0) ###################################################Calculate: Phase Differences trimmed_dis = synth_dis[left_idx:right_idx] trimmed_synth = synth_mag[left_idx:right_idx] trimmed_fitshifted_mag = fitshifted_mag[left_idx:right_idx] al_data = np.angle(hilbert(fitshifted_mag),deg=False)[left_idx:right_idx] al_synth = np.angle(hilbert(np.real(synth_mag)),deg=False)[left_idx:right_idx] data_synth_diff = phase_diff_func(al_synth,al_data) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": trimmed_oth_fitshifted_mag = oth_fitshifted_mag[left_idx:right_idx] al_oth = np.angle(hilbert(oth_fitshifted_mag),deg=False)[left_idx:right_idx] oth_synth_diff = phase_diff_func(al_synth,al_oth) oth_data_diff = phase_diff_func(al_oth,al_data) if abs(aero_diff) > 0: idx = ma.array(np.abs(oth_data_diff)<aero_diff) self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_oth[~idx])),color="darkgreen",linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(oth_synth_diff[~idx]),color="tab:pink",alpha=.8,linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(oth_data_diff[~idx]),color="tab:grey",alpha=.8,linestyle=":") self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_data[~idx])),color="k",linestyle=":") self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_synth[~idx])),color="r",linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(data_synth_diff[~idx]),color="tab:red",alpha=.8,linestyle=":") # import pdb; pdb.set_trace() # not_trimmed_dis = (trimmed_dis[~idx]) # not_trimmed_dis[np.diff(~idx,prepend=[0])] = ma.masked # not_al_data = (al_data[~idx]) # not_al_data[np.diff(~idx)] = ma.masked # not_al_synth = (al_synth[~idx]) # not_al_synth[np.diff(~idx)] = ma.masked # not_al_oth = (al_oth[~idx]) # not_al_oth[np.diff(~idx)] = ma.masked # not_data_synth_diff = (data_synth_diff[~idx]) # not_data_synth_diff[np.diff(~idx)] = ma.masked # not_oth_synth_diff = (oth_synth_diff[~idx]) # not_oth_synth_diff[np.diff(~idx)] = ma.masked # not_oth_data_diff = (oth_data_diff[~idx]) # not_oth_data_diff[np.diff(~idx)] = ma.masked trimmed_dis = (trimmed_dis[idx]) al_data = (al_data[idx]) al_synth = (al_synth[idx]) al_oth = (al_oth[idx]) data_synth_diff = (data_synth_diff[idx]) oth_synth_diff = (oth_synth_diff[idx]) oth_data_diff = (oth_data_diff[idx]) self.ax1.plot(trimmed_dis,np.rad2deg(al_oth),color="darkgreen") self.ax2.plot(trimmed_dis,oth_synth_diff,color="tab:pink",alpha=.8) self.ax2.plot(trimmed_dis,oth_data_diff,color="tab:grey",alpha=.8) self.ax1.plot(trimmed_dis,np.rad2deg(al_data),color="k") self.ax1.plot(trimmed_dis,np.rad2deg(al_synth),color="r") self.ax2.plot(trimmed_dis,data_synth_diff,color="tab:red",alpha=.8) # self.ax2.get_xaxis.set_ticklabels self.ax0.set_xlim(*self.parent.ax.get_xlim()) self.ax0.set_ylim(*self.parent.ax.get_ylim()) self.ax1.set_ylabel("Phase Angles") self.ax2.set_ylabel("Phase Differences") ###################################################Axis 2.1: Power Spectrum # inner = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=outer[2])#, hspace=0.) # self.ax2 = self.fig.add_subplot(inner[0]) ###################################################Axis 2.2: Phase Statistics self.ax3 = self.fig.add_subplot(outer[3]) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": self.ax3.hist(oth_synth_diff,range=bin_range,bins=bin_num,color="tab:pink",alpha=.5,zorder=2) self.ax3.hist(oth_data_diff,range=bin_range,bins=bin_num,color="tab:grey",alpha=.5,zorder=1) self.ax3.hist(data_synth_diff,range=bin_range,bins=bin_num,color="tab:red",alpha=.5,zorder=3) self.ax3.axvline(np.median(data_synth_diff),color="k",alpha=.5,zorder=5,linestyle=":") self.ax3.axvline(np.mean(data_synth_diff),color="k",alpha=.5,zorder=5) self.ax3.axvspan(np.mean(data_synth_diff)-np.std(data_synth_diff),np.mean(data_synth_diff)+np.std(data_synth_diff),color="tab:grey",alpha=.3,zorder=0) self.ax3.annotate(r"$\theta_{mean}$ = $%.1f^\circ \pm %.1f^\circ$"%(np.mean(data_synth_diff),np.std(data_synth_diff)) + "\n" + r"$\theta_{median}$ = %.1f$^\circ$"%np.median(data_synth_diff),xy=(0.02,1-0.02),xycoords="axes fraction",bbox=dict(boxstyle="round", fc="w",alpha=.5),fontsize=self.fontsize,va='top',ha='left') self.ax3.set_ylabel(r"$\Delta \theta$ Count") self.fig.suptitle("%s\n%s\n"%(dsk_row["sz_name"],track)) ###################################################Power Figure N = (right_idx-left_idx) #Length of signal in distance domain NW = 3 #following Parker and O'brien '97 and HJ-Gordon '03 we use a time-bandwith product of 6 (Nw is half) Ns = 5 #Number of points to use in running average smoothing #Handle Distance Domain # import pdb; pdb.set_trace() Sk_complex, weights, eigenvalues=pmtm(itshifted_mag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # smoothed_tshifted_freq = np.convolve(smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing tdata_freqs = np.linspace(0.0, 1.0/(2.0*ddis), N-N//2) #0 to Nyquest self.power_ax = self.power_fig.add_subplot(111) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": Sk_complex, weights, eigenvalues=pmtm(oth_itshifted_mag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 oth_smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # oth_smoothed_tshifted_freq = np.convolve(oth_smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing self.power_ax.semilogy(tdata_freqs, oth_smoothed_tshifted_freq, color="darkgreen") # self.power_ax.semilogy(tdata_freqs, oth_smoothed_tshifted_freq+smoothed_tshifted_freq, color="grey") Sk_complex, weights, eigenvalues=pmtm(tot_imag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 tot_smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # tot_smoothed_tshifted_freq = np.convolve(tot_smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing self.power_ax.semilogy(tdata_freqs, tot_smoothed_tshifted_freq, color="tab:orange") #Old Numpy Method # synth_freqs = np.fft.fftfreq(len(synth_dis[left_idx:right_idx]),ddis) # tdata_freqs = np.fft.fftfreq(len(shifted_mag[left_idx:right_idx]),ddis) # tshifted_freq = np.fft.fft(shifted_mag[left_idx:right_idx]) # fitshifted_freq = np.fft.fft(fitshifted_mag[left_idx:right_idx]) # tsynth_freq = np.fft.fft(synth_mag[left_idx:right_idx]) self.power_ax.semilogy(tdata_freqs, smoothed_tshifted_freq, color="k",zorder=100) # self.power_ax.semilogy(tdata_freqs, np.abs(tshifted_freq), color="k") # self.power_ax.plot(synth_freqs, np.abs(fitshifted_freq), color="#7F7D7D") # self.power_ax.plot(synth_freqs, np.abs(tsynth_freq), color="r") self.power_ax.set_xlim(0.0,0.4) self.power_ax.set_ylim(1e-1,1e6)
def spectrogram(self,data,window_width=None,incr=None,window='Hann',equal_loudness=False,mean_normalise=True,onesided=True,multitaper=False,need_even=False): """ Compute the spectrogram from amplitude data Returns the power spectrum, not the density -- compute 10.*log10(sg) before plotting. Uses absolute value of the FT, not FT*conj(FT), 'cos it seems to give better discrimination Options: multitaper version, but it's slow, mean normalised, even, one-sided. This version is faster than the default versions in pylab and scipy.signal Assumes that the values are not normalised. TODO: Makes a copy of the data and uses that to ensure can be inverted. This is memory wasteful. Is that a problem? """ if data is None: print ("Error") datacopy = data.astype('float') if window_width is None: window_width = self.window_width if incr is None: incr = self.incr # Set of window options if window=='Hann': # This is the Hann window window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1))) elif window=='Parzen': # Parzen (window_width even) n = np.arange(window_width) - 0.5*window_width window = np.where(np.abs(n)<0.25*window_width,1 - 6*(n/(0.5*window_width))**2*(1-np.abs(n)/(0.5*window_width)), 2*(1-np.abs(n)/(0.5*window_width))**3) elif window=='Welch': # Welch window = 1.0 - ((np.arange(window_width) - 0.5*(window_width-1))/(0.5*(window_width-1)))**2 elif window=='Hamming': # Hamming alpha = 0.54 beta = 1.-alpha window = alpha - beta*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='Blackman': # Blackman alpha = 0.16 a0 = 0.5*(1-alpha) a1 = 0.5 a2 = 0.5*alpha window = a0 - a1*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) + a2*np.cos(4 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='BlackmanHarris': # Blackman-Harris a0 = 0.358375 a1 = 0.48829 a2 = 0.14128 a3 = 0.01168 window = a0 - a1*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) + a2*np.cos(4 * np.pi * np.arange(window_width) / (window_width - 1)) - a3*np.cos(6 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='Ones': window = np.ones(window_width) else: print("Unknown window, using Hann") window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1))) if equal_loudness: datacopy = self.equalLoudness(datacopy) if mean_normalise: datacopy -= datacopy.mean() starts = range(0, len(datacopy) - window_width, incr) if multitaper: from spectrum import dpss, pmtm [tapers, eigen] = dpss(window_width, 2.5, 4) counter = 0 sg = np.zeros((len(starts),window_width // 2)) for start in starts: Sk, weights, eigen = pmtm(datacopy[start:start + window_width], v=tapers, e=eigen, show=False) Sk = abs(Sk)**2 Sk = np.mean(Sk.T * weights, axis=1) sg[counter:counter + 1,:] = Sk[window_width // 2:].T counter += 1 sg = np.fliplr(sg) else: if need_even: starts = np.hstack((starts, np.zeros((window_width - len(datacopy) % window_width),dtype=int))) ft = np.zeros((len(starts), window_width)) for i in starts: ft[i // incr, :] = window * datacopy[i:i + window_width] ft = fft.fft(ft) #ft = np.fft.fft(ft) if onesided: sg = np.absolute(ft[:, :window_width // 2]) else: sg = np.absolute(ft) #sg = (ft*np.conj(ft))[:,window_width // 2:].T return sg
def Mtmpsd_ssb(self, signal, wlen, inc, NIS, alpha, beta, c): """ Spectral Subtraction Multitaper Spectrum Estimation Short-term Energy Entropy Ratio :param signal: noisy speech :param wlen: frame length :param inc: frame shift :param NIS: leding unvoiced (noise) frame number :param alpha: over subtraction factor in spectral subtraction :param beta: gain compensation factor :param c: gain factor (0: power spectrum, 1: amplitude spectrum) :return output: denoise speech """ w2 = int(wlen / 2) + 1 wind = np.hamming(wlen) # hamming window y = Speech().enframe(signal, list(wind), inc).T # enframe fn = y.shape[1] # frame number N = len(signal) # signal length fft_frame = np.fft.fft(y, axis=0) # FFT abs_frame = np.abs(fft_frame[0:w2, :]) # positive frequency amplitude ang_frame = np.angle(fft_frame[0:w2, :]) # positive frequency phase # smoothing in 3 neighbour frame abs_frame_backup = abs_frame for i in range(1, fn - 1, 2): abs_frame_backup[:, i] = 0.25 * abs_frame[:, i - 1] + 0.5 * abs_frame[:, i] + 0.25 * abs_frame[:, i + 1] abs_frame = abs_frame_backup # multitaper spectrum estimation power spectrum PSDFrame = np.zeros((w2, fn)) # PSD in each frame for i in range(fn): # PSDFrame[:, i] = pmtm(y[:, i], NW = 3, NFFT=wlen) Sk_complex, weights, eigenvalues = pmtm(y[:, i], NW=3, NFFT=wlen) Sk = (np.abs(Sk_complex)**2).transpose() PSDTwoSide = np.mean(Sk * weights, axis=1) PSDFrame[:, i] = PSDTwoSide[0:w2] PSDFrameBackup = PSDFrame for i in range(1, fn - 1, 2): PSDFrameBackup[:, i] = 0.25 * PSDFrame[:, i - 1] + 0.5 * PSDFrame[:, i] + 0.25 * PSDFrame[:, i + 1] PSDFrame = PSDFrameBackup # average PSD of leading unvoiced segment NoisePSD = np.mean(PSDFrame[:, 0:NIS], axis=1) # spectral subtraction -> gain factor g = np.zeros((w2, fn)) # gain factor g_n = np.zeros((w2, fn)) for k in range(fn): g[:, k] = (PSDFrame[:, k] - alpha * NoisePSD) / PSDFrame[:, k] g_n[:, k] = beta * NoisePSD / PSDFrame[:, k] gix = np.where(g[:, k] < 0) g[gix, k] = g_n[gix, k] gf = g if c == 0: g = gf else: g = np.sqrt(gf) SubFrame = g * abs_frame # spectral subtraction amplitude output = Speech().OverlapAdd2(SubFrame, ang_frame, wlen, inc) # synthesis output = output / np.max(np.abs(output)) # normalized ol = len(output) if ol < N: output = np.concatenate((output, np.zeros(N - ol))) return output
def run(self): ''' Create the directory to save the processing results, read the registration and mark data, compare both files and separate the signal by each mark, then take each group of marks and apply Multitaper processing ''' self.__record = pd.DataFrame() name = str(self.__subject) + '_' + str(self.__cc) path_Record = self.loc + '/' + name + '/' + self.__date + '/Record_' + name + '.csv' path_Mark = self.loc + '/' + name + '/' + self.__date + '/Mark_' + name + '.csv' self.__fs = 250 values = [] frec = [] now = datetime.now() d = (now.strftime("%m-%d-%Y"), now.strftime("%H-%M-%S")) path = self.path_save + '/' + name path_new = path + '/' + d[0] try: if not os.path.isdir(path): os.mkdir(path) if not os.path.isdir(path_new): os.mkdir(path_new) else: pass except OSError as e: if e.errno != errno.EEXIST: raise print('Building ... ' + str(self.__subject) + '_' + str(self.__cc)) Record = pd.read_csv(path_Record, sep=';', index_col=0) Mark = pd.read_csv(path_Mark, sep=';', index_col=0) index = list(range(0, len(Record['C1']))) Record['i'] = index listMark = Mark.values.tolist() Markdata = [] for i in range(0, len(listMark) - 1): start = list(Record.i[Record.H == Mark.iloc[i, 0]]) end = list(Record.i[Record.H == Mark.iloc[i + 1, 0]]) MO = Record[start[0]:end[0]].drop(columns=['H', 'i']) Markdata.append(MO) # 0: FCZ #1: Oz -FCZ #2: O1-FCZ #3: PO7-FCZ #4: O2-FCZ #5: PO8-FCZ #6: PO3-FCZ #7: PO4-FCZ for i in range(0, len(Markdata) - 1): data = Markdata[i].to_numpy() Sk_complex, weights, _ = pmtm(data[i], NW=2, k=4, show=False) Sk = abs(Sk_complex)**2 Sk = Sk.transpose() Sk = np.mean(Sk * weights, axis=1) frequencies = np.linspace(0, 250, 1024) position = np.where((frequencies >= 7) & (frequencies <= 8.5)) maxValue = np.max(Sk[position[0]]) values.append(maxValue) posicion = np.where(Sk == maxValue) maxValuex = frequencies[posicion[0]] frec.append(maxValuex[0]) doc = pd.DataFrame(values, columns=['Max']) doc['Fre'] = frec if not os.path.isdir(self.loc): os.mkdir(self.loc) header = True else: if os.path.isfile(self.loc + name): header = False else: header = True doc.to_csv(path_new + '/' + 'Parameters' + '_' + name + '.csv', mode='a', header=header, index=True, sep=';')
def plot_spcgram_grid(rawfile, mode, start_time=None, end_time=None, W=2**12, ws=None, sim_dt=0.02, out_file=None): sim_dt *= ms if ws is None: ws = W / 10 if mode is 'Homogenous': rawfile = tables.open_file(rawfile, mode='r') PyrInps = (rawfile.root.PyrInps.read() / 1000) * kHz IntInps = (rawfile.root.IntInps.read() / 1000) * kHz PopRateSig_Pyr_list = rawfile.root.PopRateSig_Pyr.read() PopRateSig_Int_list = rawfile.root.PopRateSig_Int.read() rawfile.close() figure(1, figsize=[6 * len(PyrInps), 5 * len(IntInps)]) figure(2, figsize=[6 * len(PyrInps), 5 * len(IntInps)]) fmax = (1 / (sim_dt)) / 2 runtime = len(PopRateSig_Pyr_list[0]) * sim_dt / ms if start_time is None: start_time = 0 if end_time is None: end_time = runtime if start_time > runtime or end_time > runtime: raise ValueError( 'Please provide start time and end time within the simulation time window!' ) for ii in range(len(IntInps)): ii2 = len(IntInps) - ii - 1 for pi in range(len(PyrInps)): idx = pi * len(IntInps) + ii2 sp_idx = ii * len(PyrInps) + pi RateSig_Pyr = PopRateSig_Pyr_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Pyr -= np.mean(RateSig_Pyr) RateSig_Int = PopRateSig_Int_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Int -= np.mean(RateSig_Int) NFFT = W * 2 freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] N_segs = int((len(RateSig_Pyr) / ws) - (W - ws) / ws + 1) RateMTS_Pyr = np.zeros((NFFT / 2, N_segs)) for i in range(N_segs): data = RateSig_Pyr[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) RateMTS_Pyr[:, i] = Sks[:NFFT / 2] / W RateMTS_Pyr = np.squeeze( RateMTS_Pyr[np.where(freq_vect / Hz <= 300), :]) N_segs = int((len(RateSig_Int) / ws) - (W - ws) / ws + 1) RateMTS_Int = np.zeros((NFFT / 2, N_segs)) for i in range(N_segs): data = RateSig_Int[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) RateMTS_Int[:, i] = Sks[:NFFT / 2] / W RateMTS_Int = np.squeeze( RateMTS_Int[np.where(freq_vect / Hz <= 300), :]) figure(1) subplot(len(IntInps), len(PyrInps), sp_idx + 1) imshow(RateMTS_Pyr, origin="lower", extent=[ start_time, end_time, freq_vect[0] / Hz, freq_vect[-1] / Hz ], aspect="auto", cmap='jet') xlabel('Time (ms)') ylabel('Frequency (Hz)') title('Pyr. Inp.: %s, Int. Inp.:%s' % (PyrInps[pi], IntInps[ii2])) figure(2) subplot(len(IntInps), len(PyrInps), sp_idx + 1) imshow(RateMTS_Int, origin="lower", extent=[ start_time, end_time, freq_vect[0] / Hz, freq_vect[-1] / Hz ], aspect="auto", cmap='jet') xlabel('Time (ms)') ylabel('Frequency (Hz)') title('Pyr. Inp.: %s, Int. Inp.:%s' % (PyrInps[pi], IntInps[ii2])) else: rawfile = tables.open_file(rawfile, mode='r') IPois_As = rawfile.root.IPois_As.read() IPois_fs = (rawfile.root.IPois_fs.read()) * Hz PopRateSig_Pyr_list = rawfile.root.PopRateSig_Pyr.read() PopRateSig_Int_list = rawfile.root.PopRateSig_Int.read() rawfile.close() figure(1, figsize=[6 * len(IPois_fs), 5 * len(IPois_As)]) figure(2, figsize=[6 * len(IPois_fs), 5 * len(IPois_As)]) fmax = (1 / (sim_dt)) / 2 runtime = len(PopRateSig_Pyr_list[0]) * sim_dt / ms if start_time is None: start_time = 0 if end_time is None: end_time = runtime if start_time > runtime or end_time > runtime: raise ValueError( 'Please provide start time and end time within the simulation time window!' ) for pi, IP_A in enumerate(IPois_As): for ii, IP_f in enumerate(IPois_fs): idx = pi * len(IPois_fs) + ii RateSig_Pyr = PopRateSig_Pyr_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Pyr -= np.mean(RateSig_Pyr) RateSig_Int = PopRateSig_Int_list[idx][int(start_time * ms / sim_dt ):int(end_time * ms / sim_dt)] RateSig_Int -= np.mean(RateSig_Int) NFFT = W * 2 freq_vect = np.linspace(0, fmax / Hz, NFFT / 2) * Hz freq_vect = freq_vect[np.where(freq_vect / Hz <= 300)] N_segs = int((len(RateSig_Pyr) / ws) - (W - ws) / ws + 1) RateMTS_Pyr = np.zeros((NFFT / 2, N_segs)) for i in range(N_segs): data = RateSig_Pyr[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) RateMTS_Pyr[:, i] = Sks[:NFFT / 2] / W RateMTS_Pyr = np.squeeze( RateMTS_Pyr[np.where(freq_vect / Hz <= 300), :]) N_segs = int((len(RateSig_Int) / ws) - (W - ws) / ws + 1) RateMTS_Int = np.zeros((NFFT / 2, N_segs)) for i in range(N_segs): data = RateSig_Int[i * ws:i * ws + W] a = pmtm(data, NFFT=NFFT, NW=2.5, method='eigen', show=False) Sks = np.mean(abs(a[0])**2 * a[1], axis=0) RateMTS_Int[:, i] = Sks[:NFFT / 2] / W RateMTS_Int = np.squeeze( RateMTS_Int[np.where(freq_vect / Hz <= 300), :]) figure(1) subplot(len(IPois_As), len(IPois_fs), idx + 1) imshow(RateMTS_Pyr, origin="lower", extent=[ start_time, end_time, freq_vect[0] / Hz, freq_vect[-1] / Hz ], aspect="auto", cmap='jet') xlabel('Time (ms)') ylabel('Frequency (Hz)') title('IP Amp.: %s, IP Freq.:%s' % (IP_A, IP_f)) figure(2) subplot(len(IPois_As), len(IPois_fs), idx + 1) imshow(RateMTS_Int, origin="lower", extent=[ start_time, end_time, freq_vect[0] / Hz, freq_vect[-1] / Hz ], aspect="auto", cmap='jet') xlabel('Time (ms)') ylabel('Frequency (Hz)') title('IP Amp.: %s, IP Freq.:%s' % (IP_A, IP_f)) if not (out_file is None): figure(1) savefig(out_file + '_Pyr.png') figure(2) savefig(out_file + '_Int.png') show()
def spectrogram(self, window_width=None,incr=None,window='Hann',equal_loudness=False,mean_normalise=True,onesided=True,multitaper=False,need_even=False): """ Compute the spectrogram from amplitude data Returns the power spectrum, not the density -- compute 10.*log10(sg) 10.*log10(sg) before plotting. Uses absolute value of the FT, not FT*conj(FT), 'cos it seems to give better discrimination Options: multitaper version, but it's slow, mean normalised, even, one-sided. This version is faster than the default versions in pylab and scipy.signal Assumes that the values are not normalised. """ if self.data is None or len(self.data)==0: print("ERROR: attempted to calculate spectrogram without audiodata") return if window_width is None: window_width = self.window_width if incr is None: incr = self.incr # clean handling of very short segments: if len(self.data) <= window_width: window_width = len(self.data) - 1 self.sg = np.copy(self.data) if self.sg.dtype != 'float': self.sg = self.sg.astype('float') # Set of window options if window=='Hann': # This is the Hann window window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1))) elif window=='Parzen': # Parzen (window_width even) n = np.arange(window_width) - 0.5*window_width window = np.where(np.abs(n)<0.25*window_width,1 - 6*(n/(0.5*window_width))**2*(1-np.abs(n)/(0.5*window_width)), 2*(1-np.abs(n)/(0.5*window_width))**3) elif window=='Welch': # Welch window = 1.0 - ((np.arange(window_width) - 0.5*(window_width-1))/(0.5*(window_width-1)))**2 elif window=='Hamming': # Hamming alpha = 0.54 beta = 1.-alpha window = alpha - beta*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='Blackman': # Blackman alpha = 0.16 a0 = 0.5*(1-alpha) a1 = 0.5 a2 = 0.5*alpha window = a0 - a1*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) + a2*np.cos(4 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='BlackmanHarris': # Blackman-Harris a0 = 0.358375 a1 = 0.48829 a2 = 0.14128 a3 = 0.01168 window = a0 - a1*np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1)) + a2*np.cos(4 * np.pi * np.arange(window_width) / (window_width - 1)) - a3*np.cos(6 * np.pi * np.arange(window_width) / (window_width - 1)) elif window=='Ones': window = np.ones(window_width) else: print("Unknown window, using Hann") window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(window_width) / (window_width - 1))) if equal_loudness: self.sg = self.equalLoudness(self.sg) if mean_normalise: self.sg -= self.sg.mean() starts = range(0, len(self.sg) - window_width, incr) if multitaper: [tapers, eigen] = dpss(window_width, 2.5, 4) counter = 0 out = np.zeros((len(starts),window_width // 2)) for start in starts: Sk, weights, eigen = pmtm(self.sg[start:start + window_width], v=tapers, e=eigen, show=False) Sk = abs(Sk)**2 Sk = np.mean(Sk.T * weights, axis=1) out[counter:counter + 1,:] = Sk[window_width // 2:].T counter += 1 self.sg = np.fliplr(out) else: if need_even: starts = np.hstack((starts, np.zeros((window_width - len(self.sg) % window_width),dtype=int))) # this mode is optimized for speed, but reportedly sometimes # results in crashes when lots of large files are batch processed. # The FFTs here could be causing this, but I'm not sure. # hi_mem = False should switch FFTs to go over smaller vectors # and possibly use less caching, at the cost of 1.5x longer CPU time. hi_mem = True if hi_mem: ft = np.zeros((len(starts), window_width)) for i in starts: ft[i // incr, :] = self.sg[i:i + window_width] ft = np.multiply(window, ft) if onesided: self.sg = np.absolute(fft.fft(ft)[:, :window_width //2]) else: self.sg = np.absolute(fft.fft(ft)) else: if onesided: ft = np.zeros((len(starts), window_width//2)) for i in starts: winddata = window * self.sg[i:i + window_width] ft[i // incr, :] = fft.fft(winddata)[:window_width//2] else: ft = np.zeros((len(starts), window_width)) for i in starts: winddata = window * self.sg[i:i + window_width] ft[i // incr, :] = fft.fft(winddata) self.sg = np.absolute(ft) del ft gc.collect() #sg = (ft*np.conj(ft))[:,window_width // 2:].T return self.sg
# multitaper spec = [] kur = [] kurd = [] kurt = [] kura = [] kurs = [] for i in np.arange(0, 8384000, 400): # 1310*16*400 # default output length 512 - but it is symmetric, therefore it is 257 unique values # about the frequency # dt=1/200s, n=400 # df=1/(n*dt)=0.5s # k=5, 5 tapper -> we simply use the first one # we only keep the first 25 cause: # delta: 0.5-4Hz; theta: 4-8Hz; alpha: 8-12Hz; sigma: 12-20Hz; normalized by the total power from 0-20Hz sk = np.apply_along_axis(lambda x: pmtm(x, NW=3, k=5, show=False), axis=-1, arr=image[:, i:(i + 400)] + 1e-7) # pmtm error if input zeros sk = sk[:, 0] # 0 is spectrum spec1 = np.mean((abs(sk[0][0, :41]), abs(sk[1][0, :41])), axis=0) spec2 = np.mean((abs(sk[2][0, :41]), abs(sk[3][0, :41])), axis=0) spec3 = np.mean((abs(sk[4][0, :41]), abs(sk[5][0, :41])), axis=0) the_spec = np.array([spec1, spec2, spec3]) spec.append(the_spec) # 3,41 # kurtosis tmp = np.apply_along_axis(lambda x: np.sum((x - np.mean(x))**4) / 400 / (np.std(x) + 1e-7)**4, axis=-1, arr=image[:, i:(i + 400)] + 1e-7) # 6, kur.append(tmp)
def get_spectrogram(self, nframes, lframes): """ Go through the data frame by frame and perform transformation. They can be plotted using pcolormesh x, y and z are ndarrays and have the same shape. In order to access the contents use these kind of indexing as below: #Slices parallel to frequency axis nrows = np.shape(x)[0] for i in range (nrows): plt.plot(x[i,:], z[i,:]) #Slices parallel to time axis ncols = np.shape(y)[1] for i in range (ncols): plt.plot(y[:,i], z[:, i]) :return: frequency, time and power for XYZ plot, """ from spectrum import dpss, pmtm assert self.method in ['fft', 'welch', 'mtm'] x = self.data_array fs = self.fs # define an empty np-array for appending pout = np.zeros(nframes * lframes) if self.method == 'fft': # go through the data array section wise and create a results array for i in range(nframes): f, p, _ = self.get_fft(x[i * lframes:(i + 1) * lframes] * self.get_window(lframes)) pout[i * lframes:(i + 1) * lframes] = p elif self.method == 'welch': # go through the data array section wise and create a results array for i in range(nframes): f, p = self.get_pwelch(x[i * lframes:(i + 1) * lframes] * self.get_window(lframes)) pout[i * lframes:(i + 1) * lframes] = p elif self.method == 'mtm': [tapers, eigen] = dpss(lframes, NW=2) f = self.get_fft_freqs_only(x[0:lframes]) # go through the data array section wise and create a results array for i in range(nframes): p = pmtm(x[i * lframes:(i + 1) * lframes] * self.get_window(lframes), e=tapers, v=eigen, method='adapt', show=False) # pay attention that mtm uses padding, so we have to cut the output array pout[i * lframes:(i + 1) * lframes] = np.fft.fftshift( p[0:lframes, 0]) # create a mesh grid from 0 to nframes -1 in Y direction xx, yy = np.meshgrid(f, np.arange(nframes)) # fold the results array to the mesh grid zz = np.reshape(pout, (nframes, lframes)) return xx, yy * lframes / fs, zz