Skip to content

Commit d7839c4

Browse files
committed
temp merge in mne-tools#1477 to get CIs green
1 parent 5579392 commit d7839c4

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

doc/whats_new.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The following authors contributed for the first time. Thank you so much! 🤩
2727
The following authors had contributed before. Thank you for sticking around! 🤘
2828

2929
* `Stefan Appelhoff`_
30+
* `Daniel McCloy`_
3031

3132

3233
Detailed list of changes
@@ -61,6 +62,7 @@ Detailed list of changes
6162
- Updated MEG/iEEG writers to satisfy the stricter checks in the latest BIDS validator releases: BTi/4D run folders now retain their ``.pdf`` suffix (falling back to the legacy naming when an older validator is detected), KIT marker files encode the run via the ``acq`` entity instead of ``run``, datasets lacking iEEG montages receive placeholder ``electrodes.tsv``/``coordsystem.json`` files, and the ``AssociatedEmptyRoom`` entry stores dataset-relative paths by `Bruno Aristimunha`_ (:gh:`1449`)
6263
- Made the lock helpers skip reference counting when the optional ``filelock`` dependency is missing, preventing spurious ``AttributeError`` crashes during reads, by `Bruno Aristimunha`_ (:gh:`1469`)
6364
- Fixed a bug in :func:`mne_bids.read_raw_bids` that caused it to fail when reading BIDS datasets where the acquisition time was specified in local time rather than UTC only in Windows, by `Bruno Aristimunha`_ (:gh:`1452`)
65+
- Fixed bug in :func:`~mne_bids.write_raw_bids` where incorrect unit was sometimes written into ``channels.tsv`` file when converting data to BrainVision, EDF, or EEGLAB formats, by `Daniel McCloy`_ (:gh:`1477`)
6466

6567
⚕️ Code health
6668
^^^^^^^^^^^^^^

mne_bids/tests/test_write.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3433,7 +3433,7 @@ def test_convert_eeg_formats(dir_name, fmt, fname, reader, tmp_path):
34333433
# load channels.tsv; the unit should be Volts
34343434
channels_fname = bids_output_path.copy().update(suffix="channels", extension=".tsv")
34353435
channels_tsv = _from_tsv(channels_fname)
3436-
assert channels_tsv["units"][0] == "V"
3436+
assert channels_tsv["units"][0] == "µV"
34373437

34383438
if fmt == "BrainVision":
34393439
assert Path(raw2.filenames[0]).suffix == ".eeg"

mne_bids/write.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def _should_use_bti_pdf_suffix() -> bool:
136136
return use_pdf_suffix
137137

138138

139-
def _channels_tsv(raw, fname, overwrite=False):
139+
def _channels_tsv(raw, fname, *, convert_fmt, overwrite=False):
140140
"""Create a channels.tsv file and save it.
141141
142142
Parameters
@@ -145,6 +145,10 @@ def _channels_tsv(raw, fname, overwrite=False):
145145
The data as MNE-Python Raw object.
146146
fname : str | mne_bids.BIDSPath
147147
Filename to save the channels.tsv to.
148+
convert_fmt : str | None
149+
Which format the data are being converted to (determines what gets written in
150+
the "unit" column). If ``None`` then we assume no conversion is happening (the
151+
raw data files are being copied from the source tree into the BIDS folder tree).
148152
overwrite : bool
149153
Whether to overwrite the existing file.
150154
Defaults to False.
@@ -193,11 +197,32 @@ def _channels_tsv(raw, fname, overwrite=False):
193197
ch_type.append(map_chs[_channel_type])
194198
description.append(map_desc[_channel_type])
195199
low_cutoff, high_cutoff = (raw.info["highpass"], raw.info["lowpass"])
196-
if raw._orig_units:
200+
# If data are being *converted*, unit is determined by destination format:
201+
# - `eeglabio.raw.export_set` always converts V to µV, cf:
202+
# https://github.com/jackz314/eeglabio/blob/3961bb29daf082767ea44e7c7d9da2df10971c37/eeglabio/raw.py#L57
203+
#
204+
# - `mne.export._edf_bdf._export_raw_edf_bdf` always converts V to µV, cf:
205+
# https://github.com/mne-tools/mne-python/blob/1b921f4af5154bad40202d87428a2583ef896a00/mne/export/_edf_bdf.py#L61-L63
206+
#
207+
# - `pybv.write_brainvision` converts V to µV by default (and we don't alter that)
208+
# https://github.com/bids-standard/pybv/blob/2832c80ee00d12990a8c79f12c843c0d4ddc825b/pybv/io.py#L40
209+
# https://github.com/mne-tools/mne-bids/blob/1e0a96e132fc904ba856d42beaa9ddddb985f1ed/mne_bids/write.py#L1279-L1280
210+
if convert_fmt:
211+
volt_like = "µV" if convert_fmt in ("BrainVision", "EDF", "EEGLAB") else "V"
212+
units = [
213+
volt_like
214+
if ch_i["unit"] == FIFF.FIFF_UNIT_V
215+
else _unit2human.get(ch_i["unit"], "n/a")
216+
for ch_i in raw.info["chs"]
217+
]
218+
# if raw data is merely copied, check `raw._orig_units`
219+
elif raw._orig_units:
197220
units = [raw._orig_units.get(ch, "n/a") for ch in raw.ch_names]
221+
# If `raw._orig_units` is missing, assume SI units
198222
else:
199223
units = [_unit2human.get(ch_i["unit"], "n/a") for ch_i in raw.info["chs"]]
200-
units = [u if u not in ["NA"] else "n/a" for u in units]
224+
# fixup "NA" (from `_unit2human`) → "n/a"
225+
units = [u if u not in ["NA"] else "n/a" for u in units]
201226

202227
# Translate from MNE to BIDS unit naming
203228
for idx, mne_unit in enumerate(units):
@@ -2229,7 +2254,6 @@ def write_raw_bids(
22292254
emptyroom_fname=associated_er_path,
22302255
overwrite=overwrite,
22312256
)
2232-
_channels_tsv(raw, channels_path.fpath, overwrite)
22332257

22342258
# create parent directories if needed
22352259
_mkdir_p(os.path.dirname(data_path))
@@ -2288,6 +2312,14 @@ def write_raw_bids(
22882312
f"for {datatype} datatype."
22892313
)
22902314

2315+
# this can't happen until after value of `convert` has been determined
2316+
_channels_tsv(
2317+
raw,
2318+
channels_path.fpath,
2319+
convert_fmt=format if convert else None,
2320+
overwrite=overwrite,
2321+
)
2322+
22912323
# raise error when trying to copy files (copyfile_*) into same location
22922324
# (src == dest, see https://github.com/mne-tools/mne-bids/issues/867)
22932325
if (

0 commit comments

Comments
 (0)