بنقرة واحدة
coherence
Magnitude-squared / imaginary coherence — spectral-domain connectivity
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Magnitude-squared / imaginary coherence — spectral-domain connectivity
التثبيت باستخدام 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 | coherence |
| description | Magnitude-squared / imaginary coherence — spectral-domain connectivity |
| layer | L3 |
| group | connectivity |
| metadata | {"tags":["operator","connectivity","coherence","imaginary_coherence","csd"],"modalities":["eeg","meg","seeg","ecog","lfp"],"step_string":"coherence","analysis_goal_allowed":["feature_extraction","clinical_screening","exploratory","connectivity","online_inference"],"analysis_goal_forbidden":["source_localization"]} |
Computes magnitude-squared coherence and (optionally) imaginary coherence across channel pairs at a given frequency band. Imaginary coherence (Nolte 2004) is volume-conduction robust, like wPLI but in the spectral domain.
Input / Output: (n_channels, n_times) → (n_channels, n_channels).
C_xy(f) = |S_xy(f)|² / (S_xx(f) · S_yy(f)) # magnitude-squared
C_imag_xy(f) = imag(S_xy(f)) / sqrt(S_xx(f) · S_yy(f)) # imaginary
Where S_xy is the cross-spectral density via Welch.
coherence:{fmin},{fmax},{kind}
| Parameter | Type | Default | Description |
|---|---|---|---|
fmin, fmax | float, float | required | Band. |
kind | str | "mag2" | "mag2" or "imaginary". |
nperseg (kw) | int | sfreq | Welch segment length. |
EEG: prefer "imaginary" to suppress volume conduction. MEG / sEEG / ECoG / LFP: "mag2" or "imaginary" both valid.
Use when: spectral-domain connectivity; band-power coupling.
Don't use when: phase-only analysis (use PLV/PLI); source-level data where volume conduction is gone.
After bandpass / notch / drop_bads; on continuous data.
| Failure | Symptom | Detection |
|---|---|---|
| Recording too short | Welch fails. | If n_t < 4 · nperseg raise recoverable. |
| Empty band | All zero. | Pre-check fmax < sfreq/2. |
from __future__ import annotations
import numpy as np
from scipy.signal import csd
def coherence(
data: np.ndarray, sfreq: float, fmin: float, fmax: float,
kind: str = "mag2", nperseg: int | None = None,
) -> np.ndarray:
"""Pairwise coherence at band-mean."""
if nperseg is None:
nperseg = int(sfreq)
n_ch = data.shape[0]
out = np.zeros((n_ch, n_ch), dtype=np.float32)
for i in range(n_ch):
for j in range(i, n_ch):
f, Sxy = csd(data[i], data[j], fs=sfreq, nperseg=nperseg)
_, Sxx = csd(data[i], data[i], fs=sfreq, nperseg=nperseg)
_, Syy = csd(data[j], data[j], fs=sfreq, nperseg=nperseg)
mask = (f >= fmin) & (f <= fmax)
if kind == "imaginary":
num = np.imag(Sxy[mask])
denom = np.sqrt(np.abs(Sxx[mask] * Syy[mask])) + 1e-30
v = float(np.mean(np.abs(num / denom)))
else:
num = np.abs(Sxy[mask]) ** 2
denom = np.abs(Sxx[mask] * Syy[mask]) + 1e-30
v = float(np.mean(num / denom))
out[i, j] = out[j, i] = v
return out
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_coherence(
data_dict: Dict[str, Any], *,
fmin: float, fmax: float, kind: str = "mag2",
nperseg: int | None = None,
) -> Dict[str, Any]:
"""Pairwise coherence.
Parameters
----------
data_dict : dict
fmin, fmax : float
kind : str
"mag2" / "imaginary".
nperseg : int or None
Returns
-------
dict — `meta["coherence"]: (n_ch, n_ch)`.
Raises
------
EasyBCIOperatorError
recoverable=False for invalid band; recoverable=True for short recordings.
Modality coverage
-----------------
EEG / MEG / sEEG / ECoG / LFP: yes.
References
----------
Nolte et al. 2004; Welch 1967.
"""
sfreq = float(data_dict["frequency"])
if fmax >= sfreq / 2 or fmin >= fmax or kind not in ("mag2", "imaginary"):
raise EasyBCIOperatorError(
operator="coherence",
reason=f"invalid fmin={fmin}, fmax={fmax}, kind={kind}",
recoverable=False,
)
if nperseg is None:
nperseg = int(sfreq)
if data_dict["data"].shape[-1] < 4 * nperseg:
raise EasyBCIOperatorError(
operator="coherence",
reason="recording too short for Welch",
recoverable=True, fallback_step="coherence with smaller nperseg",
)
t0 = time.monotonic()
from scipy.signal import csd
data = data_dict["data"]
n_ch = data.shape[0]
coh = np.zeros((n_ch, n_ch), dtype=np.float32)
for i in range(n_ch):
for j in range(i, n_ch):
f, Sxy = csd(data[i], data[j], fs=sfreq, nperseg=nperseg)
_, Sxx = csd(data[i], data[i], fs=sfreq, nperseg=nperseg)
_, Syy = csd(data[j], data[j], fs=sfreq, nperseg=nperseg)
mask = (f >= fmin) & (f <= fmax)
if kind == "imaginary":
num = np.imag(Sxy[mask])
denom = np.sqrt(np.abs(Sxx[mask] * Syy[mask])) + 1e-30
v = float(np.mean(np.abs(num / denom)))
else:
num = np.abs(Sxy[mask]) ** 2
denom = np.abs(Sxx[mask] * Syy[mask]) + 1e-30
v = float(np.mean(num / denom))
coh[i, j] = coh[j, i] = v
elapsed = time.monotonic() - t0
out = dict(data_dict)
out["elapsed_s"] = elapsed
out["meta"] = {**out.get("meta", {}), "coherence": coh,
"coherence_band": [fmin, fmax], "coherence_kind": kind}
record_step_elapsed("coherence", elapsed, (data_dict.get("meta") or {}).get("step_cache_key"))
return out
bci/neural-processing/connectivity_resting/connectivity.md.