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

Issue:
JOSS publication
At the MNE-Sprint in Paris, @teonbrooks @jasmainak and I discussed about writing a short report on MNE-BIDS and publishing it in [JOSS](https://joss.theoj.org/about).

JOSS articles generally provide a very high level description of the software and its relevance:

> Your submission should probably be somewhere between 250-1000 words.

It would allow us to properly point to MNE-BIDS in citations and get some scholarly recognition for our work.

I suggest that we take `pybids` as an example and create a [`/paper`](https://github.com/bids-standard/pybids/tree/master/paper) directory in our repository where we prepare the submission.

Publishing at JOSS would mean that mne-bids stays separate from mne-python instead of being integrated eventually. In a short discussion with @agramfort, we all approved of this idea, because it will allow us to stay with our lightweight and "independent" repository, while users can still benefit from mne-bids by using it as a simple "module" to MNE-Python.




Discussion:
One example of a JOSS publication is [Altair by Jake VanderPlas et al](https://www.theoj.org/joss-papers/joss.01057/10.21105.joss.01057.pdf)

It also seems to show up on [Google Scholar](https://scholar.google.de/citations?hl=de&user=0tDjsNUAAAAJ&view_op=list_works&sortby=pubdate)
I think this is a great idea. let's set this up this week and we work from there
I am hoping the API will be rather stable by the summer so it can be
written during the summer. So yes +1. Let me know how to split
the work. A suggestion is to be as inclusive as possible with authors.

yes, we can add whoever made even one commit to the author list.
> I am hoping the API will be rather stable by the summer

I am hoping it is stable by the end of week ;)
re-visiting this issue, I think we are at a good point to draft a paper. we can create a md doc and add it to the repo. thoughts?
okay for me but maybe @sappelhoff should take the lead
sure, I am happy to put up a draft soon where we can iterate towards a publication-ready document :)
gr8


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -14,8 +14,8 @@
     raise RuntimeError('Could not determine version')
 
 
-descr = ('An MNE project for organizing and formatting MEG and EEG data '
-         'according to the BIDS specification.')
+descr = ('MNE-BIDS: Organizing MEG, EEG, and iEEG data according to the BIDS '
+         'specification and facilitating their analysis with MNE-Python')
 
 DISTNAME = 'mne-bids'
 DESCRIPTION = descr


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

Issue:
BIDS converter uses extension name to determine manufacturer, which is not always true
I have some files that were converted from KIT to FIF. I would like to set up my folders/files in BIDS but I noticed that the original manufacturer information is falling back to Elekta instead of KIT. I think this would be a problem with any system that was using MNE that read in their original source files but were saved to FIF. Is there a way to get the original manufacturer information from the FIF file or would this be a manual step for the user. If so, we should document that somewhere.


Discussion:

Resolving patch:
diff --git a/examples/convert_mne_sample.py b/examples/convert_mne_sample.py
--- a/examples/convert_mne_sample.py
+++ b/examples/convert_mne_sample.py
@@ -41,8 +41,15 @@
 output_path = op.join(data_path, '..', 'MNE-sample-data-bids')
 
 ###############################################################################
+#
+# .. note::
+#
+#   ``mne-bids`` will infer the manufacturer information from the file
+#   extension. If your file format is non-standard for the
+#   manufacturer, please update the manufacturer field in the sidecars
+#   manually.
+#
 # Specify the raw_file and events_data and run the BIDS conversion.
-
 raw = mne.io.read_raw_fif(raw_fname)
 bids_basename = make_bids_basename(subject='01', session='01',
                                    task='audiovisual', run='01')
diff --git a/mne_bids/write.py b/mne_bids/write.py
--- a/mne_bids/write.py
+++ b/mne_bids/write.py
@@ -777,11 +777,17 @@ def write_raw_bids(raw, bids_basename, output_path, events_data=None,
                    event_id=None, overwrite=False, verbose=True):
     """Walk over a folder of files and create BIDS compatible folder.
 
-    .. warning:: The original files are simply copied over if the original
-                 file format is BIDS-supported for that modality. Otherwise,
-                 this function will convert to a BIDS-supported file format
-                 while warning the user. For EEG and iEEG data, conversion will
-                 be to BrainVision format, for MEG conversion will be to FIF.
+    .. warning:: * The original files are simply copied over if the original
+                   file format is BIDS-supported for that modality. Otherwise,
+                   this function will convert to a BIDS-supported file format
+                   while warning the user. For EEG and iEEG data, conversion
+                   will be to BrainVision format, for MEG conversion will be
+                   to FIF.
+
+                 * ``mne-bids`` will infer the manufacturer information
+                   from the file extension. If your file format is non-standard
+                   for the manufacturer, please update the manufacturer field
+                   in the sidecars manually.
 
     Parameters
     ----------


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

Issue:
[joss] list supported python versions in pypi
piggy-backing off of one of @TomDonoghue's comments:
> Is there a minimum version of Python3 required? I guess that there is some minimum required sub-version of Py3 required, but it's not clear what that would be, and it might be useful to note that.

you can add supported python versions for pypi, you can add these:
```
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
```
[in your setup.py](https://github.com/mne-tools/mne-bids/blob/20fbb881afaab75206db3d8c2d4b226c4c3bc212/setup.py#L50)
you can also set [`python_requires`](https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires) in `setup.py` to ensure people do not use the incorrect python version with your package.


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -37,6 +37,7 @@
           download_url=DOWNLOAD_URL,
           long_description=open('README.rst').read(),
           long_description_content_type='text/x-rst',
+          python_requires='~=3.5',
           classifiers=[
               'Intended Audience :: Science/Research',
               'Intended Audience :: Developers',
@@ -48,6 +49,9 @@
               'Operating System :: POSIX',
               'Operating System :: Unix',
               'Operating System :: MacOS',
+              'Programming Language :: Python :: 3.5',
+              'Programming Language :: Python :: 3.6',
+              'Programming Language :: Python :: 3.7',
           ],
           platforms='any',
           packages=find_packages(),


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

Issue:
[BUG] can't find coordsystem.json when no acq present
~~this assumes there is a folder level in between the subject folder and modality folder, but this level is optional. the test only checks for one instance:~~

The recent introduction assumes that bids files will have the optional acq entity in its filename. It should check that acq is not None before prepending. this causes a passive failure to load but it does warn.
https://github.com/mne-tools/mne-bids/blob/47ad7ddf8de47e473fa89f4304c044e3406085de/mne_bids/read.py#L545-L546


Discussion:

Resolving patch:
diff --git a/mne_bids/read.py b/mne_bids/read.py
--- a/mne_bids/read.py
+++ b/mne_bids/read.py
@@ -465,8 +465,9 @@ def read_raw_bids(bids_basename, bids_root, kind=None, extra_params=None,
     # Try to find an associated electrodes.tsv and coordsystem.json
     # to get information about the status and type of present channels
     acq = params['acq']
-    elec_suffix = 'acq-{}*_electrodes.tsv'.format(acq)
-    coord_suffix = 'acq-{}*_coordsystem.json'.format(acq)
+    search_modifier = f'acq-{acq}' if acq else ''
+    elec_suffix = f'{search_modifier}*_electrodes.tsv'
+    coord_suffix = f'{search_modifier}*_coordsystem.json'
     electrodes_fname = _find_matching_sidecar(bids_fname, bids_root,
                                               suffix=elec_suffix,
                                               allow_fail=True)


Test patch:
diff --git a/mne_bids/tests/test_read.py b/mne_bids/tests/test_read.py
--- a/mne_bids/tests/test_read.py
+++ b/mne_bids/tests/test_read.py
@@ -49,6 +49,8 @@
     subject=subject_id, session=session_id, run=run, acquisition=acq,
     task=task)
 
+bids_basename_minimal = make_bids_basename(subject=subject_id, task=task)
+
 # Get the MNE testing sample data - USA
 data_path = testing.data_path()
 raw_fname = op.join(data_path, 'MEG', 'sample',
@@ -398,9 +400,11 @@ def test_handle_eeg_coords_reading():
         assert raw_test.info['dig'] is None
 
 
+@pytest.mark.parametrize('bids_basename', [bids_basename,
+                                           bids_basename_minimal])
 @pytest.mark.filterwarnings(warning_str['nasion_not_found'])
 @pytest.mark.filterwarnings(warning_str['channel_unit_changed'])
-def test_handle_ieeg_coords_reading():
+def test_handle_ieeg_coords_reading(bids_basename):
     """Test reading iEEG coordinates from BIDS files."""
     bids_root = _TempDir()
Repository: mne-tools/mne-bids

Issue:
Use MNE's Sphinx GitHub Substitution
See https://github.com/mne-tools/mne-python/pull/8283#discussion_r492649817


Discussion:
Yes, that's be cool, I agree :-)
I don't see this happening anytime soon… so closing
wouldn't it simply be copying over this file: https://github.com/mne-tools/mne-python/blob/master/doc/sphinxext/gh_substitutions.py

and adding a line to conf.py?

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -37,7 +37,8 @@
     'sphinx.ext.intersphinx',
     'sphinx_gallery.gen_gallery',
     'numpydoc',
-    'gen_cli'  # custom extension, see ./sphinxext/gen_cli.py
+    'gen_cli',  # custom extension, see ./sphinxext/gen_cli.py
+    'gh_substitutions',  # custom extension, see ./sphinxext/gh_substitutions.py
 ]
 
 # generate autosummary even if no references
diff --git a/doc/sphinxext/gh_substitutions.py b/doc/sphinxext/gh_substitutions.py
new file mode 100644
--- /dev/null
+++ b/doc/sphinxext/gh_substitutions.py
@@ -0,0 +1,33 @@
+"""Provide a convenient way to link to GitHub issues and pull requests.
+
+Link to any issue or PR using :gh:`issue-or-pr-number`.
+
+Adapted from:
+https://doughellmann.com/blog/2010/05/09/defining-custom-roles-in-sphinx/
+
+"""
+from docutils.nodes import reference
+from docutils.parsers.rst.roles import set_classes
+
+
+def gh_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
+    """Link to a GitHub issue."""
+    try:
+        # issue/PR mode (issues/PR-num will redirect to pull/PR-num)
+        int(text)
+    except ValueError:
+        # direct link mode
+        slug = text
+    else:
+        slug = 'issues/' + text
+    text = '#' + text
+    ref = 'https://github.com/mne-tools/mne-bids/' + slug
+    set_classes(options)
+    node = reference(rawtext, text, refuri=ref, **options)
+    return [node], []
+
+
+def setup(app):
+    """Do setup."""
+    app.add_role('gh', gh_role)
+    return


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

Issue:
[MAINT] remove try-except in copyfile edf
These lines should be removed when

- [x] https://github.com/mne-tools/mne-python/pull/8558 is merged
- [ ] MNE 0.22 is released

right, @a-hurst ?

see: 

https://github.com/mne-tools/mne-bids/blob/18cc4f912495e8de8ab30d9c3077b19c923bebf4/mne_bids/copyfiles.py#L456-L478


Discussion:
Yep, this is correct!

Resolving patch:
diff --git a/mne_bids/copyfiles.py b/mne_bids/copyfiles.py
--- a/mne_bids/copyfiles.py
+++ b/mne_bids/copyfiles.py
@@ -454,29 +454,7 @@ def copyfile_edf(src, dest, anonymize=None):
         pid, sex, birthdate, name = id_info.split(' ')
         startdate, admin_code, tech, equip = rec_info.split(' ')[1:5]
 
-        # Try to anonymize recording date using 4-digit year from
-        # "Startdate" field from "local recording identification"
-        # section, because the generic "startdate" field only
-        # supports 2-digit years.
-        #
-        # XXX: recording dates are specified twice in EDF/EDF+/BDF,
-        # MNE-Python currently parses the 2-digit year field. If that is
-        # changed to defaulting to the 4-digit field, this try-except
-        # clause can be removed. See:
-        # https://github.com/mne-tools/mne-python/issues/8544
-        try:
-            true_year = datetime.strptime(startdate, '%d-%b-%Y').year
-            newdate = raw.info['meas_date'].replace(year=true_year)
-            raw.info['meas_date'] = newdate
-        except ValueError as e:
-            # We could not parse the "Startdate" field from "local recording
-            # identification" section (e.g., because it was "X").
-            # So fall back to using the standard "startdate" field that only
-            # supports 2-digit years.
-            # This is what MNE-Python currently parses and puts into
-            # raw.info["meas_date"]
-            if "does not match format '%d-%b-%Y'" not in str(e):
-                raise e
+        # Try to anonymize the recording date
         daysback, keep_his = _check_anonymize(anonymize, raw, '.edf')
         info = anonymize_info(raw.info, daysback=daysback, keep_his=keep_his)
         startdate = datetime.strftime(info['meas_date'], '%d-%b-%Y').upper()
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@
           long_description_content_type='text/markdown',
           python_requires='~=3.6',
           install_requires=[
-              'mne >=0.21',
+              'mne >=0.21.2',
               'numpy >=1.14',
               'scipy >=0.18.1',
           ],


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

Issue:
check argument works differently in BIDSPath.__init__() vs BIDSPath.update()
@adam2392 it seems #729 missed something in `BIDSPath.update()`:

```python
from mne_bids import BIDSPath

# good
p = BIDSPath(suffix='dataset_description', extension='.json', check=False)

# error
p = BIDSPath(extension='.json')
p.update(suffix='dataset_description', check=False)
```


Discussion:
the issue here is that for the error case you initialize the BIDSPath without `check`, so it's defaulting to TRUE

then in the update call, the check for false chars (what's triggering the error) is happening BEFORE updating `check` from True to False.

The fix is thus, to first update check during the update call.


Resolving patch:
diff --git a/mne_bids/path.py b/mne_bids/path.py
--- a/mne_bids/path.py
+++ b/mne_bids/path.py
@@ -547,6 +547,10 @@ def update(self, *, check=None, **kwargs):
         >>> print(bids_path.basename)
         sub-test_ses-two_acq-test_ieeg.vhdr
         """
+        # Update .check attribute
+        if check is not None:
+            self.check = check
+
         for key, val in kwargs.items():
             if key == 'root':
                 _validate_type(val, types=('path-like', None), item_name=key)
@@ -603,9 +607,7 @@ def update(self, *, check=None, **kwargs):
                 self.suffix in SUFFIX_TO_DATATYPE:
             self.datatype = SUFFIX_TO_DATATYPE[self.suffix]
 
-        # Update .check attribute and perform a check of the entities.
-        if check is not None:
-            self.check = check
+        # Perform a check of the entities.
         self._check()
         return self
 


Test patch:
diff --git a/mne_bids/tests/test_path.py b/mne_bids/tests/test_path.py
--- a/mne_bids/tests/test_path.py
+++ b/mne_bids/tests/test_path.py
@@ -950,8 +950,16 @@ def test_datasetdescription_with_bidspath(return_bids_test_dir):
             root=return_bids_test_dir, suffix='dataset_description',
             extension='.json')
 
+    # initialization should work
     bids_path = BIDSPath(
         root=return_bids_test_dir, suffix='dataset_description',
         extension='.json', check=False)
     assert bids_path.fpath.as_posix() == \
            Path(f'{return_bids_test_dir}/dataset_description.json').as_posix()
+
+    # setting it via update should work
+    bids_path = BIDSPath(root=return_bids_test_dir,
+                         extension='.json', check=True)
+    bids_path.update(suffix='dataset_description', check=False)
+    assert bids_path.fpath.as_posix() == \
+           Path(f'{return_bids_test_dir}/dataset_description.json').as_posix()
Repository: mne-tools/mne-bids

Issue:
acq_time is optional in scans.tsv files while we make it required
see:

```
~/work/src/mne-bids/mne_bids/read.py in _handle_scans_reading(scans_fname, raw, bids_path, verbose)
    206     data_fname = bids_path.datatype + '/' + fname
    207     fnames = scans_tsv['filename']
--> 208     acq_times = scans_tsv['acq_time']
    209     row_ind = fnames.index(data_fname)
    210

KeyError: 'acq_time'
```


Discussion:

Resolving patch:
diff --git a/mne_bids/read.py b/mne_bids/read.py
--- a/mne_bids/read.py
+++ b/mne_bids/read.py
@@ -206,7 +206,10 @@ def _handle_scans_reading(scans_fname, raw, bids_path, verbose=False):
     # to work nicely with windows
     data_fname = bids_path.datatype + '/' + fname
     fnames = scans_tsv['filename']
-    acq_times = scans_tsv['acq_time']
+    if 'acq_time' in scans_tsv:
+        acq_times = scans_tsv['acq_time']
+    else:
+        acq_times = ['n/a'] * len(fnames)
     row_ind = fnames.index(data_fname)
 
     # check whether all split files have the same acq_time


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

Issue:
CIs are failing
Circle runs fail every night, needs Investigation. I will try to have a look today or tomorrow.


Discussion:
I found the problem (it's either a bug in `openneuro-py` or in OpenNeuro; in any case we'll be able to work around it in `openneuro-py`). Will release a fix ASAP.

cc @yjmantilla
WIP @ https://github.com/hoechenberger/openneuro-py/pull/59

Resolving patch:
diff --git a/mne_bids/inspect.py b/mne_bids/inspect.py
--- a/mne_bids/inspect.py
+++ b/mne_bids/inspect.py
@@ -9,8 +9,16 @@
 import numpy as np
 
 import mne
-from mne.preprocessing import annotate_flat
+
 from mne.utils import logger, verbose
+from mne.fixes import _compare_version
+
+if _compare_version(mne.__version__, '<', '1.0.dev0'):
+    from mne.preprocessing import annotate_flat
+    _annotate_flat_func = annotate_flat
+else:
+    from mne.preprocessing import annotate_amplitude
+    _annotate_flat_func = annotate_amplitude
 
 from mne_bids import read_raw_bids, mark_channels
 from mne_bids.read import _from_tsv, _read_events
@@ -56,8 +64,10 @@ def inspect_dataset(bids_path, find_flat=True, l_freq=None, h_freq=None,
         will be marked as ``bad`` in ``*_channels.tsv``.
 
         .. note::
-            This function calls :func:`mne.preprocessing.annotate_flat` and
-            will only consider segments of at least **50 ms consecutive
+            This function calls ``mne.preprocessing.annotate_amplitude``
+            (MNE-Python 1.0 or newer) or ``mne.preprocessing.annotate_flat``
+            (older versions of MNE-Python)
+            and will only consider segments of at least **50 ms consecutive
             flatness** as "flat" (deviating from MNE-Python's default of 5 ms).
             If more than 5 percent of a channel's data has been marked as flat,
             the entire channel will be added to the list of bad channels. Only
@@ -125,7 +135,18 @@ def _inspect_raw(*, bids_path, l_freq, h_freq, find_flat, show_annotations):
 
     if find_flat:
         raw.load_data()  # Speeds up processing dramatically
-        flat_annot, flat_chans = annotate_flat(raw=raw, min_duration=0.05)
+        if _annotate_flat_func.__name__ == 'annotate_amplitude':
+            flat_annot, flat_chans = annotate_amplitude(
+                raw=raw,
+                flat=0,
+                min_duration=0.05,
+                bad_percent=5
+            )
+        else:  # annotate_flat
+            flat_annot, flat_chans = annotate_flat(
+                raw=raw,
+                min_duration=0.05
+            )
         new_annot = raw.annotations + flat_annot
         raw.set_annotations(new_annot)
         raw.info['bads'] = list(set(raw.info['bads'] + flat_chans))


Test patch:
diff --git a/test_requirements.txt b/test_requirements.txt
--- a/test_requirements.txt
+++ b/test_requirements.txt
@@ -5,7 +5,7 @@ matplotlib>=3.1
 pandas>=0.24.0
 nibabel>=2.5
 pybv>=0.6
-openneuro-py>=2021.8
+openneuro-py>=2022.1
 EDFlib-Python>=1.0.2
 pytest
 pytest-cov
Repository: mne-tools/mne-bids

Issue:
sphinx gallery update, mirror mne-python fix
https://github.com/mne-tools/mne-bids/blob/81bccd63f44099af30846af895d46ed0d112483d/doc/_static/style.css#L11-L15

we might need to mirror this change: https://github.com/mne-tools/mne-python/pull/10364


Discussion:

Resolving patch:
diff --git a/mne_bids/write.py b/mne_bids/write.py
--- a/mne_bids/write.py
+++ b/mne_bids/write.py
@@ -57,6 +57,9 @@
                              ANONYMIZED_JSON_KEY_WHITELIST)
 
 
+_FIFF_SPLIT_SIZE = '2GB'  # MNE-Python default; can be altered during debugging
+
+
 def _is_numeric(n):
     return isinstance(n, (np.integer, np.floating, int, float))
 
@@ -890,8 +893,10 @@ def _write_raw_fif(raw, bids_fname):
         should be saved.
 
     """
-    raw.save(bids_fname, fmt=raw.orig_format, split_naming='bids',
-             overwrite=True)
+    raw.save(
+        bids_fname, fmt=raw.orig_format, split_size=_FIFF_SPLIT_SIZE,
+        split_naming='bids', overwrite=True
+    )
 
 
 def _write_raw_brainvision(raw, bids_fname, events, overwrite):


Test patch:
diff --git a/mne_bids/tests/test_read.py b/mne_bids/tests/test_read.py
--- a/mne_bids/tests/test_read.py
+++ b/mne_bids/tests/test_read.py
@@ -28,6 +28,7 @@
 from mne_bids.utils import (_write_json)
 from mne_bids.sidecar_updates import _update_sidecar
 from mne_bids.path import _find_matching_sidecar
+import mne_bids.write
 from mne_bids.write import write_anat, write_raw_bids, get_anat_landmarks
 
 subject_id = '01'
@@ -949,7 +950,7 @@ def test_bads_reading(tmp_path):
 
 
 @pytest.mark.filterwarnings(warning_str['channel_unit_changed'])
-def test_write_read_fif_split_file(tmp_path):
+def test_write_read_fif_split_file(tmp_path, monkeypatch):
     """Test split files are read correctly."""
     # load raw test file, extend it to be larger than 2gb, and save it
     bids_root = tmp_path / 'bids'
@@ -962,13 +963,18 @@ def test_write_read_fif_split_file(tmp_path):
     write_raw_bids(raw, bids_path, verbose=False)
     bids_path.update(acquisition='01')
     n_channels = len(raw.ch_names)
-    n_times = int(2.2e9 / (n_channels * 4))  # enough to produce a split
+    n_times = int(2.5e6 / n_channels)  # enough to produce a 10MB split
     data = np.empty((n_channels, n_times), dtype=np.float32)
     raw = mne.io.RawArray(data, raw.info)
     big_fif_fname = pathlib.Path(tmp_dir) / 'test_raw.fif'
-    raw.save(big_fif_fname)
+
+    split_size = '10MB'
+    raw.save(big_fif_fname, split_size=split_size)
     raw = _read_raw_fif(big_fif_fname, verbose=False)
-    write_raw_bids(raw, bids_path, verbose=False)
+
+    with monkeypatch.context() as m:  # Force MNE-BIDS to split at 10MB
+        m.setattr(mne_bids.write, '_FIFF_SPLIT_SIZE', split_size)
+        write_raw_bids(raw, bids_path, verbose=False)
 
     # test whether split raw files were read correctly
     raw1 = read_raw_bids(bids_path=bids_path)