com um clique
coherence
Magnitude-squared / imaginary coherence — spectral-domain connectivity
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
Magnitude-squared / imaginary coherence — spectral-domain connectivity
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional 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.