.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/example_echt.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. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_example_echt.py: Endpoint-corrected Hilbert transform (ECHT) phase estimation ============================================================ This example shows how to causally estimate the phase of a signal using the Endpoint-corrected Hilbert transform (ECHT) [1]_. Uses `meegkit.phase.ECHT()`. References ---------- .. [1] Schreglmann, S. R., Wang, D., Peach, R. L., Li, J., Zhang, X., Latorre, A., ... & Grossman, N. (2021). Non-invasive suppression of essential tremor via phase-locked disruption of its temporal coherence. Nature communications, 12(1), 363. .. GENERATED FROM PYTHON SOURCE LINES 18-29 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from scipy.signal import hilbert from meegkit.phase import ECHT rng = np.random.default_rng(38872) plt.rcParams["axes.grid"] = True plt.rcParams["grid.linestyle"] = ":" .. GENERATED FROM PYTHON SOURCE LINES 30-34 Build data ----------------------------------------------------------------------------- First, we generate a multi-component signal with amplitude and phase modulations, as described in the paper [1]_. .. GENERATED FROM PYTHON SOURCE LINES 34-43 .. code-block:: Python f0 = 2 N = 500 sfreq = 100 time = np.linspace(0, N / sfreq, N) X = np.cos(2 * np.pi * f0 * time - np.pi / 4) phase_true = np.angle(hilbert(X)) X += rng.normal(0, 0.5, N) # Add noise .. GENERATED FROM PYTHON SOURCE LINES 44-48 Compute phase and amplitude ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We compute the Hilbert phase, as well as the phase obtained with the ECHT filter. .. GENERATED FROM PYTHON SOURCE LINES 48-59 .. code-block:: Python phase_hilbert = np.angle(hilbert(X)) # Hilbert phase # Compute ECHT-filtered signal filt_BW = f0 / 2 l_freq = f0 - filt_BW / 2 h_freq = f0 + filt_BW / 2 echt = ECHT(l_freq, h_freq, sfreq) Xf = echt.fit_transform(X) phase_echt = np.angle(Xf) .. GENERATED FROM PYTHON SOURCE LINES 60-65 Visualize signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here we plot the original signal, its Fourier spectrum, and the phase obtained with the Hilbert transform and the ECHT filter. The ECHT filter provides a much smoother phase estimate than the Hilbert transform .. GENERATED FROM PYTHON SOURCE LINES 65-82 .. code-block:: Python fig, ax = plt.subplots(3, 1, figsize=(8, 6)) ax[0].plot(time, X) ax[0].set_xlabel("Time (s)") ax[0].set_title("Test signal") ax[0].set_ylabel("Amplitude") ax[1].psd(X, Fs=sfreq, NFFT=2048*4, noverlap=sfreq) ax[1].set_ylabel("PSD (dB/Hz)") ax[1].set_title("Test signal's Fourier spectrum") ax[2].plot(time, phase_true, label="True phase", ls=":") ax[2].plot(time, phase_echt, label="ECHT phase", lw=.5, alpha=.8) ax[2].plot(time, phase_hilbert, label="Hilbert phase", lw=.5, alpha=.8) ax[2].set_title("Phase") ax[2].set_ylabel("Amplitude") ax[2].set_xlabel("Time (s)") ax[2].legend(loc="upper right", fontsize="small") plt.tight_layout() plt.show() .. image-sg:: /auto_examples/images/sphx_glr_example_echt_001.png :alt: Test signal, Test signal's Fourier spectrum, Phase :srcset: /auto_examples/images/sphx_glr_example_echt_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.305 seconds) .. _sphx_glr_download_auto_examples_example_echt.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_echt.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_echt.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_