From 178d7d34970c86246d7e5fba231e70fa6530f4bd Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Thu, 4 Aug 2022 14:59:28 +0200 Subject: [PATCH 1/4] handle empty TSVs robustly and warn --- mne_bids/tests/test_tsv_handler.py | 6 ++++++ mne_bids/tsv_handler.py | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/mne_bids/tests/test_tsv_handler.py b/mne_bids/tests/test_tsv_handler.py index 1f0017989..3fa070e4a 100644 --- 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(UserWarning, 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. diff --git a/mne_bids/tsv_handler.py b/mne_bids/tsv_handler.py index 871c8818f..0ef65090f 100644 --- a/mne_bids/tsv_handler.py +++ b/mne_bids/tsv_handler.py @@ -1,7 +1,9 @@ """Private functions to handle tabular data.""" -import numpy as np from collections import OrderedDict from copy import deepcopy +from warnings import warn + +import numpy as np def _combine_rows(data1, data2, drop_column=None): @@ -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 From 0de29dbb4f1819edd22ac7afa9ec098f9ac96fdf Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Thu, 4 Aug 2022 15:02:31 +0200 Subject: [PATCH 2/4] add whatsnew --- doc/whats_new.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index b18097380..57a5ea227 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -47,7 +47,9 @@ Detailed list of changes - :func:`~mne_bids.write_raw_bids` now stores participant weight and height in ``participants.tsv``, by `Richard Höchenberger`_ (:gh:`1031`) -- :func:`~mne_bids.write_raw_bids` now supports EGI format by `Anand Saini`_, `Scott Huberty`_ and `Mathieu Scheltienne`_ (:gh:`1006`) +- :func:`~mne_bids.write_raw_bids` now supports EGI format, by `Anand Saini`_, `Scott Huberty`_ and `Mathieu Scheltienne`_ (:gh:`1006`) + +- TSV files that are empty (i.e., only a header row is present) are now handled more robustly and a warning is issued, by `Stefan Appelhoff`_ (:gh:`1038`) 🧐 API and behavior changes ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 31b649f7dfa4b61ec2fc8ef9a26e70b9b7a5fa8c Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Thu, 4 Aug 2022 16:05:28 +0200 Subject: [PATCH 3/4] use mne warn, not warnings warn --- mne_bids/tsv_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne_bids/tsv_handler.py b/mne_bids/tsv_handler.py index 0ef65090f..aac9bbb07 100644 --- a/mne_bids/tsv_handler.py +++ b/mne_bids/tsv_handler.py @@ -1,8 +1,8 @@ """Private functions to handle tabular data.""" from collections import OrderedDict from copy import deepcopy -from warnings import warn +from mne.utils import warn import numpy as np From 1a9b9a5865c98511b2ce1bc2e57a22d01dc55eb4 Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Thu, 4 Aug 2022 16:28:02 +0200 Subject: [PATCH 4/4] fix warn type --- mne_bids/tests/test_tsv_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne_bids/tests/test_tsv_handler.py b/mne_bids/tests/test_tsv_handler.py index 3fa070e4a..ae5f7d8ce 100644 --- a/mne_bids/tests/test_tsv_handler.py +++ b/mne_bids/tests/test_tsv_handler.py @@ -65,7 +65,7 @@ def test_tsv_handler(tmp_path): # test an empty tsv (just headers) _to_tsv(odict(onset=[], duration=[], trial_type=[]), d_path) - with pytest.warns(UserWarning, match="TSV file is empty"): + with pytest.warns(RuntimeWarning, match="TSV file is empty"): d = _from_tsv(d_path) d = _drop(d, "n/a", "trial_type")