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

Issue:
`write_raw_bids` shoudn't write stim channels to `electrodes.tsv`
I suppose I will label this as a bug, as the current behaviour is inconsistent with the BIDS standard, per discussion in #1006 

`write_raw_bids` shouldn't write stim channels to the `electrodes.tsv` sidecar file, because stim channels don't have associated electrodes.

I can amend the code in `_write_electrodes_tsv`, and submit a PR. I will suggest something like:
```
if ch['kind'] == FIFF.FIFFV_STIM_CH:
    continue
```
at the beginning of this for loop:
https://github.com/mne-tools/mne-bids/blob/54d50f61e01424081793db7ef3f68659319056cc/mne_bids/dig.py#L140-L152


Discussion:
+1 on fixing this, I like your proposal!

Edit:
I'd add a log message with severity `DEBUG` too

Resolving patch:
diff --git a/mne_bids/dig.py b/mne_bids/dig.py
--- a/mne_bids/dig.py
+++ b/mne_bids/dig.py
@@ -138,7 +138,11 @@ def _write_electrodes_tsv(raw, fname, datatype, overwrite=False):
     # create list of channel coordinates and names
     x, y, z, names = list(), list(), list(), list()
     for ch in raw.info['chs']:
-        if (
+        if ch['kind'] == FIFF.FIFFV_STIM_CH:
+            logger.debug(f"Not writing stim chan {ch['ch_name']} "
+                         f"to electrodes.tsv")
+            continue
+        elif (
             np.isnan(ch['loc'][:3]).any() or
             np.allclose(ch['loc'][:3], 0)
         ):


Test patch:
diff --git a/mne_bids/tests/test_dig.py b/mne_bids/tests/test_dig.py
--- a/mne_bids/tests/test_dig.py
+++ b/mne_bids/tests/test_dig.py
@@ -325,3 +325,28 @@ def test_convert_montage():
     assert pos['coord_frame'] == 'mri'
     assert_almost_equal(pos['ch_pos']['EEG 001'],
                         [-0.0313669, 0.0540269, 0.0949191])
+
+
+def test_electrodes_io(tmp_path):
+    """Ensure only electrodes end up in *_electrodes.json."""
+    raw = _load_raw()
+    raw.pick_types(eeg=True, stim=True)  # we don't need meg channels
+    bids_root = tmp_path / 'bids1'
+    bids_path = _bids_path.copy().update(root=bids_root, datatype='eeg')
+    write_raw_bids(raw=raw, bids_path=bids_path)
+
+    electrodes_path = (
+        bids_path.copy()
+        .update(
+            task=None,
+            run=None,
+            space='CapTrak',
+            suffix='electrodes',
+            extension='.tsv'
+        )
+    )
+    with open(electrodes_path, encoding='utf-8') as sidecar:
+        n_entries = len([line for line in sidecar
+                         if 'name' not in line])  # don't need the header
+        # only eeg chs w/ electrode pos should be written to electrodes.tsv
+        assert n_entries == len(raw.get_channel_types('eeg'))
Repository: mne-tools/mne-bids

Issue:
Gracefully handle situations where TSV files only contain the column headers
`_from_tsv()` should probably raise an exception, warn, or return `None` if it can only find a header, but no actual data in the parsed TSV file.

Issue reported on the forum:
https://mne.discourse.group/t/errors-with-read-raw-bids-with-edf-files/4082

Affected OpenNeuro dataset:
https://openneuro.org/datasets/ds002720


Discussion:
I think warn and return None would be good.


Resolving patch:
diff --git a/mne_bids/tsv_handler.py b/mne_bids/tsv_handler.py
--- a/mne_bids/tsv_handler.py
+++ b/mne_bids/tsv_handler.py
@@ -1,8 +1,10 @@
 """Private functions to handle tabular data."""
-import numpy as np
 from collections import OrderedDict
 from copy import deepcopy
 
+from mne.utils import warn
+import numpy as np
+
 
 def _combine_rows(data1, data2, drop_column=None):
     """Add two OrderedDict's together and optionally drop repeated data.
@@ -109,7 +111,10 @@ def _drop(data, values, column):
     # Cast `values` to the same dtype as `new_data_col` to avoid a NumPy
     # FutureWarning, see
     # https://github.com/mne-tools/mne-bids/pull/372
-    values = np.array(values, dtype=new_data_col.dtype)
+    dtype = new_data_col.dtype
+    if new_data_col.shape == (0,):
+        dtype = np.array(values).dtype
+    values = np.array(values, dtype=dtype)
 
     mask = np.in1d(new_data_col, values, invert=True)
     for key in new_data.keys():
@@ -147,8 +152,16 @@ def _from_tsv(fname, dtypes=None):
     if not len(dtypes) == info.shape[1]:
         raise ValueError('dtypes length mismatch. Provided: {0}, '
                          'Expected: {1}'.format(len(dtypes), info.shape[1]))
+    empty_cols = 0
     for i, name in enumerate(column_names):
-        data_dict[name] = info[:, i].astype(dtypes[i]).tolist()
+        values = info[:, i].astype(dtypes[i]).tolist()
+        data_dict[name] = values
+        if len(values) == 0:
+            empty_cols += 1
+
+    if empty_cols == len(column_names):
+        warn(f"TSV file is empty: '{fname}'")
+
     return data_dict
 
 


Test patch:
diff --git a/mne_bids/tests/test_tsv_handler.py b/mne_bids/tests/test_tsv_handler.py
--- a/mne_bids/tests/test_tsv_handler.py
+++ b/mne_bids/tests/test_tsv_handler.py
@@ -63,6 +63,12 @@ def test_tsv_handler(tmp_path):
     d = _from_tsv(d_path)
     assert d['a'] == ['1', '2', '3', '4']
 
+    # test an empty tsv (just headers)
+    _to_tsv(odict(onset=[], duration=[], trial_type=[]), d_path)
+    with pytest.warns(RuntimeWarning, match="TSV file is empty"):
+        d = _from_tsv(d_path)
+    d = _drop(d, "n/a", "trial_type")
+
 
 def test_contains_row_different_types():
     """Test that _contains_row() can handle different dtypes without warning.
Repository: mne-tools/mne-bids

Issue:
MAINT: New release?
It has been ~6 months, time for a release? Also it might be necessary to work with the imminent 1.2 release, not sure. But it's generally better if `mne-*` release before `mne` itself. mne-connectivity and mne-realtime have released recently. WDYT?


Discussion:
I'm always happy whenever I see new releases! Let's do it!
I simply moved all open issues tagged for 0.11 to the 0.12 milestone. ;)
Who volunteers to do it? Not me :)
I see @sappelhoff thumb-up'd your suggestion, so I guess it's all on him now 😁
I can do it ~~soon~~ on Saturday :+1:

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -143,8 +143,9 @@
 
 html_context = {
     'versions_dropdown': {
-        'dev': 'v0.11 (devel)',
-        'stable': 'v0.10 (stable)',
+        'dev': 'v0.12 (devel)',
+        'stable': 'v0.11 (stable)',
+        'v0.10': 'v0.10',
         'v0.9': 'v0.9',
         'v0.8': 'v0.8',
         'v0.7': 'v0.7',
diff --git a/mne_bids/__init__.py b/mne_bids/__init__.py
--- a/mne_bids/__init__.py
+++ b/mne_bids/__init__.py
@@ -1,6 +1,6 @@
 """MNE software for easily interacting with BIDS compatible datasets."""
 
-__version__ = '0.11.dev0'
+__version__ = '0.11'
 from mne_bids import commands
 from mne_bids.report import make_report
 from mne_bids.path import (BIDSPath, get_datatypes, get_entity_vals,


Test patch:
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
--- a/.github/workflows/unit_tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -112,7 +112,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-18.04, ubuntu-latest, macos-latest, windows-latest]
+        os: [ubuntu-20.04, ubuntu-latest, macos-latest, windows-latest]
         python-version: ["3.7", "3.10"]  # Oldest and newest supported versions
         mne-version: [mne-stable]
         bids-validator-version: [validator-stable]
@@ -141,10 +141,6 @@ jobs:
         python-version: ${{ matrix.python-version }}
 
     - name: Restore cache
-      # Restoring cache on Ubuntu 20.04 seems buggy
-      # only do it on other operating systems
-      # https://stackoverflow.com/q/61875869/5201771
-      if: "matrix.os != 'ubuntu-latest'"
       uses: actions/cache@v3
       with:
         path: ${{ env.pythonLocation }}
Repository: mne-tools/mne-bids

Issue:
CI: Problem with `gen_cli.py`
see: https://app.circleci.com/pipelines/github/mne-tools/mne-bids/4785/workflows/21ad6804-1cc2-42dd-9133-f24de2ea3db5/jobs/6923

```
Traceback (most recent call last):
  File "/home/circleci/mne_bids_env/lib/python3.9/site-packages/sphinx/events.py", line 94, in emit
    results.append(listener.handler(self.app, *args))
  File "/home/circleci/project/doc/sphinxext/gen_cli.py", line 84, in generate_cli_rst
    output[0], output[2] = output[2], output[0]
IndexError: list index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/circleci/mne_bids_env/lib/python3.9/site-packages/sphinx/cmd/build.py", line 276, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/home/circleci/mne_bids_env/lib/python3.9/site-packages/sphinx/application.py", line 262, in __init__
    self._init_builder()
  File "/home/circleci/mne_bids_env/lib/python3.9/site-packages/sphinx/application.py", line 335, in _init_builder
    self.events.emit('builder-inited')
  File "/home/circleci/mne_bids_env/lib/python3.9/site-packages/sphinx/events.py", line 105, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function generate_cli_rst at 0x7fe9bf90c160> for event 'builder-inited' threw an exception (exception: list index out of range)
```

https://github.com/mne-tools/mne-bids/blob/46b0a5300ed5c17ca93b8bbf1d9542069597ef62/doc/sphinxext/gen_cli.py#L1


Discussion:
I tested this locally and it only starts failing when updating to MNE dev version.
Ahh, could this be related to https://github.com/mne-tools/mne-python/pull/11266 ?
@larsoner I think it may fail here because of the removed `print(output)` in `run_subprocess` from https://github.com/mne-tools/mne-python/pull/11266

Do you have a suggestion on what to fix here?

Resolving patch:
diff --git a/doc/sphinxext/gen_cli.py b/doc/sphinxext/gen_cli.py
--- a/doc/sphinxext/gen_cli.py
+++ b/doc/sphinxext/gen_cli.py
@@ -76,8 +76,7 @@ def generate_cli_rst(app=None):
             cmd_name = fname[:-3]
             run_name = op.join(cli_path, fname)
             output, _ = run_subprocess([sys.executable, run_name, '--help'],
-                                       stdout=subprocess.PIPE,
-                                       stderr=subprocess.PIPE, verbose=False)
+                                       verbose=False)
             output = output.splitlines()
 
             # Swap usage and title lines


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

Issue:
doc build fails because of mne (main)
> ImportError: cannot import name 'psd_welch' from 'mne.time_frequency' (/home/circleci/mne_bids_env/lib/python3.9/site-packages/mne/time_frequency/__init__.py)


https://app.circleci.com/pipelines/github/mne-tools/mne-bids/4820/workflows/813d1bc7-3b45-463b-af0e-3d5ddab39dc7/jobs/6961


Discussion:
seems to be due to:

- https://github.com/mne-tools/mne-python/pull/11304

Resolving patch:
diff --git a/examples/convert_nirs_to_bids.py b/examples/convert_nirs_to_bids.py
--- a/examples/convert_nirs_to_bids.py
+++ b/examples/convert_nirs_to_bids.py
@@ -29,7 +29,7 @@
 import shutil
 
 import mne
-import mne_nirs  # For convenient downloading of example data
+from mne_nirs import datasets  # For convenient downloading of example data
 
 from mne_bids import write_raw_bids, BIDSPath, print_dir_tree
 from mne_bids.stats import count_events
@@ -44,7 +44,7 @@
 # We will use the MNE-NIRS package which includes convenient functions to
 # download openly available datasets.
 
-data_dir = pathlib.Path(mne_nirs.datasets.fnirs_motor_group.data_path())
+data_dir = pathlib.Path(datasets.fnirs_motor_group.data_path())
 
 # Let's see whether the data has been downloaded using a quick visualization
 # of the directory tree.


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

Issue:
Cut 0.12 release
In preparation for the MNE-Python 1.3 release alongside with new standalone installers that will also feature the M E-BIDS-Pipeline, we should soon make a new release of MNE-BIDS (within the next two weeks or so?)


Discussion:
@sappelhoff Do you think you'd have time to cut a release within the next few days? Otherwise I could try to give it a shot, but I'm on a tight schedule :/

cc @larsoner 
I'm on vacation and have some time on my hands, so I can do it 👍 

Anything we should wait for / get in first?
Great!

I don't think we have any blockers. 👍

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -143,8 +143,9 @@
 
 html_context = {
     'versions_dropdown': {
-        'dev': 'v0.12 (devel)',
-        'stable': 'v0.11 (stable)',
+        'dev': 'v0.13 (devel)',
+        'stable': 'v0.12 (stable)',
+        'v0.11': 'v0.11',
         'v0.10': 'v0.10',
         'v0.9': 'v0.9',
         'v0.8': 'v0.8',
diff --git a/mne_bids/__init__.py b/mne_bids/__init__.py
--- a/mne_bids/__init__.py
+++ b/mne_bids/__init__.py
@@ -1,6 +1,6 @@
 """MNE software for easily interacting with BIDS compatible datasets."""
 
-__version__ = '0.12.dev0'
+__version__ = '0.12'
 from mne_bids import commands
 from mne_bids.report import make_report
 from mne_bids.path import (BIDSPath, get_datatypes, get_entity_vals,


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

Issue:
doc build fails: "tut-ieeg-localize" moved
Our doc build is failing with a warning because the reference to `tut-ieeg-localize` cannot be found anymore. Was this something in MNE-Python that has now moved? @alexrockhill do you know more? :-)

> /home/circleci/project/doc/auto_examples/convert_ieeg_to_bids.rst:1083: WARNING: undefined label: 'tut-ieeg-localize'

https://app.circleci.com/pipelines/github/mne-tools/mne-bids/5179/workflows/d0b5cc9b-cda4-436b-9e96-1edeea651d21/jobs/7347


Discussion:
It nows lives in a separate repo with a different intersphinx

https://mne.tools/mne-gui-addons/auto_examples/locate_ieeg_micro.html#locating-micro-scale-intracranial-electrode-contacts

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -166,6 +166,7 @@
 intersphinx_mapping = {
     'python': ('https://docs.python.org/3', None),
     'mne': ('https://mne.tools/dev', None),
+    'mne-gui-addons': ('https://mne.tools/mne-gui-addons', None),
     'numpy': ('https://numpy.org/devdocs', None),
     'scipy': ('https://scipy.github.io/devdocs', None),
     'matplotlib': ('https://matplotlib.org', None),


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

Issue:
MNE-BIDS 0.13 release
A release of MNE-BIDS has been requested: https://mne.discourse.group/t/mne-bids-0-13-release-date/7291/2

Our last release has been in December 2022, so I feel like cutting a release now is reasonable.

I'll migrate issues from the [0.13 milestone](https://github.com/mne-tools/mne-bids/milestone/14) to a new 0.14 milestone.

Please comment here if you need some particular thing to be fixed before the release.

cc @agramfort @hoechenberger @larsoner 


Discussion:
All green from my end
ok green for me too !

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

we should probably wait for the MNE-Python 1.5 release:

- https://github.com/mne-tools/mne-python/issues/11843

... and then support `mne>=1.4`

Resolving patch:
diff --git a/mne_bids/__init__.py b/mne_bids/__init__.py
--- a/mne_bids/__init__.py
+++ b/mne_bids/__init__.py
@@ -1,6 +1,6 @@
 """MNE software for easily interacting with BIDS compatible datasets."""
 
-__version__ = "0.13.dev0"
+__version__ = "0.13"
 from mne_bids import commands
 from mne_bids.report import make_report
 from mne_bids.path import (


Test patch:
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
--- a/.github/workflows/unit_tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -100,11 +100,11 @@ jobs:
       run: |
         python -m pip install .[full]
         python -c 'import mne_bids; print(mne_bids.__version__)'
-        python -c 'import pybv; print(pybv.__version__)'
         python -c 'import nibabel; print(nibabel.__version__)'
+        python -c 'import pybv; print(pybv.__version__)'
+        python -c 'import pymatreader; print(pymatreader.__version__)'
         python -c 'import matplotlib; print(matplotlib.__version__)'
         python -c 'import pandas; print(pandas.__version__)'
-        python -c 'import pymatreader; print(pymatreader.__version__)'
         python -c 'import EDFlib; print("EDFlib has no .__version__")'
 
   test:
@@ -171,13 +171,13 @@ jobs:
     - name: Install MNE (stable)
       if: "matrix.mne-version == 'mne-stable'"
       run: |
-        git clone --single-branch --branch maint/1.4 https://github.com/mne-tools/mne-python.git
+        git clone --single-branch --branch maint/1.5 https://github.com/mne-tools/mne-python.git
         python -m pip install -e ./mne-python
 
     - name: Install MNE (previous stable)
       if: "matrix.mne-version == 'mne-prev-stable'"
       run: |
-        git clone --single-branch --branch maint/1.3 https://github.com/mne-tools/mne-python.git
+        git clone --single-branch --branch maint/1.4 https://github.com/mne-tools/mne-python.git
         python -m pip install -e ./mne-python
 
     - name: Install MNE (main)
diff --git a/test_requirements.txt b/test_requirements.txt
--- a/test_requirements.txt
+++ b/test_requirements.txt
@@ -1,13 +1,12 @@
+mne>=1.4
 numpy>=1.20.2
 scipy>=1.6.3
-mne>=1.3
-matplotlib>=3.4.0
-pandas>=1.2.4
 nibabel>=3.2.1
 pybv>=0.7.5
-openneuro-py>=2022.2
-EDFlib-Python>=1.0.6
 pymatreader>=0.0.30
+matplotlib>=3.4.0
+pandas>=1.2.4
+EDFlib-Python>=1.0.6
 pytest
 pytest-cov
 pytest-sugar
Repository: mne-tools/mne-bids

Issue:
Q: Release?
It would be good to cut a MNE-BIDS release before the MNE-Python 1.6 release because it looks like the `mne.io`->`mne._fiff` stuff isn't in the latest release (e.g., see [circleci main failure in MNE](https://app.circleci.com/pipelines/github/mne-tools/mne-python/21889/workflows/b613fb80-7a0e-4c45-b2cc-02b8f0d9e589/jobs/61509)). Any chance to cut one in the next couple of days?


Discussion:
Yes, I will make a release tomorrow :+1:

Resolving patch:
diff --git a/mne_bids/__init__.py b/mne_bids/__init__.py
--- a/mne_bids/__init__.py
+++ b/mne_bids/__init__.py
@@ -1,6 +1,6 @@
 """MNE software for easily interacting with BIDS compatible datasets."""
 
-__version__ = "0.14.dev0"
+__version__ = "0.14"
 from mne_bids import commands
 from mne_bids.report import make_report
 from mne_bids.path import (


Test patch:
Repository: blakeblackshear/frigate

Issue:
Small issue with handling of the crop argument
The new cropping setting is a nice addition but when using `crop=0` the image still gets cropped. This is because `request.args.get('crop', 0)` returns the specified value as a string and obviously `bool('0')` is `True`. I think the easiest fix would be to simply use the `type` parameter: `crop = bool(request.args.get('crop', 0, type=int))`. That way if `crop` is `0` or a string that's not a number, it will return `False`, and `True` otherwise.


Discussion:

Resolving patch:
diff --git a/detect_objects.py b/detect_objects.py
--- a/detect_objects.py
+++ b/detect_objects.py
@@ -384,7 +384,7 @@ def best(camera_name, label):
             best_object = object_processor.get_best(camera_name, label)
             best_frame = best_object.get('frame', np.zeros((720,1280,3), np.uint8))
             
-            crop = bool(request.args.get('crop', 0))
+            crop = bool(request.args.get('crop', 0, type=int))
             if crop:
                 region = best_object.get('region', [0,0,300,300])
                 best_frame = best_frame[region[1]:region[3], region[0]:region[2]]


Test patch:
Repository: blakeblackshear/frigate

Issue:
Crash when trying to clean up the cache/out of space
So, I let my disk space run out (plug for https://github.com/blakeblackshear/frigate/issues/994 :) ). Frigate helpfully tried to clean up `/tmp/cache` but ended up crashing:
```
frigate.events                 WARNING : More than 90% of the cache is used.
frigate.events                 WARNING : Consider increasing space available at /tmp/cache or reducing max_seconds in your clips config.
frigate.events                 WARNING : Proactively cleaning up the cache...
Exception in thread event_processor:
Traceback (most recent call last):
  File "/opt/frigate/frigate/events.py", line 193, in run
    event_type, camera, event_data = self.event_queue.get(timeout=10)
  File "/usr/lib/python3.8/multiprocessing/queues.py", line 108, in get
    raise Empty
_queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/opt/frigate/frigate/events.py", line 196, in run
    self.refresh_cache()
  File "/opt/frigate/frigate/events.py", line 121, in refresh_cache
    oldest_clip = min(self.cached_clips.values(), key=lambda x:x['start_time'])
ValueError: min() arg is an empty sequence
```

Sounds like some better error handling would be helpful here.


Discussion:

Resolving patch:
diff --git a/frigate/events.py b/frigate/events.py
--- a/frigate/events.py
+++ b/frigate/events.py
@@ -123,7 +123,7 @@ def refresh_cache(self):
 
         # if we are still using more than 90% of the cache, proactively cleanup
         cache_usage = shutil.disk_usage("/tmp/cache")
-        if (
+        while (
             cache_usage.used / cache_usage.total > 0.9
             and cache_usage.free < 200000000
             and len(self.cached_clips) > 0
@@ -133,13 +133,10 @@ def refresh_cache(self):
                 "Consider increasing space available at /tmp/cache or reducing max_seconds in your clips config."
             )
             logger.warning("Proactively cleaning up the cache...")
-            while cache_usage.used / cache_usage.total > 0.9:
-                oldest_clip = min(
-                    self.cached_clips.values(), key=lambda x: x["start_time"]
-                )
-                del self.cached_clips[oldest_clip["path"]]
-                os.remove(os.path.join(CACHE_DIR, oldest_clip["path"]))
-                cache_usage = shutil.disk_usage("/tmp/cache")
+            oldest_clip = min(self.cached_clips.values(), key=lambda x: x["start_time"])
+            del self.cached_clips[oldest_clip["path"]]
+            os.remove(os.path.join(CACHE_DIR, oldest_clip["path"]))
+            cache_usage = shutil.disk_usage("/tmp/cache")
 
     def create_clip(self, camera, event_data, pre_capture, post_capture):
         # get all clips from the camera with the event sorted


Test patch: