Custom OPM sensor montages

Hi there,

Is there a way to import MEG position and orientation into the raw data in MNE?

Some details: I’m using MNE with a custom OPM system. I can import my data into MNE easily because it is collected in a fif file. However, there is no sensor orientation and location info on the fif because the vendor doesn’t provide that functionality yet.

I have digitized the sensor positions and orientations myself, and now I’d like to import the sensor positions and orientations.

There is some set custom montage functionality in MNE, but it seems to be EEG specific. I couldn’t find similar montage functionality for MEG - I’m guessing because custom MEG montages are a new problem due to OPM.

Your advice would be greatly appreciated.

Thanks,
Tim.

hi Tim,

have you looked at https://mne.tools/stable/auto_examples/datasets/opm_data.html ?

Alex

Thanks Alex!

Based on your suggestion, I found mne.use_coil_def, which I think is there to define the sensor volume. I will need a file like this for the FieldLine OPM sensors. Is there any guidance on the file format that I can use for making my own coil_def files for Fieldline sensors?

Regarding the sensor locations and orientation (with respect to the head), this seems to be already in the raw .fif file in the opm_data.html example. It looks like it is in raw.info[‘chs’][i][‘loc’]. Is that correct?

Best,
Tim.

Some additional information.

In the MNE example (QuSpin), if I look at raw.info[‘ch’][0], I get the following results
In [15]: raw.info[‘chs’][0]
Out[15]:
{‘scanno’: 1,
‘logno’: 1111,
‘kind’: 1 (FIFFV_MEG_CH),
‘range’: 1.0,
‘cal’: 3.7000000285836165e-10,
‘coil_type’: 9999,
‘loc’: array([ 0.0160798 , 0.03519166, 0.1367435 , -0.013699 , 0.97966099,
-0.200192 , -0.99316001, 0.0099 , 0.116395 , 0.11601 ,
0.200417 , 0.97282499]),
‘unit’: 112 (FIFF_UNIT_T),
‘unit_mul’: 0 (FIFF_UNITM_NONE),
‘ch_name’: ‘MEG1111’,
‘coord_frame’: 1 (FIFFV_COORD_DEVICE)}

For my system (FieldLine), here is what the info looks like. Clearly, the loc data needs to be updated.
In [20]: rawFL.info[‘chs’][0]
Out[20]:
{‘scanno’: 1,
‘logno’: 1,
‘kind’: 1 (FIFFV_MEG_CH),
‘range’: 1.0,
‘cal’: 7.047108980363866e-17,
‘coil_type’: 3024 (FIFFV_COIL_VV_MAG_T3),
‘loc’: array([-3., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
‘unit’: 112 (FIFF_UNIT_T),
‘unit_mul’: 0 (FIFF_UNITM_NONE),
‘ch_name’: ‘00:01:28’,
‘coord_frame’: 1 (FIFFV_COORD_DEVICE)}

Can you advise on the contents of ‘loc’ array, as well as how to make a coil_def.dat file?

Best,
Tim.

I think FieldLine coil defs were added last week, maybe updating to latest development version will be enough? see MRG, ENH: Add FieldLine and Kernel OPMs (#9394) · mne-tools/mne-python@323ab3f · GitHub

Thanks Dan. I will update to running the dev version then. This is awesome!

Any advice as to the elements of the ‘loc’ array in raw.info[‘chs’]?

Best,
Tim.

Hi Dan and Alex,

I’m still learning about the functionality of MNE python, so thanks for your patience. I’ve gotten closer to the solution of my issue with setting sensor location and orientation wrt the head, but have a couple of follow up questions. Hopefully, this will get me to the finish line.

On the MNE python website, I found the following about the Info class:
loc array, shape (12,)
Channel location. For MEG this is the position plus the normal given by a 3x3 rotation matrix. For EEG this is the position followed by reference position (with 6 unused). The values are specified in device coordinates for MEG and in head coordinates for EEG channels, respectively.

In the OPM example Alex recommended above, it has raw.info[‘chs’][0][‘loc’] equal to:
([ 0.0160798 , 0.03519166, 0.1367435 , -0.013699 , 0.97966099,
-0.200192 , -0.99316001, 0.0099 , 0.116395 , 0.11601 ,
0.200417 , 0.97282499])

Can you please help me with the following questions?

  1. Does that mean that the location is: [0.0160798 , 0.03519166, 0.1367435]
  2. Is the location array in metres?
  3. Is the rotation matrix correctly reshaped as follows?
    -0.013699 , 0.97966099, -0.200192 ,
    -0.99316001, 0.0099, 0.116395 ,
    0.11601, 0.200417, 0.97282499

Thanks for your help on this.

Tim.

hi Tim,

I’m still learning about the functionality of MNE python, so thanks for your patience. I’ve gotten closer to the solution of my issue with setting sensor location and orientation wrt the head, but have a couple of follow up questions. Hopefully, this will get me to the finish line.

:mountain_biking_man: :grinning:

On the MNE python website, I found the following about the Info class:
loc array, shape (12,)
Channel location. For MEG this is the position plus the normal given by a 3x3 rotation matrix. For EEG this is the position followed by reference position (with 6 unused). The values are specified in device coordinates for MEG and in head coordinates for EEG channels, respectively.

In the OPM example Alex recommended above, it has raw.info[‘chs’][0][‘loc’] equal to:
([ 0.0160798 , 0.03519166, 0.1367435 , -0.013699 , 0.97966099,
-0.200192 , -0.99316001, 0.0099 , 0.116395 , 0.11601 ,
0.200417 , 0.97282499])

Can you please help me with the following questions?

  1. Does that mean that the location is: [0.0160798 , 0.03519166, 0.1367435]

yes

  1. Is the location array in metres?

yes

  1. Is the rotation matrix correctly reshaped as follows?
    -0.013699 , 0.97966099, -0.200192 ,
    -0.99316001, 0.0099, 0.116395 ,
    0.11601, 0.200417, 0.97282499

I would say yes but if not just transpose.

I would use plot_alignment anyway once set to see how it looks

Alex

1 Like

This is great! Thank you. I should be good from here.

Thanks for all you do for this research community!

Best,
Tim.

Hello, if it is a custom OPM sensor, how can I get the rotation matrix representing the normal direction of the sensor? I want to know which vector gets the normal direction of the current sensor after passing through the rotation matrix.

hello,everyone, Does the qustion has a solution? if the direction of meg sensor is know (n1,n2,n3),How can we get the rotation matrix (e11,e12,e13;e21,e22,e23;e31,e32,e33)?