Skip to content

Commit

Permalink
Add support for new channel type "DBS" (#800)
Browse files Browse the repository at this point in the history
* Add support for new channel type "DBS"

* Fix small error

* Style fix

* Fix datatype handling

* Update whats_new

* Update doc/whats_new.rst

Co-authored-by: Richard Höchenberger <[email protected]>

Co-authored-by: Richard Höchenberger <[email protected]>
  • Loading branch information
richardkoehler and hoechenberger authored May 27, 2021
1 parent 544d48f commit 79c7889
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Enhancements
- :class:`mne_bids.BIDSPath` now has property getter and setter methods for all BIDS entities, i.e., you can now do things like ``bids_path.subject = 'foo'`` and don't have to resort to ``bids_path.update()``. This also ensures you'll get proper completion suggestions from your favorite Python IDE, by `Richard Höchenberger`_ (:gh:`786`)
- :func:`mne_bids.write_raw_bids` now stores information about continuous head localization measurements (e.g., Elekta/Neuromag cHPI) in the MEG sidecar file, by `Richard Höchenberger`_ (:gh:`794`)
- :func:`mne_bids.write_raw_bids` gained a new parameter `empty_room` that allows to specify an associated empty-room recording when writing an MEG data file. This information will be stored in the ``AssociatedEmptyRoom`` field of the MEG JSON sidecar file, by `Richard Höchenberger`_ (:gh:`795`)
- Added support for the new channel type `'dbs'` (Deep Brain Stimulation), which was introduced in MNE-Python 0.23, by `Richard Köhler`_ (:gh:`800`)

API and behavior changes
^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions mne_bids/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def test_handle_datatype():
sampling_rate = 100
data = random((n_channels, sampling_rate))
# datatype is given, check once for each datatype
channel_types = ['grad', 'eeg', 'ecog', 'seeg']
datatypes = ['meg', 'eeg', 'ieeg', 'ieeg']
channel_types = ['grad', 'eeg', 'ecog', 'seeg', 'dbs']
datatypes = ['meg', 'eeg', 'ieeg', 'ieeg', 'ieeg']
for ch_type, datatype in zip(channel_types, datatypes):
info = mne.create_info(n_channels, sampling_rate,
ch_types=[ch_type] * 2)
Expand Down
9 changes: 9 additions & 0 deletions mne_bids/tests/test_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,15 @@ def test_vhdr(_bids_validate, tmpdir):
write_raw_bids(raw, bids_path, overwrite=False)
_bids_validate(bids_root)

# Now let's test that the same works for new channel type 'dbs'
raw = _read_raw_brainvision(raw_fname)
raw.set_channel_types({raw.ch_names[i]: 'dbs'
for i in mne.pick_types(raw.info, eeg=True)})
bids_root = tmpdir.mkdir('bids_dbs')
bids_path.update(root=bids_root)
write_raw_bids(raw, bids_path, overwrite=False)
_bids_validate(bids_root)

# Test coords and impedance writing
# first read the data and set a montage
data_path = op.join(testing.data_path(), 'montage')
Expand Down
8 changes: 4 additions & 4 deletions mne_bids/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _get_ch_type_mapping(fro='mne', to='bids'):
if fro == 'mne' and to == 'bids':
mapping = dict(eeg='EEG', misc='MISC', stim='TRIG', emg='EMG',
ecog='ECOG', seeg='SEEG', eog='EOG', ecg='ECG',
resp='RESP', bio='MISC',
resp='RESP', bio='MISC', dbs='DBS',
# MEG channels
meggradaxial='MEGGRADAXIAL', megmag='MEGMAG',
megrefgradaxial='MEGREFGRADAXIAL',
Expand All @@ -80,7 +80,7 @@ def _get_ch_type_mapping(fro='mne', to='bids'):
RESP='resp',
# No MEG channels for now
# Many to one mapping
VEOG='eog', HEOG='eog')
VEOG='eog', HEOG='eog', DBS='dbs')
else:
raise ValueError('Only two types of mappings are currently supported: '
'from mne to bids, or from bids to mne. However, '
Expand Down Expand Up @@ -125,7 +125,7 @@ def _handle_datatype(raw, datatype, verbose=True):
datatype = 'meg'
else:
datatypes = list()
ieeg_types = ['seeg', 'ecog']
ieeg_types = ['seeg', 'ecog', 'dbs']
if any(ieeg_type in raw for ieeg_type in ieeg_types):
datatypes.append('ieeg')
if 'meg' in raw:
Expand Down Expand Up @@ -459,7 +459,7 @@ def _check_datatype(raw, datatype):
elif datatype == 'meg' and datatype in raw:
datatype_matches = True
elif datatype == 'ieeg':
ieeg_types = ('seeg', 'ecog')
ieeg_types = ('seeg', 'ecog', 'dbs')
if any(ieeg_type in raw for ieeg_type in ieeg_types):
datatype_matches = True
if not datatype_matches:
Expand Down
8 changes: 5 additions & 3 deletions mne_bids/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ def _channels_tsv(raw, fname, overwrite=False, verbose=True):
emg='ElectroMyoGram',
misc='Miscellaneous',
bio='Biological',
ias='Internal Active Shielding')
ias='Internal Active Shielding',
dbs='Deep Brain Stimulation')
get_specific = ('mag', 'ref_meg', 'grad')

# get the manufacturer from the file in the Raw object
Expand Down Expand Up @@ -643,6 +644,8 @@ def _sidecar_json(raw, task, manufacturer, fname, datatype,
if ch['kind'] == FIFF.FIFFV_MISC_CH])
n_stimchan = len([ch for ch in raw.info['chs']
if ch['kind'] == FIFF.FIFFV_STIM_CH]) - n_ignored
n_dbschan = len([ch for ch in raw.info['chs']
if ch['kind'] == FIFF.FIFFV_DBS_CH])

# Set DigitizedLandmarks to True if any of LPA, RPA, NAS are found
# Set DigitizedHeadPoints to True if any "Extra" points are found
Expand Down Expand Up @@ -723,8 +726,7 @@ def _sidecar_json(raw, task, manufacturer, fname, datatype,
ch_info_json_ieeg = [
('iEEGReference', 'n/a'),
('ECOGChannelCount', n_ecogchan),
('SEEGChannelCount', n_seegchan)]

('SEEGChannelCount', n_seegchan + n_dbschan)]
ch_info_ch_counts = [
('EEGChannelCount', n_eegchan),
('EOGChannelCount', n_eogchan),
Expand Down

0 comments on commit 79c7889

Please sign in to comment.