This Python script provides an implementation of the Synchrosqueezing Transform (SST) for one-dimensional signals. The code is a direct translation of a Julia script, designed to preserve the specific phase relationships required for the algorithm to work correctly.
The Synchrosqueezing Transform is a time-frequency analysis technique that sharpens the time-frequency representation (TFR) of a signal, making it easier to identify and extract individual frequency components, especially for signals where the frequency changes over time.
The script requires the following Python libraries:
numpyscipymatplotlib(for the example usage)
You can install these dependencies using pip:
pip install numpy scipy matplotlibThis is the main function that computes the Synchrosqueezing Transform.
x(1D numpy array): The input signal.fs(int, optional): The sampling frequency of the signal. Defaults to 1.t(1D numpy array, optional): The time steps at which to compute the STFT. If not provided, it defaults tonp.arange(len(x)).window(str, optional): The window function to use. Defaults to 'hann'. Must be a window with an odd length.nperseg(int, optional): The number of samples per segment of the STFT. Defaults to 256 or the length of the signal, whichever is smaller.nfft(int, optional): The number of FFT points. Defaults to the length of the signal.
f(1D numpy array): The frequency bins.t(1D numpy array): The time steps.TFR(2D numpy array): The standard Short-Time Fourier Transform (STFT) of the signal.RTFR(2D numpy array): The Synchrosqueezed STFT of the signal.
The script can be run directly from the command line to see an example of the Synchrosqueezing Transform applied to a chirp signal.
python sq_stft.pyThis will generate a plot showing two subplots:
- The standard Short-Time Fourier Transform (STFT).
- The Synchrosqueezed STFT (sqSTFT).
The red dashed line in both plots indicates the true instantaneous frequency of the chirp signal. As you can see, the Synchrosqueezed STFT provides a much sharper and more concentrated representation of the signal's frequency content over time compared to the standard STFT.
import matplotlib.pyplot as plt
from scipy.signal import chirp
# 1. Generate a chirp signal
fs = 1000
T = 2
time_vec = np.linspace(0, T, int(fs * T), endpoint=False)
f_start = 10
f_end = fs / 4
sig = chirp(time_vec, f0=f_start, f1=f_end, t1=T, method='linear')
# 2. Compute STFT and Synchrosqueezed STFT
n_fft = 512
n_perseg = 129 # Must be odd
hop_size = 2
t_steps = np.arange(0, len(sig), hop_size)
f, times, TFR, RTFR = sqSTFT(sig, fs=fs, t=t_steps, window='hann', nperseg=n_perseg, nfft=n_fft)
# 3. Plot the results
# ... (plotting code) ...