OPM-BIDS conversion

I’m having a really difficult time converting OPM data to BIDS format and could really use some insight from anyone who has already done this. Currently I have an error in write_raw_bids, as follows:

Traceback (most recent call last):
  File "/data/pt_02830/Piloting/Pilot_Analysis/BIDS_Converter/bids_converter_thermal.py", line 134, in <module>
    write_raw_bids(raw, bids_path, events=events, event_id=event_id, overwrite=True, allow_preload=True,
  File "<decorator-gen-445>", line 12, in write_raw_bids
  File "/data/pt_02830/Piloting/py/venv/lib/python3.10/site-packages/mne_bids/write.py", line 2010, in write_raw_bids
    _channels_tsv(raw, channels_path.fpath, overwrite)
  File "/data/pt_02830/Piloting/py/venv/lib/python3.10/site-packages/mne_bids/write.py", line 155, in _channels_tsv
    ch_type.append(map_chs[_channel_type])
KeyError: 'mag'

If I hunt down the source of the error to map_chs[_channel_type], in

def _get_ch_type_mapping(fro="mne", to="bids")

I find the only MEG channels defined are
MEG channels: meggradaxial="MEGGRADAXIAL", megmag="MEGMAG", megrefgradaxial="MEGREFGRADAXIAL", meggradplanar="MEGGRADPLANAR", megrefmag="MEGREFMAG",

are the only MEG channel types found. If I try to convert my channels to match the above specs using:

raw.set_channel_types()

and setting the channel types according to:

for ch_type in channel_df['type'].to_list():
      if ch_type == 'MEGMAG':
              mne_channel_converted.append('megmag')
      elif ch_type == 'MEGREFMAG':
              mne_channel_converted.append('refmegmag')

where channel_df contains the channels written at the time of recording, I get the following error:

Traceback (most recent call last):
  File "/data/pt_02830/Piloting/Pilot_Analysis/BIDS_Converter/bids_converter_thermal.py", line 129, in <module>
    raw.set_channel_types(dict(zip(channel_df['name'].to_list(), mne_channel_converted)))
  File "<decorator-gen-23>", line 12, in set_channel_types
  File "/data/pt_02830/Piloting/py/venv/lib/python3.10/site-packages/mne/_fiff/meas_info.py", line 570, in set_channel_types
    raise ValueError(
ValueError: This function cannot change to this channel type: megmag. Accepted channel types are bio, chpi, csd, dbs, dipole, ecg, ecog, eeg, emg, eog, exci, eyegaze, fnirs_cw_amplitude, fnirs_fd_ac_amplitude, fnirs_fd_phase, fnirs_od, gof, grad, gsr, hbo, hbr, ias, mag, misc, pupil, ref_meg, resp, seeg, stim, syst, temperature.

which says ‘mag’ is one of the accepted forms (my original channel type it complains about). So I then try and convert, using:

mne_channel_converted = []
for ch_type in channel_df['type'].to_list():
    if ch_type == 'MEGMAG':
        mne_channel_converted.append('mag')
    elif ch_type == 'MEGREFMAG':
        mne_channel_converted.append('ref_meg')

which works, and I get no errors. But the problem is that the _channel.tsv file that is written then has all mag and ref_meg channels listed as ‘MISC’ - which is incorrect. This seems to be because prior to the conversion I tried, if I do

print(raw.info['chs'])

for a given channel (here LD(Z)), after the conversion this gives:

'ch_name': 'LD-Z', 'coil_type': 0 (FIFFV_COIL_NONE), 'logno': 2, 'coord_frame': 1 (FIFFV_COORD_DEVICE), 'kind': 1 (FIFFV_MEG_CH), 'unit': 112 (FIFF_UNIT_T)}

whereas before the conversion (in the version that fails for write_raw_bids), it looked like this:

'ch_name': 'LD-Z', 'coil_type': 8002 (FIFFV_COIL_QUSPIN_ZFOPM_MAG2), 'logno': 2, 'coord_frame': 1 (FIFFV_COORD_DEVICE), 'kind': 1 (FIFFV_MEG_CH), 'unit': 112 (FIFF_UNIT_T)}

so essentially I can’t use this conversion because I then lose the correct coil_type, which affects the write to BIDS format

I can’t figure out how to preserve the correct mne.info, while also having a channel type recognised in the write_raw_bids function, which is odd as in the docs there is clearly added support for OPM data, as in

def get_coil_types():

I can clearly see

 megmag=(
            FIFF.FIFFV_COIL_POINT_MAGNETOMETER,
            FIFF.FIFFV_COIL_VV_MAG_W,
            FIFF.FIFFV_COIL_VV_MAG_T1,
            FIFF.FIFFV_COIL_VV_MAG_T2,
            FIFF.FIFFV_COIL_VV_MAG_T3,
            FIFF.FIFFV_COIL_NM_122,
            FIFF.FIFFV_COIL_MAGNES_MAG,
            FIFF.FIFFV_COIL_BABY_MAG,
            # support for OPM data
            FIFF.FIFFV_COIL_QUSPIN_ZFOPM_MAG,  # QuSpin v1
            FIFF.FIFFV_COIL_QUSPIN_ZFOPM_MAG2,  # QuSpin v2
            FIFF.FIFFV_COIL_FIELDLINE_OPM_MAG_GEN1,  # FieldLine v1
            FIFF.FIFFV_COIL_KERNEL_OPM_MAG_GEN1,  # Kernel

Does anyone have any tips/tricks that have worked for them? I can’t figure out how to meddle with the mne.info object correctly to have both a supported channel type, and the correct OPM coil type

  • MNE version: 1.7.1
  • operating system: Debian

you could try updating to the development version of mne-bids. Some OPM channel support has been included there, see the changelog: What’s new? — MNE-BIDS 0.16.0.dev48+ged75468b documentation and include OPM channels as megmag under .pick/get_coil_types() by AmaiaBA · Pull Request #1222 · mne-tools/mne-bids · GitHub

you can get the dev version like this: pip install --upgrade https://github.com/mne-tools/mne-bids/archive/refs/heads/main.zip

Thank you for the suggestion! I will try this and let you know if it solves my issue by the end of this week hopefully :slight_smile:

I just had a quick check and it definitely works much much better!

The only issue I see is that sensors that were and should be MEGREFMAG are cast to MEGMAG, even though if I do:

print(raw.info['chs']) 

before calling write_raw_bids, I can see the ‘kind’ for these sensors is listed as:

'kind': 301 (FIFFV_REF_MEG_CH)

rather than:

'kind': 1 (FIFFV_MEG_CH)

which I see for my other OPM sensors. Any ideas what might be going on there? Everything else is working well though so thank you, this is great progress!

1 Like

I’m assuming it’s because the coil type is the same, so this may be something I’m stuck with :slight_smile: