Lead field spikes using sample BEM - bug or explainable?

External Email - Use Caution

I've found something unusual in the lead fields computed using MNE-Python
that I can't explain. When arrays containing a large number of magnetometer
sensors are used with the 'sample' subject BEM
(sample-5120-5120-5120-bem.fif) and the ico4 source space to create a
forward model, there are some unusual strong spikes in the lead field.
These spikes are not present when I use a spherical BEM model instead.

To demonstrate, I created three different theoretical arrays of point
magnetometers (coil_id: 2000) measuring roughly the normal component of the
magnetic field with respect to the scalp surface. Each model contains an
increasing number of total sensors (102 sensors, 1632 sensors, and 3672
sensors).

Figure 1 shows the lead field for a particular dipole (#364 using ico4
source space) for each array using a spherical BEM model. A smooth dipolar
response is shown for each that is roughly equivalent over the arrays. The
peak response for each array doesn't change appreciably, but there is an
improvement in detail of the lead field. All evoked topomap plots are fixed
to the same color bar limits (400 fT).

Figure 2 shows the same set of lead fields but with the 'sample' subject
BEM instead. It shows curiously strong spikes present in the two high
density arrays. These spikes vary in their location and magnitude. The main
dipolar response is still present, and appears to be fairly consistent.
However, due to the spikes, the peak response for each array is vastly
different. Again, evoked topomap plots use a fixed color bar limit at 400
fT.

Are these lead field patterns in Figure 2 explainable? They certainly seem
like erroneous values, but perhaps something about the BEM model creates a
focusing effect for the magnetic field response when we sample at different
spatial frequencies? I'm happy to provide some sample forward models for
inspection.

Thanks,
Taylor Williams
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200206/5959b6a6/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Figure1.jpeg
Type: image/jpeg
Size: 149829 bytes
Desc: not available
Url : http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200206/5959b6a6/attachment-0002.jpeg
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Figure2.jpeg
Type: image/jpeg
Size: 162665 bytes
Desc: not available
Url : http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200206/5959b6a6/attachment-0003.jpeg

External Email - Use Caution

I'm not sure offhand what would cause this. Can you share a script to
produce the bottom plot in the source 364, 1632-point-magnetometer case?
That would help us look into what specifically what (at least: where in the
code) is causing the value to become so large.

Eric

External Email - Use Caution

Eric,

Please find the forward model and script for the 1632 magnetometer array in
the following folder. Script is also attached.
https://drive.google.com/drive/folders/1dX7YZSCa4RAcn_b4JH3I0CADe2ZOQIM-?usp=sharing

A bit more context on the forward model: It places point magnetometers on
102 simulated rectangular 24mm x 24mm chips that are projected towards the
scalp from the standard Neuromag sensor locations. The center point of each
sensor cluster is 1.5mm above the nearest outer skin surface from the BEM.
All sensors are sensitive in the z-direction and preserve the orientation
vector from the derived Neuromag magnetometer.

This script generates the full set of lead fields in the Evoked object Y0.
There are plenty of other instances where this occurs, not just dipole
#364. Let me know if you have any questions about the construction of the
forward model that I can answer for context. I'm curious to see what you
think.

Thanks,
Taylor

        External Email - Use Caution

I'm not sure offhand what would cause this. Can you share a script to
produce the bottom plot in the source 364, 1632-point-magnetometer case?
That would help us look into what specifically what (at least: where in the
code) is causing the value to become so large.

Eric

        External Email - Use Caution

I've found something unusual in the lead fields computed using MNE-Python
that I can't explain. When arrays containing a large number of magnetometer
sensors are used with the 'sample' subject BEM
(sample-5120-5120-5120-bem.fif) and the ico4 source space to create a
forward model, there are some unusual strong spikes in the lead field.
These spikes are not present when I use a spherical BEM model instead.

To demonstrate, I created three different theoretical arrays of point
magnetometers (coil_id: 2000) measuring roughly the normal component of the
magnetic field with respect to the scalp surface. Each model contains an
increasing number of total sensors (102 sensors, 1632 sensors, and 3672
sensors).

Figure 1 shows the lead field for a particular dipole (#364 using ico4
source space) for each array using a spherical BEM model. A smooth dipolar
response is shown for each that is roughly equivalent over the arrays. The
peak response for each array doesn't change appreciably, but there is an
improvement in detail of the lead field. All evoked topomap plots are fixed
to the same color bar limits (400 fT).

Figure 2 shows the same set of lead fields but with the 'sample' subject
BEM instead. It shows curiously strong spikes present in the two high
density arrays. These spikes vary in their location and magnitude. The main
dipolar response is still present, and appears to be fairly consistent.
However, due to the spikes, the peak response for each array is vastly
different. Again, evoked topomap plots use a fixed color bar limit at 400
fT.

Are these lead field patterns in Figure 2 explainable? They certainly
seem like erroneous values, but perhaps something about the BEM model
creates a focusing effect for the magnetic field response when we sample at
different spatial frequencies? I'm happy to provide some sample forward
models for inspection.

Thanks,
Taylor Williams
_______________________________________________
Mne_analysis mailing list
Mne_analysis at nmr.mgh.harvard.edu
Mne_analysis Info Page

_______________________________________________
Mne_analysis mailing list
Mne_analysis at nmr.mgh.harvard.edu
Mne_analysis Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200207/9552f743/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: view_lead_field.py
Type: text/x-python-script
Size: 1398 bytes
Desc: not available
Url : http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200207/9552f743/attachment-0001.bin

External Email - Use Caution

I've updated the shared folder to include a binary version of the Info and
src objects used to create this forward model. To create the forward model,
you can use the following:

import mne
from mne.datasets import sample
import pickle

bem_fname = sample.data_path() +
'/subjects/sample/bem/sample-5120-5120-5120-bem-sol.fif'
trans_fname = sample.data_path() + '/MEG/sample/sample_audvis_raw-trans.fif'

#Compute src for ico4 spacing from scratch
src = mne.setup_source_space('sample', spacing='ico4')
#Or, read src from file, pre-calculated using the command above
#src = pickle.load(open('/LOCAL_PATH_HERE/ico4_src.fif','rb'))

info =
pickle.load(open('/LOCAL_PATH_HERE/sample_bem_1632mag_info.pkl','rb'))

fwd = mne.make_forward_solution(info, trans_fname, src, bem_fname)

External Email - Use Caution

One quick likely candidate -- adding `mindist=5` yields:

    222 source space points omitted because of the 5.0-mm distance limit.
    199 source space point omitted because of the 5.0-mm distance limit.

So there are a bunch of sources very close to the inner skull surface. In
fact even just `mindist=2` gives:

    2 source space points omitted because of the 2.0-mm distance limit.
    2 source space point omitted because of the 2.0-mm distance limit.

If I do:

import pickle
import numpy as np
import mne
from mne.datasets import sample
bem_fname = sample.data_path() +
'/subjects/sample/bem/sample-5120-5120-5120-bem-sol.fif'
trans_fname = sample.data_path() + '/MEG/sample/sample_audvis_raw-trans.fif'
src = mne.read_source_spaces('ico4_src.fif')
info = pickle.load(open('sample_bem_1632mag_info.pkl','rb'))
fwd = mne.make_forward_solution(info, trans_fname, src, bem_fname, mindist=2)
fwd_other = mne.read_forward_solution('sample_bem_1632mag_ico4_fwd.fif')
for s, so in zip(fwd['src'], fwd_other['src']):
    bads = np.setdiff1d(so['vertno'], s['vertno'])
    print(bads)

I get:

[1049 7657]
[ 827 17466]

Feel free to check to see if these are (some of) the worst offenders that
you've seen. If not, then try the 5mm version and check if the bad ones are
in there (it might depend on the geometry in the vicinity of the points).
If so it seems like the explanation for the problem might be that the
sources are too close to the BEM surface. And maybe our default `mindist=0`
is not the safest choice...

Eric

External Email - Use Caution

Eric,

This is a good idea. I spent some time investigating, and determined that
for the model I provided, dipoles at different depths are equal offenders.
This exercise helped me to stumble onto the issue, though, I believe. It
seems that a small number of sensor positions are colliding with the scalp
surface. I made a different sensing array with the same number of 1632
sensors, but with a 1cm scalp offset, and the issue disappears.

The way I built the array was to choose a scalp projected point for the
center of a flat sensing chip (24mm x 24mm) that extends in the x-y plane
orthogonal to the normal direction at that scalp location. In hindsight,
this assumes that the head that is convex, which is not true in some
regions. The curious thing is that, when I view the co-registration with
the 'head-dense' surface shown, it appears as though there are no
collisions with the outer skin surface.

Do you know of a decent way to detect any sensor locations that are inside
the outer skin BEM surface to avoid problems like this in the future? Does
the outer skin surface include things like the ears?

Taylor

External Email - Use Caution

The curious thing is that, when I view the co-registration with the
'head-dense' surface shown, it appears as though there are no collisions
with the outer skin surface.

The BEM is made from a smoothed, downsampled version of this surface. If
you use `plot_alignment` and use `surfaces='head'` or
`surfaces='outer_skin'` it might show you that one instead.

Do you know of a decent way to detect any sensor locations that are inside
the outer skin BEM surface to avoid problems like this in the future?

You can use some private functions/classes
<https://github.com/mne-tools/mne-python/blob/master/mne/surface.py#L546-L590&gt;
from `mne.surface` for this, with the caveat that the API is not guaranteed
(subject to change at any time without maintaining backward compatibility).

Does the outer skin surface include things like the ears?

Yes it will but these will be smoothed in some fashion for the BEM.

Eric
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.nmr.mgh.harvard.edu/pipermail/mne_analysis/attachments/20200213/d1eb3813/attachment.html

External Email - Use Caution

Thank you. To close this out, using mne.surface._points_outside_surface()
in v0.20, I was able to compare the sensor locations (manually transformed
into MRI coordinates first) to the BEM mesh for the outer skin surface.
About 10% of the sensor locations in the model are inside the outer skin
surface. I'm working on an alternate approach to generating high density
on-scalp sensor locations now.

Taylor