From f4597ba4d75416dbe25ab6a08df1eadf17d9ec27 Mon Sep 17 00:00:00 2001 From: Florian Hofer Date: Mon, 28 Oct 2024 15:16:37 +0100 Subject: [PATCH 1/5] Allow exporting edf where a channel contains only constant values (#12911) --- doc/changes/devel/12911.bugfix.rst | 1 + mne/export/_edf.py | 2 ++ mne/export/tests/test_export.py | 10 ++++++++++ 3 files changed, 13 insertions(+) create mode 100644 doc/changes/devel/12911.bugfix.rst diff --git a/doc/changes/devel/12911.bugfix.rst b/doc/changes/devel/12911.bugfix.rst new file mode 100644 index 00000000000..c04a23d645d --- /dev/null +++ b/doc/changes/devel/12911.bugfix.rst @@ -0,0 +1 @@ +Allow exporting edf where a channel contains only constant values, by `Florian Hofer`_. diff --git a/mne/export/_edf.py b/mne/export/_edf.py index 424d5250356..ef870692014 100644 --- a/mne/export/_edf.py +++ b/mne/export/_edf.py @@ -138,6 +138,8 @@ def _export_raw(fname, raw, physical_range, add_ch_type): if physical_range == "auto": # per channel type pmin = ch_types_phys_min[ch_type] pmax = ch_types_phys_max[ch_type] + if pmax == pmin: + pmax = pmin + 1 prange = pmin, pmax signals.append( diff --git a/mne/export/tests/test_export.py b/mne/export/tests/test_export.py index 400dbc4fe7e..706a83476e4 100644 --- a/mne/export/tests/test_export.py +++ b/mne/export/tests/test_export.py @@ -379,6 +379,16 @@ def test_export_edf_signal_clipping(tmp_path, physical_range, exceeded_bound): assert raw_read.get_data().max() <= physical_range[1] +@edfio_mark() +def test_export_edf_with_constant_channel(tmp_path): + """Test if exporting to edf works if a channel contains only constant values.""" + temp_fname = tmp_path / "test.edf" + raw = RawArray(np.zeros((1, 10)), info=create_info(1, 1)) + raw.export(temp_fname) + raw_read = read_raw_edf(temp_fname, preload=True) + assert_array_equal(raw_read.get_data(), np.zeros((1, 10))) + + @edfio_mark() @pytest.mark.parametrize( ("input_path", "warning_msg"), From 7250311b2ce52ed8f50bacf193636350bf796ffb Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Mon, 28 Oct 2024 10:37:29 -0400 Subject: [PATCH 2/5] DOC: Document Linux desktop workaround (#12900) --- doc/_static/default_linux_dock_icon.png | Bin 0 -> 2050 bytes doc/_static/mne_python_dock_icon.png | Bin 0 -> 2506 bytes doc/install/advanced.rst | 31 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 doc/_static/default_linux_dock_icon.png create mode 100644 doc/_static/mne_python_dock_icon.png diff --git a/doc/_static/default_linux_dock_icon.png b/doc/_static/default_linux_dock_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..63156ae58654c3cf15eee6b2edb8627b34972c81 GIT binary patch literal 2050 zcmV+d2>thoP)ZgXgFbngSdJ^%m!Ep$a#bVG7w zVRUJ4ZXi@?ZDjydXmublHy}@AbRaS?GBhACIXW~sIy5*SK}{e;~cf1E5NgAV_opl|Uj*2u`d67bUSMIQCMjF9zxuZ;@6 z=zSl_CN)St?85*BNPt>2`2YY1R zo=)-BOG#ck83U>#FOnlI+uIiKDs=skRy3V~BhR7giTw=|kkSPJ*_6!DzRI>Dh!1k% zhaZp}eZD1|TLupc4dCw)*RmuyGp3;{V)HZ0t@WJOCS$zyQj&MRmSVI&#>MadhWPNw zrtNMCJakMyRp5IR9xvh8)%Z?m65l-&XX;s<*Uu(M>4KClI6YRow2f(kOhVdxIO({` zw|?;3rs11TXS=1WMwHBC=^YwlBCGJt=i{57TW)|NRlFdK3Z}zfKm0l7@~wvYZ)(KD zO=SCYELFO`yW;X>z3MT#B0@t$W#qs8?t2Z#ynO7~v0pWELnAR=PlQ7@BV~@<&+2HhAKL9hgO`Rc zwB+7Gk{EsN1^QD8Z+tb007_OsKs9Y`XwCGwGG8WN3SWm4z^PG{FO5q4?Zcm9=5E)$ zK2(f*`Vf!Oue2D`3cl|%HKDVCnS45fZ`IP8$Dghm4M9UCB<7bK{&Cym?3jSUgd#%N^=i21HSm2)vYnaaN4{+7=x$-{~+im^%g{rHIz+rUhBkqrW58n@OoFpp@jvq%+ zG|EO1&vl5$VoYS!np_!#1qYvh|Kl%=S;6F9D z{z4-?FoL313XEru5AgNlv0d+YRPZqDW=A`~TrX@wr{`x8A>PU~qlnNwuPPavz6os}9(Y`Xd<3uQk3%;3fY zdq;bw-RMl-8Z@-9E!_?uOJ$HX9aW1lG=74fff0trst+Lu;9H#_3B+bQ&5u__lOE_+$Mls$3iOstn(GA%^M}I|>aQem}k! z{Lx;SZ=BF~Om;yKaQA+m@r=u`y4o>lh~PxTZtw|R+OaJSf`FTM9`h()Lh@bs_j?_K zh7L?_yGeKk`s#nN`YRLO69amZIz2IoYxf*JxoJ>bTcfycfbVku-e6F zYTo0?Uw#n@G<4x)qhzhnd-Hv?@)81pBmxp^*GSL*9=uk{PmL*3SKlF7uM`D?Xb)QNS*iIymuugN#jxrM`0VWLCVVcJV|I2navQpv$GfP*bav2m g2!7CX2!7D?e+81en=mWDO8@`>07*qoM6N<$f*w%hU;qFB literal 0 HcmV?d00001 diff --git a/doc/_static/mne_python_dock_icon.png b/doc/_static/mne_python_dock_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..abd77ff9d82f2da398a7b6e4ba7e53f3a6b987e0 GIT binary patch literal 2506 zcmV;*2{rbKP)ZgXgFbngSdJ^%m!Ep$a#bVG7w zVRUJ4ZXi@?ZDjydXmublHy}@AbRaS?GBhACIXX2kIy5*SK}{eQ?8qpwVHbkS*4T0=}5QIgD8^P^H+YOYR!m`tD?{sF`&Yj-5ckaD@xU=15 znRcer*_p-eKRIc8d+xc<@1Ap?bIx-f;kxUt^VonA+igI*bP;@`=_2?>(}o3?Tk#Or zbtx1I%f+%REX%@i8~`LqLRD2%RV5q_FBefffBkaaz&+0+m&-9bJ4-&F$F}WN>l=mv zz^PNG08kW#o}M1!@i@_F6hRQ0YG2dAUDsu1W`=Y+&C=3R!|m9%jjrqHx=tVvAdyJW z-{0S~QP5QIOeRArmBKX5W;TmynjAlVoOC+P&Ye4n#bWDjvnk-VZ8JGJNhXtNMsq95 zG)*QZCWysi3=R&Ws%pb+tsC4h493UDo8HT-DU-=iC=^I0lZ3Rbb8%JwMyx98qZrjhFTYRE|*)^hNIOoO|$0QUKjZ6>}*pEYNcv9xteQr*LBI~ z^Y6PJ2t|l}_@+u7i<$pEiR-?1ZtvRqQ9@fU0}-t33FeNyLidM;32aY-0Cs+c?7v@J zt{>XAli=_k5Wy|XlYQX;q02_lJ~9LXXA0n*wLSOpIr7gw^PXqt^Lbp?U2z**6TDC; zR9zT!$1fpr?H}+Y@MI6v+eyFn=<@%SK#0xXcp59R15bg#8-HQ$*eirS{#D#tzKg4Z zB3Xp)*^Mzd20+KvpP_i~ukjQJrjNl32XMahH5Tst4xR!?;K|^LfLQq{KUw`2e% zm7Y6(gD5Ki2o6X~Aev|D3y%N0SOUSS6dQzcr8vL}i^#>r#TB{g>hWp{NG@0QL!ksl z35s?fmtK88W6$3~cYGH;JMN;K74Q^r6>$B?5>gSwIdIiV>AsTqXTQyQ6t25($tm!a@m(1{5kUUoL<)Q+XLGxT=77&3zOOKZ&>m!IS=Vwc=Lf z1&~hq;L_h-V)kcu)iQZmrBbQ+;K5Rk;a493B?wvv1VgyNEa+6FduYhrtuD1r^Ko2nhn)kYQXUDg_Bhom?L7gir*r zl;Kyv4gFKx_K7iOoEZOj<0M}A3iJgTJ$OCEaDa>srUy=?v(y}froffKQ@U~GZr{P3 zc61U*PIpxsS6jL^9(s~JNGyQ|MaSXChZcC?+8}}>fGhBBLFSRy=J?^2QJ5EzW_=^N z-af?83sVdQdU)q8otcha9=z!bECdtGiG55vr#NYJF)>x<2(Zb6%|$S5D3&cuw}dMR z@9A}OzW(iK-QbcWt#GFcTYPZA_IUVEn%l15&aPM)&lS1n@gn^}3$_KIEWlEwouC21 zDX;}F3f%wnG`EuCl5miO+QsD^QRt5IA5rEfz%4u8;meheMCgCM6gAKY{j=od9Wuy7r7CM8%H`o41&@DS|{^a`^D!H3jl61j(|@o;`b3bZ|A->Y^yp)6>&*!_K!Nk;tlEy{`Ru zJRWbFL9J3Po9hCPMxz7*fu)FAdpBTnqpKdlt?6MCKA*gW$o|p z|3LJ*rfGF`Qr+O9C^9fGupXOQqJe>dy0RwLbdnN}$D5LkaK03a#pvtntE=vs&&~!1 z2QSDWuW1^CgM)R~Uo*I>sw9)im3M7zkR(a$+O=yZFkcKUfL?UhPc}bE;CX+Si>}pz9mqnvdhKGmS^37|S#_;fPL(tHKT-I&q~VMwXi}b=q9`PjNpxK&l}fD|)?JS@O=DnSpzbMaH8nM}F&>Z8+uO_Z z^fc*ox@qU>r&nW%MB>6s=>*@)ZrQShL?S^pn?=|4x{`R`XP7J#i9|j)NxY{e2m-ym zz4Z3>E~jlTE-qpi2BlI7%d(c^-l8a?sw$eM5ekI}hr@Jsc78C^w$GL*iga~#t$1?T z4z*?`__ +if needed: + +.. code-block:: ini + + [Desktop Entry] + Type=Application + Version=1.5 + Name=MNE-Python + StartupWMClass=MNE-Python + Icon=/path/to/mne-python/mne/icons/mne_default_icon.png + SingleMainWindow=true + NoDisplay=true + +It should make the icon appear correctly in the dock: + +.. image:: ../_static/mne_python_dock_icon.png + :alt: MNE-Python dock icon + GPU acceleration with CUDA ^^^^^^^^^^^^^^^^^^^^^^^^^^ From e15292fc0bc8d5e32dd6d6099a839bf810963f3a Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Mon, 28 Oct 2024 16:13:09 +0100 Subject: [PATCH 3/5] eegbci api: allow downloading multiple subjects (#12918) --- doc/changes/devel/12918.apichange.rst | 1 + doc/documentation/datasets.rst | 18 +++-- examples/decoding/decoding_csp_eeg.py | 11 +-- examples/preprocessing/eeg_bridging.py | 2 +- examples/preprocessing/muscle_ica.py | 2 +- .../time_frequency/time_frequency_erds.py | 2 +- mne/datasets/eegbci/eegbci.py | 80 +++++++++++++------ mne/datasets/eegbci/tests/test_eegbci.py | 18 ++++- mne/datasets/utils.py | 5 +- tutorials/forward/35_eeg_no_mri.py | 2 +- .../40_artifact_correction_ica.py | 4 +- 11 files changed, 98 insertions(+), 47 deletions(-) create mode 100644 doc/changes/devel/12918.apichange.rst diff --git a/doc/changes/devel/12918.apichange.rst b/doc/changes/devel/12918.apichange.rst new file mode 100644 index 00000000000..958662b1b6f --- /dev/null +++ b/doc/changes/devel/12918.apichange.rst @@ -0,0 +1 @@ +Deprecate ``subject`` parameter in favor of ``subjects`` in :func:`mne.datasets.eegbci.load_data`, by `Stefan Appelhoff`_. diff --git a/doc/documentation/datasets.rst b/doc/documentation/datasets.rst index 70da39cccd8..0a0280ae5ac 100644 --- a/doc/documentation/datasets.rst +++ b/doc/documentation/datasets.rst @@ -161,17 +161,23 @@ EEGBCI motor imagery ==================== :func:`mne.datasets.eegbci.load_data` -The EEGBCI dataset is documented in :footcite:`SchalkEtAl2004`. The data set is -available at PhysioNet :footcite:`GoldbergerEtAl2000`. The dataset contains -64-channel EEG recordings from 109 subjects and 14 runs on each subject in EDF+ -format. The recordings were made using the BCI2000 system. To load a subject, -do:: +The EEGBCI dataset is documented in :footcite:`SchalkEtAl2004` and on the +`PhysioNet documentation page `_. +The data set is available at PhysioNet :footcite:`GoldbergerEtAl2000`. +It contains 64-channel EEG recordings from 109 subjects and 14 runs on each +subject in EDF+ format. The recordings were made using the BCI2000 system. +To load a subject, do:: from mne.io import concatenate_raws, read_raw_edf from mne.datasets import eegbci - raw_fnames = eegbci.load_data(subject, runs) + subjects = [1] # may vary + runs = [4, 8, 12] # may vary + raw_fnames = eegbci.load_data(subjects, runs) raws = [read_raw_edf(f, preload=True) for f in raw_fnames] + # concatenate runs from subject raw = concatenate_raws(raws) + # make channel names follow standard conventions + eegbci.standardize(raw) .. topic:: Examples diff --git a/examples/decoding/decoding_csp_eeg.py b/examples/decoding/decoding_csp_eeg.py index 2ffd18d34b4..5859edde166 100644 --- a/examples/decoding/decoding_csp_eeg.py +++ b/examples/decoding/decoding_csp_eeg.py @@ -10,8 +10,9 @@ See https://en.wikipedia.org/wiki/Common_spatial_pattern and :footcite:`Koles1991`. The EEGBCI dataset is documented in -:footcite:`SchalkEtAl2004` and is available at PhysioNet -:footcite:`GoldbergerEtAl2000`. +:footcite:`SchalkEtAl2004` and on the +`PhysioNet documentation page `_. +The dataset is available at PhysioNet :footcite:`GoldbergerEtAl2000`. """ # Authors: Martin Billinger # @@ -40,15 +41,15 @@ # avoid classification of evoked responses by using epochs that start 1s after # cue onset. tmin, tmax = -1.0, 4.0 -subject = 1 +subjects = 1 runs = [6, 10, 14] # motor imagery: hands vs feet -raw_fnames = eegbci.load_data(subject, runs) +raw_fnames = eegbci.load_data(subjects, runs) raw = concatenate_raws([read_raw_edf(f, preload=True) for f in raw_fnames]) eegbci.standardize(raw) # set channel names montage = make_standard_montage("standard_1005") raw.set_montage(montage) -raw.annotations.rename(dict(T1="hands", T2="feet")) +raw.annotations.rename(dict(T1="hands", T2="feet")) # as documented on PhysioNet raw.set_eeg_reference(projection=True) # Apply band-pass filter diff --git a/examples/preprocessing/eeg_bridging.py b/examples/preprocessing/eeg_bridging.py index b0eb50a039d..37d85c55df6 100644 --- a/examples/preprocessing/eeg_bridging.py +++ b/examples/preprocessing/eeg_bridging.py @@ -65,7 +65,7 @@ raw_data = dict() # store infos for electrode positions for sub in range(1, 11): print(f"Computing electrode bridges for subject {sub}") - raw_fname = mne.datasets.eegbci.load_data(subject=sub, runs=(1,))[0] + raw_fname = mne.datasets.eegbci.load_data(subjects=sub, runs=(1,))[0] raw = mne.io.read_raw(raw_fname, preload=True, verbose=False) mne.datasets.eegbci.standardize(raw) # set channel names raw.set_montage(montage, verbose=False) diff --git a/examples/preprocessing/muscle_ica.py b/examples/preprocessing/muscle_ica.py index 64c14f5f5af..f61d1e22bc4 100644 --- a/examples/preprocessing/muscle_ica.py +++ b/examples/preprocessing/muscle_ica.py @@ -97,7 +97,7 @@ for sub in (1, 2): raw = mne.io.read_raw_edf( - mne.datasets.eegbci.load_data(subject=sub, runs=(1,))[0], preload=True + mne.datasets.eegbci.load_data(subjects=sub, runs=(1,))[0], preload=True ) mne.datasets.eegbci.standardize(raw) # set channel names montage = mne.channels.make_standard_montage("standard_1005") diff --git a/examples/time_frequency/time_frequency_erds.py b/examples/time_frequency/time_frequency_erds.py index 1d805121739..93272eb7aa3 100644 --- a/examples/time_frequency/time_frequency_erds.py +++ b/examples/time_frequency/time_frequency_erds.py @@ -50,7 +50,7 @@ # First, we load and preprocess the data. We use runs 6, 10, and 14 from # subject 1 (these runs contains hand and feet motor imagery). -fnames = eegbci.load_data(subject=1, runs=(6, 10, 14)) +fnames = eegbci.load_data(subjects=1, runs=(6, 10, 14)) raw = concatenate_raws([read_raw_edf(f, preload=True) for f in fnames]) raw.rename_channels(lambda x: x.strip(".")) # remove dots from channel names diff --git a/mne/datasets/eegbci/eegbci.py b/mne/datasets/eegbci/eegbci.py index 83dde035d1b..91d78f57a03 100644 --- a/mne/datasets/eegbci/eegbci.py +++ b/mne/datasets/eegbci/eegbci.py @@ -9,7 +9,7 @@ from os import path as op from pathlib import Path -from ...utils import _url_to_local_path, logger, verbose +from ...utils import _url_to_local_path, logger, verbose, warn from ..utils import _do_path_update, _downloader_params, _get_path, _log_time_size EEGMI_URL = "https://physionet.org/files/eegmmidb/1.0.0/" @@ -21,7 +21,9 @@ def data_path(url, path=None, force_update=False, update_path=None, *, verbose=N This is a low-level function useful for getting a local copy of a remote EEGBCI dataset :footcite:`SchalkEtAl2004`, which is also available at PhysioNet - :footcite:`GoldbergerEtAl2000`. + :footcite:`GoldbergerEtAl2000`. Metadata, such as the meaning of event markers + may be obtained from the + `PhysioNet documentation page `_. Parameters ---------- @@ -92,8 +94,10 @@ def data_path(url, path=None, force_update=False, update_path=None, *, verbose=N @verbose def load_data( - subject, - runs, + subjects=None, + runs=None, + *, + subject=None, path=None, force_update=False, update_path=None, @@ -103,14 +107,19 @@ def load_data( """Get paths to local copies of EEGBCI dataset files. This will fetch data for the EEGBCI dataset :footcite:`SchalkEtAl2004`, which is - also available at PhysioNet :footcite:`GoldbergerEtAl2000`. + also available at PhysioNet :footcite:`GoldbergerEtAl2000`. Metadata, such as the + meaning of event markers may be obtained from the + `PhysioNet documentation page `_. Parameters ---------- - subject : int - The subject to use. Can be in the range of 1-109 (inclusive). + subjects : int | list of int + The subjects to use. Can be in the range of 1-109 (inclusive). runs : int | list of int The runs to use (see Notes for details). + subject : int + This parameter is deprecated and will be removed in mne version 1.9. + Please use ``subjects`` instead. path : None | path-like Location of where to look for the EEGBCI data. If ``None``, the environment variable or config parameter ``MNE_DATASETS_EEGBCI_PATH`` is used. If neither @@ -149,11 +158,11 @@ def load_data( For example, one could do:: >>> from mne.datasets import eegbci - >>> eegbci.load_data(1, [6, 10, 14], "~/datasets") # doctest:+SKIP + >>> eegbci.load_data([1, 2], [6, 10, 14], "~/datasets") # doctest:+SKIP - This would download runs 6, 10, and 14 (hand/foot motor imagery) runs from subject 1 - in the EEGBCI dataset to "~/datasets" and prompt the user to store this path in the - config (if it does not already exist). + This would download runs 6, 10, and 14 (hand/foot motor imagery) runs from subjects + 1 and 2 in the EEGBCI dataset to "~/datasets" and prompt the user to store this path + in the config (if it does not already exist). References ---------- @@ -161,8 +170,27 @@ def load_data( """ import pooch + # XXX: Remove this with mne 1.9 ↓↓↓ + # Also remove the subject parameter at that point. + # Also remove the `None` default for subjects and runs params at that point. + if subject is not None: + subjects = subject + warn( + "The ``subject`` parameter is deprecated and will be removed in version " + "1.9. Use the ``subjects`` parameter (note the `s`) to suppress this " + "warning.", + FutureWarning, + ) + del subject + if subjects is None or runs is None: + raise ValueError("You must pass the parameters ``subjects`` and ``runs``.") + # ↑↑↑ + t0 = time.time() + if not hasattr(subjects, "__iter__"): + subjects = [subjects] + if not hasattr(runs, "__iter__"): runs = [runs] @@ -198,20 +226,22 @@ def load_data( # fetch the file(s) data_paths = [] sz = 0 - for run in runs: - file_part = f"S{subject:03d}/S{subject:03d}R{run:02d}.edf" - destination = Path(base_path, file_part) - data_paths.append(destination) - if destination.exists(): - if force_update: - destination.unlink() - else: - continue - if sz == 0: # log once - logger.info("Downloading EEGBCI data") - fetcher.fetch(file_part) - # update path in config if desired - sz += destination.stat().st_size + for subject in subjects: + for run in runs: + file_part = f"S{subject:03d}/S{subject:03d}R{run:02d}.edf" + destination = Path(base_path, file_part) + data_paths.append(destination) + if destination.exists(): + if force_update: + destination.unlink() + else: + continue + if sz == 0: # log once + logger.info("Downloading EEGBCI data") + fetcher.fetch(file_part) + # update path in config if desired + sz += destination.stat().st_size + _do_path_update(path, update_path, config_key, name) if sz > 0: _log_time_size(t0, sz) diff --git a/mne/datasets/eegbci/tests/test_eegbci.py b/mne/datasets/eegbci/tests/test_eegbci.py index 6ce58861c44..40ef5ee030f 100644 --- a/mne/datasets/eegbci/tests/test_eegbci.py +++ b/mne/datasets/eegbci/tests/test_eegbci.py @@ -2,12 +2,26 @@ # License: BSD-3-Clause # Copyright the MNE-Python contributors. +import pytest + from mne.datasets import eegbci def test_eegbci_download(tmp_path, fake_retrieve): """Test Sleep Physionet URL handling.""" - for subj in range(4): - fnames = eegbci.load_data(subj + 1, runs=[3], path=tmp_path, update_path=False) + subjects = range(1, 5) + for subj in subjects: + fnames = eegbci.load_data(subj, runs=[3], path=tmp_path, update_path=False) assert len(fnames) == 1, subj assert fake_retrieve.call_count == 4 + + # XXX: remove in version 1.9 + with pytest.warns(FutureWarning, match="The ``subject``"): + fnames = eegbci.load_data( + subject=subjects, runs=[3], path=tmp_path, update_path=False + ) + assert len(fnames) == 4 + + # XXX: remove in version 1.9 + with pytest.raises(ValueError, match="You must pass the parameters"): + fnames = eegbci.load_data(path=tmp_path, update_path=False) diff --git a/mne/datasets/utils.py b/mne/datasets/utils.py index 34dbf0ef803..1b8dc535daa 100644 --- a/mne/datasets/utils.py +++ b/mne/datasets/utils.py @@ -347,9 +347,8 @@ def _download_all_example_data(verbose=True): sleep_physionet, ) - eegbci.load_data(1, [6, 10, 14], update_path=True) - for subj in range(4): - eegbci.load_data(subj + 1, runs=[3], update_path=True) + eegbci.load_data(subjects=1, runs=[6, 10, 14], update_path=True) + eegbci.load_data(subjects=range(1, 5), runs=[3], update_path=True) logger.info("[done eegbci]") sleep_physionet.age.fetch_data(subjects=[0, 1], recording=[1]) diff --git a/tutorials/forward/35_eeg_no_mri.py b/tutorials/forward/35_eeg_no_mri.py index 0fca916cabf..10d13864670 100644 --- a/tutorials/forward/35_eeg_no_mri.py +++ b/tutorials/forward/35_eeg_no_mri.py @@ -48,7 +48,7 @@ # .. note:: See :ref:`plot_montage` to view all the standard EEG montages # available in MNE-Python. -(raw_fname,) = eegbci.load_data(subject=1, runs=[6]) +(raw_fname,) = eegbci.load_data(subjects=1, runs=[6]) raw = mne.io.read_raw_edf(raw_fname, preload=True) # Clean channel names to be able to use a standard 1005 montage diff --git a/tutorials/preprocessing/40_artifact_correction_ica.py b/tutorials/preprocessing/40_artifact_correction_ica.py index 87db02be1f8..5eeb7b79d64 100644 --- a/tutorials/preprocessing/40_artifact_correction_ica.py +++ b/tutorials/preprocessing/40_artifact_correction_ica.py @@ -532,9 +532,9 @@ raws = list() icas = list() -for subj in range(4): +for subj in range(1, 5): # EEGBCI subjects are 1-indexed; run 3 is a left/right hand movement task - fname = mne.datasets.eegbci.load_data(subj + 1, runs=[3])[0] + fname = mne.datasets.eegbci.load_data(subj, runs=[3])[0] raw = mne.io.read_raw_edf(fname).load_data().resample(50) # remove trailing `.` from channel names so we can set montage mne.datasets.eegbci.standardize(raw) From f9ab4376906ea51da1cd38cae8bcd14cf559c154 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 20:48:22 -0400 Subject: [PATCH 4/5] [pre-commit.ci] pre-commit autoupdate (#12920) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0bdb943efd6..5a58d5d71fb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: # Ruff mne - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.0 + rev: v0.7.1 hooks: - id: ruff name: ruff lint mne From 98d55b4a9e29065766c29c3453336640844096ab Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Tue, 29 Oct 2024 11:25:28 -0500 Subject: [PATCH 5/5] dedent (#12925) --- mne/viz/backends/_qt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/viz/backends/_qt.py b/mne/viz/backends/_qt.py index 11270aa7251..b1cd43788ef 100644 --- a/mne/viz/backends/_qt.py +++ b/mne/viz/backends/_qt.py @@ -965,7 +965,7 @@ def func(button): callback(button_name) finally: widget.unsetCursor() - break + break widget.buttonClicked.connect(func) return _QtDialogWidget(widget, modal)