def smoothen_image(image, width): kernel = blackman(width)[:, None] * blackman(width) kernel /= np.sum(kernel) result = np.empty_like(image) for i in range(3): result[:, :, i] = convolve2d(image[:, :, i], kernel, mode="same") return result
def test_basic(self): assert_allclose(windows.blackman(6, sym=False), [0, 0.13, 0.63, 1.0, 0.63, 0.13], atol=1e-14) assert_allclose(windows.blackman(7, sym=False), [0, 0.09045342435412804, 0.4591829575459636, 0.9203636180999081, 0.9203636180999081, 0.4591829575459636, 0.09045342435412804], atol=1e-8) assert_allclose(windows.blackman(6), [0, 0.2007701432625305, 0.8492298567374694, 0.8492298567374694, 0.2007701432625305, 0], atol=1e-14) assert_allclose(windows.blackman(7, True), [0, 0.13, 0.63, 1.0, 0.63, 0.13, 0], atol=1e-14)
def calculateSpectrum(taxis, data, fmax=0, slopeTime=5e-12, fbins=None): # slopeTime = 5 #rising and falling time in ps # fbins = None #target frequency resolution in GHz; Set to None if no zeropadding wanted # tmax = None #set time limit; dt = np.mean(np.diff(taxis)) # apply window function N = int(slopeTime / dt) window = windows.blackman(2 * N) window = np.hstack((window[:N], np.ones(len(taxis) - 2 * N, ), window[N:])) data *= window # fourier transform to target frequency resolution by zeropadding if fbins is not None: N = int(1 / dt / fbins) else: N = len(taxis) fd = np.fft.rfft(data, N) freq = np.fft.rfftfreq(N, dt) phase = np.unwrap(np.angle(fd)) return freq[freq < fmax], fd[freq < fmax], phase[freq < fmax]
def get_MBS(x,fs,T0mean): # Obtain the mean-based signal MBS=np.zeros(len(x)) halfL=int(1.6*T0mean[0]/2) StepExp=3 Step=2**StepExp for m in range(halfL, len(x)-halfL, Step): if len(T0mean)==1: halfL=int(1.7*T0mean[0]/2) else: halfL=int(1.7*T0mean[m]/2) Blackwin=blackman(2*halfL) start=int(m-halfL) stop=int(m+halfL) if stop>len(x): break if start>0: vec=x[start:stop]*Blackwin MBS[m]=np.mean(vec) t=np.where(MBS!=0)[0] MBS=np.interp(np.arange(len(x)), t, MBS[t]) MBS[np.isnan(MBS)]=0 MBS=zeroPhaseHPFilt(MBS,fs, 70,10) MBS=MBS/max(abs(MBS)) MBS=smooth(MBS,7) return MBS
def give_many_fft( fs: int, time_data: np.ndarray, threshold: float = 0.01, sample_duration: int = config.SAMPLE_DURATION, block_duration: int = config.BLOCK_DURATION, step_fraction: int = config.STEP_FRACTION, fft_size: int = config.FFT_SIZE, fft_ratio: int = config.FFT_RATIO, ): """From frequency sampling and content of a wav file, make the spectrogram""" sample_size = fs * sample_duration window_size = int(fs * block_duration / 1000) window = ssw.blackman(window_size) step = window_size // step_fraction n_steps = sample_size // step padding_left = np.zeros(step) padding_right = np.zeros(max(0, sample_size - len(time_data) - step)) time_data_2 = np.concatenate( (padding_left, time_data, padding_right))[:sample_size] for k in range(n_steps - step_fraction): sound_part = time_data_2[k * step:k * step + window_size] sound_windowed = window * sound_part if max(abs(sound_windowed)) < threshold: continue yield abs(fft(sound_windowed, fft_size * fft_ratio)[:fft_size])
def smooth(data, window_type='hann', filter_width=11, sigma=2, plot_on=1): """ Smooth 1d data with moving window (uses filtfilt to have zero phase distortion) Wrapper for scipy.signal.filtfilt To do: consider replacing with sosfiltfilt Inputs: data: numpy array window_type ('hann'): string ('boxcar', 'gaussian', 'hann', 'bartlett', 'blackman') filter_width (11): int (wider is more smooth) odd is ideal sigma (2.): scalar std deviation only used for gaussian plot_on (1): int determines plotting. 0 none, 1 plot signal, 2: also plot filter Outputs data_smoothed: signal after being smoothed filter_window: the window used for smoothing Notes: Uses gustaffson's method to handle edge artifacts Currently accepted window_type options: hann (default) - cosine bump filter_width is only param blackman - more narrowly peaked bump than hann boxcar - flat-top of length filter_width bartlett - triangle gaussian - sigma determines width """ if window_type == 'boxcar': filter_window = windows.boxcar(filter_width) elif window_type == 'hann': filter_window = windows.hann(filter_width) elif window_type == 'bartlett': filter_window = windows.bartlett(filter_width) elif window_type == 'blackman': filter_window = windows.blackman(filter_width) elif window_type == 'gaussian': filter_window = windows.gaussian(filter_width, sigma) filter_window = filter_window / np.sum(filter_window) data_smoothed = signal.filtfilt(filter_window, 1, data, method="gust") # pad if plot_on: if plot_on > 1: plt.plot(filter_window) plt.title(f'{window_type} filter') plt.figure('signal', figsize=(10, 5)) plt.plot(data, color=(0.7, 0.7, 0.7), label='noisy signal', linewidth=1) plt.plot(data_smoothed, color='r', label='smoothed signal') plt.xlim(0, len(data_smoothed)) plt.xlabel('sample') plt.grid(True) plt.legend() return data_smoothed, filter_window
def process(self, data): data = deepcopy(data) winData = data.data if self.windowType == FourierTransform.WindowTypes.Hann: winData *= windows.hann(len(winData), sym=False) elif self.windowType == FourierTransform.WindowTypes.Blackman: winData *= windows.blackman(len(winData), sym=False) elif self.windowType == FourierTransform.WindowTypes.Flattop: winData *= windows.flattop(len(winData), sym=False) elif self.windowType == FourierTransform.WindowTypes.Tukey: winData *= windows.tukey(len(winData), sym=False, alpha=self.alpha) data.data = np.fft.rfft(winData, axis=0, norm='ortho') data.axes[0] = np.fft.rfftfreq(len(data.axes[0]), np.mean(np.diff(data.axes[0]))) return data
def THDN(y, fs, lpf): """ Performs a windowed fft of a time-series signal y and calculate THDN. + Estimates fundamental frequency by finding peak value in fft + Skirts the fundamental by finding local minimas and throws those values away + Applies a Low-pass filter at fc (100kHz) + Calculates THD+N by calculating the rms ratio of the entire signal to the fundamental removed signal :returns: THD and fundamental frequency """ # PERFORM FFT # TODO: Do this in the frequency domain, and take any skirts with it? y -= np.mean(y) w = blackman(len(y)) # TODO Kaiser? yf = np.fft.rfft(y * w) freqs = np.fft.rfftfreq(len(yf)) # FIND FUNDAMENTAL (peak of frequency spectrum) idx = np.argmax(np.abs(yf)) freq = freqs[idx] # no units f0 = freq * fs / 2 # in hertz # APPLY LOW PASS FILTERING fc = int(lpf * len(y) / fs) yf[fc:] = 1e-10 fundamental_rms = np.sqrt(np.sum(np.abs( yf / len(y))**2)) # Parseval'amp_string Theorem # NOTCH REJECT FUNDAMENTAL AND MEASURE NOISE # Find local minimas around fundamental frequency and throw away values within boundaries of minima window. # TODO: create boundary w.r.thread_continuous. mainlobe width of the windowing function rather than finding local minimas lowermin, uppermin = find_range(abs(yf), idx) print(f'Boundary window: {lowermin*fs/len(y)} and {uppermin*fs/len(y)}') yf[lowermin:uppermin] = 1e-10 noise_rms = np.sqrt(np.sum(np.abs( yf / len(y))**2)) # Parseval'amp_string Theorem THDN = noise_rms / fundamental_rms print(f'Sample Rate: {fs}') print(f'Frequency: {round(abs(f0), 2)} Hz') print( f"THD+N: {round(THDN * 100, 4)}% or {round(20 * np.log10(THDN), 1)}dB" ) return THDN, f0, yf
def get_fft_window(window_type, window_length): # Generate the window with the right number of points window = None if window_type == "Bartlett": window = windows.bartlett(window_length) if window_type == "Blackman": window = windows.blackman(window_length) if window_type == "Blackman Harris": window = windows.blackmanharris(window_length) if window_type == "Flat Top": window = windows.flattop(window_length) if window_type == "Hamming": window = windows.hamming(window_length) if window_type == "Hanning": window = windows.hann(window_length) # If no window matched, use a rectangular window if window is None: window = np.ones(window_length) # Return the window return window
def make_spectrogram( fs: int, time_data: np.ndarray, plot: bool = False, desc: str = '', sample_duration: int = config.SAMPLE_DURATION, block_duration: int = config.BLOCK_DURATION, step_fraction: int = config.STEP_FRACTION, fft_size: int = config.FFT_SIZE, fft_ratio: int = config.FFT_RATIO, ) -> np.ndarray: """From frequency sampling and content of a wav file, make the spectrogram""" window_size = int(fs * block_duration / 1000) window = ssw.blackman(window_size) sample_size = fs * sample_duration step = window_size // step_fraction n_steps = sample_size // step padding_left = np.zeros(step) padding_right = np.zeros(max(0, sample_size - len(time_data) - step)) time_data_2 = np.concatenate( (padding_left, time_data, padding_right))[:sample_size] spectrogram = np.zeros((n_steps, fft_size), dtype=float) for k in range(n_steps - step_fraction): sound_part = time_data_2[k * step:k * step + window_size] sound_windowed = window * sound_part ft = abs(fft(sound_windowed, fft_size * fft_ratio)[:fft_size]) spectrogram[k, :] = ft if plot: title = desc + ' - ' if desc else '' plt.title(f"{title}{fs} - {spectrogram.shape}") plt.imshow(spectrogram, interpolation='nearest') plt.show() return spectrogram
def toSpec(data,sf,minfreq,maxfreq,winlen_sec): # Function based on fourierICA.m # https://www.cs.helsinki.fi/group/neuroinf/code/fourierica/html/fourierica.html overlapfactor = 8 hamm=True chans,T=data.shape winsize=int(np.floor(winlen_sec*sf)) wininterval=int(np.ceil(winsize/overlapfactor)) numwins=int(np.floor((1.*T-winsize)/wininterval+1)) startfftind=int(np.floor(minfreq*winlen_sec)) #compute frequency indices (for the STFT) if startfftind<0: print('minfreq must be positive') perro=gato endfftind=int(np.floor(maxfreq*winlen_sec))+1 nyquistfreq=int(np.floor(winsize/2)) if endfftind>nyquistfreq: print('maxfreq must be less than the Nyquist frequency') perro=gato fftsize=int(endfftind-startfftind) # Initialization of tensor X, which is the main data matrix input to the code which follows. X=np.zeros((fftsize,numwins,chans)).astype(np.complex64) window=np.array([0,winsize]) # Define window initial limits if hamm: hammwin=blackman(winsize, False) # Construct Hamming window if necessary # Short-time Fourier transform (window sampling + fft) for j in range(numwins): datawin=data[:,window[0]:window[1]] # Extract data window if hamm: datawin=datawin @ np.diag(hammwin) # Multiply by a Hamming window if necessary datawin_ft=fft(datawin) # Do FFT X[:,j,:]=(datawin_ft[:,startfftind:endfftind]).T window=window+wininterval # New data window interval params = (fftsize, numwins, chans,wininterval,winsize) return X, params
def FFT(signal, sr): w = np.linspace(0, 2 * sr, len(signal)) f1 = 20 * np.log10(np.abs(fft(signal))) N = len(signal) w1 = windows.hann(N) w2 = windows.hamming(N) w3 = windows.blackman(N) f2 = 20 * np.log10(np.abs(fft(signal * w1))) f3 = 20 * np.log10(np.abs(fft(signal * w2))) f4 = 20 * np.log10(np.abs(fft(signal * w3))) fig, (ax0, ax1, ax2, ax3) = plt.subplots(nrows=4, sharex=True, constrained_layout=True) ax0.plot(w[0:len(signal) // 2], f1[0:len(f1) // 2]) ax0.set(title='FFT sin ventana', ylabel='dB') ax1.plot(w[0:len(signal) // 2], f2[0:len(f2) // 2]) ax1.set(title='FFT con ventana hann', ylabel='dB') ax2.plot(w[0:len(signal) // 2], f3[0:len(f3) // 2]) ax2.set(title='FFT con ventana hamming', ylabel='dB') ax3.plot(w[0:len(signal) // 2], f4[0:len(f4) // 2]) ax3.set(title='FFT con ventana blackman', ylabel='dB', xlabel='Frecuencia [Hz]') return fig
DEVICE = None # input device (numeric ID or substring) logging.basicConfig(level=config.LOG_LEVEL, format=config.LOG_FORMAT, datefmt=config.LOG_DATE_FMT) _model = make_model(evaluate=True, sample_duration=SAMPLE_DURATION) try: if LIST_DEVICES: logging.info(f"Devices: {sd.query_devices()}") exit(0) _samplerate = sd.query_devices(DEVICE, "input")["default_samplerate"] _block_size = int(_samplerate * config.BLOCK_DURATION / 1000) _window = ssw.blackman(_block_size) _fft_size = config.FFT_SIZE mln = MedianLastN(5, -1) def _callback(in_data, _, __, ___): sound = in_data.T[0] if max(sound) < 0.01: return # logging.info(f"in_data: {len(in_data.flatten())}") _this_fft = abs( fft(_window * sound, _fft_size * config.FFT_RATIO)[:_fft_size]) _this_set = _this_fft[None, :] _this_labels = _model.predict(_this_set) label_pred = np.argmax(_this_labels, axis=1)[0]
def main(): # GENERATED SIGNAL ================================================================================================= Ft = 1000 # Signal Frequency N1 = 8192 # Number of points (Spectrum Bins) M1 = 50 # Number of Cycles runtime1 = M1 * (N1 - 1) / (Ft * N1) signal_step = M1 / (Ft * N1) x1 = np.linspace(0.0, N1 * signal_step, N1) y1 = np.cos(2 * np.pi * Ft * x1 + np.pi / 2) f = interpolate.interp1d(x1, y1) yrms1 = rms_flat(y1) # DIGITIZED SIGNAL ================================================================================================= N2 = 8192 # Number of points (Spectrum Bins) cycles = 25 # have enough cycles to sufficiently attenuate the non-integer cycle during windowing Fs = (N2 * Ft) / cycles # Sampling Frequency (Hz) of Digitizer (Ft * N1 / M1) # For anti-aliasing effects, try 900Hz or 950Hz... These are below the 1000Hz y frequency lpf = 100e3 x2 = np.arange(0, N2, 1) y2 = np.zeros(N2) digital_step = 1 / Fs for position, placeholder in enumerate(y2): try: y2[position] = f(x2[position] * digital_step) except ValueError: y2[position] = 0 yrms2 = rms_flat(y2) # FFT ============================================================================================================== xf1 = np.linspace(0.0, 1.0 / signal_step, N1) yf1 = fft(y1) w1 = blackman(N1) ywf1 = fft(y1 * w1) xf2 = np.linspace(0.0, Fs, N2) yf2 = fft(y2) w2 = blackman(N2) ywf2 = fft(y2 * w2) # Find %THD+N thdn, f0, noise_f = THDN(y2, Fs, lpf) # PLOT ============================================================================================================= # PLOT time series y and included sampled data overlay ======================================================== fig, (ax1, ax2) = plt.subplots(2, 1, constrained_layout=True) ax1.plot(x1 * 1e3, y1, '-') ax1.plot(x2 * digital_step * 1e3, y2, '.:') ax1.set_title('Generated Signal (with digitized overlay)') ax1.set_xlabel('time (ms)') ax1.set_ylabel('amplitude') t = ax1.text(0.95, 0.01, f'Signal Frequency: {Ft}Hz\nSampling Frequency: {Fs}Hz', verticalalignment='bottom', horizontalalignment='right', transform=ax1.transAxes, fontsize=9) t.set_bbox(dict(facecolor='white', alpha=0.5, edgecolor='white')) ax1.set_xlim([0, runtime1 * 1e3]) ax2.plot(x2, y2, '.:') ax2.set_title('Digitized Waveform') ax2.set_xlabel('samples (N)') ax2.set_ylabel('amplitude') if runtime1 / digital_step > N2: ax2.set_xlim([0, N2 - 1]) else: ax2.set_xlim([0, runtime1 / digital_step]) fig.suptitle('Waveform Digitalization') # PLOT frequency response ========================================================================================== fig, (ax3, ax4) = plt.subplots(2, 1, constrained_layout=True) ax3.plot(xf1[0:N1], 20 * np.log10(2 * np.abs(yf1[0:N1] / (yrms1 * N1))), '-b') # scaling is applied. ax3.plot(xf1[0:N1], 20 * np.log10(2 * np.abs(ywf1[0:N1] / (yrms1 * N1))), '-r') # scaling is applied. # ax3.set_xlim([20, sample_rate/2]) # units are in kHz ax3.set_xlim(20, 30000) ax3.legend(['FFT', 'FFT w. window']) ax3.set_title('Generated Waveform Spectral Response') ax3.set_xlabel('frequency (Hz)') ax3.set_ylabel('magnitude (dB)') ax3.grid() ax4.plot(xf2[0:N2], 20 * np.log10(2 * np.abs(yf2[0:N2] / (yrms2 * N2))), '-b') # scaling is applied. ax4.plot(xf2[0:N2], 20 * np.log10(2 * np.abs(ywf2[0:N2] / (yrms2 * N2))), '-r') # scaling is applied. # ax4.set_xlim([100, Fs/2]) # units are in kHz ax4.set_xlim(100, 30000) ax4.legend(['FFT', 'FFT w. window']) ax4.set_title('Digitized Waveform Spectral Response') ax4.set_xlabel('frequency (Hz)') ax4.set_ylabel('magnitude (dB)') ax4.grid() # PLOT fundamental removed time series y ===================================================================== fig, (ax5, ax6) = plt.subplots(2, 1, constrained_layout=True) ax5.plot(x2, np.fft.irfft(noise_f), '-') ax5.set_xlim(0, N2) ax6.plot(xf2[0:N2 // 2], 20 * np.log10( (2 * np.abs(noise_f[0:N2 // 2] / (yrms2 * N2)))), '-b') # ax6.set_xlim(20, sample_rate/2) ax6.set_xlim(20, 30000) ax6.set_ylim(-300, np.max(noise_f)) ax5.set_title('Windowing time-series response of Measured Noise') ax5.set_xlabel('samples (#N)') ax5.set_ylabel('amplitude') t = ax5.text( 0.95, 0.01, f'Signal Frequency: {round(f0, 2)}Hz\nSampling Frequency: {Fs/1000}kHz', verticalalignment='bottom', horizontalalignment='right', transform=ax5.transAxes, fontsize=9) t.set_bbox(dict(facecolor='white', alpha=0.5, edgecolor='white')) ax6.set_title('Spectral Response of Measured Noise') ax6.set_xlabel('frequency (Hz)') ax6.set_ylabel('magnitude (dB)') t2 = ax6.text( 0.95, 0.01, f'THD+N: {round(thdn * 100, 4)}% or {round(20 * np.log10(thdn), 1)}dB', verticalalignment='bottom', horizontalalignment='right', transform=ax6.transAxes, fontsize=9) t2.set_bbox(dict(facecolor='white', alpha=0.5, edgecolor='white')) ax6.grid() plt.show()
def UpdateGraph(self, RawData): self.const = FileHandle.getResolution() #self.const =0.00325*4 print(self.const) self.lifeGraph.clear() try: if self.lifefft == False and self.StoreMeas.isChecked(): self.storeGraph.addItem(self.curve) else: self.storeGraph.clear() except: None self.Data = [] self.time = [] self.curve = self.lifeGraph.getPlotItem().plot() #Sortiert die Rohdaten nach nach Order und Wandelt aus dem macht aus dem 12 bit zweierkomplement ein 16 Bit zweierkomplement if len(RawData) > 50: # Wählt nach den Einstellungen aus, ob life FFt oder nicht #for i in range(0, len(RawData)-1,2): # self.Data.append(int.from_bytes((RawData[i],(0xf0 ^ RawData[i+1]) if 0x08 & RawData[i+1] else RawData[i+1] ),byteorder='little',signed=True)) for i in range(0, len(RawData) - 1, 2): self.Data.append( int.from_bytes((RawData[i], RawData[i + 1]), byteorder='little', signed=False)) if self.DelayLine == None: self.Data = np.true_divide(self.Data, (65536 / 3.3)) else: if (self.MotorCntrl.Positions[0] > self.MotorCntrl.Positions[3]): # Normierung auf ADC-Auflösung und Spannungsteilerverhältnis von 3.3 self.Data.reverse() self.Data = np.true_divide(self.Data, (65536 / 3.3)) Reverse = True else: Reverse = False # Normierung auf ADC-Auflösung und Spannungsteilerverhältnis von 3.3 self.Data = np.true_divide(self.Data, (65536 / 3.3)) #Erstellen einer Zeitachse aus Equidistanten Messpunkten self.time = np.arange(0, len(self.Data), 1) * self.const #Abbilden der Kurve print("PP Value:") print( abs(max(self.Data[0:len(self.Data / 4)])) + abs(min(self.Data[0:len(self.Data / 4)]))) self.curve.setData(self.time, self.Data) #Speichern, oder nicht if self.StoreMeas.isChecked(): if self.DelayLine == None: CSVProcess(self.time, self.Data, self.folder, self.progressBar.value()) else: CSVProcess(self.time, self.Data, self.folder + "\Forward", str(self.progressBar.value( ))) if Reverse == False else CSVProcess( self.time, self.Data, self.folder + "\Backward", str(self.progressBar.value())) #Life FFT oder nicht if self.lifefft or not self.StoreMeas.isChecked(): window = windows.blackman(len(self.Data)) my_fft = fft(self.Data * window) freq = np.linspace(0.0, 1.0 / (2.0 * self.const * 1e-12), len(self.Data) // 2) my_fft = np.abs(my_fft / len(self.Data)) my_fft = 2 * my_fft[1:len(self.Data) // 2 + 1] my_fft = 20 * np.log10(my_fft) freqmask = freq > 7e12 noicemean = np.mean(my_fft[freqmask]) freqmask = freq < 5e12 dataitem = self.storeGraph.getPlotItem().plot() dataitem.setData(freq[freqmask], my_fft[freqmask]) else: self.NumberOfRuns = self.NumberOfRuns + 1 #Wiederhohlen der Messung und Updaten des Messfortschrittbalkens if (self.NumberOfRuns > 1): self.NumberOfRuns = self.NumberOfRuns - 1 self.progressBar.setValue(self.progressBar.maximum() - self.NumberOfRuns) if self.NumberOfRuns % 20 == 0: self.storeGraph.clear() RawData.clear() gc.collect() self.TimerThread.start() else: self.progressBar.setValue(self.progressBar.maximum()) self.LogBox.setPlainText("Finished")
def pre_processing(self): """ Complete various pre-processing steps for encoded protein sequences before doing any of the DSP-related functions or transformations. Zero-pad the sequences, remove any +/- infinity or NAN values, get the approximate protein spectra and window function parameter names. Parameters ---------- :self (PyDSP object): instance of PyDSP class. Returns ------- None """ #zero-pad encoded sequences so they are all the same length self.protein_seqs = zero_padding(self.protein_seqs) #get shape parameters of proteins seqs self.num_seqs = self.protein_seqs.shape[0] self.signal_len = self.protein_seqs.shape[1] #replace any positive or negative infinity or NAN values with 0 self.protein_seqs[self.protein_seqs == -np.inf] = 0 self.protein_seqs[self.protein_seqs == np.inf] = 0 self.protein_seqs[self.protein_seqs == np.nan] = 0 #replace any NAN's with 0's #self.protein_seqs.fillna(0, inplace=True) self.protein_seqs = np.nan_to_num(self.protein_seqs) #initialise zeros array to store all protein spectra self.fft_power = np.zeros((self.num_seqs, self.signal_len)) self.fft_real = np.zeros((self.num_seqs, self.signal_len)) self.fft_imag = np.zeros((self.num_seqs, self.signal_len)) self.fft_abs = np.zeros((self.num_seqs, self.signal_len)) #list of accepted spectra, window functions and filters all_spectra = ['power', 'absolute', 'real', 'imaginary'] all_windows = [ 'hamming', 'blackman', 'blackmanharris', 'gaussian', 'bartlett', 'kaiser', 'barthann', 'bohman', 'chebwin', 'cosine', 'exponential' 'flattop', 'hann', 'boxcar', 'hanning', 'nuttall', 'parzen', 'triang', 'tukey' ] all_filters = [ 'savgol', 'medfilt', 'symiirorder1', 'lfilter', 'hilbert' ] #set required input parameters, raise error if spectrum is none if self.spectrum == None: raise ValueError( 'Invalid input Spectrum type ({}) not available in valid spectra: {}' .format(self.spectrum, all_spectra)) else: #get closest correct spectra from user input, if no close match then raise error spectra_matches = (get_close_matches(self.spectrum, all_spectra, cutoff=0.4)) if spectra_matches == []: raise ValueError( 'Invalid input Spectrum type ({}) not available in valid spectra: {}' .format(self.spectrum, all_spectra)) else: self.spectra = spectra_matches[0] #closest match in array if self.window_type == None: self.window = 1 #window = 1 is the same as applying no window else: #get closest correct window function from user input window_matches = (get_close_matches(self.window, all_windows, cutoff=0.4)) #check if sym=True or sym=False #get window function specified by window input parameter, if no match then window = 1 if window_matches != []: if window_matches[0] == 'hamming': self.window = hamming(self.signal_len, sym=True) self.window_type = "hamming" elif window_matches[0] == "blackman": self.window = blackman(self.signal_len, sym=True) self.window = "blackman" elif window_matches[0] == "blackmanharris": self.window = blackmanharris(self.signal_len, sym=True) #** self.window_type = "blackmanharris" elif window_matches[0] == "bartlett": self.window = bartlett(self.signal_len, sym=True) self.window_type = "bartlett" elif window_matches[0] == "gaussian": self.window = gaussian(self.signal_len, std=7, sym=True) self.window_type = "gaussian" elif window_matches[0] == "kaiser": self.window = kaiser(self.signal_len, beta=14, sym=True) self.window_type = "kaiser" elif window_matches[0] == "hanning": self.window = hanning(self.signal_len, sym=True) self.window_type = "hanning" elif window_matches[0] == "barthann": self.window = barthann(self.signal_len, sym=True) self.window_type = "barthann" elif window_matches[0] == "bohman": self.window = bohman(self.signal_len, sym=True) self.window_type = "bohman" elif window_matches[0] == "chebwin": self.window = chebwin(self.signal_len, sym=True) self.window_type = "chebwin" elif window_matches[0] == "cosine": self.window = cosine(self.signal_len, sym=True) self.window_type = "cosine" elif window_matches[0] == "exponential": self.window = exponential(self.signal_len, sym=True) self.window_type = "exponential" elif window_matches[0] == "flattop": self.window = flattop(self.signal_len, sym=True) self.window_type = "flattop" elif window_matches[0] == "boxcar": self.window = boxcar(self.signal_len, sym=True) self.window_type = "boxcar" elif window_matches[0] == "nuttall": self.window = nuttall(self.signal_len, sym=True) self.window_type = "nuttall" elif window_matches[0] == "parzen": self.window = parzen(self.signal_len, sym=True) self.window_type = "parzen" elif window_matches[0] == "triang": self.window = triang(self.signal_len, sym=True) self.window_type = "triang" elif window_matches[0] == "tukey": self.window = tukey(self.signal_len, sym=True) self.window_type = "tukey" else: self.window = 1 #window = 1 is the same as applying no window #calculate convolution from protein sequences if self.convolution is not None: if self.window is not None: self.convoled_seqs = signal.convolve( self.protein_seqs, self.window, mode='same') / sum( self.window) if self.filter != None: #get closest correct filter from user input filter_matches = (get_close_matches(self.filter, all_filters, cutoff=0.4)) #set filter attribute according to approximate user input if filter_matches != []: if filter_matches[0] == 'savgol': self.filter = savgol_filter(self.signal_len, self.signal_len) elif filter_matches[0] == 'medfilt': self.filter = medfilt(self.signal_len) elif filter_matches[0] == 'symiirorder1': self.filter = symiirorder1(self.signal_len, c0=1, z1=1) elif filter_matches[0] == 'lfilter': self.filter = lfilter(self.signal_len) elif filter_matches[0] == 'hilbert': self.filter = hilbert(self.signal_len) else: self.filter = "" #no filter
def smoothen(data, width): kernel = blackman(width) kernel /= np.sum(kernel) return np.convolve(data, kernel, mode="same")
def testbench(): #Parametros del muestreo N = np.power(2, 10) fs = np.power(2, 10) #Size del montecarlo S = 200 #Limites de la distribucion de fr l1 = -2 * (fs / N) l2 = 2 * (fs / N) #Amplitud Ao = 2 * np.ones((S, 1), dtype=float) #Fase Po = np.zeros((S, 1), dtype=float) #Frecuencia central fo = int(np.round(N / 4)) #Cantidad ventanas Nw = 2 #Fr sera una variable aleatoria de distribucion uniforme entre -2 y 2 #Genero 200 realizaciones de fr fr = np.random.uniform(l1, l2, S).reshape(S, 1) #Genero 200 realizaciones de f1 f1 = fo + fr #Enciendo el generador de funciones generador = gen.signal_generator(fs, N) #Genero 200 realizaciones de x (t, x) = generador.sinewave(Ao, f1, Po) #Genera una matriz con las 5 ventanas w = np.array([], dtype='float').reshape(N, 0) for j in range(0, Nw): if j is 0: wj = np.ones((N, 1), dtype=float) elif j is 1: wj = win.flattop(N).reshape(N, 1) elif j is 2: wj = win.hann(N).reshape(N, 1) elif j is 3: wj = win.blackman(N).reshape(N, 1) elif j is 4: wj = win.flattop(N).reshape(N, 1) w = np.hstack([w, wj.reshape(N, 1)]) #Inicializo el analizador de espectro analizador = sa.spectrum_analyzer(fs, N, algorithm="fft") for j in range(0, Nw): wi = w[:, j].reshape(N, 1) Ao_estimador = np.array([], dtype='float').reshape(1, 0) #Contempla la energia o potencia en un ancho de banda Ao2_estimador = np.array([], dtype='float').reshape(1, 0) for i in range(0, S): xi = x[:, i].reshape(N, 1) xi = xi * wi #Obtengo el espectro para las i esima realizacion de x (f, Xi) = analizador.module(xi) aux = Xi[(fo - 2):(fo + 3)] #Calculo una realizacion del estimador Aoi_estimador = Xi[fo].reshape(1, 1) #Ao2i_estimador = np.sqrt(np.sum(np.power(aux,2))).reshape(1,1) Ao2i_estimador = np.sqrt(np.sum(np.power(aux, 2)) / 5).reshape( 1, 1) #Lo adjunto a los resultados Ao_estimador = np.hstack([Ao_estimador, Aoi_estimador]) Ao2_estimador = np.hstack([Ao2_estimador, Ao2i_estimador]) plt.figure() plt.hist(np.transpose(Ao_estimador), bins='auto') plt.axis('tight') plt.title('Energia en el bin para ventana #' + str(j)) plt.xlabel('Variable aleatoria') plt.ylabel('Probabilidad') plt.grid() plt.figure() plt.hist(np.transpose(Ao2_estimador), bins='auto') plt.title('Energia en un ancho de banda para ventana #' + str(j)) plt.axis('tight') plt.xlabel('Variable aleatoria') plt.ylabel('Probabilidad') plt.grid() sesgo = np.mean(Ao_estimador) - Ao[0, 0] varianza = np.mean(np.power(Ao_estimador - np.mean(Ao_estimador), 2)) sesgo2 = np.mean(Ao2_estimador) - Ao[0, 0] varianza2 = np.mean(np.power(Ao2_estimador - np.mean(Ao2_estimador), 2)) print('------------Ventana #' + str(j) + '--------------') print('Estimador: Energia en un bin') print('Sesgo: ' + str(sesgo)) print('Varianza: ' + str(varianza)) print('Estimador: Energia en un ancho de banda (5 bin)') print('Sesgo: ' + str(sesgo2)) print('Varianza: ' + str(varianza2)) i = i + 1 return w
import matplotlib.pyplot as plt from scipy.fftpack import fft N = 1000 Fs = 1000 tt = np.arange(0.0, N/Fs, 1/Fs) ff = np.arange(0.0, Fs, N/Fs) # ahora podemos simular que los canales están desconectados, # o que una señal de ruido blanco, normalmente distribuido ingresa al ADC. canales_ADC = 1 a0 = 1 # Volt f0 = N/4 * Fs/N dd = win.blackman(N) bfrec = ff <= Fs/2 ft_dd = fft( dd ) # ft_dd = fft( dd, axis = 0 ) plt.close('all') plt.figure(2) plt.plot( ff[bfrec], np.abs(ft_dd[bfrec]) ) # plt.plot( ff[bfrec], 20*np.log10(np.abs(ft_dd[bfrec])) ) plt.ylabel('Módulo [¿Volts?]') plt.xlabel('Frecuencia [Hz]') plt.figure(1)