Repository: mne-tools/mne-python

Issue:
Extrapolated MEG field on scalp surface
Is there a possibility to get projected field maps on scalp surface in MNE-python
make_field_map currently is projecting MEG field maps on helmet surface only

Thank you



Discussion:
As far as I know not yet sorry

in the file 
mne-python/mne/forward/_field_interpolation.py
in the definition of  make_field_map

on line 383          _make_surface_mapping(evoked.info, this_surf, this_type,
                              trans, n_jobs=n_jobs)
Do you think if this function is called with head surface instead of helmet surface for MEG evoked data, then that would solve my problem and give extrapolated MEG fields to scalp instead of helmet?

that's worth trying !

Yes actually I was using this function to plot the MEG fields to the scalp, you just need to give the surface you want and it will do a re-mapping to that surf.

Do you need the code?
Or I can open a PR with the changes, if we want to add this option the make_field_map.

beware though with using a private function. There's no guarantee that we will support it or that it will be available in future `mne` versions. It can be a temporary workaround for now. The more permanent solution is what yousra suggests with a PR


Resolving patch:
diff --git a/examples/plot_meg_eeg_fields_3d.py b/examples/plot_meg_eeg_fields_3d.py
--- a/examples/plot_meg_eeg_fields_3d.py
+++ b/examples/plot_meg_eeg_fields_3d.py
@@ -33,5 +33,14 @@
 maps = make_field_map(evoked, trans_fname, subject='sample',
                       subjects_dir=subjects_dir, n_jobs=1)
 
-# explore several points in time
-[evoked.plot_field(maps, time=time) for time in [0.09, .11]]
+# Plot MEG and EEG fields in the helmet and scalp surface in the same figure.
+evoked.plot_field(maps, time=0.11)
+
+# Compute the MEG fields in the scalp surface
+evoked.pick_types(meg=True, eeg=False)
+maps_head = make_field_map(evoked, trans_fname, subject='sample',
+                           subjects_dir=subjects_dir, n_jobs=1,
+                           meg_surf='head')
+
+# Plot MEG fields both in scalp surface and the helmet in the same figure.
+evoked.plot_field([maps_head[0], maps[1]], time=0.11)
diff --git a/mne/forward/_field_interpolation.py b/mne/forward/_field_interpolation.py
--- a/mne/forward/_field_interpolation.py
+++ b/mne/forward/_field_interpolation.py
@@ -306,7 +306,8 @@ def _make_surface_mapping(info, surf, ch_type='meg', trans=None, mode='fast',
 
 
 def make_field_map(evoked, trans='auto', subject=None, subjects_dir=None,
-                   ch_type=None, mode='fast', n_jobs=1, trans_fname=None):
+                   ch_type=None, mode='fast', meg_surf='helmet',
+                   n_jobs=1, trans_fname=None):
     """Compute surface maps used for field display in 3D
 
     Parameters
@@ -331,6 +332,9 @@ def make_field_map(evoked, trans='auto', subject=None, subjects_dir=None,
         Either `'accurate'` or `'fast'`, determines the quality of the
         Legendre polynomial expansion used. `'fast'` should be sufficient
         for most applications.
+    meg_surf : str
+        Should be ``'helmet'`` or ``'head'`` to specify in which surface
+        to compute the MEG field map. The default value is ``'helmet'``
     n_jobs : int
         The number of jobs to run in parallel.
 
@@ -369,9 +373,13 @@ def make_field_map(evoked, trans='auto', subject=None, subjects_dir=None,
     if trans is not None:
         trans = read_trans(trans)
 
+    if meg_surf not in ['helmet', 'head']:
+        raise ValueError('Surface to plot MEG fields must be '
+                         '"helmet" or "head"')
+
     surfs = []
     for this_type in types:
-        if this_type == 'meg':
+        if this_type == 'meg' and meg_surf == 'helmet':
             surf = get_meg_helmet_surf(info, trans)
         else:
             surf = get_head_surf(subject, subjects_dir=subjects_dir)


Test patch:
diff --git a/mne/forward/tests/test_field_interpolation.py b/mne/forward/tests/test_field_interpolation.py
--- a/mne/forward/tests/test_field_interpolation.py
+++ b/mne/forward/tests/test_field_interpolation.py
@@ -120,9 +120,10 @@ def test_make_field_map_eeg():
     assert_true(len(fmd[0]['ch_names']), 59)
 
 
+@testing.requires_testing_data
 @slow_test
 def test_make_field_map_meg():
-    """Test interpolation of MEG field onto helmet
+    """Test interpolation of MEG field onto helmet | head
     """
     evoked = read_evokeds(evoked_fname, condition='Left Auditory')
     info = evoked.info
@@ -158,6 +159,17 @@ def test_make_field_map_meg():
 
     assert_raises(ValueError, make_field_map, evoked, ch_type='foobar')
 
+    # now test the make_field_map on head surf for MEG
+    evoked.pick_types(meg=True, eeg=False)
+    fmd = make_field_map(evoked, trans_fname, meg_surf='head',
+                         subject='sample', subjects_dir=subjects_dir)
+    assert_true(len(fmd) == 1)
+    assert_array_equal(fmd[0]['data'].shape, (642, 106))  # maps data onto surf
+    assert_true(len(fmd[0]['ch_names']), 106)
+
+    assert_raises(ValueError, make_field_map, evoked, meg_surf='foobar',
+                  subjects_dir=subjects_dir, trans=trans_fname)
+
 
 def _setup_args(info):
     """Helper to test_as_meg_type_evoked."""