diff --git a/.gitignore b/.gitignore index edb02525d..630e32356 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,8 @@ instance/ # Sphinx documentation doc/_build/ +docc/generated/ +doc/sg_execution_times.rst # PyBuilder target/ diff --git a/README.md b/README.md index 688fc74cf..8082223f7 100644 --- a/README.md +++ b/README.md @@ -84,23 +84,43 @@ your question. # Citing -If you use the ``ICLabel`` model, please consider citing our paper: - - Li et al., (2022). MNE-ICALabel: Automatically annotating ICA components with ICLabel in Python. Journal of Open Source Software, 7(76), 4484, https://doi.org/10.21105/joss.04484 - -with the corresponding BibTex: - - @article{Li2022, - doi = {10.21105/joss.04484}, - url = {https://doi.org/10.21105/joss.04484}, - year = {2022}, - publisher = {The Open Journal}, - volume = {7}, - number = {76}, - pages = {4484}, - author = {Adam Li and Jacob Feitelberg and Anand Prakash Saini and Richard Höchenberger and Mathieu Scheltienne}, - title = {MNE-ICALabel: Automatically annotating ICA components with ICLabel in Python}, - journal = {Journal of Open Source Software} - } +If you use the ``mne-icalabel``, please consider citing our paper: + +``` +@article{Li2022, + title = {MNE-ICALabel: Automatically annotating ICA components with ICLabel in Python}, + volume = {7}, + ISSN = {2475-9066}, + url = {http://dx.doi.org/10.21105/joss.04484}, + DOI = {10.21105/joss.04484}, + number = {76}, + journal = {Journal of Open Source Software}, + publisher = {The Open Journal}, + author = {Li, Adam and Feitelberg, Jacob and Saini, Anand Prakash and H\"{o}chenberger, Richard and Scheltienne, Mathieu}, + year = {2022}, + month = aug, + pages = {4484} +} +``` + +And the paper associated to the model used: + +- **ICLabel** + +``` +@article{PionTonachini2019, + title = {ICLabel: An automated electroencephalographic independent component classifier, dataset, and website}, + volume = {198}, + ISSN = {1053-8119}, + url = {http://dx.doi.org/10.1016/j.neuroimage.2019.05.026}, + DOI = {10.1016/j.neuroimage.2019.05.026}, + journal = {NeuroImage}, + publisher = {Elsevier BV}, + author = {Pion-Tonachini, Luca and Kreutz-Delgado, Ken and Makeig, Scott}, + year = {2019}, + month = sep, + pages = {181–197} +} +``` Future versions of the software are aimed at improved models and may have different papers associated with it. diff --git a/doc/Makefile b/doc/Makefile index d4bb2cbb9..a26b76be2 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,20 +1,35 @@ # Minimal makefile for Sphinx documentation -# -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= +SPHINXOPTS ?= -nWT --keep-going SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build -# Put it first so that "make" without argument is like "make help". +.PHONY: help Makefile clean html html-noplot linkcheck linkcheck-grep view + +first_target: help + help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " html-noplot to make standalone HTML files without plotting" + @echo " clean to clean HTML files" + @echo " linkcheck to check all external links for integrity" + @echo " linkcheck-grep to grep the linkcheck result" + @echo " view to view the built HTML" + +html: + $(SPHINXBUILD) . _build/html -b html $(SPHINXOPTS) + +html-noplot: + $(SPHINXBUILD) . _build/html -b html $(SPHINXOPTS) -D plot_gallery=0 + +clean: + rm -rf _build generated sg_execution_times.rst + +linkcheck: + $(SPHINXBUILD) . _build/linkcheck -b linkcheck -D plot_gallery=0 -.PHONY: help Makefile +linkcheck-grep: + @! grep -h "^.*:.*: \[\(\(local\)\|\(broken\)\)\]" _build/linkcheck/output.txt -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) +view: + @python -c "import webbrowser; webbrowser.open_new_tab('file://$(PWD)/_build/html/index.html')" diff --git a/doc/_static/favicon.ico b/doc/_static/favicon.ico deleted file mode 100644 index b0a1b57a5..000000000 Binary files a/doc/_static/favicon.ico and /dev/null differ diff --git a/doc/_static/mne_helmet.png b/doc/_static/mne_helmet.png deleted file mode 100644 index bb2124669..000000000 Binary files a/doc/_static/mne_helmet.png and /dev/null differ diff --git a/doc/_static/mne_logo_small.png b/doc/_static/mne_logo_small.png deleted file mode 100644 index df55643e7..000000000 Binary files a/doc/_static/mne_logo_small.png and /dev/null differ diff --git a/doc/_static/style.css b/doc/_static/style.css index b10216ddc..c1b52f0ac 100644 --- a/doc/_static/style.css +++ b/doc/_static/style.css @@ -7,41 +7,58 @@ --pst-font-family-monospace: 'Source Code Pro', var(--pst-font-family-monospace-system); /* colors that aren't responsive to light/dark mode */ --mne-color-discord: #5865F2; - --mne-color-primary: #007bff; - --mne-color-primary-highlight: #0063cc; /* font weight */ --mne-font-weight-semibold: 600; } html[data-theme="light"] { + /* pydata-sphinx-theme overrides */ + /* ↓↓↓ use default "info" colors for "primary" */ + --pst-color-primary: #276be9; + --pst-color-primary-bg: #dce7fc; + /* ↓↓↓ use default "primary" colors for "info" */ + --pst-color-info: var(--pst-teal-500); + --pst-color-info-bg: var(--pst-teal-200); + /* ↓↓↓ use "warning" colors for "secondary" */ + --pst-color-secondary: var(--pst-color-warning); + --pst-color-secondary-bg: var(--pst-color-warning-bg); + /* ↓↓↓ make sure new primary (link) color propagates to links on code */ + --pst-color-inline-code-links: var(--pst-color-link); + /* ↓↓↓ make sure new secondary (hover) color propagates to hovering on table rows */ + --pst-color-table-row-hover-bg: var(--pst-color-secondary-bg); /* topbar logo links */ --mne-color-github: #000; - --mne-color-discourse: #000; + --mne-color-discourse: #d0232b; --mne-color-mastodon: #2F0C7A; /* code block copy button */ --copybtn-opacity: 0.75; /* card header bg color */ --mne-color-card-header: rgba(0, 0, 0, 0.05); - /* section headings */ - --mne-color-heading: #003e80; - /* pydata-sphinx-theme overrides */ - --pst-color-primary: var(--mne-color-primary); - --pst-color-primary-highlight: var(--mne-color-primary-highlight); - --pst-color-info: var(--pst-color-primary); - --pst-color-border: #ccc; - --pst-color-background: #fff; - --pst-color-link: var(--pst-color-primary-highlight); /* sphinx-gallery overrides */ --sg-download-a-background-color: var(--pst-color-primary); --sg-download-a-background-image: unset; --sg-download-a-border-color: var(--pst-color-border); - --sg-download-a-color: #fff; + --sg-download-a-color: var(--sd-color-primary-text); --sg-download-a-hover-background-color: var(--pst-color-primary-highlight); --sg-download-a-hover-box-shadow-1: none; --sg-download-a-hover-box-shadow-2: none; } html[data-theme="dark"] { + /* pydata-sphinx-theme overrides */ + /* ↓↓↓ use default "info" colors for "primary" */ + --pst-color-primary: #79a3f2; + --pst-color-primary-bg: #06245d; + /* ↓↓↓ use default "primary" colors for "info" */ + --pst-color-info: var(--pst-teal-400); + --pst-color-info-bg: var(--pst-teal-800); + /* ↓↓↓ use "warning" colors for "secondary" */ + --pst-color-secondary: var(--pst-color-warning); + --pst-color-secondary-bg: var(--pst-color-warning-bg); + /* ↓↓↓ make sure new primary (link) color propagates to links on code */ + --pst-color-inline-code-links: var(--pst-color-link); + /* ↓↓↓ make sure new secondary (hover) color propagates to hovering on table rows */ + --pst-color-table-row-hover-bg: var(--pst-color-secondary-bg); /* topbar logo links */ --mne-color-github: rgb(240, 246, 252); /* from their logo SVG */ --mne-color-discourse: #FFF9AE; /* from their logo SVG */ @@ -50,27 +67,15 @@ html[data-theme="dark"] { --copybtn-opacity: 0.25; /* card header bg color */ --mne-color-card-header: rgba(255, 255, 255, 0.2); - /* section headings */ - --mne-color-heading: #b8cbe0; - /* pydata-sphinx-theme overrides */ - --pst-color-primary: var(--mne-color-primary); - --pst-color-primary-highlight: var(--mne-color-primary-highlight); - --pst-color-info: var(--pst-color-primary); - --pst-color-border: #333; - --pst-color-background: #000; - --pst-color-link: #66b0ff; /* sphinx-gallery overrides */ --sg-download-a-background-color: var(--pst-color-primary); --sg-download-a-background-image: unset; --sg-download-a-border-color: var(--pst-color-border); - --sg-download-a-color: #000; + --sg-download-a-color: var(--sd-color-primary-text); --sg-download-a-hover-background-color: var(--pst-color-primary-highlight); --sg-download-a-hover-box-shadow-1: none; --sg-download-a-hover-box-shadow-2: none; } -h1, h2, h3, h4, h5, h6 { - color: var(--mne-color-heading); -} /* ************************************************************ Sphinx fixes */ @@ -98,11 +103,6 @@ html[data-theme="dark"] img { filter: none; } -/* prev/next links */ -.prev-next-area a p.prev-next-title { - color: var(--pst-color-link); -} - /* make versionadded smaller and inline with param name */ /* don't do for deprecated / versionchanged; they have extra info (too long to fit) */ div.versionadded > p { @@ -127,11 +127,11 @@ a.sphx-glr-backref-instance:hover { } /* backreference links: make non-MNE func/meth calls resemble regular code */ a[class^="sphx-glr-backref-module"] { - color: rgb(var(--pst-color-text-base)); + color: var(--pst-color-text-base); } /* backreference links: make MNE calls bold and colorful */ a[class^="sphx-glr-backref-module-mne"] { - color: rgb(var(--pst-color-link)); + color: var(--pst-color-link); font-weight: var(--mne-font-weight-semibold); } /* suppress redundant note at top of every tutorial and signature at the end */ @@ -147,8 +147,15 @@ p.sphx-glr-signature { border-radius: 0.5rem; /* ↓↓↓↓↓↓↓ these two rules copied from sphinx-design */ box-shadow: 0 .125rem .25rem var(--sd-color-shadow) !important; + text-decoration: none; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } +.sphx-glr-download a.download code { + color: var(--sg-download-a-color); +} +.sphx-glr-download a.download::before { + color: var(--sg-download-a-color); +} /* Report embedding */ iframe.sg_report { width: 95%; @@ -175,20 +182,45 @@ iframe.sg_report { top: 0; } -/* TODO: Either pydata-sphinx-theme (for using Bootstrap) or sphinx-gallery (for adding table formatting) should fix this */ -.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>* { - --bs-table-accent-bg: var(--bs-table-striped-bg); +/* ******************************************************** HTML repr tables */ + +/* make table responsive to pydata-sphinx-theme's light/dark mode */ +.table > :not(caption) > * > * { color: var(--pst-color-text-base); } -.table-hover>tbody>tr:hover>* { - --bs-table-accent-bg: var(--bs-table-hover-bg); - color: var(--pst-color-text-base); +.mne-repr-table tbody tr:hover { + background-color: var(--pst-color-table-row-hover-bg); } -.rendered_html table { - color: var(--pst-color-text-base); +.mne-repr-section-toggle > button > svg > path { + fill: var(--pst-color-text-base); } - - +/* make the expand/collapse button look nicer */ +.mne-repr-section-toggle > button { + padding: 20%; +} +/* make section header rows more distinct (and harmonize with pydata-sphinx-theme table +style in the process). Color copied from pydata-sphinx-theme; 2px copied from bootstrap. +*/ +.mne-repr-table th { + border-bottom: 2px solid var(--pst-color-primary); +} +/* harmonize the channel names buttons with the rest of the table */ +.mne-ch-names-btn { + font-size: inherit; + padding: 0.25rem; + min-width: 1.5rem; + font-weight: bold; +} +/* +.mne-ch-names-btn:hover { + background-color: var(--pst-color-); + text-decoration: underline; +} +.mne-ch-names-btn:focus-visible { + outline: 0.1875rem solid var(--pst-color-accent); + outline-offset: 0.1875rem; +} +*/ /* ***************************************************** sphinx-design fixes */ p.btn a { color: unset; @@ -221,16 +253,16 @@ aside.footnote:last-child { } /* ******************************************************* navbar icon links */ -#navbar-icon-links i.fa-square-github::before { +.navbar-icon-links svg.fa-square-github { color: var(--mne-color-github); } -#navbar-icon-links i.fa-discourse::before { +.navbar-icon-links svg.fa-discourse { color: var(--mne-color-discourse); } -#navbar-icon-links i.fa-discord::before { +.navbar-icon-links svg.fa-discord { color: var(--mne-color-discord); } -#navbar-icon-links i.fa-mastodon::before { +.navbar-icon-links svg.fa-mastodon { color: var(--mne-color-mastodon); } @@ -241,7 +273,6 @@ aside.footnote:last-child { } /* topbar nav active */ .bd-header.navbar-light#navbar-main .navbar-nav > li.active > .nav-link { - color: var(--pst-color-link); font-weight: var(--mne-font-weight-semibold); } /* topbar nav hover */ @@ -249,18 +280,6 @@ aside.footnote:last-child { .bd-header.navbar-light#navbar-main .navbar-nav li a.nav-link:hover { color: var(--pst-color-secondary); } -/* sidebar nav */ -nav.bd-links .active > a, -nav.bd-links .active:hover > a, -.toc-entry a.nav-link.active, -.toc-entry a.nav-link.active:hover { - color: var(--pst-color-link); -} -/* sidebar nav hover */ -nav.bd-links li > a:hover, -.toc-entry a.nav-link:hover { - color: var(--pst-color-secondary); -} /* *********************************************************** homepage logo */ img.logo { @@ -272,10 +291,13 @@ img.logo { ul.quicklinks a { font-weight: var(--mne-font-weight-semibold); color: var(--pst-color-text-base); + text-decoration: none; +} +ul.quicklinks a svg { + color: var(--pst-color-text-muted); } ul.quicklinks a:hover { text-decoration: none; - color: var(--pst-color-secondary); } h5.card-header { margin-top: 0px; @@ -286,7 +308,6 @@ h5.card-header::before { height: 0px; margin-top: 0px; } - /* ******************************************************* homepage carousel */ div.frontpage-gallery { overflow: hidden; @@ -295,7 +316,7 @@ div.frontpage-gallery { } div.frontpage-gallery a { text-decoration: none; - color: rgb(var(--pst-color-text-base)); + color: var(--pst-color-text-base); } div.frontpage-gallery img.card-img { transform: scale(1.8); @@ -320,7 +341,7 @@ div.frontpage-gallery:hover .fadeout { needed for dark mode. */ div.card { border: 1px solid var(--pst-color-border); - background-color: rgb(var(--pst-color-background)); + background-color: var(--pst-color-background); } .card-header { border-bottom-color: var(--pst-color-border); @@ -339,9 +360,8 @@ div#contributor-avatars div.card img { border-radius: unset; } div#contributor-avatars div.card img { - width: 3em; + width: 2.5em; } - .contributor-avatar { clip-path: circle(closest-side); } @@ -379,3 +399,17 @@ img.hidden { td.justify { text-align-last: justify; } + +/* Matplotlib HTML5 video embedding */ +div.sphx-glr-animation video { + max-width: 100%; + height: auto; +} + +/* fix sidebar scrollbars */ +.sidebar-primary-items__end { + margin-bottom: 0 !important; + margin-top: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; +} diff --git a/doc/api.rst b/doc/api.rst deleted file mode 100644 index 23204d8c7..000000000 --- a/doc/api.rst +++ /dev/null @@ -1,94 +0,0 @@ -### -API -### - -.. automodule:: mne_icalabel - :no-members: - :no-inherited-members: - -This is the application programming interface (API) reference -for classes (``CamelCase`` names) and functions -(``underscore_case`` names) of MNE-ICALabel. - -Most-used functions -=================== - -.. currentmodule:: mne_icalabel - -.. autosummary:: - :toctree: ./generated/api - - label_components - -ICLabel -======= - -This is the model originally available for `EEGLab `_. -The model was ported from matconvnet using `pytorch `_ or -`Microsoft onnxruntime `_. - -ICLabel is designed to classify ICs fitted with an extended infomax ICA -decomposition algorithm on EEG datasets referenced to a common average and -filtered between [1., 100.] Hz. It is possible to run ICLabel on datasets that -do not meet those specification, but the classification performance -might be negatively impacted. Moreover, the ICLabel paper did not study the -effects of these preprocessing steps. - -Architecture: - -.. image:: _static/ICLabel_DagNN_Architecture.png - :width: 400 - :alt: ICLabel Neural Network Architecture - :align: center - -The model has three inputs: image (topomap), psd, and autocorrelation features. -To encourage generalization, the image feature is rotated and negated, thus -quadrupling the feature. After 3 convolutional layer with a ReLu activation, -the 3 features are concatenated for the final layer. - -.. currentmodule:: mne_icalabel.iclabel - -.. autosummary:: - :toctree: ./generated/api - - iclabel_label_components - get_iclabel_features - run_iclabel - -Features -======== - -Contains functions to extract features from `~mne.preprocessing.ICA` instance and `~mne.io.Raw` or -`~mne.Epochs` instances using MNE-Python. - -.. currentmodule:: mne_icalabel.features - -.. autosummary:: - :toctree: ./generated/api - - get_topomaps - -Annotating Components -===================== -To facilitate annotation of the ICA components, we provide an API that conforms to the -derivative standard of BIDS for EEG data. - -.. currentmodule:: mne_icalabel.annotation - -.. autosummary:: - :toctree: ./generated/api - - mark_component - write_components_tsv - -In addition, as of v0.3, we have introduced a beta-version of a GUI that -assists in annotated ICA components. This was heavily inspired by the annotation -process in ``ICLabel``. If you use this feature, please note that there may be -significant bugs still. Please report these in the GH issues tab. - -.. currentmodule:: mne_icalabel - -.. autosummary:: - :toctree: ./generated/api - - gui.label_ica_components diff --git a/doc/api/iclabel.rst b/doc/api/iclabel.rst new file mode 100644 index 000000000..76b2d2d94 --- /dev/null +++ b/doc/api/iclabel.rst @@ -0,0 +1,68 @@ +:orphan: + +ICLabel +======= + +This is the model originally available for `EEGLab `_. +The model was ported from matconvnet using `pytorch `_ or +`Microsoft onnxruntime `_. + +ICLabel is designed to classify ICs fitted with an extended infomax ICA +decomposition algorithm on *EEG datasets* referenced to a common average and +filtered between (1, 100) Hz. It is possible to run ICLabel on datasets that +do not meet those specification, but the classification performance +might be negatively impacted. Moreover, the ICLabel paper did not study the +effects of these preprocessing steps. + +Architecture +------------ + +.. image:: ../_static/ICLabel_DagNN_Architecture.png + :width: 400 + :alt: ICLabel Neural Network Architecture + :align: center + +.. raw:: html + +

+ +The model has three inputs: image (topomap), psd, and autocorrelation features. +To encourage generalization, the image feature is rotated and negated, thus +quadrupling the feature. After 3 convolutional layer with a ReLu activation, +the 3 features are concatenated for the final layer. + +API +--- + +.. currentmodule:: mne_icalabel.iclabel + +.. autosummary:: + :toctree: ../generated/api + + iclabel_label_components + get_iclabel_features + run_iclabel + +Cite +---- + +If you use ICLabel, please also cite the original +paper\ :footcite:p:`PionTonachini2019`. + +.. footbibliography:: + +.. code-block:: + + @article{PionTonachini2019, + title = {ICLabel: An automated electroencephalographic independent component classifier, dataset, and website}, + volume = {198}, + ISSN = {1053-8119}, + url = {http://dx.doi.org/10.1016/j.neuroimage.2019.05.026}, + DOI = {10.1016/j.neuroimage.2019.05.026}, + journal = {NeuroImage}, + publisher = {Elsevier BV}, + author = {Pion-Tonachini, Luca and Kreutz-Delgado, Ken and Makeig, Scott}, + year = {2019}, + month = sep, + pages = {181–197} + } diff --git a/doc/api/index.rst b/doc/api/index.rst new file mode 100644 index 000000000..843bf524b --- /dev/null +++ b/doc/api/index.rst @@ -0,0 +1,68 @@ +API +=== + +This is the application programming interface (API) reference +for classes (``CamelCase`` names) and functions +(``underscore_case`` names) of MNE-ICALabel. + +Most-used function +------------------ + +The most commonly used function is :func:`mne_icalabel.label_components` which takes an +mne instance (:class:`mne.io.Raw`, :class:`mne.Epochs`) and its ICA decomposition to +label the components using the specified method/model. + +.. currentmodule:: mne_icalabel + +.. autosummary:: + :toctree: ../generated/api + + label_components + +Models +------ + +.. card-carousel:: 4 + + .. card:: ICLabel + :link: iclabel.html + :link-type: url + +Features +-------- + +On top of the available models, ``mne-icalabel`` provides a set of functions to extract +features from `~mne.preprocessing.ICA` instance and `~mne.io.Raw` / `~mne.Epochs` +instances using MNE-Python. Those features can then be used to train new models. + +.. currentmodule:: mne_icalabel.features + +.. autosummary:: + :toctree: ../generated/api + + get_topomaps + +Annotating Components +--------------------- + +Finally, to facilitate annotation of the ICA components, we provide an API that conforms +to the derivative standard of BIDS for EEG data to write the annotations to a TSV file. + +.. currentmodule:: mne_icalabel.annotation + +.. autosummary:: + :toctree: ../generated/api + + mark_component + write_components_tsv + +In addition, as of version 0.3, we have introduced a beta-version of a GUI that +assists in annotated ICA components. This was heavily inspired by the annotation +process in ``ICLabel``. + +.. currentmodule:: mne_icalabel.gui + +.. autosummary:: + :toctree: ../generated/api + + label_ica_components diff --git a/doc/bibliography.rst b/doc/bibliography.rst deleted file mode 100644 index 4a310352d..000000000 --- a/doc/bibliography.rst +++ /dev/null @@ -1,12 +0,0 @@ -:orphan: - -.. _general_bibliography: - -General bibliography -==================== - -The references below are arranged alphabetically by first author. - -.. bibliography:: ./references.bib - :all: - :list: enumerated diff --git a/doc/changes/0.2.rst b/doc/changes/0.2.rst index 65bf0af1e..2b61864ab 100644 --- a/doc/changes/0.2.rst +++ b/doc/changes/0.2.rst @@ -12,7 +12,7 @@ .. include:: ./authors.inc -Version 0.3 +Version 0.2 =========== - Add functions for annotating and labeling ICA components in BIDS format :func:`mne_icalabel.annotation.write_components_tsv`, :func:`mne_icalabel.annotation.mark_component` (:pr:`60` by `Adam Li`_) diff --git a/doc/cite.rst b/doc/cite.rst new file mode 100644 index 000000000..950ed2397 --- /dev/null +++ b/doc/cite.rst @@ -0,0 +1,46 @@ +Cite +==== + +If you use ``mne-icalabel``, please consider citing our paper\ :footcite:p:`Li2022`. + +.. footbibliography:: + +.. code-block:: + + @article{Li2022, + title = {MNE-ICALabel: Automatically annotating ICA components with ICLabel in Python}, + volume = {7}, + ISSN = {2475-9066}, + url = {http://dx.doi.org/10.21105/joss.04484}, + DOI = {10.21105/joss.04484}, + number = {76}, + journal = {Journal of Open Source Software}, + publisher = {The Open Journal}, + author = {Li, Adam and Feitelberg, Jacob and Saini, Anand Prakash and H\"{o}chenberger, Richard and Scheltienne, Mathieu}, + year = {2022}, + month = aug, + pages = {4484} + } + +And the paper of the associated model. + +ICLabel\ :footcite:p:`PionTonachini2019` +---------------------------------------- + +.. footbibliography:: + +.. code-block:: + + @article{PionTonachini2019, + title = {ICLabel: An automated electroencephalographic independent component classifier, dataset, and website}, + volume = {198}, + ISSN = {1053-8119}, + url = {http://dx.doi.org/10.1016/j.neuroimage.2019.05.026}, + DOI = {10.1016/j.neuroimage.2019.05.026}, + journal = {NeuroImage}, + publisher = {Elsevier BV}, + author = {Pion-Tonachini, Luca and Kreutz-Delgado, Ken and Makeig, Scott}, + year = {2019}, + month = sep, + pages = {181–197} + } diff --git a/doc/conf.py b/doc/conf.py index 96046e182..1905f31fc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -123,11 +123,7 @@ "version_match": switcher_version_match, }, } -# Custom sidebar templates, maps document names to template names. -html_sidebars = { - "index": ["search-field.html"], -} - +html_sidebars = {"**": []} html_context = { "pygment_light_style": "tango", "pygment_dark_style": "native", diff --git a/doc/index.rst b/doc/index.rst index 3c191d401..a98a14cc6 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -13,10 +13,11 @@ typically very noisy and contains various non-neural signals, such as heartbeat artifacts. `Independent Component Analysis (ICA) `_ is a common procedure to remove these artifacts. However, removing artifacts requires manual annotation of ICA components, which is subject to human error and very -laborious when operating on large datasets. The first few versions of -``mne-icalabel`` replicated the popular ICLabel model for Python (previously -only available in MATLAB's EEGLab). In future versions, the package aims to -develop more robust models that build upon the ICLabel model. +laborious when operating on large datasets. + +The first few versions of ``mne-icalabel`` replicated the popular ICLabel model for +Python (previously only available in MATLAB's EEGLab). In future versions, the package +aims to develop more robust models that build upon the ICLabel model. We encourage you to use the package for your research and also build on top with relevant Pull Requests (PR). See our examples for walk-throughs of how to @@ -25,15 +26,16 @@ use the package and see our ``mne-icalabel`` is licensed under the `BSD license`_. A full copy of the license can be found `on GitHub `_. +See our :ref:`changes/index:Changelog` for a full list of changes. Contents -------- .. toctree:: :maxdepth: 2 + :hidden: install - api + api/index generated/examples/index - -See our :ref:`changes/index:Changelog` for a full list of changes. + cite diff --git a/doc/make.bat b/doc/make.bat index 954237b9b..1d93d72f7 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -1,35 +1,56 @@ -@ECHO OFF +@echo off -pushd %~dp0 +REM Minimal makefile for Sphinx documentation -REM Command file for Sphinx documentation +REM Set default options and commands +set SPHINXOPTS=-nWT --keep-going +set SPHINXBUILD=sphinx-build -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end +if "%1" == "html" goto html +if "%1" == "html-noplot" goto html-noplot +if "%1" == "clean" goto clean +if "%1" == "linkcheck" goto linkcheck +if "%1" == "linkcheck-grep" goto linkcheck-grep +if "%1" == "view" goto view +REM Define targets :help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +echo Please use `make ^` where ^ is one of +echo html to make standalone HTML files +echo html-noplot to make standalone HTML files without plotting +echo clean to clean HTML files +echo linkcheck to check all external links for integrity +echo linkcheck-grep to grep the linkcheck result +echo view to view the built HTML +goto :eof + +:html +%SPHINXBUILD% . _build\html -b html %SPHINXOPTS% +goto :eof + +:html-noplot +%SPHINXBUILD% . _build\html -b html %SPHINXOPTS% -D plot_gallery=0 +goto :eof + +:clean +rmdir /s /q _build generated +del sg_execution_times.rst +goto :eof + +:linkcheck +%SPHINXBUILD% . _build\linkcheck -b linkcheck -D plot_gallery=0 +goto :eof + +:linkcheck-grep +findstr /C:"[broken]" _build\linkcheck\output.txt > nul +if %errorlevel% equ 0 ( + echo Lines with [broken]: + findstr /C:"[broken]" _build\linkcheck\output.txt +) else ( + echo No lines with [broken] found. +) +goto :eof -:end -popd +:view +python -c "import webbrowser; webbrowser.open_new_tab(r'file:///%cd%\_build\html\index.html')" +goto :eof diff --git a/doc/references.bib b/doc/references.bib index fedf349c4..274e45065 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -1,9 +1,22 @@ -@article{iclabel2019, - author = {Luca Pion-Tonachini and Ken Kreutz-Delgado and Scott Makeig}, - doi = {https://doi.org/10.1016/j.neuroimage.2019.05.026}, +@article{Li2022, + author = {Li, Adam and Feitelberg, Jacob and Saini, Anand Prakash and H\"{o}chenberger, Richard and Scheltienne, Mathieu}, + doi = {10.21105/joss.04484}, + journal = {Journal of Open Source Software}, + month = {August}, + number = {76}, + pages = {4484}, + title = {MNE-ICALabel: Automatically annotating ICA components with ICLabel in Python}, + volume = {7}, + year = {2022} +} + +@article{PionTonachini2019, + author = {Pion-Tonachini, Luca and Kreutz-Delgado, Ken and Makeig, Scott}, + doi = {10.1016/j.neuroimage.2019.05.026}, journal = {NeuroImage}, - pages = {181-197}, - title = {ICLabel: An automated electroencephalographic independent component classifier, dataset, and website}, + month = {September}, + pages = {181–197}, + title = {ICLabel: An automated electroencephalographic independent component classifier, dataset, and website}, volume = {198}, year = {2019} } diff --git a/examples/00_iclabel.py b/examples/00_iclabel.py index b7576f3ae..4f9efa293 100644 --- a/examples/00_iclabel.py +++ b/examples/00_iclabel.py @@ -5,7 +5,7 @@ ============================================================== This tutorial covers automatically repairing signals using ICA with -the ICLabel model\ :footcite:`iclabel2019`, which originates in EEGLab. +the ICLabel model\ :footcite:`PionTonachini2019`, which originates in EEGLab. For conceptual background on ICA, see :ref:`this scikit-learn tutorial `. For a basic understanding of how to use ICA to remove artifacts, see `the @@ -212,7 +212,7 @@ # # The output of the ICLabel ``label_components`` function produces # predicted probability values for each of these classes in that order. -# See :footcite:`iclabel2019` for full details. +# See :footcite:`PionTonachini2019` for full details. ic_labels = label_components(filt_raw, ica, method="iclabel") diff --git a/mne_icalabel/iclabel/features.py b/mne_icalabel/iclabel/features.py index 7fbd9b0f4..96004b95e 100644 --- a/mne_icalabel/iclabel/features.py +++ b/mne_icalabel/iclabel/features.py @@ -37,7 +37,7 @@ def get_iclabel_features(inst: Union[BaseRaw, BaseEpochs], ica: ICA): autocorr : array of shape (1, 100, 1, n_components) The autocorrelations feature. Depending on the length of the raw data passed in, different methods of computing autocorrelation - will be used. See :footcite:t:`iclabel2019` for details. + will be used. See :footcite:t:`PionTonachini2019` for details. References ---------- diff --git a/mne_icalabel/iclabel/features.pyi b/mne_icalabel/iclabel/features.pyi index 117fee922..01b06b612 100644 --- a/mne_icalabel/iclabel/features.pyi +++ b/mne_icalabel/iclabel/features.pyi @@ -28,7 +28,7 @@ def get_iclabel_features(inst: BaseRaw | BaseEpochs, ica: ICA): autocorr : array of shape (1, 100, 1, n_components) The autocorrelations feature. Depending on the length of the raw data passed in, different methods of computing autocorrelation - will be used. See :footcite:t:`iclabel2019` for details. + will be used. See :footcite:t:`PionTonachini2019` for details. References ---------- diff --git a/mne_icalabel/iclabel/label_components.py b/mne_icalabel/iclabel/label_components.py index 6329d3411..bf8e2797d 100644 --- a/mne_icalabel/iclabel/label_components.py +++ b/mne_icalabel/iclabel/label_components.py @@ -32,7 +32,7 @@ def iclabel_label_components( - Autocorrelation, based on the ICA decomposition and the provided instance. - For more information, see :footcite:t:`iclabel2019`. + For more information, see :footcite:t:`PionTonachini2019`. Parameters ---------- diff --git a/mne_icalabel/iclabel/label_components.pyi b/mne_icalabel/iclabel/label_components.pyi index c44b28073..152524ddf 100644 --- a/mne_icalabel/iclabel/label_components.pyi +++ b/mne_icalabel/iclabel/label_components.pyi @@ -28,7 +28,7 @@ def iclabel_label_components( - Autocorrelation, based on the ICA decomposition and the provided instance. - For more information, see :footcite:t:`iclabel2019`. + For more information, see :footcite:t:`PionTonachini2019`. Parameters ---------- diff --git a/mne_icalabel/iclabel/network/__init__.py b/mne_icalabel/iclabel/network/__init__.py index 421a4f037..661882e9a 100644 --- a/mne_icalabel/iclabel/network/__init__.py +++ b/mne_icalabel/iclabel/network/__init__.py @@ -21,7 +21,8 @@ def run_iclabel( """Run the ICLabel network on the provided set of features. The features are un-formatted and are as-returned by - `~mne_icalabel.iclabel.get_iclabel_features`. + `~mne_icalabel.iclabel.get_iclabel_features`. For more information, + see :footcite:t:`PionTonachini2019`. Parameters ---------- @@ -41,6 +42,10 @@ def run_iclabel( The predicted numerical probability values for all labels in ICLabel output. Columns are ordered with ``'Brain'``, ``'Muscle'``, ``'Eye'``, ``'Heart'``, ``'Line Noise'``, ``'Channel Noise'``, and ``'Other'``. + + References + ---------- + .. footbibliography:: """ _check_option("backend", backend, (None, "torch", "onnx")) if backend is None: