The coherence values I obtain using spectral_connectivity don't make sense to me.

  • MNE-Python version: 0.24
  • operating system: Mac 11.6.1

I’m trying to familiarize myself with the various EEG functional connectivity measures that can be computed using spectral_connectivity in mne.connectivity. For a simple example, I considered 10 seconds of EEG data with sampling frequency 200 Hz and restricted myself to just 5 channels. The result is stored in a data matrix, data, which has dimensions 5-by-2000.

From there I proceeded as follows:

data_win=np.expand_dims(data, axis=0) #has shape 1-by-5-2000
fmin=(.5,4,8,12) 
fmax=(4,8,12,30)

S,freqs,times,n_epochs,n_tapers=spectral_connectivity(data_win,sfreq=200, method='coh', mode='fourier', fmin=fmin, fmax=fmax, faverage=True )

The size of S is 5-by-5-by-4, which makes sense since I have 5 channels and am averaging over four frequency bands. However, none of the matrices S[:,:,0], S[:,:,1], …S[:,:,3] are symmetric and none have one’s along the diagonal as I would expect. In fact, all four matrices are the same, indeed lower triangular with one’s below the diagonal and zeros everywhere else.

Am I overlooking something important with regard to the command syntax or is there a basic principal I’m failing to realize? Results I obtained using the connectivipy package made perfectly good sense to me.

Update: Wasn’t sure whether or not to post this as a reply. When I change mode='fourier' to mode='multitaper' , I obtain results that make a bit more sense. For example, S[:,:,0] corresponds to coherence values averaged over the band .5 to 4 Hz. The output for this matrix, rounded to two decimal, places is given by

[[0.   0.   0.   0.   0.  ]
 [0.97 0.   0.   0.   0.  ]
 [0.91 0.81 0.   0.   0.  ]
 [0.92 0.96 0.78 0.   0.  ]
 [0.54 0.6  0.55 0.68 0.  ]]

Of course, if these nonzero entries are correct, I can fill in the remaining entries by setting diagonal entries equal to 1 and utilizing the fact that the matrix must be symmetric. But it’s not clear why spectral_connectivity doesn’t do that for me automatically.

I now see that the function performs as expected. As it states in the function’s documentation, “By default, the connectivity between all signals is computed (only connections corresponding to the lower-triangular part of the connectivity matrix).” A simple way I found to get the remaining entries of the matrix, S is to use np.fill_diagonal(S, 1)
followed by S=S + S.T - np.diag(S.diagonal())

The moderator may wish to remove my original question given that the answer was easily discovered in the documentation.