`output="complex"` for Welch method should only allow `average=None`
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 74/100
Hướng nghiên cứu
Bắt đầu bằng cách lần theo cách xử lý Welch của output="complex" và average trong epochs.compute_psd(), sau đó kiểm tra cách Spectrum.plot() chuyển đổi các hệ số thành công suất. Thêm kiểm tra để từ chối các giá trị average khác None khi đầu ra là số phức, đồng thời tìm các kiểm thử hiện có bao quát các chế độ đầu ra Welch và việc vẽ biểu đồ. Hoàn tất khi tổ hợp không hợp lệ phát sinh lỗi rõ ràng, còn average=None và đầu ra công suất vẫn giữ hành vi như mong đợi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description of the problem
For Welch method, if average is requested with output="complex", segments are aggregated for complex coefficients, which can mess up the phase information in the resulting coefficients. Subsequently computing power from these coefficients gives very different results to if output="power" was used directly. This also affects the conversion to power from coefficients in Spectrum.plot().
Steps to reproduce
import numpy as np
import mne
from mne.time_frequency.psd import _median_biases
data_path = mne.datasets.sample.data_path()
raw = mne.io.read_raw_fif(
data_path / "MEG" / "sample" / "sample_audvis_filt-0-40_raw.fif", verbose=False
)
raw.pick("eeg", exclude="bads").crop(tmax=60).load_data(verbose=False)
epochs = mne.make_fixed_length_epochs(raw, duration=4.0, preload=True, verbose=False)
kwargs = dict(method="welch", n_fft=128, verbose=False) # 4 segments per epoch
def coefs_to_power(spectrum):
"""Convert complex Welch coefficients to one-sided power."""
coefs = spectrum.get_data()
freqs, sfreq = spectrum.freqs, spectrum.info["sfreq"]
# double all bins except DC and Nyquist (scipy.signal.spectrogram does this for
# mode="psd", but not for mode="complex")
scale = np.where((freqs == 0) | np.isclose(freqs, sfreq / 2), 1.0, 2.0)
if coefs.ndim == 4: # unaggregated: (epoch, channel, freq, segment)
scale = scale[:, np.newaxis]
return (coefs * coefs.conj()).real * scale
for average in ("mean", "median"):
power = epochs.compute_psd(output="power", average=average, **kwargs).get_data()
# output="complex" with average!=None aggregates the complex coefficients across
# segments, so power computed afterwards is wrong
spec = epochs.compute_psd(output="complex", average=average, **kwargs)
power_agg_first = coefs_to_power(spec)
# correct: average=None, compute power per segment, then aggregate
spec = epochs.compute_psd(output="complex", average=None, **kwargs)
power_seg = coefs_to_power(spec)
if average == "mean":
power_agg_last = power_seg.mean(axis=-1)
else:
n_segments = power_seg.shape[-1]
power_agg_last = (
np.median(power_seg, axis=-1) / _median_biases(n_segments)[n_segments]
)
print(f"average={average!r}")
for name, psd in (
("complex -> aggregate -> power", power_agg_first),
("complex -> power -> aggregate", power_agg_last),
):
ratio = psd / power
print(
f" {name}: ratio to output='power' median={np.median(ratio):.3f} "
f"min={ratio.min():.3g} max={ratio.max():.3g} "
f"allclose={np.allclose(psd, power, rtol=1e-6, atol=0)}"
)
Link to data
No response
Expected results
average!=None with output="complex" is not allowed, as it gives invalid coefficients.
Actual results
Computing output="complex" with average!=None is allowed, and gives very different results when trying to compute power from these coefficients, compared to the proper approach of unaggregated coefficients → unaggregated power → aggregated power (which is what happens with output="power").
average='mean'
complex -> aggregate -> power: ratio to output='power' median=0.131 min=2.06e-08 max=0.992 allclose=False
complex -> power -> aggregate: ratio to output='power' median=1.000 min=1 max=1 allclose=True
average='median'
complex -> aggregate -> power: ratio to output='power' median=0.326 min=9.42e-08 max=36.2 allclose=False
complex -> power -> aggregate: ratio to output='power' median=1.000 min=1 max=1 allclose=True
Additional information
AI disclosure: Claude Opus 5.5 initially identified the problem, which I further investigated.
- Ngôn ngữ chính
- Python
- Star
- 3.6k
- Fork
- 1.6k
- Merge trung bình
- 1 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 74
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của mne-tools/mne-python
-
Incorrect scaling of complex multitaper coefficients with `normalization="full"`Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởBUG
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
mne-tools/mne-python#14493 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`compute_average_dev_head_t` averages head rotation with squared time weights (translation uses linear weights)Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởBUG
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
mne-tools/mne-python#14478 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`mne.stats.f_oneway` returns wrong (even negative) F for small integer dtypesCó thể đã có người làm @darshpatel1052 đã nhận 2 ngày trước. Đang mởBUG
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
mne-tools/mne-python#14477 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
ENH: Add `description` filter parameter to `Raw.crop_by_annotations()`Có thể đã có người làm @aman-coder03 đã nhận 212 ngày trước. Đang mởENH
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
mne-tools/mne-python#13743 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
cannot plot into matplotlib subfigureCó thể đã có người làm @ishaaaan17 đã nhận 2 ngày trước. Đang mởBUG
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
mne-tools/mne-python#14481 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của mne-tools/mne-python
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
its-me-prash/vwgroup-connect-ha#2019 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
KonstantinStarovoytov/kitden#21 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
RefactorĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
ehmatthes/gh-profiler#166 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
smart-on-fhir/smart-fetch#73 ·
-
good first issue help wanted
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 85/100
RizgarOzan/playcal#13 ·