Repository: mne-tools/mne-python

Issue:
BUG: Inconsistent Welch results by API
### Description of the problem

If you use `inst.compute_psd` with default arguments, you get very different results compared to if you do `mne.time_frequency.psd_array_welch`.

### Steps to reproduce

```Python
import mne
from mne.datasets import sample

data_path = sample.data_path()
meg_path = data_path / "MEG" / "sample"
raw_fname = meg_path / "sample_audvis_filt-0-40_raw.fif"

raw = mne.io.read_raw_fif(raw_fname)

evoked = mne.EvokedArray(raw.get_data(), raw.info)

psd = evoked.compute_psd(method='welch', average=False)
print(psd.shape)

psd2, freqs = mne.time_frequency.psd_array_welch(
    evoked.get_data(picks='data'), evoked.info['sfreq'], average=False)
print(psd2.shape)
```


### Link to data

_No response_

### Expected results

The same shape output.

### Actual results

compute_psd : (366, 1025, 20)

psd_array_welch: (366, 129, 162)

### Additional information

cc @drammock since I think this relates to changes you've made.


Discussion:
To me it looks like "just" a difference in "n_fft" default. And `psd_array_welch`'s default of 256 is pretty small for typical data, and `compute_psd`'s default of 1024 is better. But it's odd that the [`evoked.compute_psd`](https://mne.tools/stable/generated/mne.Evoked.html#mne.Evoked.compute_psd) docs don't mention that the default is different. We should document where the defaults of `compute_psd` differ from the `psd_array_*` methods (might just be `n_fft`?) in `compute_psd` then we're okay I think. (The default of 1024 is better in my mind than 256 so don't want to change that, and doesn't seem worth it to change `psd_array_welch` to match by deprecation.)
I only see the 256 default documented in `psd_array_welch`, I don't see 1024 mentioned anywhere although that seems to be the case from the data but maybe I'm just missing it
The `n_fft` default for `compute_psd()` is actually data-dependent and was inherited from the legacy `plot_psd()` and `plot_psd_topo()` functions. It is:

https://github.com/mne-tools/mne-python/blob/43414ba878ee7746464a8fd5aa7f4a555ea0bd5e/mne/time_frequency/spectrum.py#L283-L284

I'll add a docstring note about the default.
What do you think about changing the default in `mne.time_frequency.psd_array_welch` to match @drammock ? I agree with @larsoner that that tends to be rather few points for how high sampling rates tend to be nowadays but I'm not overly opinionated. I am a bit opinionated that I don't particularly like how two seemingly synonymous APIs don't have the same defaults, I think ideally they'd be the same.

Resolving patch:
diff --git a/mne/time_frequency/spectrum.py b/mne/time_frequency/spectrum.py
--- a/mne/time_frequency/spectrum.py
+++ b/mne/time_frequency/spectrum.py
@@ -279,7 +279,7 @@ def _set_legacy_nfft_default(self, tmin, tmax, method, method_kw):
         This method returns ``None`` and has a side effect of (maybe) updating
         the ``method_kw`` dict.
         """
-        if method == "welch" and method_kw.get("n_fft", None) is None:
+        if method == "welch" and method_kw.get("n_fft") is None:
             tm = _time_mask(self.times, tmin, tmax, sfreq=self.info["sfreq"])
             method_kw["n_fft"] = min(np.sum(tm), 2048)
 
diff --git a/mne/utils/docs.py b/mne/utils/docs.py
--- a/mne/utils/docs.py
+++ b/mne/utils/docs.py
@@ -1704,7 +1704,8 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
 
 _fmin_fmax = """\
 fmin, fmax : float
-    The lower- and upper-bound on frequencies of interest. Default is {}"""
+    The lower- and upper-bound on frequencies of interest. Default is
+    {}"""
 
 docdict["fmin_fmax_psd"] = _fmin_fmax.format(
     "``fmin=0, fmax=np.inf`` (spans all frequencies present in the data)."
@@ -2578,10 +2579,13 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
 **method_kw
     Additional keyword arguments passed to the spectral estimation
     function (e.g., ``n_fft, n_overlap, n_per_seg, average, window``
-    for Welch method, or
-    ``bandwidth, adaptive, low_bias, normalization`` for multitaper
-    method). See :func:`~mne.time_frequency.psd_array_welch` and
-    :func:`~mne.time_frequency.psd_array_multitaper` for details.
+    for Welch method, or ``bandwidth, adaptive, low_bias, normalization``
+    for multitaper method). See :func:`~mne.time_frequency.psd_array_welch`
+    and :func:`~mne.time_frequency.psd_array_multitaper` for details. Note
+    that for Welch method if ``n_fft`` is unspecified its default will be
+    the smaller of ``2048`` or the number of available time samples (taking into
+    account ``tmin`` and ``tmax``), not ``256`` as in
+    :func:`~mne.time_frequency.psd_array_welch`.
 """
 
 docdict["method_kw_tfr"] = _method_kw_tfr_template.format(


Test patch: