Repository: mne-tools/mne-bids

Issue:
Key error in mne_bids.write_raw_bids for Elekta Triux file (ias)
Dear mne_bids developers,

thanks for the great work you are putting into this tool.

#### Describe the bug
Unfortunately I ran into an error that might most likely be a bug:
When including raw fif-files to a BIDS-Dataset a key error occurs. This happens to unprocessed (and undamaged) files using mne0.21 and also mne0.22.dev0. I am using the latest stable mne_bids version as obtained via pip.

#### Steps to reproduce
The code I am executing is the following:

```
bids_root = "/home/idrael/DATA/MEG/BIDS_clinic"
data_root = "/home/idrael/DATA/MEG_playground"


def convert_dcm_folder(subj):
    try:
        anafolder = os.path.join(data_root, subj, "data", "anat", subj)
        folder = str(glob.glob((anafolder + '/1*/100*/100*'), recursive=True)[0])
        convert_directory(folder, anafolder, compression=True, reorient=True)
    except OSError as e:
        print(e)

for subj in subjects:
    data_dir = os.path.join(data_root, subj, "data")
    raws = glob.glob(data_dir + "/*.fif")
    bids_path = BIDSPath(subject=subj, session=session, task="resting", root=bids_root)
    for run, rawfile in enumerate(raws):
        run += 1
        raw = mne.io.read_raw(rawfile)
        bids_path.update(run=run)
        write_raw_bids(raw, bids_path, overwrite=True)    # this breaks with fif-files due to an IAS-Key Error
    convert_dcm_folder(subj)
    anafolder = os.path.join(data_root, subj, "data", "anat", subj)
    niis = glob.glob(anafolder + "/*.nii*")
    try:
        for n in niis:
            write_anat(n, bids_path=bids_path, overwrite=True)
    except Exception as e:
        print(e)
```

#### This results in the following error message:
Writing '/home/idrael/DATA/MEG/BIDS_clinic/dataset_description.json'...

{
    "Name": " ",
    "BIDSVersion": "1.4.0",
    "DatasetType": "raw",
    "Authors": [
        "Please cite MNE-BIDS in your publication before removing this (citations in README)"
    ]
}
Reading 0 ... 1201999  =      0.000 ...  1201.999 secs...

Writing '/home/idrael/DATA/MEG/BIDS_clinic/sub-PP05071984/ses-resting/meg/sub-PP05071984_ses-resting_task-resting_run-01_meg.json'...

{
    "TaskName": "resting",
    "Manufacturer": "Elekta",
    "PowerLineFrequency": 50.0,
    "SamplingFrequency": 1000.0,
    "SoftwareFilters": "n/a",
    "RecordingDuration": 1201.999,
    "RecordingType": "continuous",
    "DewarPosition": "n/a",
    "DigitizedLandmarks": false,
    "DigitizedHeadPoints": false,
    "MEGChannelCount": 306,
    "MEGREFChannelCount": 0,
    "EEGChannelCount": 64,
    "EOGChannelCount": 2,
    "ECGChannelCount": 1,
    "EMGChannelCount": 0,
    "MiscChannelCount": 2,
    "TriggerChannelCount": 18
}
Traceback (most recent call last):
  File "/home/idrael/DATA/git/SourceLoc/src/01_create_DS_and_Folders.py", line 38, in <module>
    write_raw_bids(raw, bids_path, overwrite=True)    # this breaks with fif-files due to an IAS-Key Error
  File "/home/idrael/anaconda3/envs/MEG_dev/lib/python3.8/site-packages/mne_bids/write.py", line 1118, in write_raw_bids
    _channels_tsv(raw, channels_path.fpath, overwrite, verbose)
  File "/home/idrael/anaconda3/envs/MEG_dev/lib/python3.8/site-packages/mne_bids/write.py", line 109, in _channels_tsv
    ch_type.append(map_chs[_channel_type])
KeyError: 'ias'




#### Thank you for looking into it, please let me know if you need a minimal working example.
Best, 
R. Kreidenhuber


Discussion:
I am looking into it
Thanks for reporting! 
@agramfort Seems there's an IAS channel type we're currently not handling?
Thanks,

I think it might also be something concerning "internal active shielding".
yes I am on it

>


Resolving patch:
diff --git a/mne_bids/utils.py b/mne_bids/utils.py
--- a/mne_bids/utils.py
+++ b/mne_bids/utils.py
@@ -71,7 +71,8 @@ def _get_ch_type_mapping(fro='mne', to='bids'):
                        # MEG channels
                        meggradaxial='MEGGRADAXIAL', megmag='MEGMAG',
                        megrefgradaxial='MEGREFGRADAXIAL',
-                       meggradplanar='MEGGRADPLANAR', megrefmag='MEGREFMAG')
+                       meggradplanar='MEGGRADPLANAR', megrefmag='MEGREFMAG',
+                       ias='MEGOTHER')
 
     elif fro == 'bids' and to == 'mne':
         mapping = dict(EEG='eeg', MISC='misc', TRIG='stim', EMG='emg',
diff --git a/mne_bids/write.py b/mne_bids/write.py
--- a/mne_bids/write.py
+++ b/mne_bids/write.py
@@ -91,7 +91,8 @@ def _channels_tsv(raw, fname, overwrite=False, verbose=True):
                     eog='ElectroOculoGram',
                     emg='ElectroMyoGram',
                     misc='Miscellaneous',
-                    bio='Biological')
+                    bio='Biological',
+                    ias='Internal Active Shielding')
     get_specific = ('mag', 'ref_meg', 'grad')
 
     # get the manufacturer from the file in the Raw object


Test patch:
diff --git a/mne_bids/tests/test_write.py b/mne_bids/tests/test_write.py
--- a/mne_bids/tests/test_write.py
+++ b/mne_bids/tests/test_write.py
@@ -600,6 +600,24 @@ def test_fif_anonymize(_bids_validate):
     _bids_validate(bids_root)
 
 
+@pytest.mark.filterwarnings(warning_str['channel_unit_changed'])
+def test_fif_ias():
+    """Test writing FIF files with internal active shielding."""
+    data_path = testing.data_path()
+    raw_fname = op.join(data_path, 'MEG', 'sample',
+                        'sample_audvis_trunc_raw.fif')
+    raw = _read_raw_fif(raw_fname)
+
+    raw.set_channel_types({raw.ch_names[0]: 'ias'})
+
+    bids_root = _TempDir()
+    data_path = BIDSPath(subject='sample', root=bids_root)
+
+    write_raw_bids(raw, data_path)
+    raw = read_raw_bids(data_path)
+    assert raw.info['chs'][0]['kind'] == FIFF.FIFFV_IAS_CH
+
+
 def test_kit(_bids_validate):
     """Test functionality of the write_raw_bids conversion for KIT data."""
     bids_root = _TempDir()