Repository: mne-tools/mne-python

Issue:
problem in visualising the inverse source solution when more than one volume labels are used
How can the code can be modified to visualize the inverse solution of volume source space on MRI
 when two volume labels are given. 
For example in the code give: 
labels_vol = ['Left-Hippocampus', 'Right-Hippocampus']

[visualization of volume source space on MRI.docx](https://github.com/mne-tools/mne-python/files/2028419/visualization.of.volume.source.space.on.MRI.docx)






Discussion:
@poojaprabhu9 please edit the issue as I did here https://github.com/mne-tools/mne-python/issues/5223 to avoid the .docx file. Tell us when it's done.
@agramfort . Sorry for Docx file. Here is the code. 

```
import numpy as np  
import os.path as op
import matplotlib.pyplot as plt
import mne
from mne.datasets import sample
from mne import setup_volume_source_space, setup_source_space
from mne import make_forward_solution
from mne.minimum_norm import make_inverse_operator, apply_inverse
from nilearn.plotting import plot_stat_map
from nilearn.image import index_img
# Set dir
data_path = sample.data_path()
subject = 'sample'
data_dir = op.join(data_path, 'MEG', subject)
subjects_dir = op.join(data_path, 'subjects')
bem_dir = op.join(subjects_dir, subject, 'bem')
# Set file names
fname_aseg = op.join(subjects_dir, subject, 'mri', 'aseg.mgz')
fname_model = op.join(bem_dir, '%s-5120-bem.fif' % subject)
fname_bem = op.join(bem_dir, '%s-5120-bem-sol.fif' % subject)
fname_evoked = data_dir + '/sample_audvis-ave.fif'
fname_trans = data_dir + '/sample_audvis_raw-trans.fif'
fname_fwd = data_dir + '/sample_audvis-meg-oct-6-mixed-fwd.fif'
fname_cov = data_dir + '/sample_audvis-shrunk-cov.fif'
#########################################################################
labels_vol = ['Left-Hippocampus']  # labels_vol = ['Left-Hippocampus', ‘Right-Hippocampus’]
sphere=(0,0,0,120)
src = setup_volume_source_space(subject, mri=fname_aseg, pos=2.0, sphere=sphere,
                                        volume_label=labels_vol, subjects_dir=subjects_dir, 
                                        verbose=True)
fwd = make_forward_solution(fname_evoked, fname_trans, src, fname_bem, mindist=5.0,  
                            meg=True, eeg=False, n_jobs=1)
src_fwd = fwd['src']
n = sum(src_fwd[i]['nuse'] for i in range(len(src_fwd)))
print('the fwd src space contains %d spaces and %d points' % (len(src_fwd), n))
# Compute inverse solution 
snr = 3.0           
inv_method = 'MNE' # or MNE
lambda2 = 1.0 / snr ** 2
# Load data
condition = 'Left Auditory'
evoked = mne.read_evokeds(fname_evoked, condition=condition,
                          baseline=(None, 0))
noise_cov = mne.read_cov(fname_cov)
# Compute inverse operator
inverse_operator = make_inverse_operator(evoked.info, fwd, noise_cov,
                                         depth=None, fixed=False)
stcs = apply_inverse(evoked, inverse_operator, lambda2, inv_method,
                     pick_ori=None)
######################################################################
src = fwd['src']
img = stcs.as_volume(src, mri_resolution=False)  # set True for full MRI resolution
t1_fname = data_path + '/subjects/sample/mri/T1.mgz'
# Plotting with nilearn ######################################################
plot_stat_map(index_img(img, 200), t1_fname, threshold=2*1e-9,
              title='%s (t=%.1f s.)' % (inv_method, stcs.times[61]))
plt.show()


```
we have a regression on this with the new SourceMorph PR :(

see this gist https://gist.github.com/agramfort/394e0155945261ccf3faeea0f66d8dbe
to replicate the problem.

Basically we now again only take the first label from the VolSourceEstimate ...

cc @poojaprabhu9 

Resolving patch:
diff --git a/mne/morph.py b/mne/morph.py
--- a/mne/morph.py
+++ b/mne/morph.py
@@ -616,23 +616,32 @@ def _interpolate_data(stc, morph, mri_resolution=True, mri_space=True,
                 "Cannot infer original voxel size for reslicing... "
                 "set mri_resolution to boolean value or apply morph first.")
         from mne.io.constants import BunchConst
+        # Now deal with the fact that we may have multiple sub-volumes
+        inuse = [morph[k]['inuse'] for k in range(len(morph))]
+        src_shape = [morph[k]['shape'] for k in range(len(morph))]
+        assert len(set(map(tuple, src_shape))) == 1
         morph = BunchConst(src_data=_get_src_data(morph)[0])
+    else:
+        # Make a list as we may have many inuse when using multiple sub-volumes
+        inuse = [morph.src_data['inuse']]
+
+    shape3d = morph.src_data['src_shape']
 
     # setup volume parameters
     n_times = stc.data.shape[1]
-    shape3d = morph.src_data['src_shape']
     shape = (n_times,) + shape3d
     vols = np.zeros(shape)
 
-    mask3d = morph.src_data['inuse'].reshape(shape3d).astype(np.bool)
-    n_vertices = np.sum(mask3d)
-
     n_vertices_seen = 0
-    for k, vol in enumerate(vols):  # loop over time instants
+    for this_inuse in inuse:
+        mask3d = this_inuse.reshape(shape3d).astype(np.bool)
+        n_vertices = np.sum(mask3d)
         stc_slice = slice(n_vertices_seen, n_vertices_seen + n_vertices)
-        vol[mask3d] = stc.data[stc_slice, k]
 
-    n_vertices_seen += n_vertices
+        for k, vol in enumerate(vols):  # loop over time instants
+            vol[mask3d] = stc.data[stc_slice, k]
+
+        n_vertices_seen += n_vertices
 
     # use mri resolution as represented in src
     if mri_resolution:


Test patch:
diff --git a/mne/tests/test_morph.py b/mne/tests/test_morph.py
--- a/mne/tests/test_morph.py
+++ b/mne/tests/test_morph.py
@@ -14,9 +14,13 @@
 from mne import (SourceEstimate, VolSourceEstimate, VectorSourceEstimate,
                  read_evokeds, SourceMorph, compute_source_morph,
                  read_source_morph, read_source_estimate,
-                 read_forward_solution, grade_to_vertices, morph_data)
+                 read_forward_solution, grade_to_vertices, morph_data,
+                 setup_volume_source_space, make_forward_solution,
+                 make_sphere_model, make_ad_hoc_cov)
 from mne.datasets import testing
-from mne.minimum_norm import apply_inverse, read_inverse_operator
+from mne.minimum_norm import (apply_inverse, read_inverse_operator,
+                              make_inverse_operator)
+from mne.source_space import get_volume_labels_from_aseg
 from mne.utils import (run_tests_if_main, requires_nibabel, _TempDir,
                        requires_dipy, requires_h5py, requires_version)
 from mne.fixes import _get_args
@@ -27,6 +31,7 @@
 sample_dir = op.join(data_path, 'MEG', 'sample')
 subjects_dir = op.join(data_path, 'subjects')
 fname_evoked = op.join(sample_dir, 'sample_audvis-ave.fif')
+fname_trans = op.join(sample_dir, 'sample_audvis_trunc-trans.fif')
 fname_inv_vol = op.join(sample_dir,
                         'sample_audvis_trunc-meg-vol-7-meg-inv.fif')
 fname_fwd_vol = op.join(sample_dir,
@@ -494,4 +499,36 @@ def test_morph_stc_sparse():
             spacing=None, sparse=True, xhemi=True, subjects_dir=subjects_dir)
 
 
+@requires_nibabel()
+@testing.requires_testing_data
+def test_volume_labels_morph(tmpdir):
+    """Test generating a source space from volume label."""
+    # see gh-5224
+    evoked = mne.read_evokeds(fname_evoked)[0].crop(0, 0)
+    evoked.pick_channels(evoked.ch_names[:306:8])
+    evoked.info.normalize_proj()
+    n_ch = len(evoked.ch_names)
+    aseg_fname = op.join(subjects_dir, 'sample', 'mri', 'aseg.mgz')
+    label_names = get_volume_labels_from_aseg(aseg_fname)
+    src = setup_volume_source_space(
+        'sample', subjects_dir=subjects_dir, volume_label=label_names[:2],
+        mri=aseg_fname)
+    assert len(src) == 2
+    assert src.kind == 'volume'
+    n_src = sum(s['nuse'] for s in src)
+    sphere = make_sphere_model('auto', 'auto', evoked.info)
+    fwd = make_forward_solution(evoked.info, fname_trans, src, sphere)
+    assert fwd['sol']['data'].shape == (n_ch, n_src * 3)
+    inv = make_inverse_operator(evoked.info, fwd, make_ad_hoc_cov(evoked.info),
+                                loose=1.)
+    stc = apply_inverse(evoked, inv)
+    assert stc.data.shape == (n_src, 1)
+    img = stc.as_volume(src, mri_resolution=True)
+    n_on = np.array(img.dataobj).astype(bool).sum()
+    assert n_on == 291  # was 291 on `master` before gh-5590
+    img = stc.as_volume(src, mri_resolution=False)
+    n_on = np.array(img.dataobj).astype(bool).sum()
+    assert n_on == 44  # was 20 on `master` before gh-5590
+
+
 run_tests_if_main()