docs(plan): use correlation-based find_bads_eog to fix ICA on small recordings
Browse filesCode reviewer caught a latent blocker: with 4 EEG channels, ICA fits only 3
components, and find_bads_eog's default z-score measure cannot reach the
default 3.0 threshold (algebraic ceiling sqrt(n-1)). Switch to
measure='correlation', threshold=0.9 so the EOG-correlated component is
reliably flagged before Task 4 lands.
docs/superpowers/plans/2026-04-30-day2-eeg-mne-ica-pipeline.md
CHANGED
|
@@ -541,7 +541,16 @@ def remove_artifacts_with_ica(
|
|
| 541 |
verbose="ERROR",
|
| 542 |
)
|
| 543 |
ica.fit(out, picks="eeg", verbose="ERROR")
|
| 544 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
ica.exclude = list(bad_idx)
|
| 546 |
logger.info(
|
| 547 |
"ICA fit: n_components=%d, EOG-correlated rejected=%d",
|
|
|
|
| 541 |
verbose="ERROR",
|
| 542 |
)
|
| 543 |
ica.fit(out, picks="eeg", verbose="ERROR")
|
| 544 |
+
# Use raw correlation (not z-score) so we can reliably flag artifact
|
| 545 |
+
# components on small recordings where n_components < 10 makes the
|
| 546 |
+
# default z-score threshold algebraically unreachable.
|
| 547 |
+
bad_idx, _ = ica.find_bads_eog(
|
| 548 |
+
out,
|
| 549 |
+
ch_name=eog_ch_name,
|
| 550 |
+
measure="correlation",
|
| 551 |
+
threshold=0.9,
|
| 552 |
+
verbose="ERROR",
|
| 553 |
+
)
|
| 554 |
ica.exclude = list(bad_idx)
|
| 555 |
logger.info(
|
| 556 |
"ICA fit: n_components=%d, EOG-correlated rejected=%d",
|