en un clic
plv
Phase-Locking Value — pairwise phase synchrony (Lachaux 1999)
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
Phase-Locking Value — pairwise phase synchrony (Lachaux 1999)
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle 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 | plv |
| description | Phase-Locking Value — pairwise phase synchrony (Lachaux 1999) |
| layer | L3 |
| group | connectivity |
| metadata | {"tags":["operator","connectivity","plv","phase","lachaux"],"modalities":["eeg","meg","seeg","ecog","lfp"],"step_string":"plv","analysis_goal_allowed":["feature_extraction","exploratory","connectivity"],"analysis_goal_forbidden":["source_localization","online_inference"]} |
Computes pairwise PLV across channels — a measure of how consistently the instantaneous phase of two signals locks in time. Range [0, 1]: 0 = independent, 1 = perfectly phase-locked.
Input / Output: (n_channels, n_times) → (n_channels, n_channels).
For two channels x, y:
φ_x(t), φ_y(t) = instantaneous phase via Hilbert (or bandpassed Hilbert).
PLV(x, y) = | (1/T) · Σ_t exp(j · (φ_x(t) − φ_y(t))) |
Bandpass before PLV — the analysis is meaningful only for narrow-band phase.
plv:{fmin},{fmax}
| Parameter | Type | Default | Description |
|---|---|---|---|
fmin, fmax | float, float | required | Narrow band edges. |
n_segments (kw) | int | 1 | Segment count for time-averaged PLV. |
| Modality | Bands | Notes |
|---|---|---|
| EEG / MEG | alpha (8–13), beta (13–30), gamma (30–80) | Standard cognition. |
| sEEG / ECoG | gamma / HFO | Functional mapping. |
| LFP | theta / gamma | Hippocampal coupling. |
Use when: functional connectivity / phase coupling; PAC carrier analysis (per-band step).
Don't use when: amplitude-only analyses; online inference (cost); wide-band (need narrow band for meaningful phase).
| Failure | Symptom | Detection |
|---|---|---|
| Wide-band input | PLV is mean ~ 1/sqrt(T) (random phase). | If fmax - fmin > 5 Hz warn. |
| Volume conduction (EEG) | All-pair PLV ≈ 1. | Use REST or Laplacian first. |
from __future__ import annotations
import numpy as np
from scipy.signal import hilbert, butter, filtfilt
def plv(
data: np.ndarray, sfreq: float, fmin: float, fmax: float
) -> np.ndarray:
"""Pairwise PLV across channels."""
b, a = butter(4, [fmin / (sfreq/2), fmax / (sfreq/2)], btype="bandpass")
filtered = filtfilt(b, a, data, axis=-1)
phases = np.angle(hilbert(filtered, axis=-1))
n_ch = data.shape[0]
plv_mat = np.zeros((n_ch, n_ch), dtype=np.float32)
for i in range(n_ch):
for j in range(i, n_ch):
diff = phases[i] - phases[j]
plv_mat[i, j] = plv_mat[j, i] = float(np.abs(np.mean(np.exp(1j * diff))))
return plv_mat
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_plv(
data_dict: Dict[str, Any], *, fmin: float, fmax: float,
) -> Dict[str, Any]:
"""Phase-locking value pairwise matrix.
Parameters
----------
data_dict : dict
fmin, fmax : float
Narrow band.
Returns
-------
dict — `meta["plv"]: (n_ch, n_ch)`.
Raises
------
EasyBCIOperatorError
recoverable=True for wide-band input or fmax >= Nyquist.
Modality coverage
-----------------
EEG / MEG / sEEG / ECoG / LFP: yes. fNIRS / spike: forbidden.
References
----------
Lachaux et al. 1999.
"""
sfreq = float(data_dict["frequency"])
if fmax >= sfreq / 2 or fmin >= fmax:
raise EasyBCIOperatorError(
operator="plv", reason=f"invalid band fmin={fmin}, fmax={fmax}, sfreq={sfreq}",
recoverable=False,
)
t0 = time.monotonic()
from scipy.signal import hilbert, butter, filtfilt
b, a = butter(4, [fmin / (sfreq/2), fmax / (sfreq/2)], btype="bandpass")
filtered = filtfilt(b, a, data_dict["data"], axis=-1)
phases = np.angle(hilbert(filtered, axis=-1))
n_ch = data_dict["data"].shape[0]
plv_mat = np.zeros((n_ch, n_ch), dtype=np.float32)
for i in range(n_ch):
for j in range(i, n_ch):
diff = phases[i] - phases[j]
plv_mat[i, j] = plv_mat[j, i] = float(np.abs(np.mean(np.exp(1j * diff))))
elapsed = time.monotonic() - t0
out = dict(data_dict)
out["elapsed_s"] = elapsed
out["meta"] = {**out.get("meta", {}), "plv": plv_mat, "plv_band": [fmin, fmax]}
record_step_elapsed("plv", elapsed, (data_dict.get("meta") or {}).get("step_cache_key"))
return out
bci/neural-processing/connectivity_resting/connectivity.md for
paradigm-level guidance.