ワンクリックで
comb-filter
Multi-harmonic comb filter — remove power-line fundamental + all harmonics in one pass
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Multi-harmonic comb filter — remove power-line fundamental + all harmonics in one pass
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Neurodata Without Borders (.nwb) — the de-facto standard for in-vivo electrophysiology (Neuropixels / AIBS / DANDI / IBL)
Index of L0 data-format loader skills by family
Index of all L2 paradigm skills by group + analysis_goal → paradigm matrix
Two-phase BCI data preprocessing pipeline: deep-inspect → plan → propose → user confirm → automated code/execute/QC/export
BIDS-iEEG sidecar (*_channels.tsv / *_electrodes.tsv / *_coordsystem.json / *_ieeg.json) — clinical sEEG / ECoG standard
Multiscale Electrophysiology Format v3 (Mayo Clinic) — long-duration encrypted sEEG
| name | comb_filter |
| description | Multi-harmonic comb filter — remove power-line fundamental + all harmonics in one pass |
| layer | L3 |
| group | filter |
| metadata | {"tags":["operator","filter","comb","powerline","harmonics"],"modalities":["eeg","meg","seeg","ecog","fnirs"],"step_string":"comb","analysis_goal_allowed":["classification","feature_extraction","clinical_screening","exploratory","generic","online_inference"],"analysis_goal_forbidden":["phase_amplitude_coupling"]} |
A single-pass digital comb filter that creates equispaced notches at a
fundamental frequency (e.g., 50 Hz) and all its integer harmonics
up to Nyquist (100, 150, 200, ... 50 · k Hz). Cheaper than chaining 5–10
notch_filter calls, and the harmonic alignment guarantees that the
notch widths are uniformly Q-bound.
Input / Output: (n_channels, n_times) → same shape.
A digital comb (notch-mode) with fundamental f0 and N harmonics is
H(z) = (1 − r^N · z^(−N)) / (1 − r · z^(−1)) # band-stop variant
implemented via scipy.signal.iircomb(w0=f0/(sfreq/2), Q=Q, ftype="notch").
The Q parameter sets the notch width — higher Q is a sharper notch
(less neighbour bleeding) but rings longer.
Zero-phase is enforced via filtfilt.
comb:{f0},{Q}
| Parameter | Type | Default | Description |
|---|---|---|---|
f0 | float | 50.0 | Fundamental frequency (50 EU / 60 US). |
Q | float | 30.0 | Notch sharpness; 20 = wider, 50 = tighter. |
max_harmonics (kw) | int | None | Stop after N harmonics; default = up to Nyquist. |
| Modality | Q | Notes |
|---|---|---|
| EEG | 30 | Standard line-noise removal; minimal alpha/beta impact. |
| MEG | 30 | SQUID baseline; line noise dominant. |
| sEEG | 25 | High-gamma analysis: keep Q moderate so 100 / 150 Hz notch doesn't drink into the analysis band. |
| fNIRS | n/a | Hemodynamic band has no line noise. |
Hard exclusion for phase_amplitude_coupling: comb's harmonic notches
land at frequencies that may be the PAC carrier; use selective notch:f0
on the fundamental only instead.
Use when: line noise + many harmonics dominate; you want one-pass cleanup; downstream is classification / ERP / band-power.
Don't use when: PAC / cross-frequency analysis (use single notch); the harmonic frequencies coincide with paradigm-relevant content (SSVEP at 25/50/75 Hz hits 50 Hz fundamental).
bandpass to avoid notch side-lobes folding into the
analysis band.| Failure | Symptom | Detection |
|---|---|---|
| Notch too wide (Q low) | Visible dip in PSD around f0 ± 2 Hz. | Compute PSD; if mean(PSD[f0-2:f0+2]) < 0.7 * neighbour raise warning. |
| Harmonic above signal of interest | SSVEP / response peaks attenuated. | If SSVEP paradigm + f0 divides response → log warning. |
| Recording too short | Edge transients dominate. | If n_t · sfreq / 1000 < 50 · Q / f0 raise recoverable. |
notch:60 if
US power, or notch_filter:50,Q=50 (high-Q single notch).from __future__ import annotations
import numpy as np
from scipy.signal import iircomb, filtfilt
def comb_filter(
data: np.ndarray, sfreq: float, f0: float = 50.0, Q: float = 30.0
) -> np.ndarray:
"""Multi-harmonic notch via digital comb."""
w0 = f0 / (sfreq / 2)
if w0 >= 1.0:
raise ValueError(f"comb: f0={f0} >= Nyquist {sfreq/2}")
b, a = iircomb(w0, Q, ftype="notch", fs=sfreq)
return filtfilt(b, a, data, axis=-1, padtype="even").astype(data.dtype, copy=False)
from typing import Any, Dict
import time
import numpy as np
from easybci_lib.tools.neural_processing.operator_errors import EasyBCIOperatorError
from easybci_lib.tools.neural_processing.preprocess.step_cache import record_step_elapsed
def operator_comb(
data_dict: Dict[str, Any], *, f0: float = 50.0, Q: float = 30.0,
) -> Dict[str, Any]:
"""Multi-harmonic comb notch.
Parameters
----------
data_dict : dict
OperatorIO.
f0 : float
Fundamental frequency (default 50.0 Hz).
Q : float
Notch sharpness (default 30.0).
Returns
-------
dict
OperatorIO with line-noise + harmonics removed.
Raises
------
EasyBCIOperatorError
recoverable=True for f0 >= Nyquist.
Modality coverage
-----------------
EEG / MEG / sEEG / ECoG: yes.
fNIRS: no (no line noise in hemodynamic band).
PAC tasks: forbidden — use selective `notch:f0` instead.
References
----------
Mitra & Bokil 2007 — comb filter for line noise harmonics.
"""
sfreq = float(data_dict["frequency"])
if f0 >= sfreq / 2:
raise EasyBCIOperatorError(
operator="comb", reason=f"f0={f0} >= Nyquist {sfreq/2}",
recoverable=True, fallback_step=f"notch:{f0}",
)
t0 = time.monotonic()
from scipy.signal import iircomb, filtfilt
w0 = f0 / (sfreq / 2)
b, a = iircomb(w0, Q, ftype="notch", fs=sfreq)
new_data = filtfilt(b, a, data_dict["data"], axis=-1, padtype="even").astype(
data_dict["data"].dtype, copy=False
)
elapsed = time.monotonic() - t0
out = dict(data_dict)
out["data"] = new_data
out["elapsed_s"] = elapsed
out["meta"] = {**out.get("meta", {}), "comb": {"f0": f0, "Q": Q}}
record_step_elapsed("comb", elapsed, (data_dict.get("meta") or {}).get("step_cache_key"))
return out