Analyses
PSD, intra- and inter-brain measures functions
| Option | Description |
|---|---|
| title | analyses.py |
| authors | Phoebe Chen, Florence Brun, Guillaume Dumas |
| date | 2020-03-18 |
behav_corr(data, behav, data_name, behav_name, p_thresh, multiple_corr=True, verbose=False)
Correlates neural data with behavioral parameters using appropriate linear correlation methods.
This function first checks for data normality, then applies either Pearson's or Spearman's correlation. For connectivity data, it can apply multiple comparison correction.
Parameters
data : np.ndarray Data to correlate with behavior. Can be either: - 1D array of values (same shape as behav) - 3D array of connectivity values with shape (n_dyads, n_channels, n_channels)
np.ndarray
1D array of behavioral values (e.g., timing, performance scores)
str
Description of the data (used for plot labeling if verbose=True)
str
Description of the behavioral parameter (used for plot labeling if verbose=True)
float
Significance threshold for correlation tests (typically 0.05)
bool, optional
Whether to apply multiple comparison correction (default=True). Uses the FDR-BH method when True.
bool, optional
Whether to generate visualization of the correlation (default=False)
Returns
corr_tuple : namedtuple A named tuple containing: - r: correlation coefficient(s) - For 1D data: a single float - For connectivity data: array of shape (n_channels, n_channels) - pvalue: p-value(s) (original or corrected if multiple_corr=True) - strat: string indicating which strategy was used ('normal', 'non_normal', or information about multiple comparison correction)
Notes
When correlating connectivity matrices with behavioral data, only the significant correlations are returned in the r matrix, with non-significant values set to zero.
Examples
Correlating average alpha power with reaction times
result = behav_corr(alpha_power, reaction_times, 'Alpha Power', 'RT (ms)', 0.05) r_value = result.r p_value = result.pvalue
compute_conn_mvar(complex_signal, mvar_params, ica_params, measure_params, check_stability=True)
Computes connectivity measures based on multivariate autoregressive (MVAR) modeling.
This function fits MVAR models to the data and computes directed connectivity measures based on those models, with optional ICA for source separation.
Parameters
complex_signal : np.ndarray Complex analytic signals with shape (2, n_epochs, n_channels, n_freq_bins, n_times)
dict
Dictionary of MVAR model parameters with keys: - 'mvar_order': int, order of the MVAR model - 'fitting_method': str, method for fitting the MVAR model - 'delta': float, regularization parameter
dict
Dictionary of ICA parameters with keys: - 'method': str, ICA algorithm to use - 'random_state': int, random seed for reproducibility
dict
Dictionary defining the connectivity measure to compute with keys: - 'name': str, name of the connectivity measure (e.g., 'PDC', 'DTF') - 'n_fft': int, number of FFT points
bool, optional
Whether to verify the stability of the MVAR model (default=True) If True, the function will check if the model is stable and prompt for continuation or epoch merging if necessary.
Returns
connectivity : np.ndarray Connectivity measure matrix with shape: (n_epochs, n_freq, n_channels, n_channels, n_fft) or (1, n_freq, n_channels, n_channels, n_fft) if epochs are merged
Notes
MVAR-based connectivity measures provide information about directed (causal) relationships between signals, unlike most of the other connectivity metrics implemented in this module.
The function relies on the MVARICA approach: 1. Apply ICA to separate independent sources 2. Fit an MVAR model to the sources 3. Compute connectivity measures in the source space 4. Back-project to the original signal space
For stability, the number of time samples should be substantially larger than: mvar_order × n_channels^2
Warnings
This function is computationally intensive, especially for high model orders and large numbers of channels.
If the MVAR model is unstable, the function will offer to merge epochs to increase the sample size for more stable estimation.
References
Baccalá, L. A., & Sameshima, K. (2001). Partial directed coherence: a new concept in neural structure determination. Biological cybernetics, 84(6), 463-474.
Examples
mvar_params = {'mvar_order': 5, 'fitting_method': 'least_squares', 'delta': 0.0} ica_params = {'method': 'extended-infomax', 'random_state': 42} measure_params = {'name': 'PDC', 'n_fft': 512} conn = compute_conn_mvar(complex_signal, mvar_params, ica_params, measure_params)
compute_freq_bands(data, sampling_rate, freq_bands, filter_signal=True, **filter_options)
Computes analytic signals for specified frequency bands using FIR filtering and Hilbert transform.
This function performs bandpass filtering for each defined frequency band, then applies the Hilbert transform to obtain complex-valued analytic signals.
Parameters
data : np.ndarray EEG data from two participants with shape (2, n_epochs, n_channels, n_times)
int
Sampling rate of the EEG data in Hz
dict
Dictionary defining frequency bands: {'band_name': [fmin, fmax], ...} e.g., {'alpha': [8, 12], 'beta': [12, 20]}
bool, optional
Whether to apply bandpass filtering (default=True) If False, the Hilbert transform is applied directly to the input signals
**filter_options Additional arguments for mne.filter.filter_data, such as: - filter_length: Length of the FIR filter in samples or 's' for seconds - l_trans_bandwidth: Width of the transition band at the low cut-off frequency - h_trans_bandwidth: Width of the transition band at the high cut-off frequency
Returns
complex_signal : np.ndarray Complex-valued analytic signals with shape: (2, n_epochs, n_channels, n_freq_bands, n_times) where n_freq_bands corresponds to the number of frequency bands in freq_bands
Notes
Unlike compute_single_freq which uses the multitaper method, this function: 1. Applies a bandpass filter to isolate the specified frequency band 2. Uses the Hilbert transform to compute the analytic signal
This approach may be computationally more efficient when analyzing broader frequency bands rather than individual frequencies.
The order of frequency bands in the output corresponds to their order in the freq_bands dictionary.
Examples
bands = {'theta': [4, 8], 'alpha': [8, 13], 'beta': [13, 30]} complex_signals = compute_freq_bands(data, 256, bands, ... filter_length='auto', l_trans_bandwidth=1)
compute_nmPLV(data, sampling_rate, freq_range1, freq_range2, **filter_options)
Computes n:m Phase-Locking Value for cross-frequency coupling between participants.
This function calculates the phase synchronization between two participants when their brain oscillations operate at different frequency ranges with an integer ratio relationship (n:m).
Parameters
data : np.ndarray EEG data from two participants with shape (2, n_epochs, n_channels, n_times)
int
Sampling rate of the EEG data in Hz
List[float]
Frequency range [fmin, fmax] for participant 1
List[float]
Frequency range [fmin, fmax] for participant 2
**filter_options Additional arguments for the underlying filtering functions
Returns
con : np.ndarray n:m PLV connectivity matrix with shape (n_freq, 2n_channels, 2n_channels)
Notes
n:m Phase Locking Value measures synchronization between oscillations at different frequencies when there exists an n:m ratio between them. For example, if participant 1 shows activity at 10 Hz and participant 2 at 20 Hz, this would be a 1:2 relationship.
The function: 1. Computes the ratio between the mean frequencies of the two ranges 2. Applies appropriate phase multiplication to account for the frequency ratio 3. Calculates the phase locking value between the adjusted phases
This measure is useful for studying cross-frequency coupling between brains, where different participants might exhibit coordination at different frequency bands.
References
Palva, J. M., Palva, S., & Kaila, K. (2005). Phase synchrony among neuronal oscillations in the human cortex. Journal of Neuroscience, 25(15), 3962-3972.
Examples
Computing 1:2 PLV between alpha (participant 1) and beta (participant 2)
nm_plv = compute_nmPLV(data, sampling_rate=256, ... freq_range1=[8, 12], freq_range2=[16, 24])
compute_single_freq(data, sampling_rate, freq_range)
Computes analytic signals for each frequency in the specified range using multitaper method.
This function calculates complex-valued time-frequency representations for each integer frequency in the given range.
Parameters
data : np.ndarray EEG data from two participants with shape (2, n_epochs, n_channels, n_times)
int
Sampling rate of the EEG data in Hz
List[float]
A list [fmin, fmax] specifying the frequency range to analyze. Every integer frequency from fmin to fmax will be included.
Returns
complex_signal : np.ndarray Complex-valued analytic signals with shape: (2, n_epochs, n_channels, n_tapers, n_frequencies, n_times)
Notes
This function uses MNE's implementation of the multitaper method with 4 cycles per frequency, which provides a good balance between time and frequency resolution.
Time-frequency decomposition is calculated for each participant separately.
Examples
complex_tf = compute_single_freq(data, sampling_rate=256, freq_range=[8, 30]) print(f"Shape: {complex_tf.shape}") # (2, n_epochs, n_channels, n_tapers, 23, n_times)
compute_sync(complex_signal, mode, epochs_average=True)
Computes frequency-domain connectivity measures from analytic signals.
This function calculates various connectivity metrics between all possible channel pairs based on the input complex-valued signals.
Parameters
complex_signal : np.ndarray Complex analytic signals with shape (2, n_epochs, n_channels, n_freq_bins, n_times)
str
Connectivity measure to compute. Options: - 'envelope_corr': envelope correlation - correlation between signal envelopes - 'pow_corr': power correlation - correlation between signal power - 'plv': phase locking value - consistency of phase differences - 'ccorr': circular correlation coefficient - circular statistic for phase coupling - 'coh': coherence - normalized cross-spectrum - 'imaginary_coh': imaginary coherence - imaginary part of coherence (volume conduction resistant) - 'pli': phase lag index - asymmetry of phase difference distribution - 'wpli': weighted phase lag index - weighted version of PLI with improved properties
bool, optional
If True, connectivity values are averaged across epochs (default) If False, epoch-by-epoch connectivity is preserved
Returns
con : np.ndarray Connectivity matrix with shape: - If epochs_average=True: (n_freq, 2n_channels, 2n_channels) - If epochs_average=False: (n_freq, n_epochs, 2n_channels, 2n_channels)
Notes
Mathematical formulations for each connectivity measure:
-
PLV: |⟨e^(i(φₓ-φᵧ))⟩| Measures consistency of phase differences across time
-
Envelope correlation: corr(env(x), env(y)) Pearson correlation between signal envelopes
-
Coherence: |⟨XY*⟩|²/(⟨|X|²⟩⟨|Y|²⟩) Normalized cross-spectrum
-
Imaginary coherence: |Im(⟨XY*⟩)|/√(⟨|X|²⟩⟨|Y|²⟩) Takes only imaginary part which is less affected by volume conduction
-
PLI: |⟨sign(Im(XY*))⟩| Quantifies asymmetry in phase difference distribution
-
wPLI: |⟨|Im(XY)|sign(Im(XY))⟩|/⟨|Im(XY*)|⟩ Weighted version that downweights phase differences near 0 or π
Raises
ValueError If an unsupported connectivity metric is specified
indices_connectivity_interbrain(epoch_hyper)
Computes indices for interbrain connectivity analysis between EEG channels of two participants.
This function generates all possible pairs of channel indices where the first channel belongs to participant 1 and the second to participant 2, based on a merged epochs object.
Parameters
epoch_hyper : mne.Epochs A merged Epochs object containing data from both participants, with channels ordered such that the first half belongs to participant 1 and the second half to participant 2.
Returns
channels : List[Tuple[int, int]] List of tuples, each containing a pair of channel indices (i, j) where: - i is an index of a channel from participant 1 (in range 0 to n_channels/2 - 1) - j is an index of a channel from participant 2 (in range n_channels/2 to n_channels - 1)
Notes
This function assumes that the channels in epoch_hyper are organized as: [participant1_ch1, ..., participant1_chN, participant2_ch1, ..., participant2_chN]
EOG channels are automatically excluded before generating the pairs.
Examples
interbrain_pairs = indices_connectivity_interbrain(merged_epochs) print(f"Number of interbrain channel pairs: {len(interbrain_pairs)}")
indices_connectivity_intrabrain(epochs)
Computes indices for intrabrain connectivity analysis between all EEG channels.
This function generates all possible pairs of EEG channel indices for a single participant, excluding EOG channels.
Parameters
epochs : mne.Epochs A participant's Epochs object containing channel information
Returns
channels : List[Tuple[int, int]] List of tuples, each containing a pair of channel indices (i, j) where i < j. These indices correspond to all possible pairs of EEG channels for the participant.
Notes
This function automatically removes EOG channels before generating the pairs. The resulting indices can be used as input for connectivity analyses within a single brain.
Examples
channel_pairs = indices_connectivity_intrabrain(participant_epochs) print(f"Number of channel pairs: {len(channel_pairs)}")
pair_connectivity(data, sampling_rate, frequencies, mode, epochs_average=True)
Computes frequency-domain connectivity measures between two participants.
This function is a high-level interface that processes EEG data, computes analytic signals, and calculates connectivity metrics between all possible channel pairs.
Parameters
data : Union[list, np.ndarray] EEG data from two participants with shape (2, n_epochs, n_channels, n_times)
int
Sampling rate of the EEG data in Hz
Union[dict, list]
Specification of frequency bands of interest: - If dict: {'band_name': [fmin, fmax], ...} defining frequency bands e.g., {'alpha': [8, 12], 'beta': [12, 20]} - If list: [fmin, fmax] for each integer frequency in the range e.g., [5, 30] for all integer frequencies from 5 to 30 Hz
str
Connectivity measure to compute. Options: - 'envelope_corr': envelope correlation - 'pow_corr': power correlation - 'plv': phase locking value - 'ccorr': circular correlation coefficient - 'coh': coherence - 'imaginary_coh': imaginary coherence - 'pli': phase lag index - 'wpli': weighted phase lag index
bool, optional
If True, connectivity values are averaged across epochs (default) If False, epoch-by-epoch connectivity is preserved
Returns
result : np.ndarray Connectivity matrix with shape: - If epochs_average=True: (n_freq, 2n_channels, 2n_channels) - If epochs_average=False: (n_freq, n_epochs, 2n_channels, 2n_channels)
The channels are ordered as:
[participant1_ch1, ..., participant1_chN, participant2_ch1, ..., participant2_chN]
To extract only interbrain connectivity values, slice the last two dimensions:
result[:, :, 0:n_channels, n_channels:2*n_channels]
Notes
This function handles the complete process from raw EEG data to connectivity metrics: 1. Computes analytic signals for the specified frequencies 2. Applies the selected connectivity measure
Each connectivity metric has different mathematical properties and interpretations: - PLV measures consistency in phase differences regardless of amplitude - Coherence measures linear relationship between signals in frequency domain - Imaginary coherence is less susceptible to volume conduction - PLI and wPLI are robust against common sources and amplitude effects
Time complexity scales with O(n_channels^2 × n_epochs × n_frequencies × n_times)
Examples
Computing alpha band PLV
alpha_plv = pair_connectivity( ... [subj1_data, subj2_data], ... sampling_rate=256, ... frequencies={'alpha': [8, 12]}, ... mode='plv' ... )
pow(epochs, fmin, fmax, n_fft, n_per_seg, epochs_average)
Computes the Power Spectral Density (PSD) on Epochs using Welch's method.
This function calculates the power spectrum for each channel across the specified frequency range. EOG channels are automatically dropped before computation.
Parameters
epochs : mne.Epochs A participant's Epochs object containing EEG data of shape (n_epochs, n_channels, n_times).
float
Minimum frequency in Hz to include in PSD calculation.
float
Maximum frequency in Hz to include in PSD calculation.
int
Length of FFT used. Must be >= n_per_seg. If larger, the segments will be zero-padded. If n_per_seg is None, n_fft must be <= number of time points.
int or None
Length of each Welch segment (windowed with a Hamming window). If None, n_per_seg is set equal to n_fft.
bool
If True, PSD values are averaged over epochs. If False, PSD won't be averaged (the time course is maintained).
Returns
psd_tuple : namedtuple A named tuple containing: - freq_list: ndarray of frequencies (frequency bins) in Hz - psd: ndarray of PSD values with shape: - If epochs_average=True: (n_channels, n_frequencies) - If epochs_average=False: (n_epochs, n_channels, n_frequencies)
Notes
This function can be iterated on groups and/or conditions: (for epochs in epochs['epochs_%s_%s_%s' % (subj, group, cond_name)]).
The PSD values are computed using Welch's method with Hamming windows and expressed in µV²/Hz.
Examples
from mne import Epochs result = pow(epochs, fmin=1, fmax=40, n_fft=512, n_per_seg=256, epochs_average=True) frequencies = result.freq_list power_values = result.psd
xwt(sig1, sig2, freqs, n_cycles=5.0, mode='xwt')
Performs cross-wavelet transform or wavelet coherence analysis between two signals.
This function computes time-frequency representations of two signals and their cross-spectrum using continuous wavelet transform.
Parameters
sig1 : mne.Epochs EEG data of first participant
mne.Epochs
EEG data of second participant
Union[int, np.ndarray]
Frequencies of interest in Hz
float, optional
Number of cycles in the Morlet wavelet (default=5.0) Controls the time-frequency resolution trade-off
str, optional
Type of analysis to perform (default="xwt"). Options: - 'power': absolute value of cross-wavelet transform - 'phase': phase angles of cross-wavelet transform - 'xwt': raw cross-wavelet transform (complex-valued) - 'wtc': wavelet coherence
Returns
data : np.ndarray Result of the wavelet analysis with shape: (n_chans1, n_chans2, n_epochs, n_freqs, n_samples)
Notes
This function provides different types of wavelet-based analyses:
-
Cross-wavelet transform (XWT): Reveals common power and relative phase between two time series in time-frequency space
-
Wavelet coherence (WTC): Measures the correlation between two signals in the time-frequency domain normalized between 0 and 1
Unlike Fourier-based methods, wavelet analysis maintains time resolution, allowing for the study of non-stationary signals and transient relationships.
The function automatically checks that both signals have the same sampling rate, number of epochs, channels, and samples.
References
Grinsted, A., Moore, J. C., & Jevrejeva, S. (2004). Application of the cross wavelet transform and wavelet coherence to geophysical time series. Nonlinear processes in geophysics, 11(5/6), 561-566.
Maraun, D., & Kurths, J. (2004). Cross wavelet analysis: significance testing and pitfalls. Nonlinear Processes in Geophysics, 11(4), 505-514.
Examples
Computing wavelet coherence between two EEG signals
coherence = xwt(subj1_epochs, subj2_epochs, freqs=np.arange(4, 40, 1), ... n_cycles=7, mode='wtc')