internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: mne-tools/mne-python

Issue:
BUG: Notebook server produces blank images by default
@GuillaumeFavelier see https://mne.discourse.group/t/support-for-3d-brain-visualization-in-headless-mode/4375/12

I wonder if we should try to be smart about `ANTIALIAS` and set it to False under some circumstances. Maybe we can detect a MESA renderer? Or maybe we just always set it to False for the notebook backend? WDYT?


Discussion:
>  Maybe we can detect a MESA renderer?

I prefer this idea because AFAIK we encounter this issue mostly when using MESA. Plus it should be simple enough to do using `pyvista.GPUInfo` (and I think the issue with the report crashing should be solved for the next release).

> Or maybe we just always set it to False for the notebook backend? 

It might be too much. I often use the `notebook` 3d backend locally for testing so I would have to enable it explicitly. Let's keep it as a backup plan if relying on MESA is not reliable.

Resolving patch:
diff --git a/mne/viz/backends/_pyvista.py b/mne/viz/backends/_pyvista.py
--- a/mne/viz/backends/_pyvista.py
+++ b/mne/viz/backends/_pyvista.py
@@ -13,6 +13,7 @@
 
 from contextlib import contextmanager
 import os
+import re
 import sys
 import warnings
 
@@ -661,10 +662,18 @@ def _enable_antialias(self):
         # before the window has actually been made "active"...?
         # For Mayavi we have an "on activated" event or so, we should look into
         # using this for Azure at some point, too.
-        if os.getenv('AZURE_CI_WINDOWS', 'false').lower() == 'true':
-            return
         if self.figure._is_active():
-            if sys.platform != 'darwin':
+            # macOS, Azure
+            bad_system = (
+                sys.platform == 'darwin' or
+                os.getenv('AZURE_CI_WINDOWS', 'false').lower() == 'true')
+            # MESA (could use GPUInfo / _get_gpu_info here, but it takes
+            # > 700 ms to make a new window + report capabilities!)
+            # CircleCI's is: "Mesa 20.0.8 via llvmpipe (LLVM 10.0.0, 256 bits)"
+            gpu_info = self.plotter.ren_win.ReportCapabilities()
+            gpu_info = re.findall("OpenGL renderer string:(.+)\n", gpu_info)
+            bad_system |= 'mesa' in ' '.join(gpu_info).lower().split()
+            if not bad_system:
                 for renderer in self._all_renderers:
                     renderer.enable_anti_aliasing()
             for plotter in self._all_plotters:


Test patch:
Repository: mne-tools/mne-python

Issue:
Argument `theme` of `raw.plot()` or config key does not work on macOS
As spotted following the discussion here https://github.com/mne-tools/mne-qt-browser/issues/83 the argument `theme` does not change the theme on either my macOS or Windows computer.

Sample code:

```
import mne


folder = mne.datasets.sample.data_path() / 'MEG' / 'sample'
raw = mne.io.read_raw(folder / 'sample_audvis_filt-0-40_raw.fif', preload=True)
raw.plot(theme='dark')
```


Discussion:

Resolving patch:
diff --git a/mne/viz/raw.py b/mne/viz/raw.py
--- a/mne/viz/raw.py
+++ b/mne/viz/raw.py
@@ -351,7 +351,8 @@ def plot_raw(raw, events=None, duration=10.0, start=0.0, n_channels=20,
                   bgcolor=bgcolor,
                   # Qt-specific
                   precompute=precompute,
-                  use_opengl=use_opengl)
+                  use_opengl=use_opengl,
+                  theme=theme)
 
     fig = _get_browser(show=show, block=block, **params)
 


Test patch:
Repository: mne-tools/mne-python

Issue:
plot_psd with spatial_colors=True fails when some location values are nan
Adding a simple warning would help, it took me a while to realize that this was the reason my plot was all in black. Even better would be plotting only the nan electrodes in black and showind them beside the head in the little head color plot.


Discussion:
when trying I see in my terminal:

RuntimeWarning: Channel locations not available. Disabling spatial colors.

can you confirm that the warning is already there?

I only get these two:

.../site-packages/matplotlib/colors.py:259: RuntimeWarning: invalid value encountered in less if np.any((result < 0) | (result > 1)):

.../site-packages/matplotlib/colors.py:259: RuntimeWarning: invalid value encountered in greater np.any((result < 0) | (result > 1)):
please a file and a script so we can try to replicate

>


Resolving patch:
diff --git a/mne/viz/evoked.py b/mne/viz/evoked.py
--- a/mne/viz/evoked.py
+++ b/mne/viz/evoked.py
@@ -168,8 +168,8 @@ def _topo_closed(events, ax, lines, fill):
 def _rgb(x, y, z):
     """Transform x, y, z values into RGB colors."""
     rgb = np.array([x, y, z]).T
-    rgb -= rgb.min(0)
-    rgb /= np.maximum(rgb.max(0), 1e-16)  # avoid div by zero
+    rgb -= np.nanmin(rgb, 0)
+    rgb /= np.maximum(np.nanmax(rgb, 0), 1e-16)  # avoid div by zero
     return rgb
 
 


Test patch:
diff --git a/mne/viz/tests/test_evoked.py b/mne/viz/tests/test_evoked.py
--- a/mne/viz/tests/test_evoked.py
+++ b/mne/viz/tests/test_evoked.py
@@ -182,6 +182,13 @@ def test_plot_evoked():
     with pytest.raises(ValueError, match='must be reshapable into a 2D array'):
         fig = evoked.plot(time_unit='s', highlight=0.1)
 
+    # set one channel location to nan, confirm spatial_colors still works
+    evoked = _get_epochs().load_data().average('grad')  # reload data
+    evoked.info['chs'][0]['loc'][:] = np.nan
+    fig = evoked.plot(time_unit='s', spatial_colors=True)
+    line_clr = [x.get_color() for x in fig.axes[0].get_lines()]
+    assert not np.all(np.isnan(line_clr) & (line_clr == 0))
+
 
 def test_constrained_layout():
     """Test that we handle constrained layouts correctly."""
Repository: mne-tools/mne-python

Issue:
Version switcher broken when viewing dev docs
When looking at the devel docs e.g. at:

https://mne.tools/dev/index.html

and then trying to use the version switcher dropdown to switch to the documentation of an earlier release, one gets a 404.


Discussion:
Probably a new pydata-sphinx-theme / Sphinx bug. I'll look hopefully soon

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -580,7 +580,6 @@ def append_attr_meth_examples(app, what, name, obj, options, lines):
     'google_analytics_id': 'UA-37225609-1',
     'switcher': {
         'json_url': 'https://mne.tools/dev/_static/versions.json',
-        'url_template': 'https://mne.tools/{version}/',
         'version_match': switcher_version_match,
     }
 }


Test patch:
Repository: mne-tools/mne-python

Issue:
montage_sgskip.py example doesn't run
When trying to run the example in `examples/visualization/montage_sgskip.py`, I get an exception:

```python
ValueError: A head<->mri transformation matrix (trans) is required to plot head surfaces in head coordinates, `trans=None` is not allowed
```
It runs if I pass `trans='fsaverage'` but I'm not sure this is how this example intended to behave (as the BEM is based on a sphere here).

@agramfort care to take a look?


Discussion:

Resolving patch:
diff --git a/examples/visualization/montage_sgskip.py b/examples/visualization/montage_sgskip.py
--- a/examples/visualization/montage_sgskip.py
+++ b/examples/visualization/montage_sgskip.py
@@ -16,6 +16,7 @@
 # %%
 
 import os.path as op
+import numpy as np
 
 import mne
 from mne.channels.montage import get_builtin_montages
@@ -35,6 +36,7 @@
     fig = mne.viz.plot_alignment(
         # Plot options
         show_axes=True, dig='fiducials', surfaces='head',
+        trans=mne.Transform("head", "mri", trans=np.eye(4)),  # identity
         bem=sphere, info=info)
     set_3d_view(figure=fig, azimuth=135, elevation=80)
     set_3d_title(figure=fig, title=current_montage)


Test patch:
Repository: mne-tools/mne-python

Issue:
Remove recommended Qt version pinning for macOS in warning?
We somehow emit a warning under certain circumstances, suggesting users install old Qt versions. I would think this should be removed, no?

cc @larsoner 

https://github.com/mne-tools/mne-python/blob/5ff33fa5ae8c1b0004ef894d5fe009140203ed48/mne/utils/check.py#L827-L829


Discussion:

Resolving patch:
diff --git a/mne/utils/check.py b/mne/utils/check.py
--- a/mne/utils/check.py
+++ b/mne/utils/check.py
@@ -826,7 +826,7 @@ def _check_qt_version(*, return_api=False):
             if not _compare_version(version, '>=', '5.10'):
                 warn(f'macOS users should use {api} >= 5.10 for GUIs, '
                      f'got {version}. Please upgrade e.g. with:\n\n'
-                     f'    pip install "{api}>=5.10,<5.14"\n')
+                     f'    pip install "{api}>=5.10"\n')
     if return_api:
         return version, api
     else:


Test patch:
Repository: mne-tools/mne-python

Issue:
mne.Info._repr_html_() does not show correct sensor locations?
I noticed that `mne.Info._repr_html_()` does not show the correct number of digitized sensor locations. Reproducible example (reprex):

```python
import mne

info = mne.create_info(["C3", "Cz", "C4"], 256, "eeg")
info.set_montage("biosemi64")

print(info)  # shows "dig: 6 items (3 Cardinal, 3 EEG)"
print(info._repr_html_())  # shows "0 points" for "Digitized points"
```


Discussion:
yes it should be the same information so there is a bug...

> Message ID: ***@***.***>
>


Resolving patch:
diff --git a/mne/io/meas_info.py b/mne/io/meas_info.py
--- a/mne/io/meas_info.py
+++ b/mne/io/meas_info.py
@@ -1190,14 +1190,12 @@ def _repr_html_(self, caption=None):
         # repr).
 
         # meas date
-        if 'meas_date' in self and self['meas_date'] is not None:
-            meas_date = self['meas_date'].strftime(
-                "%B %d, %Y  %H:%M:%S"
-            ) + ' GMT'
-        else:
-            meas_date = None
+        meas_date = self.get('meas_date')
+        if meas_date is not None:
+            meas_date = meas_date.strftime("%B %d, %Y  %H:%M:%S") + ' GMT'
 
-        if 'projs' in self and self['projs']:
+        projs = self.get('projs')
+        if projs:
             projs = [
                 f'{p["desc"]} : {"on" if p["active"] else "off"}'
                 for p in self['projs']
@@ -1205,39 +1203,22 @@ def _repr_html_(self, caption=None):
         else:
             projs = None
 
-        if 'subject_info' in self:
-            subject_info = self['subject_info']
-        else:
-            subject_info = None
-
-        if 'lowpass' in self:
-            lowpass = self['lowpass']
-        else:
-            lowpass = None
-
-        if 'highpass' in self:
-            highpass = self['highpass']
-        else:
-            highpass = None
-
-        if 'sfreq' in self:
-            sfreq = self['sfreq']
-        else:
-            sfreq = None
-
-        if 'experimenter' in self:
-            experimenter = self['experimenter']
-        else:
-            experimenter = None
-
         info_template = repr_templates_env.get_template('info.html.jinja')
-        html += info_template.render(
-            caption=caption, meas_date=meas_date, ecg=ecg,
-            eog=eog, good_channels=good_channels, bad_channels=bad_channels,
-            projs=projs, subject_info=subject_info, lowpass=lowpass,
-            highpass=highpass, sfreq=sfreq, experimenter=experimenter
+        return html + info_template.render(
+            caption=caption,
+            meas_date=meas_date,
+            projs=projs,
+            ecg=ecg,
+            eog=eog,
+            good_channels=good_channels,
+            bad_channels=bad_channels,
+            dig=self.get('dig'),
+            subject_info=self.get('subject_info'),
+            lowpass=self.get('lowpass'),
+            highpass=self.get('highpass'),
+            sfreq=self.get('sfreq'),
+            experimenter=self.get('experimenter'),
         )
-        return html
 
 
 def _simplify_info(info):


Test patch:
Repository: mne-tools/mne-python

Issue:
update path handling in examples/decoding/decoding_rsa_sgskip.py
all of our `data_path` functions now return `pathlib.Path` objects, which allows things like the following:

https://github.com/mne-tools/mne-python/blob/37a9e5587443109515a85cdc4396af4e014ecf82/examples/datasets/brainstorm_data.py#L32-L35

Compare this to the old pattern (using `os.path.join`, often imported as `op.join`):

```py
raw_path = os.path.join(data_path, 'MEG', 'bst_raw',
                        'subj001_somatosensory_20111109_01_AUX-f.ds')
```

or the *really* old pattern (using the `+` operator on plain strings):

```py
raw_path = (data_path + '/MEG/bst_raw/' +
            'subj001_somatosensory_20111109_01_AUX-f.ds')
```

Update the paths in the file mentioned in the issue title to use the new pathlib-style, which is considered the modern, best-practice way to handle file paths.



Discussion:

Resolving patch:
diff --git a/examples/decoding/decoding_rsa_sgskip.py b/examples/decoding/decoding_rsa_sgskip.py
--- a/examples/decoding/decoding_rsa_sgskip.py
+++ b/examples/decoding/decoding_rsa_sgskip.py
@@ -30,7 +30,6 @@
 
 # %%
 
-import os.path as op
 import numpy as np
 from pandas import read_csv
 import matplotlib.pyplot as plt
@@ -52,7 +51,7 @@
 data_path = visual_92_categories.data_path()
 
 # Define stimulus - trigger mapping
-fname = op.join(data_path, 'visual_stimuli.csv')
+fname = data_path / 'visual_stimuli.csv'
 conds = read_csv(fname)
 print(conds.head(5))
 
@@ -79,9 +78,10 @@
 ##############################################################################
 # Read MEG data
 n_runs = 4  # 4 for full data (use less to speed up computations)
-fname = op.join(data_path, 'sample_subject_%i_tsss_mc.fif')
-raws = [read_raw_fif(fname % block, verbose='error')
-        for block in range(n_runs)]  # ignore filename warnings
+fnames = [data_path / 'sample_subject_{}_tsss_mc.fif'.format(b)
+          for b in range(n_runs)]
+raws = [read_raw_fif(fname, verbose='error')
+        for fname in fnames]  # ignore filename warnings
 raw = concatenate_raws(raws)
 
 events = mne.find_events(raw, min_duration=.002)


Test patch:
Repository: mne-tools/mne-python

Issue:
update path handling in examples/forward/source_space_morphing.py
all of our `data_path` functions now return `pathlib.Path` objects, which allows things like the following:

https://github.com/mne-tools/mne-python/blob/37a9e5587443109515a85cdc4396af4e014ecf82/examples/datasets/brainstorm_data.py#L32-L35

Compare this to the old pattern (using `os.path.join`, often imported as `op.join`):

```py
raw_path = os.path.join(data_path, 'MEG', 'bst_raw',
                        'subj001_somatosensory_20111109_01_AUX-f.ds')
```

or the *really* old pattern (using the `+` operator on plain strings):

```py
raw_path = (data_path + '/MEG/bst_raw/' +
            'subj001_somatosensory_20111109_01_AUX-f.ds')
```

Update the paths in the file mentioned in the issue title to use the new pathlib-style, which is considered the modern, best-practice way to handle file paths.



Discussion:

Resolving patch:
diff --git a/examples/forward/source_space_morphing.py b/examples/forward/source_space_morphing.py
--- a/examples/forward/source_space_morphing.py
+++ b/examples/forward/source_space_morphing.py
@@ -22,19 +22,17 @@
 
 # %%
 
-import os.path as op
-
 import mne
 
 data_path = mne.datasets.sample.data_path()
-subjects_dir = op.join(data_path, 'subjects')
-fname_trans = op.join(data_path, 'MEG', 'sample',
-                      'sample_audvis_raw-trans.fif')
-fname_bem = op.join(subjects_dir, 'sample', 'bem',
-                    'sample-5120-bem-sol.fif')
-fname_src_fs = op.join(subjects_dir, 'fsaverage', 'bem',
-                       'fsaverage-ico-5-src.fif')
-raw_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw.fif')
+subjects_dir = data_path / 'subjects'
+fname_trans = (
+    data_path / 'MEG' / 'sample' / 'sample_audvis_raw-trans.fif')
+fname_bem = (
+    subjects_dir / 'sample' / 'bem' / 'sample-5120-bem-sol.fif')
+fname_src_fs = (
+    subjects_dir / 'fsaverage' / 'bem' / 'fsaverage-ico-5-src.fif')
+raw_fname = data_path / 'MEG' / 'sample' / 'sample_audvis_raw.fif'
 
 # Get relevant channel information
 info = mne.io.read_info(raw_fname)


Test patch:
Repository: mne-tools/mne-python

Issue:
update path handling in examples/inverse/evoked_ers_source_power.py
all of our `data_path` functions now return `pathlib.Path` objects, which allows things like the following:

https://github.com/mne-tools/mne-python/blob/37a9e5587443109515a85cdc4396af4e014ecf82/examples/datasets/brainstorm_data.py#L32-L35

Compare this to the old pattern (using `os.path.join`, often imported as `op.join`):

```py
raw_path = os.path.join(data_path, 'MEG', 'bst_raw',
                        'subj001_somatosensory_20111109_01_AUX-f.ds')
```

or the *really* old pattern (using the `+` operator on plain strings):

```py
raw_path = (data_path + '/MEG/bst_raw/' +
            'subj001_somatosensory_20111109_01_AUX-f.ds')
```

Update the paths in the file mentioned in the issue title to use the new pathlib-style, which is considered the modern, best-practice way to handle file paths.



Discussion:

Resolving patch:
diff --git a/examples/inverse/evoked_ers_source_power.py b/examples/inverse/evoked_ers_source_power.py
--- a/examples/inverse/evoked_ers_source_power.py
+++ b/examples/inverse/evoked_ers_source_power.py
@@ -17,7 +17,6 @@
 # License: BSD-3-Clause
 
 # %%
-import os.path as op
 
 import numpy as np
 import mne
@@ -35,8 +34,8 @@
 data_path = somato.data_path()
 subject = '01'
 task = 'somato'
-raw_fname = op.join(data_path, 'sub-{}'.format(subject), 'meg',
-                    'sub-{}_task-{}_meg.fif'.format(subject, task))
+raw_fname = (data_path / 'sub-{}'.format(subject) / 'meg' /
+             'sub-{}_task-{}_meg.fif'.format(subject, task))
 
 # crop to 5 minutes to save memory
 raw = mne.io.read_raw_fif(raw_fname).crop(0, 300)
@@ -54,9 +53,9 @@
                     preload=True, decim=3)
 
 # Read forward operator and point to freesurfer subject directory
-fname_fwd = op.join(data_path, 'derivatives', 'sub-{}'.format(subject),
-                    'sub-{}_task-{}-fwd.fif'.format(subject, task))
-subjects_dir = op.join(data_path, 'derivatives', 'freesurfer', 'subjects')
+fname_fwd = (data_path / 'derivatives' / 'sub-{}'.format(subject) /
+             'sub-{}_task-{}-fwd.fif'.format(subject, task))
+subjects_dir = data_path / 'derivatives' / 'freesurfer' / 'subjects'
 
 fwd = mne.read_forward_solution(fname_fwd)
 


Test patch:
Repository: mne-tools/mne-python

Issue:
update path handling in examples/io/read_noise_covariance_matrix.py
all of our `data_path` functions now return `pathlib.Path` objects, which allows things like the following:

https://github.com/mne-tools/mne-python/blob/37a9e5587443109515a85cdc4396af4e014ecf82/examples/datasets/brainstorm_data.py#L32-L35

Compare this to the old pattern (using `os.path.join`, often imported as `op.join`):

```py
raw_path = os.path.join(data_path, 'MEG', 'bst_raw',
                        'subj001_somatosensory_20111109_01_AUX-f.ds')
```

or the *really* old pattern (using the `+` operator on plain strings):

```py
raw_path = (data_path + '/MEG/bst_raw/' +
            'subj001_somatosensory_20111109_01_AUX-f.ds')
```

Update the paths in the file mentioned in the issue title to use the new pathlib-style, which is considered the modern, best-practice way to handle file paths.



Discussion:

Resolving patch:
diff --git a/examples/io/read_noise_covariance_matrix.py b/examples/io/read_noise_covariance_matrix.py
--- a/examples/io/read_noise_covariance_matrix.py
+++ b/examples/io/read_noise_covariance_matrix.py
@@ -14,13 +14,12 @@
 
 # %%
 
-from os import path as op
 import mne
 from mne.datasets import sample
 
 data_path = sample.data_path()
-fname_cov = op.join(data_path, 'MEG', 'sample', 'sample_audvis-cov.fif')
-fname_evo = op.join(data_path, 'MEG', 'sample', 'sample_audvis-ave.fif')
+fname_cov = data_path / 'MEG' / 'sample' / 'sample_audvis-cov.fif'
+fname_evo = data_path / 'MEG' / 'sample' / 'sample_audvis-ave.fif'
 
 cov = mne.read_cov(fname_cov)
 print(cov)


Test patch:
Repository: mne-tools/mne-python

Issue:
update path handling in examples/inverse/dics_source_power.py
all of our `data_path` functions now return `pathlib.Path` objects, which allows things like the following:

https://github.com/mne-tools/mne-python/blob/37a9e5587443109515a85cdc4396af4e014ecf82/examples/datasets/brainstorm_data.py#L32-L35

Compare this to the old pattern (using `os.path.join`, often imported as `op.join`):

```py
raw_path = os.path.join(data_path, 'MEG', 'bst_raw',
                        'subj001_somatosensory_20111109_01_AUX-f.ds')
```

or the *really* old pattern (using the `+` operator on plain strings):

```py
raw_path = (data_path + '/MEG/bst_raw/' +
            'subj001_somatosensory_20111109_01_AUX-f.ds')
```

Update the paths in the file mentioned in the issue title to use the new pathlib-style, which is considered the modern, best-practice way to handle file paths.



Discussion:
This is awesome, I love the `pathlib` module. Happy to work on this next week.
Great! Everyone will do one of these pathlib issues as their "warmup" on the first day 🙂 

Resolving patch:
diff --git a/examples/inverse/dics_source_power.py b/examples/inverse/dics_source_power.py
--- a/examples/inverse/dics_source_power.py
+++ b/examples/inverse/dics_source_power.py
@@ -20,7 +20,6 @@
 # License: BSD-3-Clause
 
 # %%
-import os.path as op
 
 import numpy as np
 import mne
@@ -35,8 +34,8 @@
 data_path = somato.data_path()
 subject = '01'
 task = 'somato'
-raw_fname = op.join(data_path, 'sub-{}'.format(subject), 'meg',
-                    'sub-{}_task-{}_meg.fif'.format(subject, task))
+raw_fname = (data_path / f'sub-{subject}' / 'meg' /
+             f'sub-{subject}_task-{task}_meg.fif')
 
 # Use a shorter segment of raw just for speed here
 raw = mne.io.read_raw_fif(raw_fname)
@@ -49,9 +48,10 @@
 del raw
 
 # Paths to forward operator and FreeSurfer subject directory
-fname_fwd = op.join(data_path, 'derivatives', 'sub-{}'.format(subject),
-                    'sub-{}_task-{}-fwd.fif'.format(subject, task))
-subjects_dir = op.join(data_path, 'derivatives', 'freesurfer', 'subjects')
+fname_fwd = (data_path / 'derivatives' / f'sub-{subject}' /
+             f'sub-{subject}_task-{task}-fwd.fif')
+
+subjects_dir = data_path / 'derivatives' / 'freesurfer' / 'subjects'
 
 # %%
 # We are interested in the beta band. Define a range of frequencies, using a


Test patch: