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!

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