.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/signal_processing/spectral/plot_04_blackman_tukey_windows.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_signal_processing_spectral_plot_04_blackman_tukey_windows.py: Blackman and Tukey's spectral windows (1958) ============================================ Ralph Blackman and John Tukey's *The Measurement of Power Spectra* (1958) turned spectral estimation into an engineering procedure for the telephone and seismic data of the Bell System. Cutting a finite record out of a signal multiplies it by a rectangular window. In frequency, every tone is then smeared by that window's transform, whose sidelobes fall only slowly, so a strong tone can hide a weak one nearby. Their book named the tapered windows of Julius von Hann and Richard Hamming that trade a wider main lobe for far lower sidelobes (:func:`~engineeringkit.signal_processing.windowed_spectrum`). .. GENERATED FROM PYTHON SOURCE LINES 17-22 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from engineeringkit.signal_processing import db20, windowed_spectrum .. GENERATED FROM PYTHON SOURCE LINES 23-28 Each window's own spectrum -------------------------- Zero-padding a constant record shows the window's transform. The highest sidelobe sets how far below a strong tone a weak one can still be seen. .. GENERATED FROM PYTHON SOURCE LINES 28-43 .. code-block:: Python fs, n = 1.0, 64 expected = {"boxcar": -13.3, "hann": -31.5, "hamming": -42.7, "blackman": -58.1} fig, axes = plt.subplots(1, 2, figsize=(10, 3.8)) for name, level in expected.items(): f, magnitude = windowed_spectrum(np.ones(n), fs, window=name, n_fft=64 * n) response = db20(np.maximum(magnitude / magnitude[0], 1e-12)) first_null = np.argmax(np.diff(response) > 0) # end of the main lobe sidelobe = response[first_null:].max() print(f"{name:8s}: main lobe half-width {f[first_null] * n:.1f} bins, highest sidelobe {sidelobe:6.1f} dB") assert abs(sidelobe - level) < 0.5 axes[0].plot(f * n, response, label=name) axes[0].set(xlabel="frequency [bins]", ylabel="gain [dB]", xlim=(0, 16), ylim=(-100, 5), title="Window transforms") axes[0].legend() .. image-sg:: /api/gallery/signal_processing/spectral/images/sphx_glr_plot_04_blackman_tukey_windows_001.png :alt: Window transforms :srcset: /api/gallery/signal_processing/spectral/images/sphx_glr_plot_04_blackman_tukey_windows_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none boxcar : main lobe half-width 1.0 bins, highest sidelobe -13.3 dB hann : main lobe half-width 2.0 bins, highest sidelobe -31.5 dB hamming : main lobe half-width 2.0 bins, highest sidelobe -42.4 dB blackman: main lobe half-width 3.0 bins, highest sidelobe -58.1 dB .. GENERATED FROM PYTHON SOURCE LINES 44-50 A weak tone near a strong one ----------------------------- A tone 50 dB down sits six bins from a strong tone that falls between two bins, the worst case for leakage. The rectangular window buries it; the Blackman window reveals it. .. GENERATED FROM PYTHON SOURCE LINES 50-69 .. code-block:: Python fs, n = 1024.0, 1024 t = np.arange(n) / fs x = np.sin(2 * np.pi * 100.5 * t) + 10 ** (-50 / 20) * np.sin(2 * np.pi * 107 * t) visible = {} for name in ("boxcar", "blackman"): f, magnitude = windowed_spectrum(x, fs, window=name) level = db20(magnitude / magnitude.max()) weak = level[np.argmin(abs(f - 107))] floor = np.max(level[(f > 104) & (f < 106)]) visible[name] = weak > floor + 6 print(f"{name:8s}: weak tone at {weak:6.1f} dB, leakage between the tones {floor:6.1f} dB") axes[1].plot(f, level, label=name) assert not visible["boxcar"] and visible["blackman"] axes[1].set(xlabel="frequency [Hz]", ylabel="level [dB]", xlim=(85, 125), ylim=(-120, 5), title="Strong tone at 100.5 Hz, weak at 107 Hz") axes[1].legend() fig.tight_layout() plt.show() .. rst-class:: sphx-glr-script-out .. code-block:: none boxcar : weak tone at -22.5 dB, leakage between the tones -19.3 dB blackman: weak tone at -48.8 dB, leakage between the tones -58.1 dB .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.052 seconds) .. _sphx_glr_download_api_gallery_signal_processing_spectral_plot_04_blackman_tukey_windows.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/signal_processing/spectral/plot_04_blackman_tukey_windows.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_04_blackman_tukey_windows.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_04_blackman_tukey_windows.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_04_blackman_tukey_windows.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_