def getFrameNotes(audio, samplerate, interval): # Init some variables to describe data duration = len(audio) / samplerate frames = int(duration / interval) + 1 frameLength = int(samplerate * interval) frameNotes = [] # Go through each sample within a frame for i in range(0, frames): # Retrieve sample start = i * frameLength end = (i + 1) * frameLength frameData = audio[start:end] # Apply FFT yf = fft(frameData) xf = fftfreq(len(frameData), 1 / samplerate) # Get peak frequencies within FFT indices, properties = find_peaks(yf, threshold=200000, distance=5) # Approximate Midi pitch of each peak frequency peakFreqs = set() for j in indices: peakFreqs.add(findNearestMidiPitch(np.abs(xf[j]))) frameNotes.append(peakFreqs) return frameNotes
def cvt_to_fft(data): N = 10 T = 1 / 20 yf = fft(data) xf = fftfreq(N, T)[:N // 2] yf = 2.0 / N * np.abs(yf[0:N // 2]) return xf, yf
def bandpass_filter(signal_samples, fs, fs_high, fs_low): signal_samples = np.atleast_2d(signal_samples) freq_vector = fftfreq(signal_samples.shape[1], 1 / fs) mask = np.logical_and(freq_vector < fs_high, freq_vector >= fs_low) fft_samples = fft(signal_samples, axis=1) fft_samples[:, mask] = 0 return ifft(fft_samples, axis=1)
def load_dac_response(fn, fs, N, ch=1): """ Load the measured dac response and adjust it to target sampling frequency. Parameters ---------- fn : string filename of the resposne to be loaded fs: float sampling rate N : int length of the output vector ch: int, optional Which of the DAC channels to load the response for Returns ------- dacf_interp : array_like frequency response of the DAC for channel ch with vector length N """ npzfile = np.load(fn) dac_f = npzfile['dac_res_ch%d' % ch] # Copy spectrum to the negative frequency side dacf_complex = np.atleast_2d(dac_f[:, 1] * np.exp(1j * dac_f[:, 2])) dacf = np.concatenate((np.fliplr(np.conj(dacf_complex[:, 1:])), dacf_complex), axis=1) dac_freq = np.concatenate((np.fliplr(-np.atleast_2d(dac_f[1:, 0])), np.atleast_2d(dac_f[:, 0])), axis=1) freq_sig_fft = fft.fftfreq(N)*fs # Interpolate the dac response, do zero-padding if fs/2 > 32 GHz polyfit = interpolate.interp1d(dac_freq.flatten(), dacf.flatten(), kind='linear', bounds_error=False, fill_value=dac_f[320, 1]) dacf_interp = polyfit(freq_sig_fft) dacf_interp = np.atleast_2d(dacf_interp) return dacf_interp
def fspectrum(ts, pulse, N=0, remove_dc=True): """Computes the Fourier transform of a pulse. Args: ts (numpy.array): An array of floats specifying the time axis of the pulse. pulse (numpy.array): A complex array specifying the pulse. N (int): The number of additional timesteps to add to the pulse. This will append N zeros to the end of the pulse in order to increase the resolution of the fourier transform in frequency space. remove_dc (bool): If true, the DC offset (mean) will be subtracted from the pulse prior to computing the fourier transform. Returns: tuple: A tuple (ks, fs) representing the frequencies and the fourier transform of the input pulse. """ ks = fftfreq(len(ts) + N, ts[1] - ts[0]) if N > 0: pulse = np.concatenate([pulse, pulse[-1]*np.ones(N)]) if remove_dc: pulse -= np.mean(pulse) fs = fft(pulse) fs = fs[np.argsort(ks)] ks = np.sort(ks) return ks, fs
def _set_freqs(self): # Set freqs indexes if self._sides == "onesided": self._freqs = rfftfreq(self._nfft, 1 / self._fs) else: self._freqs = fftfreq(self._nfft, 1 / self._fs)
def pre_filter_wdm(signal, bw, os, center_freq=0): """ Ideal LP filter for selecting part of the spectrum. Uses FFT Parameters ---------- signal : array-like Input signal bw : float Filter bandwidth, normalized units os : float Oversampling factor center_freq : float center frequency, normalized units. Default is DC centered operation Returns ------- s : array-like Output signal after filtering """ # Prepare signal N = len(signal) h = np.zeros(N, dtype=sig.real.dtype) freq_axis = scifft.fftfreq(N, 1 / os) # Create filter window idx = np.where(abs(freq_axis - center_freq) < bw / 2) h[idx] = 1 # Filter and output s = (scifft.ifft(scifft.fft(signal) * h)) return s
def FWHM(freq_f, timestep): """ Find the Full Width Half Max of a function by returning the width at the halfway point of the highest peak in the frequency domain. Parameters ---------- freq_f : np.ndarray one-dimensional frequency-domain data timestep : float/int incremental change in the independent variable Returns ------- FWHM : float/int the full width half max of the signal in the frequency domain """ length = len(freq_f) PS = np.real(freq_f * np.conj(freq_f) / length) freq = np.real(fftfreq(length) * 2 * np.pi / timestep) L = np.arange(1, np.floor(length / 2), dtype='int') peaks, _ = find_peaks(PS[L]) sf = abs(freq[L][0] - freq[L][1]) results_half = peak_widths(PS[L], peaks, rel_height=0.5) FWHM = results_half[0][np.where( results_half[1] == max(results_half[1]))] * sf FWHM = FWHM[0] return FWHM
def two_sided_fft(time_arr, signal): """ Takes the 2-Sided fft of a signal given the time series vector and signal Args ---- Ts = 1/SAMPLE_RATE signal = time-series amplitude return ------ freqs = 1-sided freq vector signal_fft_2sided = FT of the signal (complex form) """ # Frequency vector Ts = time_arr[1] - time_arr[0] n = len(signal) Fs = 1 / Ts freq_2S = fftfreq(n, 1 / Fs) # Take FFT signal_fft_2S = fft(signal) / n # 2-sided FFT (normalized by the len) return freq_2S, signal_fft_2S
def signal_fft(self): # TO DO use fft filtered signal length = self.stock_prices.shape[0] N = 1 * length for i in self.stock_prices: x = self.stock_prices[i] fil_x = self.fil_stock_prices[i] y = fft(list(x)) fil_y = fft(list(fil_x)) xf = fftfreq(length, 1 / 1) self.xf = xf # ignore high frequency, cut off at 10 day periodicity 1/0.1 plt.figure(figsize=(15, 5)) plt.bar(xf[np.logical_and(xf > 0.0001, xf < 0.1)], np.abs(fil_y[np.logical_and(xf > 0.0001, xf < 0.1)]), width=0.0005) plt.legend('signal spectrum', loc='best') plt.title("FFT - " + i) plt.xlabel("1/days") plt.grid(True) if self.save_output: plt.savefig(os.path.join(self.output_path, i + "_fft.png"), dpi=300) plt.show()
def calc_and_plot(Filter_Func, Sample_Func, title): # Результат фильтра (Свёртка) conv = np.convolve(Filter_Func.y, Sample_Func.y) x = np.linspace(Sample_Func.From, Sample_Func.To, len(conv)) #plt.plot(x, conv, color='r') # Частотная характеристика окна (Фильтра) fft_lib_res = np.fft.fft(Filter_Func.y) spacing_period = (Filter_Func.From-Filter_Func.To)/Filter_Func.N xf = fftfreq(Filter_Func.N, spacing_period) lib_res_module = calc_module(fft_lib_res) fig = plt.figure() fig.suptitle(title) # Результат сглаживания subplot = fig.add_subplot(131) subplot.plot(Sample_Func.x, Sample_Func.y, color='b', label='Source Signal') subplot.plot(x, conv, color='r', label='Smoothened Signal') subplot.legend() # Фильтр subplot = fig.add_subplot(132) subplot.plot(Filter_Func.x, Filter_Func.y, color='k', label='Filter Func h(x)', marker='.') subplot.legend() # Фурье subplot = fig.add_subplot(133) #subplot.set_xlim(0, max(xf)) subplot.plot(fftshift(xf), abs(fftshift(lib_res_module))/Filter_Func.N, label='Impulse characteristics') subplot.legend() fig.show()
def prop(self, signal: QamSignal): ''' :param signal: signal object to propagation across this fiber :return: ndarray ''' center_lambda = signal.center_wavelength after_prop = np.zeros_like(signal[:]) for pol in range(0, signal.pol_number): sample = signal[pol, :] sample_fft = fft(sample) freq = fftfreq(signal[:].shape[1], 1 / signal.fs_in_fiber) omeg = 2 * np.pi * freq after_prop[pol, :] = sample_fft * np.exp( -self.alphalin * self.length / 2) after_prop[pol, :] = ifft(after_prop[pol, :]) disp = np.exp(-1j / 2 * self.beta2(center_lambda) * omeg**2 * self.length) after_prop[pol, :] = ifft(fft(after_prop[pol, :]) * disp) signal[0] = after_prop[0] signal[1] = after_prop[1] return signal
def load_fft_stream(self, dft_window: int = 4096, stream: int = 0): """ Load the FFT of the timeseries. dft_window: sample size for each DFT slice, defaults to 4096. Structure is the same as that of the timeseries. """ ts = self.load_ts_stream(stream=stream) result = {} attr = self.get_stream_attrs(stream) # Rate from MHz -> Hz acq_rate = attr['acquisition_rate'] * 1e6 channels = attr['channels'] for ch in channels: ts_ch = ts[ch] n_slices = int(ts_ch.shape[-1] / dft_window) ts_sliced = ts_ch[:, :, :n_slices * dft_window].reshape( (ts_ch.shape[0], ts_ch.shape[1], n_slices, -1)) # Apply DFT to sliced ts and return DFT in the original shape # freq is a single array since acq_rate is the same for all data in the stream data_freq = _apply_DFT(ts_sliced, dft_window) result[ch] = np.ascontiguousarray(data_freq) frequency = fftshift(fftfreq(dft_window, d=1 / acq_rate)) return frequency, result
def NoiseFreq(self, savename, ch): from scipy.fft import fft, fftfreq T = 1 / 2000000. N = self.amp_chan[str(ch)].shape[0] batchsize = self.amp_chan[str(ch)].shape[1] batch_noise = [] fig, ax = plt.subplots() for n in range(batchsize): yf = fft(self.amp_chan[str(ch)][:, n]) xf = fftfreq(N, T)[:N // 2] batch_noise.append(yf) ax.plot(xf, 2.0 / N * np.abs(yf[0:N // 2]), color='gray') mean_noise = np.mean(np.absolute(np.array(batch_noise)), axis=0) avg_wf = np.mean(self.amp_chan[str(ch)][:, 3:-3], axis=1) avg_noise = fft(avg_wf) ax.plot(xf, 2.0 / N * np.abs(mean_noise[0:N // 2]), color='black', label='Mean of noise') ax.plot(xf, 2.0 / N * np.abs(avg_noise[0:N // 2]), color='red', label='Noise of mean wf') ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('Frequency (Hz)') ax.set_ylabel('Arbitrary Unit.') ax.set_ylim(0.1**7, 0.1**3) ax.legend() fig.savefig(savename) plt.close()
def fourier_demo(): # number of signal points N = 500 # sample spacing T = 1 / 1000 x = np.linspace(0.0, N * T, N, endpoint=False) y = (10 * np.sin(30 * 2.0 * np.pi * x) + 1 * np.sin(40 * 2.0 * np.pi * x) + 3 * np.sin(65 * 2.0 * np.pi * x) + 3 * np.sin(75 * 2.0 * np.pi * x)) plot_y = (10 * np.sin(30 * x) + 1 * np.sin(40 * x) + 3 * np.sin(65 * x) + 3 * np.sin(75 * x)) yf = fft.fft(y) xf = fft.fftfreq(N, T) xf = fft.fftshift(xf) yplot = fft.fftshift(yf) fig = go.Figure() fig.add_trace(go.Scatter(y=plot_y, x=x % 360, mode='lines')) fig.update_layout(title='<b>Waveform (Time Domain)</b>') fig.update_xaxes(title_text='Time (s)') fig.update_yaxes(title_text='Amplitude') fig.show() fig = go.Figure() fig.add_trace( go.Scatter(y=(1.0 / N * np.abs(yplot)) * 2, x=xf, mode='lines')) fig.update_layout(title='<b> Power Spectrum (Frequency Domain)</b>', xaxis=dict(range=[0, N])) fig.update_xaxes(title_text='Frequency (Hz)') fig.update_yaxes(title_text='Amplitude') fig.show()
def AnalisadorEspectro(x, t, N, Lfreq, titleTempo, titleFreq): # sinal x, vetor de tempo t # N - tamanho da fft # Lfreq - limite superior da frequencia # titletempo e titlefreq - title dos graficos do tempo e da freq. # calculando sua FT Tam = t[1] - t[0] X = fft(x, N) * Tam w = fftfreq(len(X), d = Tam) # Os indices de frequencia são mudados de 0 a N-1 para -N/2 + 1 a N/2 # posicionando a freq. zero no meio do gráfico wd = fftshift(w) Xd = fftshift(X) # calculando o modulo - magnitude do espectro ModX = np.abs(Xd) fig, ax = plt.subplots(2, 1) ax[0].plot(t, x, 'r-', lw = 2, label = "x(t)") ax[0].set_ylabel("Amplitude") ax[0].set_xlabel("tempo [s]") ax[0].grid(True) ax[0].set_title(titleTempo) ax[1].plot(wd, ModX, 'c-', lw = 2, label = "|X(jw)|") ax[1].set_ylabel("Amplitude") ax[1].set_xlabel("Freq. [Hz]") ax[1].grid(True) if Lfreq != 0: ax[1].set_xlim(0, Lfreq) ax[1].set_title(titleFreq) fig.tight_layout() return ModX,wd
def read_signals(grabaciones): for i in grabaciones: data = "./grabaciones/"+i+"g.wav" print(data) fs,data_signal=read(data) t=np.arange(len(data_signal))/fs plt.figure(figsize=(15,8)) plt.plot(t,data_signal) plt.title("Temperatura :"+"%s"%i+" ºC en el dominio del tiempo") plt.xlabel("Time [s]") plt.ylabel("Amplitude") plt.grid() plt.show() Nmuestras = len(data_signal) yff = scipy.fft.fft(data_signal) xff = fftfreq(len(data_signal), 1/fs)[:Nmuestras//2] plt.plot(xff, 2.0/Nmuestras * np.abs(yff[0:Nmuestras//2])) plt.grid() plt.title("Temperatura :"+"%s"%i+" ºC en el Dominio de la frecuencia") plt.xlabel('Frequency [Hz]') plt.ylabel('Amplitude') plt.show() print(fs)
def Filtragem_RC(x, t, T, Tam, RC=[0.1, 0.35, 1.2]): # sinal x, vetor de tempo t # T - periodo de x # Tam - taxa de amostragem # RC - valores para RC do filtro ## filtragem X = fft(x) / len(x) # criando o vetor de frequencia w = fftfreq(len(t), d=(1 / T) * Tam) for RCk in RC: H = 1 / (1 + ((1j * w) * (RCk))) # passa-baixas Y = H * X # aplicando o filtro # retornando o sinal ao dominio do tempo yt = ifft(Y) * len(x) yr = np.real(yt) # ignorando os erros de arrendondamento do fft e ifft # plotando as figuras para visualização fig, ax = plt.subplots() ax.plot(t, x, 'c--', linewidth = 2, label = "xr(t)") ax.plot(t, yr, 'r-', linewidth = 1, label = "xr_filtrado(t)") ax.set_ylabel("Amplitude") ax.set_xlabel("tempo [s]") ax.grid(True) ax.legend() ax.set_title('xr(t) e xr_filtrado(t) para RC = ' + str(RCk)) return yr
def _rrcos_pulseshaping_freq(sig, fs, T, beta): """ Root-raised cosine filter in the spectral domain by multiplying the fft of the signal with the frequency response of the rrcos filter. Parameters ---------- sig : array_like input time distribution of the signal fs : float sampling frequency of the signal T : float width of the filter (typically this is the symbol period) beta : float filter roll-off factor needs to be in range [0, 1] Returns ------- sign_out : array_like filtered signal in time domain """ f = scifft.fftfreq(sig.shape[0]) * fs nyq_fil = rrcos_freq(f, beta, T) nyq_fil /= nyq_fil.max() sig_f = scifft.fft(sig) sig_out = scifft.ifft(sig_f * nyq_fil) return sig_out
def __average_fft( loudest_pieces: np.ndarray, sample_rate: int, fft_size: int ) -> np.ndarray: # print(loudest_pieces.shape) yf = abs(fft(loudest_pieces, fft_size)).mean(0) freq = fftfreq(len(yf), 1/sample_rate) # plt.plot(np.log10(freq), yf / 10000, label="fft") # plt.show() # print(fft_size) # print(len(yf)) # print(1/sample_rate) f, _, specs = signal.stft( loudest_pieces, sample_rate, window="boxcar", nperseg=fft_size, noverlap=0, boundary=None, padded=False, ) # print(specs.shape) print(fft_size) print(np.abs(specs).mean((0, 2)).shape) print(yf[:len(yf)//2 + 1].shape) # plt.plot(np.log10(f), np.abs(specs).mean((0, 2)), label="stft") # plt.show() return np.abs(specs).mean((0, 2)), yf[:len(yf)//2 + 1]
def FBP(data, ig): '''Filter-Back-Projection for a nice description https://www.coursera.org/lecture/cinemaxe/filtered-back-projection-part-2-gJSJh ''' spread = ig.allocate(0) spreadarr = spread.as_array() recon = ig.allocate(0) reconarr = recon.as_array() l = spread.get_dimension_size('horizontal_x') # create |omega| filter freq = fftfreq(l) fltr = np.asarray([np.abs(el) for el in freq]) for i, angle in enumerate(data.geometry.angles): line = data.get_slice(angle=i).as_array() # apply filter in Fourier domain lf = fft(line) lf3 = lf * fltr bck = ifft(lf3) # backproject for j in range(recon.shape[1]): spreadarr[j] = bck.real # should use https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.rotate reconarr += rotate(spreadarr, angle, reshape=False) recon.fill(reconarr) return recon
def showfft(t_sample): # time horizon and sample period T = 10 dt = 0.02 t = np.linspace(0, T, int(T / dt), endpoint=False) # function k = 5 f = lambda t: np.cos(2 * np.pi * t * k / T) + np.sin(2 * np.pi * t * (k + 6) / T) def delta(t, t_sample): k = int(t_sample / dt) return [1 / dt if 0 == n % k else 0 for n in range(len(t))] # compute FFT F = fft(f(t)) w = fftfreq(len(F), dt) fig, ax = plt.subplots(3, 2, figsize=(16, 6)) ax[0, 0].plot(t, f(t)) fftplot(ax[0, 1], w, F) g = delta(t, t_sample) G = fft(g) ax[1, 0].plot(t, g) fftplot(ax[1, 1], w, G) h = f(t) * delta(t, t_sample) H = fft(h) ax[2, 0].plot(t, h) fftplot(ax[2, 1], w, H)
def add_dispersion(sig, fs, D, L, wl0=1550e-9): """ Add dispersion to signal. Parameters ---------- sig : array_like input signal fs : flaot sampling frequency of the signal (in SI units) D : float Dispersion factor in s/m/m L : float Length of the dispersion in m wl0 : float,optional center wavelength of the signal Returns ------- sig_out : array_like dispersed signal """ C = 2.99792458e8 N = sig.shape[-1] omega = fft.fftfreq(N, 1/fs)*np.pi*2 beta2 = D * wl0**2 / (C*np.pi*2) H = np.exp(-0.5j * omega**2 * beta2 * L).astype(sig.dtype) sff = fft.fft(fft.ifftshift(sig, axes=-1), axis=-1) sig_out = fft.fftshift(fft.ifft(sff*H)) return sig_out
def cwt(self, signal: np.ndarray, scales: np.ndarray, dt=1): """Continuous wavelet transform. Parameters ---------- signal : np.ndarray The signal to transform. scales : np.ndarray Wavelet scales. dt : float The sampling period of the signal. """ # Find the fast length for the FFT n = len(signal) fast_len = fft.next_fast_len(n) # Signal in frequency domain fs = fft.fftfreq(fast_len, d=dt) f_sig = fft.fft(signal, n=fast_len) # Compute the wavelet transform psi = np.array([self.psi_f(fs, scale) for scale in scales]) W = fft.ifft(f_sig * psi, workers=-1)[..., :n] freqs = self.central_freq(scales) return freqs, W
def Uzk(u0=None, z=50, lam=lam): A = fft2(U0) dx = np.diff(g)[0] kg = 2 * np.pi * fftfreq(n=len(g), d=dx) kx, ky = np.meshgrid(kg, kg) k = 1e6 * 2 * np.pi / lam return np.abs(ifft2(A * np.exp(-1j * z * np.sqrt(k**2 - kx**2 - ky**2))))
def get_ratios(H, t_pd, beta_d, Ls): # compute ratios of the estimated lake length (dL) and water volume change (dV) # relative to their true values given the true lake length (Ls), # dimensional friction (beta_d), and ice thickness (H) # discretization in frequency domain N = 2000 x = np.linspace(-100, 100, num=N) d = np.abs(x[1] - x[0]) k = fftfreq(N, d) # frequency k[0] = 1e-10 # set zero frequency to small number due to (integrable) singularity k *= 2 * np.pi # convert to SciPy's Fourier transform definition (angular # freq. definition) used in notes w = w_base(x, Ls / H) # compute basal velocity anomaly w_ft = fft(w) # fourier transform for numerical method beta_nd = beta_d * H / (2 * eta) # non-dimensional friction parameter # relative to viscosity/ice thickness tr = (4 * np.pi * eta) / (rho * g * H) # relaxation time lamda = t_pd / tr # ratio of oscillation time to relaxation time D1, D2 = get_Dj(lamda, beta_nd, w_ft, k) # compute surface displacements T1, T2 = get_Tj(D1, D2, x, H) # compute estimated highstand/lowstand times kappa1, kappa2 = get_kappaj(T1, T2) # compute weights for displacements dH = kappa1 * D1 + kappa2 * D2 # compute surface elevation change anomaly dS = 2 * w # elevation change at base # interpolate displacements for integration dSi = interpolate.interp1d(x, dS, fill_value="extrapolate") dHi = interpolate.interp1d(x, dH, fill_value="extrapolate") dVs = integrate.quad(dSi, -0.5 * Ls / H, 0.5 * Ls / H, full_output=1)[0] # compute estimated lake length if np.size(x[np.abs(dH) > delta]) > 0: x0 = x[np.abs(dH) > delta] else: x0 = 0 * x Lh = 2 * np.max(x0) # (problem is symmetric with respect to x) if Lh > 1e-5: dVh = integrate.quad(dHi, -0.5 * Lh, 0.5 * Lh, full_output=1)[0] dV = dVh / dVs dL = Lh * H / Ls lag = (2 / np.pi) * (np.pi - T1) else: dV = 0 dL = 0 lag = 1.01 return dV, dL, lag
def signaltest(normalized_tone): myx = [ DFT(normalized_tone[:1000], n) for n in range(0, len(normalized_tone[:1000])) ] yf = fft(normalized_tone[:1000]) new_sig = ifft(yf) xf = fftfreq(1000, 1 / SAMPLE_RATE) #Freq Kotelnikova myfreq = SAMPLE_RATE / 2 myxf = np.arange(0, myfreq, 2 * myfreq / 1000) fig, axs = plt.subplots(4, 2) fig.suptitle("Task 1") # axs[0][0].set_title("Fast Fourirer Transform") axs[0][0].plot(xf[:500], np.abs(yf)[:500]) #axs[1][0].set_title("Discrete(my) Fourirer Transform") axs[1][0].plot(myxf, np.abs(myx)[:500], "tab:green") #axs[2][0].set_title("Discrete(my) and Fast FT on one graphic") axs[2][0].plot(xf[:500], np.abs(yf)[:500]) axs[2][0].plot(myxf, np.abs(myx)[:500], "tab:green") kyx = [IDFT(myx, k) for k in range(0, len(myx))] # axs[0][1].set_title("Inverse Fast Fourirer Transform") axs[0][1].plot(new_sig[:1000]) # axs[1][1].set_title("Inverse Discrete(my) Fourirer Transform") axs[1][1].plot(kyx, "tab:green") # axs[2][1].set_title("Inverse Fast and Discrete(my) FT") #axs[2][1].plot(new_sig[:1000]) axs[2][1].plot(kyx, "tab:green") # axs[3][0].set_title("Full function") axs[3][0].plot(normalized_tone) # axs[3][1].set_title("Source signal for transform") axs[3][1].plot(normalized_tone[:1000]) plt.show()
def Ky(self): """ Wavenumber along the y-axis. """ if getattr(self, '_Ky', None) is None: nx = self.gridPadded.shape[1] kx = 2. * np.pi * fftfreq(nx, self.dx) ny = self.gridPadded.shape[0] ky = 2. * np.pi * fftfreq(ny, self.dy) Ky, Kx = np.meshgrid(ky, kx) self._Ky, self._Kx = Ky.T, Kx.T return self._Ky
def fft_plot(signal, t, period=1): font = { 'family': 'normal', 'size': 10, } matplotlib.rc('font', **font) fig = plt.figure(figsize=(12, 10)) axe0 = fig.add_subplot(3, 1, 1) axe0.set_title(f"signal") axe0.set_ylabel("y") axe0.set_xlabel("t", x=1, y=-2) axe2 = fig.add_subplot(3, 1, 2) axe2.set_title("Frequency domain Amplitude") axe2.set_ylabel("Amplitude") axe2.set_xlabel("w", x=1, y=-2) axe3 = fig.add_subplot(3, 1, 3) axe3.set_title("Frequency domain Phase") axe3.set_ylabel("Phase") axe3.set_xlabel("w", x=1, y=-2) sigfft = fft.fftshift(fft.fft(signal)) freq = fft.fftshift(fft.fftfreq(200 * 8, d=1 / 200)) axe0.plot(t, signal) axe2.plot(freq, np.abs(sigfft)) #, use_line_collection=True) axe3.plot(freq, np.angle(sigfft)) #, use_line_collection=True) plt.subplots_adjust(left=0.125, right=0.9, bottom=0.05, top=0.9, wspace=0.35, hspace=0.35) plt.show() return
def fft_mag(x, fs): """ ------------------------ INPUT: -------- x: array de una dimensión conteniendo la señal cuya fft se busca calcular fs: frecuncia a la que está muestreada la señal ------------------------ OUTPUT: -------- f: array de una dimension con con los valores correspondientes al eje de frecuencias de la fft. mag: array de una dimensión conteniendo los valores en magnitud de la fft de la señal. """ freq = fft.fftfreq(len(x), d=1 / fs) # se genera el vector de frecuencias senial_fft = fft.fft(x) # se calcula la transformada rápida de Fourier # El espectro es simétrico, nos quedamos solo con el semieje positivo f = freq[np.where(freq >= 0)] senial_fft = senial_fft[np.where(freq >= 0)] # Se calcula la magnitud del espectro mag = np.abs(senial_fft) / len(x) # Respetando la relación de Parceval # Al haberse descartado la mitad del espectro, para conservar la energía # original de la señal, se debe multiplicar la mitad restante por dos (excepto # en 0 y fm/2) mag[1:len(mag) - 1] = 2 * mag[1:len(mag) - 1] return f, mag