mekosotto commited on
Commit
32359e5
·
1 Parent(s): c743c0a

fix(eeg): guard bandpass_filter against inverted l_freq/h_freq; document picks=all

Browse files
src/pipelines/eeg_pipeline.py CHANGED
@@ -52,13 +52,24 @@ def bandpass_filter(
52
 
53
  Args:
54
  raw: Loaded `mne.io.BaseRaw` (call `.load_data()` first if from disk).
55
- l_freq: Low-cut frequency in Hz.
56
  h_freq: High-cut frequency in Hz.
57
 
58
  Returns:
59
  A filtered copy of `raw`.
 
 
 
 
60
  """
 
 
 
 
 
61
  out = raw.copy()
 
 
62
  out.filter(l_freq=l_freq, h_freq=h_freq, picks="all", verbose="ERROR")
63
  logger.info("Bandpass filter applied: %.1f-%.1f Hz", l_freq, h_freq)
64
  return out
 
52
 
53
  Args:
54
  raw: Loaded `mne.io.BaseRaw` (call `.load_data()` first if from disk).
55
+ l_freq: Low-cut frequency in Hz. Must be strictly less than `h_freq`.
56
  h_freq: High-cut frequency in Hz.
57
 
58
  Returns:
59
  A filtered copy of `raw`.
60
+
61
+ Raises:
62
+ ValueError: if `l_freq >= h_freq`. MNE silently produces a corrupted
63
+ band-stop-like result on inverted inputs, so we guard up front.
64
  """
65
+ if l_freq >= h_freq:
66
+ raise ValueError(
67
+ f"l_freq ({l_freq}) must be strictly less than h_freq ({h_freq})"
68
+ )
69
+
70
  out = raw.copy()
71
+ # picks="all" includes the EOG channel so the ICA step in
72
+ # remove_artifacts_with_ica sees a consistently-filtered EOG reference.
73
  out.filter(l_freq=l_freq, h_freq=h_freq, picks="all", verbose="ERROR")
74
  logger.info("Bandpass filter applied: %.1f-%.1f Hz", l_freq, h_freq)
75
  return out
tests/pipelines/test_eeg_pipeline.py CHANGED
@@ -81,3 +81,11 @@ class TestBandpassFilter:
81
  original_mean = raw.get_data().mean()
82
  _ = bandpass_filter(raw, l_freq=1.0, h_freq=40.0)
83
  assert raw.get_data().mean() == pytest.approx(original_mean, rel=1e-12)
 
 
 
 
 
 
 
 
 
81
  original_mean = raw.get_data().mean()
82
  _ = bandpass_filter(raw, l_freq=1.0, h_freq=40.0)
83
  assert raw.get_data().mean() == pytest.approx(original_mean, rel=1e-12)
84
+
85
+ def test_rejects_inverted_frequency_range(self) -> None:
86
+ """l_freq must be strictly < h_freq; otherwise raise instead of silently corrupting data."""
87
+ raw = self._load()
88
+ with pytest.raises(ValueError, match="must be strictly less than"):
89
+ bandpass_filter(raw, l_freq=40.0, h_freq=1.0)
90
+ with pytest.raises(ValueError, match="must be strictly less than"):
91
+ bandpass_filter(raw, l_freq=10.0, h_freq=10.0)