بنقرة واحدة
plv
Phase-Locking Value — pairwise phase synchrony (Lachaux 1999)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Phase-Locking Value — pairwise phase synchrony (Lachaux 1999)
التثبيت باستخدام 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 | 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.