Skip to content

Commit afd2c8e

Browse files
committed
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaFo/mne-python into channel_specific_epoch_rejection
2 parents 300ce43 + 7da2ab5 commit afd2c8e

67 files changed

Lines changed: 1197 additions & 452 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ jobs:
4343
brew install python@3.11
4444
which python
4545
which pip
46-
pip install --upgrade pip setuptools wheel
47-
pip install --upgrade --only-binary "numpy,scipy,dipy,statsmodels" -ve . -r requirements.txt -r requirements_testing.txt -r requirements_testing_extra.txt PyQt6
46+
pip install --upgrade pip
47+
pip install --upgrade --only-binary "numpy,scipy,dipy,statsmodels" -ve .[full,test_extra]
4848
# 3D too slow on Apple's software renderer, and numba causes us problems
4949
pip uninstall -y vtk pyvista pyvistaqt numba
5050
mkdir -p test-results
@@ -266,6 +266,9 @@ jobs:
266266
- restore_cache:
267267
keys:
268268
- data-cache-ucl-opm-auditory
269+
- restore_cache:
270+
keys:
271+
- data-cache-phantom-kit
269272
- run:
270273
name: Get data
271274
# This limit could be increased, but this is helpful for finding slow ones
@@ -431,6 +434,10 @@ jobs:
431434
key: data-cache-ucl-opm-auditory
432435
paths:
433436
- ~/mne_data/auditory_OPM_stationary # (4 G)
437+
- save_cache:
438+
key: data-cache-phantom-kit
439+
paths:
440+
- ~/mne_data/MNE-phantom-KIT-data # (1 G)
434441

435442

436443
linkcheck:

.github/workflows/tests.yml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ jobs:
5959
- os: ubuntu-latest
6060
python: '3.10'
6161
kind: conda
62-
- os: ubuntu-latest
63-
python: '3.10'
64-
kind: notebook
6562
- os: ubuntu-latest
6663
python: '3.11'
6764
kind: pip-pre
@@ -87,7 +84,6 @@ jobs:
8784
with:
8885
qt: true
8986
pyvista: false
90-
if: matrix.kind != 'notebook'
9187
# Python (if pip)
9288
- uses: actions/setup-python@v4
9389
with:
@@ -103,19 +99,13 @@ jobs:
10399
miniforge-variant: Mambaforge
104100
use-mamba: ${{ matrix.kind != 'conda' }}
105101
if: ${{ !startswith(matrix.kind, 'pip') }}
106-
- name: 'Install OSMesa VTK variant'
107-
run: |
108-
# TODO: As of 2023/02/28, notebook tests need a pinned mesalib
109-
mamba install -c conda-forge "vtk>=9.2=*osmesa*" "vtk-base>=9.2=*osmesa*" "mesalib=23.1.4" "numpy=1.24.4" "numba=0.57.1"
110-
mamba list
111-
if: matrix.kind == 'notebook'
112102
- run: ./tools/github_actions_dependencies.sh
113103
# Minimal commands on Linux (macOS stalls)
114104
- run: ./tools/get_minimal_commands.sh
115105
if: ${{ startswith(matrix.os, 'ubuntu') }}
116106
- run: ./tools/github_actions_install.sh
117107
- run: ./tools/github_actions_infos.sh
118-
# Check Qt on non-notebook
108+
# Check Qt
119109
- run: ./tools/check_qt_import.sh $MNE_QT_BACKEND
120110
if: ${{ env.MNE_QT_BACKEND != '' }}
121111
- name: Run tests with no testing data

.pre-commit-config.yaml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 23.10.1
3+
rev: 23.11.0
44
hooks:
55
- id: black
66
args: [--quiet]
77

88
# Ruff mne
99
- repo: https://github.com/astral-sh/ruff-pre-commit
10-
rev: v0.1.4
10+
rev: v0.1.5
1111
hooks:
1212
- id: ruff
1313
name: ruff mne
@@ -16,13 +16,13 @@ repos:
1616

1717
# Ruff tutorials and examples
1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.1.4
19+
rev: v0.1.5
2020
hooks:
2121
- id: ruff
2222
name: ruff tutorials and examples
2323
# D103: missing docstring in public function
2424
# D400: docstring first line must end with period
25-
args: ["--ignore=D103,D400"]
25+
args: ["--ignore=D103,D400", "--fix"]
2626
files: ^tutorials/|^examples/
2727

2828
# Codespell
@@ -37,7 +37,7 @@ repos:
3737

3838
# yamllint
3939
- repo: https://github.com/adrienverge/yamllint.git
40-
rev: v1.32.0
40+
rev: v1.33.0
4141
hooks:
4242
- id: yamllint
4343
args: [--strict, -c, .yamllint.yml]
@@ -47,7 +47,6 @@ repos:
4747
rev: v6.2.0
4848
hooks:
4949
- id: rstcheck
50+
additional_dependencies:
51+
- tomli
5052
files: ^doc/.*\.(rst|inc)$
51-
# https://github.com/rstcheck/rstcheck/issues/199
52-
# https://github.com/rstcheck/rstcheck/issues/200
53-
exclude: ^doc/(help/faq|install/manual_install|install/mne_c|install/advanced|install/updating|_includes/channel_interpolation|_includes/inverse|_includes/ssp)\.rst$

MANIFEST.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
include *.rst
22
include LICENSE.txt
33
include SECURITY.md
4-
include requirements.txt
5-
include requirements_base.txt
6-
include requirements_hdf5.txt
7-
include requirements_testing.txt
8-
include requirements_testing_extra.txt
9-
include requirements_doc.txt
104
include mne/__init__.py
115

126
recursive-include examples *.py

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ clean-cache:
2424

2525
clean: clean-build clean-pyc clean-so clean-ctags clean-cache
2626

27-
wheel_quiet:
28-
$(PYTHON) setup.py -q sdist bdist_wheel
27+
wheel:
28+
$(PYTHON) -m build
2929

3030
sample_data:
3131
@python -c "import mne; mne.datasets.sample.data_path(verbose=True);"
@@ -57,7 +57,7 @@ codespell: # running manually
5757
check-manifest:
5858
check-manifest -q --ignore .circleci/config.yml,doc,logo,mne/io/*/tests/data*,mne/io/tests/data,mne/preprocessing/tests/data,.DS_Store,mne/_version.py
5959

60-
check-readme: clean wheel_quiet
60+
check-readme: clean wheel
6161
twine check dist/*
6262

6363
nesting:

azure-pipelines.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ stages:
5151
displayName: 'Get Python'
5252
- bash: |
5353
set -eo pipefail
54-
python -m pip install --progress-bar off --upgrade pip setuptools wheel
55-
python -m pip install --progress-bar off -r requirements_base.txt -r requirements_hdf5.txt -r requirements_testing.txt
54+
python -m pip install --progress-bar off --upgrade pip build
55+
python -m pip install --progress-bar off -ve .[hdf5,test]
5656
python -m pip uninstall -yq pytest-qt # don't want to set up display, etc. for this
5757
pre-commit install --install-hooks
5858
displayName: Install dependencies
@@ -107,8 +107,8 @@ stages:
107107
displayName: 'Get Python'
108108
- bash: |
109109
set -e
110-
python -m pip install --progress-bar off --upgrade pip setuptools wheel
111-
python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git@main" pyvista scikit-learn pytest-error-for-skips python-picard "PyQt6!=6.5.1" qtpy nibabel
110+
python -m pip install --progress-bar off --upgrade pip
111+
python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git@main" pyvista scikit-learn pytest-error-for-skips python-picard "PyQt6!=6.5.1" qtpy nibabel sphinx-gallery
112112
python -m pip uninstall -yq mne
113113
python -m pip install --progress-bar off --upgrade -e .[test]
114114
displayName: 'Install dependencies with pip'
@@ -166,11 +166,10 @@ stages:
166166
displayName: 'Get Python'
167167
- bash: |
168168
set -e
169-
python -m pip install --progress-bar off --upgrade pip setuptools wheel
169+
python -m pip install --progress-bar off --upgrade pip
170170
python -m pip install --progress-bar off --upgrade --pre --only-binary=\"numpy,scipy,matplotlib,vtk\" numpy scipy matplotlib vtk
171171
python -c "import vtk"
172-
python -m pip install --progress-bar off --upgrade -r requirements.txt -r requirements_testing.txt -r requirements_testing_extra.txt
173-
python -m pip install -e .
172+
python -m pip install --progress-bar off --upgrade -ve .[full,test_extra]
174173
displayName: 'Install dependencies with pip'
175174
- bash: |
176175
set -e

doc/_includes/channel_interpolation.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ In short, data repair using spherical spline interpolation :footcite:`PerrinEtAl
2222
Spherical splines assume that the potential :math:`V(\boldsymbol{r_i})` at any point :math:`\boldsymbol{r_i}` on the surface of the sphere can be represented by:
2323

2424
.. math:: V(\boldsymbol{r_i}) = c_0 + \sum_{j=1}^{N}c_{i}g_{m}(cos(\boldsymbol{r_i}, \boldsymbol{r_{j}}))
25-
:label: model
25+
:name: model
2626

2727
where the :math:`C = (c_{1}, ..., c_{N})^{T}` are constants which must be estimated. The function :math:`g_{m}(\cdot)` of order :math:`m` is given by:
2828

2929
.. math:: g_{m}(x) = \frac{1}{4 \pi}\sum_{n=1}^{\infty} \frac{2n + 1}{(n(n + 1))^m}P_{n}(x)
30-
:label: legendre
3130

3231
where :math:`P_{n}(x)` are `Legendre polynomials`_ of order :math:`n`.
3332

@@ -36,22 +35,22 @@ where :math:`P_{n}(x)` are `Legendre polynomials`_ of order :math:`n`.
3635
To estimate the constants :math:`C`, we must solve the following two equations simultaneously:
3736

3837
.. math:: G_{ss}C + T_{s}c_0 = X
39-
:label: matrix_form
38+
:name: matrix_form
4039

4140
.. math:: {T_s}^{T}C = 0
42-
:label: constraint
41+
:name: constraint
4342

4443
where :math:`G_{ss} \in R^{N \times N}` is a matrix whose entries are :math:`G_{ss}[i, j] = g_{m}(cos(\boldsymbol{r_i}, \boldsymbol{r_j}))` and :math:`X \in R^{N \times 1}` are the potentials :math:`V(\boldsymbol{r_i})` measured at the good channels. :math:`T_{s} = (1, 1, ..., 1)^\top` is a column vector of dimension :math:`N`. Equation :eq:`matrix_form` is the matrix formulation of Equation :eq:`model` and equation :eq:`constraint` is like applying an average reference to the data. From equation :eq:`matrix_form` and :eq:`constraint`, we get:
4544

4645
.. math:: \begin{bmatrix} c_0 \\ C \end{bmatrix} = {\begin{bmatrix} {T_s}^{T} && 0 \\ T_s && G_{ss} \end{bmatrix}}^{-1} \begin{bmatrix} 0 \\ X \end{bmatrix} = C_{i}X
47-
:label: estimate_constant
46+
:name: estimate_constant
4847

4948
:math:`C_{i}` is the same as matrix :math:`{\begin{bmatrix} {T_s}^{T} && 0 \\ T_s && G_{ss} \end{bmatrix}}^{-1}` but with its first column deleted, therefore giving a matrix of dimension :math:`(N + 1) \times N`.
5049

5150
Now, to estimate the potentials :math:`\hat{X} \in R^{M \times 1}` at the bad channels, we have to do:
5251

5352
.. math:: \hat{X} = G_{ds}C + T_{d}c_0
54-
:label: estimate_data
53+
:name: estimate_data
5554

5655
where :math:`G_{ds} \in R^{M \times N}` computes :math:`g_{m}(\boldsymbol{r_i}, \boldsymbol{r_j})` between the bad and good channels. :math:`T_{d} = (1, 1, ..., 1)^\top` is a column vector of dimension :math:`M`. Plugging in equation :eq:`estimate_constant` in :eq:`estimate_data`, we get
5756

doc/_includes/inverse.rst

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ this by writing :math:`R' = R/ \lambda^2 = R \lambda^{-2}`, which yields the
7070
inverse operator
7171

7272
.. math::
73-
:label: inv_m
73+
:name: inv_m
7474
7575
M &= R' G^\top (G R' G^\top + C)^{-1} \\
7676
&= R \lambda^{-2} G^\top (G R \lambda^{-2} G^\top + C)^{-1} \\
@@ -106,12 +106,12 @@ The MNE software employs data whitening so that a 'whitened' inverse operator
106106
assumes the form
107107

108108
.. math:: \tilde{M} = M C^{^1/_2} = R \tilde{G}^\top (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1}\ ,
109-
:label: inv_m_tilde
109+
:name: inv_m_tilde
110110

111111
where
112112

113113
.. math:: \tilde{G} = C^{-^1/_2}G
114-
:label: inv_g_tilde
114+
:name: inv_g_tilde
115115

116116
is the spatially whitened gain matrix. We arrive at the whitened inverse
117117
operator equation :eq:`inv_m_tilde` by making the substitution for
@@ -128,7 +128,7 @@ operator equation :eq:`inv_m_tilde` by making the substitution for
128128
The expected current values are
129129

130130
.. math::
131-
:label: inv_j_hat_t
131+
:name: inv_j_hat_t
132132
133133
\hat{j}(t) &= Mx(t) \\
134134
&= M C^{^1/_2} C^{-^1/_2} x(t) \\
@@ -137,7 +137,7 @@ The expected current values are
137137
knowing :eq:`inv_m_tilde` and taking
138138

139139
.. math::
140-
:label: inv_tilde_x_t
140+
:name: inv_tilde_x_t
141141
142142
\tilde{x}(t) = C^{-^1/_2}x(t)
143143
@@ -151,7 +151,7 @@ to raw data. To reflect the decrease of noise due to averaging, this matrix,
151151
C_0 / L`.
152152

153153
.. note::
154-
When EEG data are included, the gain matrix :math:`G` needs to be average referenced when computing the linear inverse operator :math:`M`. This is incorporated during creating the spatial whitening operator :math:`C^{-^1/_2}`, which includes any projectors on the data. EEG data average reference (using a projector) is mandatory for source modeling and is checked when calculating the inverse operator.
154+
When EEG data are included, the gain matrix :math:`G` needs to be average referenced when computing the linear inverse operator :math:`M`. This is incorporated during creating the spatial whitening operator :math:`C^{-^1/_2}`, which includes any projectors on the data. EEG data average reference (using a projector) is mandatory for source modeling and is checked when calculating the inverse operator.
155155

156156
As shown above, regularization of the inverse solution is equivalent to a
157157
change in the variance of the current amplitudes in the Bayesian *a priori*
@@ -224,7 +224,7 @@ computational convenience we prefer to take another route, which employs the
224224
singular-value decomposition (SVD) of the matrix
225225

226226
.. math::
227-
:label: inv_a
227+
:name: inv_a
228228
229229
A &= \tilde{G} R^{^1/_2} \\
230230
&= U \Lambda V^\top
@@ -238,7 +238,7 @@ Combining the SVD from :eq:`inv_a` with the inverse equation :eq:`inv_m` it is
238238
easy to show that
239239

240240
.. math::
241-
:label: inv_m_tilde_svd
241+
:name: inv_m_tilde_svd
242242
243243
\tilde{M} &= R \tilde{G}^\top (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1} \\
244244
&= R^{^1/_2} A^\top (A A^\top + \lambda^2 I)^{-1} \\
@@ -253,23 +253,23 @@ where the elements of the diagonal matrix :math:`\Gamma` are simply
253253
.. `reginv` in our code:
254254
255255
.. math::
256-
:label: inv_gamma_k
256+
:name: inv_gamma_k
257257
258258
\gamma_k = \frac{\lambda_k}{\lambda_k^2 + \lambda^2}\ .
259259
260260
From our expected current equation :eq:`inv_j_hat_t` and our whitened
261261
measurement equation :eq:`inv_tilde_x_t`, if we take
262262

263263
.. math::
264-
:label: inv_w_t
264+
:name: inv_w_t
265265
266266
w(t) &= U^\top \tilde{x}(t) \\
267267
&= U^\top C^{-^1/_2} x(t)\ ,
268268
269269
we can see that the expression for the expected current is just
270270

271271
.. math::
272-
:label: inv_j_hat_t_svd
272+
:name: inv_j_hat_t_svd
273273
274274
\hat{j}(t) &= R^{^1/_2} V \Gamma w(t) \\
275275
&= \sum_k {\bar{v_k} \gamma_k w_k(t)}\ ,
@@ -314,7 +314,7 @@ normalization factors, it's convenient to reuse our "weighted eigenleads"
314314
definition from equation :eq:`inv_j_hat_t` in matrix form as
315315

316316
.. math::
317-
:label: inv_eigenleads_weighted
317+
:name: inv_eigenleads_weighted
318318
319319
\bar{V} = R^{^1/_2} V\ .
320320

doc/_includes/ssp.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ Without loss of generality we can always decompose any :math:`n`-channel
3030
measurement :math:`b(t)` into its signal and noise components as
3131

3232
.. math:: b(t) = b_s(t) + b_n(t)
33-
:label: additive_model
33+
:name: additive_model
3434

3535
Further, if we know that :math:`b_n(t)` is well characterized by a few field
3636
patterns :math:`b_1 \dotso b_m`, we can express the disturbance as
3737

3838
.. math:: b_n(t) = Uc_n(t) + e(t)\ ,
39-
:label: pca
39+
:name: pca
4040

4141
where the columns of :math:`U` constitute an orthonormal basis for :math:`b_1
4242
\dotso b_m`, :math:`c_n(t)` is an :math:`m`-component column vector, and the
@@ -48,12 +48,12 @@ such that the conditions described above are satisfied. We can now construct
4848
the orthogonal complement operator
4949

5050
.. math:: P_{\perp} = I - UU^\top
51-
:label: projector
51+
:name: projector
5252

5353
and apply it to :math:`b(t)` in Equation :eq:`additive_model` yielding
5454

5555
.. math:: b_{s}(t) \approx P_{\perp}b(t)\ ,
56-
:label: result
56+
:name: result
5757

5858
since :math:`P_{\perp}b_n(t) = P_{\perp}(Uc_n(t) + e(t)) \approx 0` and
5959
:math:`P_{\perp}b_{s}(t) \approx b_{s}(t)`. The projection operator
@@ -102,12 +102,12 @@ typical in EEG analysis to subtract the average reference from all the sensor
102102
signals :math:`b^{1}(t), ..., b^{n}(t)`. That is:
103103

104104
.. math:: {b}^{j}_{s}(t) = b^{j}(t) - \frac{1}{n}\sum_{k}{b^k(t)}
105-
:label: eeg_proj
105+
:name: eeg_proj
106106

107107
where the noise term :math:`b_{n}^{j}(t)` is given by
108108

109109
.. math:: b_{n}^{j}(t) = \frac{1}{n}\sum_{k}{b^k(t)}
110-
:label: noise_term
110+
:name: noise_term
111111

112112
Thus, the projector vector :math:`P_{\perp}` will be given by
113113
:math:`P_{\perp}=\frac{1}{n}[1, 1, ..., 1]`

doc/api/datasets.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ Datasets
4040
spm_face.data_path
4141
ucl_opm_auditory.data_path
4242
visual_92_categories.data_path
43+
phantom_kit.data_path
4344
phantom_4dbti.data_path
4445
phantom_kernel.data_path
4546
refmeg_noise.data_path
4647
ssvep.data_path
4748
erp_core.data_path
4849
epilepsy_ecog.data_path
49-
eyelink.data_path
50+
eyelink.data_path

0 commit comments

Comments
 (0)