Last active
November 19, 2019 22:05
-
-
Save endolith/78c044b209df89db901d19c7cd17ee80 to your computer and use it in GitHub Desktop.
Window function property testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Created on Wed Aug 03 11:56:41 2016 | |
| """ | |
| from scipy.signal.windows import (boxcar, hann, hamming, bartlett, bohman, | |
| blackman, parzen, blackmanharris, cosine, | |
| kaiser, tukey, gaussian) | |
| from scipy.fftpack import fft | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| """ | |
| all: | |
| [ | |
| 'nuttall', there are actually several, list which one it is | |
| 'flattop', there are many | |
| 'barthann', | |
| 'kaiser', there are many | |
| 'gaussian', there are many | |
| 'general_gaussian', there are many | |
| 'chebwin', there are many | |
| 'slepian', | |
| 'exponential', | |
| 'tukey', there are many | |
| 'get_window'] | |
| document synonyms too | |
| included: | |
| 'parzen', de la Vall&Poussin | |
| 'blackmanharris', minimum 4-term | |
| 'cosine', same as Harris' cosalpha(X) with alpha=1 | |
| not included: | |
| triang | |
| """ | |
| def kaiser3(M, sym): | |
| return kaiser(M, 3*np.pi, sym) | |
| def kaiser4(M, sym): | |
| return kaiser(M, 4*np.pi, sym) | |
| def kaiser5(M, sym): | |
| return kaiser(M, 5*np.pi, sym) | |
| def kaiser7(M, sym): | |
| return kaiser(M, 7*np.pi, sym) | |
| def kaiser19(M, sym): | |
| return kaiser(M, 19*np.pi, sym) | |
| def tukey0p25(M, sym): | |
| return tukey(M, alpha=0.25, sym=sym) | |
| def tukey0p5(M, sym): | |
| return tukey(M, alpha=0.5, sym=sym) | |
| def gaussian3p5(M, sym): | |
| return gaussian(M, std=15, sym=sym) | |
| # TODO: Can't use functions as keys since you need multiple parameters with | |
| # some functions | |
| windows = { | |
| boxcar: | |
| {'PSLL': 13.3, | |
| 'BW_3dB': 0.8845}, | |
| hann: | |
| {'PSLL': 31.5, | |
| 'BW_3dB': 1.4382}, | |
| cosine: # Same as Harris' Hanning alpha=1.0 | |
| {'PSLL': 23, | |
| 'BW_3dB': 1.2}, | |
| hamming: | |
| {'PSLL': 42.7, | |
| 'BW_3dB': 1.3008}, | |
| bartlett: # Same as Harris' triangle | |
| {'PSLL': 26.5, | |
| 'BW_3dB': 1.2736}, | |
| bohman: | |
| {'PSLL': 46, | |
| 'BW_3dB': 1.71}, | |
| blackman: | |
| {'PSLL': 58, | |
| 'BW_3dB': 1.68}, | |
| parzen: # same as Harris' de la Vall & Poussin ? | |
| {'PSLL': 53, | |
| 'BW_3dB': 1.82}, | |
| blackmanharris: # same as Harris' minimum 4-sample or Heinzel's BH92 | |
| {'PSLL': 92, | |
| 'BW_3dB': 1.8962}, | |
| kaiser3: # Heinzel's Kaiser3 | |
| {'PSLL': 69.6, | |
| 'BW_3dB': 1.7025}, | |
| kaiser4: | |
| {'PSLL': 94.4, | |
| 'BW_3dB': 1.9417}, | |
| kaiser5: | |
| {'PSLL': 119.8, | |
| 'BW_3dB': 2.1553}, | |
| kaiser19: | |
| {'PSLL': 172, | |
| 'BW_3dB': 4.12}, | |
| kaiser7: | |
| {'PSLL': 153, | |
| 'BW_3dB': 2.53}, | |
| tukey0p25: | |
| {'PSLL': 14, | |
| 'BW_3dB': 1.01}, | |
| tukey0p5: | |
| {'PSLL': 15, | |
| 'BW_3dB': 1.15}, | |
| gaussian3p5: | |
| {'PSLL': 69, | |
| 'BW_3dB': 1.79}, | |
| } | |
| def scallop_loss(window): | |
| M = 65536 | |
| w = window(M, sym=False) | |
| t = np.linspace(0, 1, M, endpoint=False) | |
| bin_centered = np.amax(abs(fft(np.cos((M/4 )*np.pi*t) * w))) | |
| between_bins = np.amax(abs(fft(np.cos((M/4-1)*np.pi*t) * w))) | |
| return 20*np.log10(bin_centered / between_bins) | |
| M_win = 1024 | |
| N_fft = 131072 | |
| for win, props in sorted(windows.items(), key=lambda x: x[0].__name__): | |
| # if isinstance(win, tuple): | |
| # winfunc = win[0] | |
| # params = (M_win,) + win[1:] + (False,) | |
| # w = winfunc(*params) | |
| # name = winfunc.__name__ | |
| # else: | |
| w = win(M_win, sym=False) | |
| name = win.__name__ | |
| f = fft(w, N_fft) | |
| spec = 20 * np.log10(np.abs(f / np.amax(f))) | |
| first_zero = np.argmax(np.diff(spec) > 0) | |
| PSLL = np.amax(spec[first_zero:-first_zero]) | |
| # off by one? | |
| BW_3dB = 2*np.argmax(spec <= -3.0102999566398121) / N_fft * M_win | |
| BW_6dB = 2*np.argmax(spec <= -6.0205999132796242) / N_fft * M_win | |
| print('{0:20}PSLL: {2:.2f} ({1:.2f} expected) ' | |
| 'BW: {4:.2f} ({3:.2f} expected) '.format( | |
| name, props['PSLL'], -PSLL, props['BW_3dB'], BW_3dB) | |
| ) | |
| # plt.plot(np.diff(np.abs(f))) | |
| # plt.plot(spec) | |
| #plt.ylim(-50, 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment