Skip to content

Commit

Permalink
WelchPSD, WelchCohere, replace 'hanning' with 'hann', scipy 1.9.0 (Ne…
Browse files Browse the repository at this point in the history
…uralEnsemble#511)

* removed hanning from spectral.py as default and replaced with "hann", since hanning is just an alias for hann
* add deprecation warning for 'hanning' window, add unit-tests to test for warning
  • Loading branch information
Moritz-Alexander-Kern committed Aug 9, 2022
1 parent 646cbd4 commit df8e962
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
30 changes: 21 additions & 9 deletions elephant/spectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
:license: Modified BSD, see LICENSE.txt for details.
"""

from __future__ import division, print_function, unicode_literals
import warnings

import neo
import warnings
import numpy as np
import quantities as pq
import scipy.signal
Expand All @@ -32,7 +31,7 @@
@deprecated_alias(num_seg='n_segments', len_seg='len_segment',
freq_res='frequency_resolution')
def welch_psd(signal, n_segments=8, len_segment=None,
frequency_resolution=None, overlap=0.5, fs=1.0, window='hanning',
frequency_resolution=None, overlap=0.5, fs=1.0, window='hann',
nfft=None, detrend='constant', return_onesided=True,
scaling='density', axis=-1):
"""
Expand Down Expand Up @@ -91,7 +90,7 @@ def welch_psd(signal, n_segments=8, len_segment=None,
window : str or tuple or np.ndarray, optional
Desired window to use.
See Notes [2].
Default: 'hanning'
Default: 'hann'
nfft : int, optional
Length of the FFT used.
See Notes [2].
Expand Down Expand Up @@ -196,7 +195,13 @@ def welch_psd(signal, n_segments=8, len_segment=None,
3.14573483e-08, 6.82050475e-09, 1.18183354e-10]]) * mV**2/Hz
"""

# 'hanning' window was removed with release of scipy 1.9.0, it was
# deprecated since 1.1.0.
if window == 'hanning':
warnings.warn("'hanning' is deprecated and was removed from scipy "
"with release 1.9.0. Please use 'hann' instead",
DeprecationWarning)
window = 'hann'
# initialize a parameter dict (to be given to scipy.signal.welch()) with
# the parameters directly passed on to scipy.signal.welch()
params = {'window': window, 'nfft': nfft,
Expand Down Expand Up @@ -329,7 +334,7 @@ def multitaper_psd(signal, n_segments=1, len_segment=None,
Time bandwidth product
Default: 4.0.
num_tapers : int, optional
Number of tapers used in 1. to obtain estimate of PSD. By default
Number of tapers used in 1. to obtain estimate of PSD. By default,
[2*nw] - 1 is chosen.
Default: None.
peak_resolution : pq.Quantity float, optional
Expand Down Expand Up @@ -520,7 +525,7 @@ def multitaper_psd(signal, n_segments=1, len_segment=None,
len_seg='len_segment', freq_res='frequency_resolution')
def welch_coherence(signal_i, signal_j, n_segments=8, len_segment=None,
frequency_resolution=None, overlap=0.5, fs=1.0,
window='hanning', nfft=None, detrend='constant',
window='hann', nfft=None, detrend='constant',
scaling='density', axis=-1):
r"""
Estimates coherence between a given pair of analog signals.
Expand Down Expand Up @@ -574,7 +579,7 @@ def welch_coherence(signal_i, signal_j, n_segments=8, len_segment=None,
window : str or tuple or np.ndarray, optional
Desired window to use.
See Notes [1].
Default: 'hanning'
Default: 'hann'
nfft : int, optional
Length of the FFT used.
See Notes [1].
Expand Down Expand Up @@ -607,7 +612,7 @@ def welch_coherence(signal_i, signal_j, n_segments=8, len_segment=None,
Estimate of coherency between the input time series. For each
frequency, coherency takes a value between 0 and 1, with 0 or 1
representing no or perfect coherence, respectively.
When the input arrays `signal_i` and `signal_j` are multi-dimensional,
When the input arrays `signal_i` and `signal_j` are multidimensional,
`coherency` is of the same shape as the inputs, and the frequency is
indexed depending on the type of the input. If the input is
`neo.AnalogSignal`, the first axis indexes frequency. Otherwise,
Expand Down Expand Up @@ -671,6 +676,13 @@ def welch_coherence(signal_i, signal_j, n_segments=8, len_segment=None,
"""

# TODO: code duplication with welch_psd()
# 'hanning' window was removed with release of scipy 1.9.0, it was
# deprecated since 1.1.0.
if window == 'hanning':
warnings.warn("'hanning' is deprecated and was removed from scipy "
"with release 1.9.0. Please use 'hann' instead",
DeprecationWarning)
window = 'hann'

# initialize a parameter dict for scipy.signal.csd()
params = {'window': window, 'nfft': nfft,
Expand Down
22 changes: 20 additions & 2 deletions elephant/test/test_spectral.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ def test_welch_psd_errors(self):
self.assertRaises(ValueError, elephant.spectral.welch_psd, data,
overlap=1.1)

def test_welch_psd_warnings(self):
# generate a dummy data
data = n.AnalogSignal(np.zeros(5000), sampling_period=0.001 * pq.s,
units='mV')
# Test deprecation warning for 'hanning' window
self.assertWarns(DeprecationWarning, elephant.spectral.welch_psd,
data, window='hanning')

def test_welch_psd_behavior(self):
# generate data by adding white noise and a sinusoid
data_length = 5000
Expand Down Expand Up @@ -139,7 +147,7 @@ def test_welch_psd_multidim_input(self):
noise = np.random.normal(size=(num_channel, data_length))
data_np = np.array(noise)
# Since row-column order in AnalogSignal is different from the
# conventional one, `data_np` needs to be transposed when its used to
# conventional one, `data_np` needs to be transposed when it's used to
# define an AnalogSignal
data_neo = n.AnalogSignal(data_np.T,
sampling_period=sampling_period * pq.s,
Expand Down Expand Up @@ -337,6 +345,16 @@ def test_welch_cohere_errors(self):
self.assertRaises(ValueError, elephant.spectral.welch_coherence, x, y,
overlap=1.1)

def test_welch_cohere_warnings(self):
# generate a dummy data
x = n.AnalogSignal(np.zeros(5000), sampling_period=0.001 * pq.s,
units='mV')
y = n.AnalogSignal(np.zeros(5000), sampling_period=0.001 * pq.s,
units='mV')
# Test deprecation warning for 'hanning' window
self.assertWarns(DeprecationWarning, elephant.spectral.welch_coherence,
x, y, window='hanning')

def test_welch_cohere_behavior(self):
# generate data by adding white noise and a sinusoid
data_length = 5000
Expand Down Expand Up @@ -444,7 +462,7 @@ def test_welch_cohere_multidim_input(self):
x_np = np.array(np.random.normal(size=(num_channel, data_length)))
y_np = np.array(np.random.normal(size=(num_channel, data_length)))
# Since row-column order in AnalogSignal is different from the
# convention in NumPy/SciPy, `data_np` needs to be transposed when its
# convention in NumPy/SciPy, `data_np` needs to be transposed when it's
# used to define an AnalogSignal
x_neo = n.AnalogSignal(x_np.T, units='mV',
sampling_period=sampling_period * pq.s)
Expand Down

0 comments on commit df8e962

Please sign in to comment.