Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSOC] Add decomposition plotting #208

Merged
merged 52 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
2fa5aca
Add filter storage
tsbinns May 28, 2024
6e206ce
Merge branch 'mne-tools:main' into decoding
tsbinns May 28, 2024
68a0890
Refactor results reshaping
tsbinns May 29, 2024
0368367
Fix filter indexing for storage
tsbinns May 29, 2024
bb75cb1
Update fill_doc dictionary
tsbinns May 29, 2024
115757c
Add n_components to ingored numpydoc words
tsbinns May 29, 2024
e7c9da9
Add decoding module
tsbinns May 29, 2024
5e51923
Update API with decoding module
tsbinns May 29, 2024
9fe0f28
Rename file and add suport for cwt_morlet mode
tsbinns May 29, 2024
6302a4d
Merge branch 'main' into decoding
tsbinns May 30, 2024
fa6a001
Make property docstrings private
tsbinns Jun 3, 2024
15e99e4
Bug fix error check
tsbinns Jun 3, 2024
58eca90
Bug fix fit_transform no return
tsbinns Jun 3, 2024
9b43dfb
Bug fix _check_X 2d array
tsbinns Jun 3, 2024
bb0b520
Add preliminary decomp example
tsbinns Jun 3, 2024
cdc7ce4
Merge branch 'main' into decoding
tsbinns Jun 3, 2024
8cd98e1
Merge branch 'main' into decoding
tsbinns Jun 5, 2024
a3bf253
Switch to cleaner epoch indexing
tsbinns Jun 5, 2024
ea48ce3
Fix spelling error
tsbinns Jun 5, 2024
9bcff58
Update error checking
tsbinns Jun 5, 2024
17cfeab
Merge branch 'decoding' of https://github.com/tsbinns/mne-connectivit…
tsbinns Jun 5, 2024
6c8ae97
Bug fix indices setter wrong format
tsbinns Jun 6, 2024
55b14ab
Add unit tests
tsbinns Jun 6, 2024
3861da5
Update example from review
tsbinns Jun 6, 2024
025e6c1
Update cwt_morlet params
tsbinns Jun 6, 2024
cbfcc13
Fix platform-specific failing unit test
tsbinns Jun 6, 2024
8339d40
Refactor decomposition classes
tsbinns Jun 6, 2024
bdfb626
Add test reminder
tsbinns Jun 10, 2024
a0e9560
Add decomposition plotting
tsbinns Jun 10, 2024
840f4f6
Update tests and fix getter/setters
tsbinns Jun 12, 2024
f9bc90f
Merge branch 'main' into decoding
tsbinns Jun 12, 2024
d1b35cf
Merge branch 'main' into decoding
tsbinns Jun 12, 2024
8afa1b0
Merge remote-tracking branch 'upstream/main' into decoding
tsbinns Jun 12, 2024
b8b57bb
Switch from matmul to at
tsbinns Jun 12, 2024
8cde3a6
Merge branch 'decoding' into decoding_plotting
tsbinns Jun 12, 2024
88eafb5
Shorten tests with kwargs
tsbinns Jun 13, 2024
19931fd
Merge branch 'decoding' into decoding_plotting
tsbinns Jun 13, 2024
163d802
Add decomp class to main init
tsbinns Jun 13, 2024
865fa67
Update plotting docstrings
tsbinns Jun 13, 2024
ccdad63
Add docs authorship
tsbinns Jun 13, 2024
c026d3e
Archive old example
tsbinns Jun 19, 2024
ad35318
Merge remote-tracking branch 'upstream/main' into decoding_plotting
tsbinns Jun 19, 2024
03186a0
Update decomp example formatting
tsbinns Jun 20, 2024
1314cb4
Add decomp plotting example
tsbinns Jun 20, 2024
0a3f7ac
Update epochs_multivar formatting and docs
tsbinns Jun 20, 2024
20af749
Merge branch 'main' into decoding_plotting
tsbinns Jun 25, 2024
ad5db63
Update docstring
tsbinns Jun 26, 2024
ee1c109
Update plotting
tsbinns Jun 26, 2024
7709a32
Update plotting example
tsbinns Jun 26, 2024
6719f41
Merge branch 'main' into decoding_plotting
tsbinns Jul 2, 2024
aed3675
Add link to ft example
tsbinns Jul 2, 2024
f5fa4f4
Merge branch 'decoding_plotting' of https://github.com/tsbinns/mne-co…
tsbinns Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
"n_estimated_nodes",
"n_samples",
"n_channels",
"n_patterns",
"n_filters",
"Renderer",
"n_ytimes",
"n_ychannels",
Expand Down
42 changes: 27 additions & 15 deletions examples/decoding/cohy_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Multivariate decomposition for efficient connectivity analysis
==============================================================

This example demonstrates how the tools in the decoding module can be used to
decompose data into the most relevant components of connectivity and used for
a computationally efficient multivariate analysis of connectivity, such as in
brain-computer interface (BCI) applications.
This example demonstrates how the tools in the decoding module can be used to decompose
data into the most relevant components of connectivity and used for a computationally
efficient multivariate analysis of connectivity, such as in brain-computer interface
(BCI) applications.
"""

# Author: Thomas S. Binns <[email protected]>
Expand All @@ -21,23 +21,22 @@
from matplotlib import pyplot as plt

from mne_connectivity import (
CoherencyDecomposition,
make_signals_in_freq_bands,
seed_target_indices,
spectral_connectivity_epochs,
)
from mne_connectivity.decoding import CoherencyDecomposition

########################################################################################
# Background
# ----------
#
# Multivariate forms of signal analysis allow you to simultaneously consider
# the activity of multiple signals. In the case of connectivity, the
# interaction between multiple sensors can be analysed at once and the strongest
# components of this interaction captured in a lower-dimensional set of connectivity
# spectra. This approach brings not only practical benefits (e.g. easier
# interpretability of results from the dimensionality reduction), but can also offer
# methodological improvements (e.g. enhanced signal-to-noise ratio and reduced bias).
# Multivariate forms of signal analysis allow you to simultaneously consider the
# activity of multiple signals. In the case of connectivity, the interaction between
# multiple sensors can be analysed at once and the strongest components of this
# interaction captured in a lower-dimensional set of connectivity spectra. This approach
# brings not only practical benefits (e.g. easier interpretability of results from the
# dimensionality reduction), but can also offer methodological improvements (e.g.
# enhanced signal-to-noise ratio and reduced bias).
#
# Coherency-based methods are popular approaches for analysing connectivity, capturing
# correlations between signals in the frequency domain. Various coherency-based
Expand Down Expand Up @@ -244,8 +243,7 @@
# connectivity is present. This problem can be mitigated by fitting filters to only
# those frequencies where you expect connectivity to be present, e.g. as is done with
# the decomposition class.

########################################################################################
#
# In addition to assessing the validity of the approach, we can also look at the time
# taken to run the analysis. Doing so, we see that the decomposition class is much
# faster than the ``spectral_connectivity_...()`` functions, thanks to the fact that the
Expand Down Expand Up @@ -550,6 +548,20 @@
# Ultimately, there are distinct advantages and disadvantages to both approaches, and
# one may be more suitable than the other depending on your use case.

########################################################################################
# Visualising spatial contributions to connectivity
# -------------------------------------------------
# In addition to the lower-dimensional representation of connectivity, we can also
# extract information about the spatial distributions of connectivity over channels.
# This information is captured in the spatial patterns, derived from the spatial
# filters :footcite:`HaufeEtAl2014`.
#
# The patterns (and filters) can be visualised as topomaps using the
# :meth:`~mne_connectivity.decoding.CoherencyDecomposition.plot_patterns` and
# :meth:`~mne_connectivity.decoding.CoherencyDecomposition.plot_filters` methods of the
# :class:`~mne_connectivity.decoding.CoherencyDecomposition` class, discussed in more
# detail in :doc:`cohy_decomposition_plotting`.

########################################################################################
# References
# ----------
Expand Down
172 changes: 172 additions & 0 deletions examples/decoding/cohy_decomposition_plotting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
"""
==============================================================
Visualising spatial contributions to multivariate connectivity
==============================================================

This example demonstrates how the spatial filters and patterns of connectivity obtained
from the decomposition tools in the decoding module can be visualised and interpreted.
"""

# Author: Thomas S. Binns <[email protected]>
# License: BSD (3-clause)

# %%

import mne
from mne import make_fixed_length_epochs
from mne.datasets.fieldtrip_cmc import data_path

from mne_connectivity import CoherencyDecomposition

########################################################################################
# Background
# ----------
# Multivariate forms of signal analysis allow you to simultaneously consider the
# activity of multiple signals. In the case of connectivity, the interaction between
# multiple sensors can be analysed at once and the strongest components of this
# interaction captured in a lower-dimensional set of connectivity spectra. This approach
# brings not only practical benefits (e.g. easier interpretability of results from the
# dimensionality reduction), but can also offer methodological improvements (e.g.
# enhanced signal-to-noise ratio and reduced bias).
#
# Coherency-based methods are popular approaches for analysing connectivity, capturing
# correlations between signals in the frequency domain. Various coherency-based
# multivariate methods exist, including: canonical coherency (CaCoh; multivariate
# measure of coherency/coherence) :footcite:`VidaurreEtAl2019`; and maximised imaginary
# coherency (MIC; multivariate measure of the imaginary part of coherency)
# :footcite:`EwaldEtAl2012`.
#
# These methods are described in detail in the following examples:
# - comparison of coherency-based methods - :doc:`../compare_coherency_methods`
# - CaCoh - :doc:`../cacoh`
# - MIC - :doc:`../mic_mim`
#
# The CaCoh and MIC methods work by finding spatial filters that decompose the data into
# components of connectivity, and applying them to the data. Connectivity can then be
# computed on this transformed data (see :doc:`cohy_decomposition` for more
# information).
#
# However, in addition to the connectivity scores, useful insights about the data can be
# gained by visualising the topographies of the spatial filters and their corresponding
# spatial patterns. These provide important information about the spatial distributions
# of connectivity information, and represent two complementary aspects:
#
# - The filters represent how the connectivity sources are extracted from the channel
# data, akin to an inverse model.
# - The patterns represent how the channel data is formed by the connectivity sources,
# akin to a forward model.
#
# This distinction is discussed further in Haufe *et al.* (2014)
# :footcite:`HaufeEtAl2014`, but in short: **the patterns should be used to interpret
# the contribution of distinct brain regions/sensors to a given component of
# connectivity**. Accordingly, keep in mind that the filters and patterns are not a
# replacement for source reconstruction, as without this the patterns will still only
# tell you about the spatial contributions of sensors, not underlying brain regions,
# to connectivity.

########################################################################################
# Generating the filters and patterns
# -----------------------------------
# We will first load some example MEG data collected during a hand movement task, which
# we will generate the spatial filters and patterns for (see
# `here <https://www.fieldtriptoolbox.org/tutorial/coherence/>`_ for more information on
# the data). We divide the data into continuous epochs.

# %%

# Load example MEG data
raw = mne.io.read_raw_ctf(data_path() / "SubjectCMC.ds")
raw.pick("mag")
raw.crop(50.0, 110.0).load_data()
raw.notch_filter(50)
raw.resample(100)

# Create epochs
epochs = make_fixed_length_epochs(raw, duration=2.0).load_data()

########################################################################################
# We designate the left hemisphere sensors as the seeds and the right hemisphere sensors
# as the targets. Since this is sensor-space data, we will use the MIC method to analyse
# connectivity, given its resilience to zero time-lag interactions (see
# :doc:`../compare_coherency_methods` for more information).

# %%

# Left hemisphere sensors
seeds = [idx for idx, ch_info in enumerate(epochs.info["chs"]) if ch_info["loc"][0] < 0]

# Right hemisphere sensors
targets = [
idx for idx, ch_info in enumerate(epochs.info["chs"]) if ch_info["loc"][0] > 0
]

# Define indices
indices = (seeds, targets)

########################################################################################
# To fit the filters (and in turn compute the corresponding patterns), we instantiate
# the :class:`~mne_connectivity.decoding.CoherencyDecomposition` object and call the
# :meth:`~mne_connectivity.decoding.CoherencyDecomposition.fit` method. We also define
# our connectivity frequency band of interest to be 20-30 Hz. See
# :doc:`cohy_decomposition` for more information.

# %%

# Instantiate decomposition object
mic = CoherencyDecomposition(
info=epochs.info,
method="mic",
indices=indices,
mode="multitaper",
fmin=20,
fmax=30,
rank=(3, 3),
)

# Fit filters & generate patterns
mic.fit(epochs.get_data())

########################################################################################
# Visualising the patterns
# ------------------------
# Visualising the patterns as topomaps can be done using the
# :meth:`~mne_connectivity.decoding.CoherencyDecomposition.plot_patterns` method.
#
# When interpreting patterns, note that the absolute value reflects the strength of the
# contribution to connectivity, and that the sign differences can be used to visualise
# the orientation of the underlying dipole sources. The spatial patterns are **not**
# bound between :math:`[-1, 1]`.
#
# Plotting the patterns for 20-30 Hz connectivity below, we find the strongest
# connectivity between the left and right hemispheres comes from centromedial left and
# frontolateral right sensors, based on the areas with the largest absolute values. As
# these patterns come from decomposition on sensor-space data, we make no assumptions
# about the underlying brain regions involved in this connectivity.

# %%

# Plot patterns
mic.plot_patterns(info=epochs.info, sensors="m.", size=2)

########################################################################################
# Visualising the filters
# -----------------------
# We can also visualise the filters as topomaps using the
# :meth:`~mne_connectivity.decoding.CoherencyDecomposition.plot_filters` method.
#
# Here we see that the filters show a similar topography to the patterns. However, this
# is not always the case, and you should never confuse the information represented by
# the filters (i.e. an inverse model) and patterns (i.e. a forward model), which can
# lead to very incorrect interpretations of the data :footcite:`HaufeEtAl2014`.

# %%

# Plot filters
mic.plot_filters(info=epochs.info, sensors="m.", size=2)

########################################################################################
# References
# ----------
# .. footbibliography::

# %%
1 change: 1 addition & 0 deletions mne_connectivity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
TemporalConnectivity,
)
from .datasets import make_signals_in_freq_bands
from .decoding import CoherencyDecomposition
from .effective import phase_slope_index
from .envelope import envelope_correlation, symmetric_orth
from .io import read_connectivity
Expand Down
Loading