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