Repository: scipy/scipy

Issue:
BUG: scipy.signal.periodogram window parameter
### Describe your issue.

When trying to pass an array as the `window` for scipy's periodogram, the behavior is inconsistent with the documentation. In the doc it says:
*window : str or tuple or array_like, optional
    Desired window to use. If `window` is a string or tuple, it is
    passed to `get_window` to generate the window values, which are
    DFT-even by default. See `get_window` for a list of windows and
    required parameters. If `window` is array_like it will be used
    directly as the window and its length **must be nperseg**. Defaults
    to 'boxcar'.*
However there is no **nperseg** parameter for `scipy.signal.periodogram`! Moreover, a confusing error message is thrown, as shown below.
I guess it's intended use is for windows precisely the size of the signal `x`. However in a signal analysis set up, it can be meaningful to first convolve the signal with a (shorter) window before performing the FFT (think moving average, although it's often a bad idea). When using the `nfft` parameter shorter windows work but I assume the signal gets truncated?

### Reproducing Code Example

```python
import numpy as np
from scipy.signal import windows, periodogram
                                                                                                                          
nSamples = 1000
win_size = nSamples // 4
signal = np.random.randn(nSamples)                                                                                        
                                                                                                                          
# manual short hann window as array                                                                                             
hann = windows.hann(win_size)                                                                                             

freqs, pxx = periodogram(signal, window=hann)

# this works, however doesn't fit the documentation
# not clear what exactly is happening here.. does it truncate the input signal?
# freqs, pxx = periodogram(signal, window=hann, nfft=win_size)
```


### Error message

```shell
~/.local/lib/python3.8/site-packages/scipy/signal/spectral.py in _triage_segments(window, nperseg, input_length)
   1977         elif nperseg is not None:
   1978             if nperseg != win.shape[0]:
-> 1979                 raise ValueError("value specified for nperseg is different"
   1980                                  " from length of window")
   1981     return win, nperseg

ValueError: value specified for nperseg is different from length of window
```


### SciPy/NumPy/Python version information

1.4.1 1.18.4 sys.version_info(major=3, minor=8, micro=10, releaselevel='final', serial=0)


Discussion:

Resolving patch:
diff --git a/scipy/signal/_spectral_py.py b/scipy/signal/_spectral_py.py
--- a/scipy/signal/_spectral_py.py
+++ b/scipy/signal/_spectral_py.py
@@ -169,7 +169,8 @@ def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant',
         passed to `get_window` to generate the window values, which are
         DFT-even by default. See `get_window` for a list of windows and
         required parameters. If `window` is array_like it will be used
-        directly as the window and its length must be nperseg. Defaults
+        directly as the window and its length must be equal to the length
+        of the axis over which the periodogram is computed. Defaults
         to 'boxcar'.
     nfft : int, optional
         Length of the FFT used. If `None` the length of `x` will be
@@ -281,6 +282,11 @@ def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant',
         nperseg = nfft
         nfft = None
 
+    if hasattr(window, 'size'):
+        if window.size != nperseg:
+            raise ValueError('the size of the window must be the same size '
+                             'of the input on the specified axis')
+
     return welch(x, fs=fs, window=window, nperseg=nperseg, noverlap=0,
                  nfft=nfft, detrend=detrend, return_onesided=return_onesided,
                  scaling=scaling, axis=axis)


Test patch:
diff --git a/scipy/signal/tests/test_spectral.py b/scipy/signal/tests/test_spectral.py
--- a/scipy/signal/tests/test_spectral.py
+++ b/scipy/signal/tests/test_spectral.py
@@ -215,6 +215,15 @@ def test_complex_32(self):
         assert_allclose(p, q)
         assert_(p.dtype == q.dtype)
 
+    def test_shorter_window_error(self):
+        x = np.zeros(16)
+        x[0] = 1
+        win = signal.get_window('hann', 10)
+        expected_msg = ('the size of the window must be the same size '
+                        'of the input on the specified axis')
+        with assert_raises(ValueError, match=expected_msg):
+            periodogram(x, window=win)
+
 
 class TestWelch:
     def test_real_onesided_even(self):