diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0105ca0a52f..24f85b2771c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,7 +44,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4.35.2 + uses: github/codeql-action/init@v4.35.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -58,7 +58,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v4.35.2 + uses: github/codeql-action/autobuild@v4.35.3 # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -71,4 +71,4 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4.35.2 + uses: github/codeql-action/analyze@v4.35.3 diff --git a/environment.yml b/environment.yml index 00982630e41..810b13e55b0 100644 --- a/environment.yml +++ b/environment.yml @@ -62,6 +62,7 @@ dependencies: - tqdm >=4.66 - traitlets - trame + - trame-pyvista - trame-vtk - trame-vuetify - vtk ==9.6.0 diff --git a/mne/beamformer/tests/test_lcmv.py b/mne/beamformer/tests/test_lcmv.py index 1e0443a48f3..02756a7dc14 100644 --- a/mne/beamformer/tests/test_lcmv.py +++ b/mne/beamformer/tests/test_lcmv.py @@ -564,6 +564,20 @@ def test_make_lcmv_bem(tmp_path, reg, proj, kind): make_lcmv(epochs.info, forward_fixed, data_cov_grad, reg=0.01, noise_cov=noise_cov) +@pytest.fixture(scope="module") +def evoked_fwd_noise_data(): + """Fixture to supply reusable data.""" + _, _, evoked, data_cov, noise_cov, _, _, _, _, _ = _get_data(proj=True) + assert "eeg" not in evoked + assert "meg" in evoked + sphere = mne.make_sphere_model(r0=(0.0, 0.0, 0.0), head_radius=0.080) + src = mne.setup_volume_source_space( + pos=25.0, sphere=sphere, mindist=5.0, exclude=2.0 + ) + fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere) + return evoked, fwd_sphere, noise_cov, data_cov + + @testing.requires_testing_data @pytest.mark.slowtest @pytest.mark.parametrize( @@ -576,24 +590,16 @@ def test_make_lcmv_bem(tmp_path, reg, proj, kind): (None, "max-power"), ], ) -def test_make_lcmv_sphere(pick_ori, weight_norm): +def test_make_lcmv_sphere(pick_ori, weight_norm, evoked_fwd_noise_data): """Test LCMV with sphere head model.""" # unit-noise gain beamformer and orientation # selection and rank reduction of the leadfield - _, _, evoked, data_cov, noise_cov, _, _, _, _, _ = _get_data(proj=True) - assert "eeg" not in evoked - assert "meg" in evoked - sphere = mne.make_sphere_model(r0=(0.0, 0.0, 0.0), head_radius=0.080) - src = mne.setup_volume_source_space( - pos=25.0, sphere=sphere, mindist=5.0, exclude=2.0 - ) - fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere) - + evoked, fwd_sphere, noise_cov, data_cov = evoked_fwd_noise_data # Test that we get an error if not reducing rank with ( pytest.raises(ValueError, match="Singular matrix detected"), _record_warnings(), - pytest.warns(RuntimeWarning, match="positive semidefinite"), + pytest.warns(RuntimeWarning, match="(positive semidefinite|largest eigenvalu)"), ): make_lcmv( evoked.info, diff --git a/mne/source_estimate.py b/mne/source_estimate.py index 16a4f08226f..294a892a242 100644 --- a/mne/source_estimate.py +++ b/mne/source_estimate.py @@ -3219,6 +3219,8 @@ def spatio_temporal_dist_adjacency(src, n_times, dist, verbose=None): vertices are time 1, the nodes from 2 to 2N are the vertices during time 2, etc. """ + from scipy import sparse + if src[0]["dist"] is None: raise RuntimeError( "src must have distances included, consider using " @@ -3226,11 +3228,12 @@ def spatio_temporal_dist_adjacency(src, n_times, dist, verbose=None): ) blocks = [s["dist"][s["vertno"], :][:, s["vertno"]] for s in src] # Ensure we keep explicit zeros; deal with changes in SciPy - for block in blocks: + for bi, block in enumerate(blocks): if isinstance(block, np.ndarray): block[block == 0] = -np.inf else: block.data[block.data == 0] == -1 + blocks[bi] = sparse.csr_array(block) # avoid SciPy dep warning about mat->arr edges = sparse.block_diag(blocks) edges.data[:] = np.less_equal(edges.data, dist) # clean it up and put it in coo format diff --git a/mne/utils/config.py b/mne/utils/config.py index edf58f94031..ff7ec4f6285 100644 --- a/mne/utils/config.py +++ b/mne/utils/config.py @@ -823,6 +823,7 @@ def sys_info( # "trame", # no version, see https://github.com/Kitware/trame/issues/183 "trame_client", "trame_server", + "trame_pyvista", "trame_vtk", "trame_vuetify", "", diff --git a/pyproject.toml b/pyproject.toml index f9ae4204e73..47eebca2c00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -185,6 +185,7 @@ full-no-qt = [ "threadpoolctl", "traitlets", "trame", + "trame-pyvista", "trame-vtk", "trame-vuetify", "vtk >= 9.2", diff --git a/tools/install_pre_requirements.sh b/tools/install_pre_requirements.sh index 093940e193a..9581956d1dc 100755 --- a/tools/install_pre_requirements.sh +++ b/tools/install_pre_requirements.sh @@ -61,9 +61,8 @@ python -m pip install $STD_ARGS \ git+https://github.com/BUNPC/pysnirf2 \ git+https://github.com/the-siesta-group/edfio \ git+https://github.com/python-quantities/python-quantities \ - trame trame-vtk trame-vuetify nest-asyncio2 jupyter ipyevents ipympl openmeeg \ - imageio-ffmpeg xlrd mffpy traitlets pybv eeglabio defusedxml \ - antio curryreader + trame trame-vtk trame-vuetify trame-pyvista nest-asyncio2 jupyter ipyevents ipympl \ + openmeeg imageio-ffmpeg xlrd mffpy traitlets pybv eeglabio defusedxml antio curryreader echo "::endgroup::" echo "::group::Make sure we're on a NumPy 2.0 variant"