Skip to content

Instantly share code, notes, and snippets.

@endolith
Last active November 19, 2019 22:05
Show Gist options
  • Select an option

  • Save endolith/78c044b209df89db901d19c7cd17ee80 to your computer and use it in GitHub Desktop.

Select an option

Save endolith/78c044b209df89db901d19c7cd17ee80 to your computer and use it in GitHub Desktop.
Window function property testing
"""
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