Skip to content

Commit b3abc44

Browse files
Merge branch 'doc-ref-channel-clarification' of https://github.com/Dpereaptkhamur-13/mne-python into doc-ref-channel-clarification
2 parents ca02f80 + 107a1d1 commit b3abc44

13 files changed

Lines changed: 52 additions & 30 deletions

File tree

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444

4545
# Initializes the CodeQL tools for scanning.
4646
- name: Initialize CodeQL
47-
uses: github/codeql-action/init@v4.35.2
47+
uses: github/codeql-action/init@v4.35.3
4848
with:
4949
languages: ${{ matrix.language }}
5050
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
5858
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
5959
# If this step fails, then you should remove it and run the build manually (see below)
6060
- name: Autobuild
61-
uses: github/codeql-action/autobuild@v4.35.2
61+
uses: github/codeql-action/autobuild@v4.35.3
6262

6363
# ℹ️ Command-line programs to run using the OS shell.
6464
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -71,4 +71,4 @@ jobs:
7171
# ./location_of_script_within_repo/buildscript.sh
7272

7373
- name: Perform CodeQL Analysis
74-
uses: github/codeql-action/analyze@v4.35.2
74+
uses: github/codeql-action/analyze@v4.35.3

doc/changes/dev/13894.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bug where ``picks`` was ignored in :meth:`mne.Epochs.apply_function` when ``channel_wise=False``, by `Thomas Binns`_.

doc/development/contributing.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -587,12 +587,14 @@ deprecation period when the stated release is being prepared:
587587
parameter, and (if found) update them to use the new function / parameter.
588588

589589

590+
.. _`changelog-guide`:
591+
590592
Describe your changes in the changelog
591593
--------------------------------------
592594

593-
Include in your changeset a brief description of the change in the
594-
:ref:`changelog <whats_new>` using towncrier_ format, which aggregates small,
595-
properly-named ``.rst`` files to create a changelog. This can be
595+
Include in your changeset a brief description of the changes, which will appear in the
596+
:ref:`changelog <whats_new>`, using towncrier_ format. This aggregates small,
597+
properly named ``.rst`` files to create a changelog. This can be
596598
skipped for very minor changes like correcting typos in the documentation.
597599

598600
There are six separate sections for changes, based on change type.
@@ -1024,8 +1026,9 @@ down the road. Here are the guidelines:
10241026
you are specifically asked by a maintainer to PR into another branch (e.g.,
10251027
for backports or maintenance bugfixes to the current stable version).
10261028

1027-
- Don't forget to include in your PR a brief description of the change in the
1028-
:ref:`changelog <whats_new>` (:file:`doc/whats_new.rst`).
1029+
- Don't forget to include in your PR a brief description of the change in a
1030+
changelog entry (see :ref:`the changelog section <changelog-guide>` above
1031+
for instructions).
10291032

10301033
- Our community uses the following commit tags and conventions:
10311034

doc/sphinxext/related_software.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
1. Add it to the MNE-installers if possible, and it will automatically appear.
66
2. If it's on PyPI and not in the MNE-installers, add it to the PYPI_PACKAGES set.
77
3. If it's not on PyPI, add it to the MANUAL_PACKAGES dictionary.
8+
9+
If PyPI or manual, also add package name to `related_software.txt` or
10+
`related_software_nodeps.txt` so that it's installed at doc-build time (for package
11+
metadata querying).
812
"""
913

1014
# Authors: The MNE-Python contributors.
@@ -35,6 +39,7 @@
3539
"niseq",
3640
"sesameeg",
3741
"mne-kit-gui", # moved to its own env in the installers
42+
"zuna",
3843
}
3944

4045
# If it's not available on PyPI, add it to this dict:
@@ -221,7 +226,7 @@ def run(self):
221226
return [my_list]
222227

223228

224-
def setup(app):
229+
def setup(app): # noqa: D103
225230
app.add_directive("related-software", RelatedSoftwareDirective)
226231
# Run it as soon as this is added as a Sphinx extension so that any errors
227232
# / new packages are reported early. The next call in run() will be cached.

doc/sphinxext/related_software_nodeps.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ fsleyes
44
mne-kit-gui
55
mne-videobrowser
66
hedtools # because it limits our Pandas version currently
7+
zuna # requires pytorch

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ dependencies:
6262
- tqdm >=4.66
6363
- traitlets
6464
- trame
65+
- trame-pyvista
6566
- trame-vtk
6667
- trame-vuetify
6768
- vtk ==9.6.0

mne/beamformer/tests/test_lcmv.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,20 @@ def test_make_lcmv_bem(tmp_path, reg, proj, kind):
564564
make_lcmv(epochs.info, forward_fixed, data_cov_grad, reg=0.01, noise_cov=noise_cov)
565565

566566

567+
@pytest.fixture(scope="module")
568+
def evoked_fwd_noise_data():
569+
"""Fixture to supply reusable data."""
570+
_, _, evoked, data_cov, noise_cov, _, _, _, _, _ = _get_data(proj=True)
571+
assert "eeg" not in evoked
572+
assert "meg" in evoked
573+
sphere = mne.make_sphere_model(r0=(0.0, 0.0, 0.0), head_radius=0.080)
574+
src = mne.setup_volume_source_space(
575+
pos=25.0, sphere=sphere, mindist=5.0, exclude=2.0
576+
)
577+
fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere)
578+
return evoked, fwd_sphere, noise_cov, data_cov
579+
580+
567581
@testing.requires_testing_data
568582
@pytest.mark.slowtest
569583
@pytest.mark.parametrize(
@@ -576,24 +590,16 @@ def test_make_lcmv_bem(tmp_path, reg, proj, kind):
576590
(None, "max-power"),
577591
],
578592
)
579-
def test_make_lcmv_sphere(pick_ori, weight_norm):
593+
def test_make_lcmv_sphere(pick_ori, weight_norm, evoked_fwd_noise_data):
580594
"""Test LCMV with sphere head model."""
581595
# unit-noise gain beamformer and orientation
582596
# selection and rank reduction of the leadfield
583-
_, _, evoked, data_cov, noise_cov, _, _, _, _, _ = _get_data(proj=True)
584-
assert "eeg" not in evoked
585-
assert "meg" in evoked
586-
sphere = mne.make_sphere_model(r0=(0.0, 0.0, 0.0), head_radius=0.080)
587-
src = mne.setup_volume_source_space(
588-
pos=25.0, sphere=sphere, mindist=5.0, exclude=2.0
589-
)
590-
fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere)
591-
597+
evoked, fwd_sphere, noise_cov, data_cov = evoked_fwd_noise_data
592598
# Test that we get an error if not reducing rank
593599
with (
594600
pytest.raises(ValueError, match="Singular matrix detected"),
595601
_record_warnings(),
596-
pytest.warns(RuntimeWarning, match="positive semidefinite"),
602+
pytest.warns(RuntimeWarning, match="(positive semidefinite|largest eigenvalu)"),
597603
):
598604
make_lcmv(
599605
evoked.info,

mne/epochs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2045,7 +2045,7 @@ def apply_function(
20452045
for run_idx, ch_idx in enumerate(picks):
20462046
self._data[:, ch_idx, :] = data_picks_new[run_idx]
20472047
else:
2048-
self._data = _check_fun(fun, data_in, **kwargs)
2048+
self._data[:, picks, :] = _check_fun(fun, data_in[:, picks, :], **kwargs)
20492049

20502050
return self
20512051

mne/source_estimate.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3219,18 +3219,21 @@ def spatio_temporal_dist_adjacency(src, n_times, dist, verbose=None):
32193219
vertices are time 1, the nodes from 2 to 2N are the vertices
32203220
during time 2, etc.
32213221
"""
3222+
from scipy import sparse
3223+
32223224
if src[0]["dist"] is None:
32233225
raise RuntimeError(
32243226
"src must have distances included, consider using "
32253227
"setup_source_space with add_dist=True"
32263228
)
32273229
blocks = [s["dist"][s["vertno"], :][:, s["vertno"]] for s in src]
32283230
# Ensure we keep explicit zeros; deal with changes in SciPy
3229-
for block in blocks:
3231+
for bi, block in enumerate(blocks):
32303232
if isinstance(block, np.ndarray):
32313233
block[block == 0] = -np.inf
32323234
else:
32333235
block.data[block.data == 0] == -1
3236+
blocks[bi] = sparse.csr_array(block) # avoid SciPy dep warning about mat->arr
32343237
edges = sparse.block_diag(blocks)
32353238
edges.data[:] = np.less_equal(edges.data, dist)
32363239
# clean it up and put it in coo format

mne/tests/test_epochs.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4832,20 +4832,21 @@ def test_apply_function():
48324832
info = mne.create_info(n_channels, 1000.0, "eeg")
48334833
epochs = mne.EpochsArray(data, info, events)
48344834
data_epochs = epochs.get_data()
4835+
picks = np.arange(3)
4836+
non_picks = np.arange(3, n_channels)
48354837

48364838
# apply_function to all channels at once
48374839
def fun(data):
48384840
"""Reverse channel order without changing values."""
48394841
return np.eye(data.shape[1])[::-1] @ data
48404842

4841-
want = data_epochs[:, ::-1]
4842-
got = epochs.apply_function(fun, channel_wise=False).get_data()
4843+
want = np.concatenate(
4844+
[data_epochs[:, picks][:, ::-1], data_epochs[:, non_picks]], axis=1
4845+
) # only reverse channel order of picks
4846+
got = epochs.apply_function(fun, picks=picks, channel_wise=False).get_data()
48434847
assert_array_equal(want, got)
48444848

48454849
# apply_function channel-wise (to first 3 channels) by replacing with mean
4846-
picks = np.arange(3)
4847-
non_picks = np.arange(3, n_channels)
4848-
48494850
def fun(data):
48504851
return np.full_like(data, data.mean())
48514852

0 commit comments

Comments
 (0)