def compute_spectrum_welch(sig, fs, avg_type='mean', window='hann', nperseg=None, noverlap=None, f_range=None, outlier_percent=None): """Compute the power spectral density using Welch's method. Parameters ----------- sig : 1d or 2d array Time series. fs : float Sampling rate, in Hz. avg_type : {'mean', 'median'}, optional Method to average across the windows: * 'mean' is the same as Welch's method, taking the mean across FFT windows. * 'median' uses median across FFT windows instead of the mean, to minimize outlier effect. window : str or tuple or array_like, optional, default: 'hann' Desired window to use. See scipy.signal.get_window for a list of available windows. If array_like, the array will be used as the window and its length must be nperseg. nperseg : int, optional Length of each segment, in number of samples. If None, and window is str or tuple, is set to 1 second of data. If None, and window is array_like, is set to the length of the window. noverlap : int, optional Number of points to overlap between segments. If None, noverlap = nperseg // 8. f_range : list of [float, float] optional Frequency range to sub-select from the power spectrum. outlier_percent : float, optional The percentage of outlier values to be removed. Must be between 0 and 100. Returns ------- freqs : 1d array Frequencies at which the measure was calculated. spectrum : 1d or 2d array Power spectral density. """ # Calculate the short time fourier transform with signal.spectrogram nperseg, noverlap = check_spg_settings(fs, window, nperseg, noverlap) freqs, _, spg = spectrogram(sig, fs, window, nperseg, noverlap) # Throw out outliers if indicated if outlier_percent is not None: spg = discard_outliers(spg, outlier_percent) # Average across windows spectrum = get_avg_func(avg_type)(spg, axis=-1) # Trim spectrum, if requested if f_range: freqs, spectrum = trim_spectrum(freqs, spectrum, f_range) return freqs, spectrum
def compute_spectrum_welch(sig, fs, avg_type='mean', window='hann', nperseg=None, noverlap=None, f_range=None, outlier_percent=None): """Compute the power spectral density using Welch's method. Parameters ---------- sig : 1d or 2d array Time series. fs : float Sampling rate, in Hz. avg_type : {'mean', 'median'}, optional Method to average across the windows: * 'mean' is the same as Welch's method, taking the mean across FFT windows. * 'median' uses median across FFT windows instead of the mean, to minimize outlier effects. window : str or tuple or array_like, optional, default: 'hann' Desired window to use. See scipy.signal.get_window for a list of available windows. If array_like, the array will be used as the window and its length must be nperseg. nperseg : int, optional Length of each segment, in number of samples. If None, and window is str or tuple, is set to 1 second of data. If None, and window is array_like, is set to the length of the window. noverlap : int, optional Number of points to overlap between segments. If None, noverlap = nperseg // 8. f_range : list of [float, float], optional Frequency range to sub-select from the power spectrum. outlier_percent : float, optional The percentage of outlier values to be removed. Must be between 0 and 100. Returns ------- freqs : 1d array Frequencies at which the measure was calculated. spectrum : 1d or 2d array Power spectral density. Notes ----- - Welch's method ([1]_) computes a power spectra by averaging over windowed FFTs. References ---------- .. [1] Welch, P. (1967). The use of fast Fourier transform for the estimation of power spectra: A method based on time averaging over short, modified periodograms. IEEE Transactions on Audio and Electroacoustics, 15(2), 70–73. DOI: https://doi.org/10.1109/TAU.1967.1161901 Examples -------- Compute the power spectrum of a simulated time series using Welch's method: >>> from neurodsp.sim import sim_combined >>> sig = sim_combined(n_seconds=10, fs=500, ... components={'sim_powerlaw': {}, 'sim_oscillation': {'freq': 10}}) >>> freqs, spec = compute_spectrum_welch(sig, fs=500) """ # Calculate the short time Fourier transform with signal.spectrogram nperseg, noverlap = check_spg_settings(fs, window, nperseg, noverlap) freqs, _, spg = spectrogram(sig, fs, window, nperseg, noverlap) # Throw out outliers if indicated if outlier_percent is not None: spg = discard_outliers(spg, outlier_percent) # Average across windows spectrum = get_avg_func(avg_type)(spg, axis=-1) # Trim spectrum, if requested if f_range: freqs, spectrum = trim_spectrum(freqs, spectrum, f_range) return freqs, spectrum