compute sensor connectivity

Hi,

  • MNE version: 1.0.3
  • operating system: macOS 11.1

Iā€™d like to compute connectivity of some channels and then visualize it.

According to the manual, we can use the ā€˜indicesā€™ parameter of ā€˜mne_connectivity.spectral_connectivity_epochsā€™ to define for which to compute connectivity.
https://mne.tools/mne-connectivity/stable/generated/mne_connectivity.spectral_connectivity_epochs.html#mne_connectivity.spectral_connectivity_epochs

However, if we want to compute connectivity between signals 1, 2, 3, 4 (total of 6 connections), not the connectivity between the signal 1 and signals 2, 3, 4 for example, is it possible to do that with the function, ā€˜mne_connectivity.spectral_connectivity_epochsā€™?
In this case, how should the indices look like?

Iā€™d appreciate any advice, thank you!

indices should be a tuple of two arrays, with each connection defined by ā€œindex 0 from first array <-> index 0 from second arrayā€ etc for each index. So if you want all possible connections between signals 1, 2, 3, and 4, then your tuple would be ([1, 1, 1, 2, 2, 3], [2, 3, 4, 3, 4, 4]). a shortcut to getting something like this is

from itertools import combinations
tuple(zip(*combinations([1,2,3,4], 2)))

or, if you really need the inner elements to be arrays:

tuple([np.array(x) for x in zip(*combinations([1,2,3,4], 2))])
1 Like

Thank you so much for the clarification!
However, Iā€™m not sure what the ā€˜picksā€™ in ā€˜mne_connectivity.viz.plot_sensors_connectivityā€™ then should be when visualizing, so that the number of picked channels can correspond to the size of connectivity data (6).
Below is the simplified one of my actual code. ā€˜epochsā€™ contains 62 channel EEG data.

indices = ([1, 1, 1, 2, 2, 3], [2, 3, 4, 3, 4, 4])
con = spectral_connectivity_epochs(
epochs, method=ā€˜wpli2_debiasedā€™, indices = indices, mode=ā€˜fourierā€™, faverage=True,
fmin = 8, fmax = 15)
plot_sensors_connectivity(epochs.info, con = con)

I think picks would be [1,2,3,4] in that case? But Iā€™m responding from my phone so itā€™s not easy for me to check right now. What have you tried so far? Did it fail?

Thanks for your reply!
I tried picks = [1,2,3,4], but got the following error:
ValueError: The number of channels picked (4) does not correspond to the size of the connectivity data (6)

I also tried
plot_sensors_connectivity(epochs.info, con.get_data(output='dense')[:, :, 0], picks = epochs.ch_names)
but it failed too and the error was
ValueError: zero-size array to reduction operation maximum which has no identity

@adam2392 do you know whatā€™s going on here? I canā€™t even get plot_sensors_connectivity to work without passing indices to spectral_connectivity. MWE:

from itertools import combinations
import os
import numpy as np
import mne
import mne_connectivity as mnecon

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
                                    'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False, preload=False)
raw.crop(tmax=20).load_data()
events = mne.find_events(raw, stim_channel='STI 014')
event_dict = {'auditory/left': 1, 'auditory/right': 2}
epochs = mne.Epochs(raw, events, event_id=event_dict, preload=False,
                    proj=False)

kwargs = dict(method='wpli2_debiased', mode='fourier', faverage=True,
              fmin=8, fmax=15)

# without indices
con1 = mnecon.spectral_connectivity_epochs(epochs, **kwargs)
mnecon.viz.plot_sensors_connectivity(epochs.info, con=con1)
# ValueError: The number of channels picked (364) does not correspond to the
# size of the connectivity data (141376)

# with indices
indices = tuple([np.array(x) for x in zip(*combinations([1,2,3,4], 2))])
con2 = mnecon.spectral_connectivity_epochs(epochs, indices=indices, **kwargs)
mnecon.viz.plot_sensors_connectivity(epochs.info, con=con2)
# ValueError: The number of channels picked (364) does not correspond to the
# size of the connectivity data (6)

I think this is an issue that might be because of our usage of mne-python private functions, but also requires a few bug fixes in mne-connectivity.

First of all, conn.get_data() automatically returns a compact representation, so a PR to add the ā€˜denseā€™ parameter perhaps inside the plot function.

    if isinstance(con, BaseConnectivity):
        con = con.get_data('dense')

Second of all, the error still gets raised.

Traceback (most recent call last):
  File "/Users/adam2392/Documents/mne-connectivity/test.py", line 30, in <module>
    mne_connectivity.viz.plot_sensors_connectivity(epochs.info, con=con1)
  File "/Users/adam2392/Documents/mne-connectivity/mne_connectivity/viz/_3d.py", line 58, in plot_sensors_connectivity
    raise ValueError('The number of channels picked (%s) does not '
ValueError: The number of channels picked (364) does not correspond to the size of the connectivity data (376)

Most likely this is due to the fact that there are 9 stimulus channels and then 2 bad channels, which were not dropped before running connectivity.

Sorry I donā€™t have time to figure out how to bug fix this further, but a PR to adjust the plotting functions to return ā€˜denseā€™ would be great and then I think just be mindful of dropping irrelevant channels before running analysis.

I think ideally we might have some internal private functions that can be called to check for non-data channels(?)

1 Like