Hi,
EDIT: I clarified some details below and added system info at the end
I am running RSA analysis on MEG data combined across sensors (MAG, GRAD and EEG). I tried to whiten the epoched data before applying RSA and I noticed that there’s a difference in scale between the three sensor types evan after whitening.
Here I show data from a single participant from my dataset. All epochs are lumped together after whitening, separately for each sensor type. The y-axis scales are shared across plots. X-axis is time in milliseconds, 0 is stimulus onset. There is about an order of magnitude difference in variance between plots.
I adapted the code in mne.cov.whiten_evoked
(line 2288-2292 in mne-python/mne/cov.py
) to do the whitening
# Compute covariance
noise_covs = compute_covariance(
epochs['(epoch == "written")'],
tmin=None,
tmax=0,
method=['shrunk', 'empirical', 'ledoit_wolf'],
return_estimators=True,
n_jobs=None,
projs=None,
rank='info',
verbose=True,
)
# Compute whitener
W, _ = compute_whitener(noise_covs[0],
epochs.info,
picks=picks_to_idx(epochs.info, picks))
# Apply whitener
data = epochs[cond_query].get_data(picks=picks_to_idx(epochs.info, picks))
data = (np.dot(data.swapaxes(1, 2), W)).swapaxes(1, 2)
Talking to @olafhauk about this he pointed me to this tutorial on plotting whitened data. It seems that there is also a difference in scale between sensors in the epoched data after whitening (see the output ofepochs.plot(noise_cov=noise_cov, events=True)
in the tutorial). This scale difference seems to disappear if the evoked data are whitened (see the output of evoked.plot(noise_cov=noise_cov, time_unit="s")
in the tutorial). So all in all, this seems to be a general phenomenon, not just in my data.
I also noticed that in the documentation of Epochs.plot
, under the noise_cov parameter, it says: “For data processed with SSS, the effective dependence between magnetometers and gradiometers may introduce differences in scaling, consider using mne.Evoked.plot_white()
”. This could be the reason of seeing scale differences, or could there be anything else? I don’t understand what “the effective dependence between magnetometers and gradiometers” means.
In theory whitening should bring the different sensor types to the same scale, so I wouuld be hesitant to apply another normalization step (i.e., something like StandardScaler from scikit-learn). Is there a way of fixing this so that the epoched data are on the same scale after whitening? I need epoched, not evoked data because the RSA analysis.
I’m pinging @Denis and @agramfort, I hope you don’t mind, as you are the authors of the original paper on covariance estimation and whitening based on which this is implemented (Engemann & Gramfort 2015).
Many thanks,
Máté
System info:
Platform Linux-3.10.0-1160.el7.x86_64-x86_64-with-glibc2.17
Python 3.11.6 | packaged by conda-forge | (main, Oct 3 2023, 10:40:35) [GCC 12.3.0]
Executable /home/ma09/.conda/envs/my_mne1.5/bin/python
CPU x86_64 (32 cores)
Memory 251.4 GB
Core
├☑ mne 1.5.1
├☑ numpy 1.24.4 (OpenBLAS 0.3.24 with 32 threads)
├☑ scipy 1.11.3
├☑ matplotlib 3.8.0 (backend=module://matplotlib_inline.backend_inline)
├☑ pooch 1.7.0
└☑ jinja2 3.1.2
Numerical (optional)
├☑ sklearn 1.3.1
├☑ numba 0.57.1
├☑ nibabel 5.1.0
├☑ nilearn 0.10.2
├☑ dipy 1.7.0
├☑ openmeeg 2.5.6
├☑ pandas 2.1.1
└☐ unavailable cupy
Visualization (optional)
├☑ pyvista 0.42.2 (OpenGL unavailable)
├☑ pyvistaqt 0.0.0
├☑ vtk 9.2.6
├☑ qtpy 2.4.0 (None=None)
├☑ pyqtgraph 0.13.3
├☑ mne-qt-browser 0.5.2
├☑ ipywidgets 8.1.1
├☑ trame_client 2.12.4
├☑ trame_server 2.12.0
├☑ trame_vtk 2.5.8
├☑ trame_vuetify 2.3.1
└☐ unavailable ipympl
Ecosystem (optional)
├☑ mne-bids 0.14.dev0
├☑ mne-bids-pipeline 1.5.0.dev27+g754c85f
└☐ unavailable mne-nirs, mne-features, mne-connectivity, mne-icalabel