code: def test_morphed_source_space_return():
      """Test returning a morphed source space to the original subject."""
      # let's create some random data on fsaverage
      pytest.importorskip("nibabel")
      data = rng.randn(20484, 1)
      tmin, tstep = 0, 1.0
      src_fs = read_source_spaces(fname_fs)
      stc_fs = SourceEstimate(
          data, [s["vertno"] for s in src_fs], tmin, tstep, "fsaverage"
      )
      n_verts_fs = sum(len(s["vertno"]) for s in src_fs)
  
      # Create our morph source space
      src_morph = morph_source_spaces(
          src_fs, "sample", subjects_dir=subjects_dir
      )
      n_verts_sample = sum(len(s["vertno"]) for s in src_morph)
      assert n_verts_fs == n_verts_sample
  
      # Morph the data over using standard methods
      stc_morph = compute_source_morph(
          src_fs,
          "fsaverage",
          "sample",
          spacing=[s["vertno"] for s in src_morph],
          smooth=1,
          subjects_dir=subjects_dir,
          warn=False,
      ).apply(stc_fs)
      assert stc_morph.data.shape[0] == n_verts_sample
  
      # We can now pretend like this was real data we got e.g. from an inverse.
      # To be complete, let's remove some vertices
      keeps = [
          np.sort(rng.permutation(np.arange(len(v)))[: len(v) - 10])
          for v in stc_morph.vertices
      ]
      stc_morph = SourceEstimate(
          np.concatenate(
              [stc_morph.lh_data[keeps[0]], stc_morph.rh_data[keeps[1]]]
          ),
          [v[k] for v, k in zip(stc_morph.vertices, keeps)],
          tmin,
          tstep,
          "sample",
      )
  
      # Return it to the original subject
      stc_morph_return = stc_morph.to_original_src(
          src_fs, subjects_dir=subjects_dir
      )
  
      # This should fail (has too many verts in SourceMorph)
      with pytest.warns(RuntimeWarning, match="vertices not included"):
          morph = compute_source_morph(
              src_morph,
              subject_from="sample",
              spacing=stc_morph_return.vertices,
              smooth=1,
              subjects_dir=subjects_dir,
          )
      with pytest.raises(ValueError, match="vertices do not match"):
          morph.apply(stc_morph)
  
      # Compare to the original data
      with pytest.warns(RuntimeWarning, match="vertices not included"):
          stc_morph_morph = compute_source_morph(
              src=stc_morph,
              subject_from="sample",
              spacing=stc_morph_return.vertices,
              smooth=1,
              subjects_dir=subjects_dir,
          ).apply(stc_morph)
  
      assert_equal(stc_morph_return.subject, stc_morph_morph.subject)
      for ii in range(2):
          assert_array_equal(
              stc_morph_return.vertices[ii],
              stc_morph_morph.vertices[ii],
          )
      # These will not match perfectly because morphing pushes data around
      corr = np.corrcoef(
          stc_morph_return.data[:, 0], stc_morph_morph.data[:, 0]
      )[0, 1]
      assert corr > 0.99, corr
  
      # Explicitly test having two vertices map to the same target vertex. We
      # simulate this by having two vertices be at the same position.
      src_fs2 = src_fs.copy()
      vert1, vert2 = src_fs2[0]["vertno"][:2]
      src_fs2[0]["rr"][vert1] = src_fs2[0]["rr"][vert2]
      stc_morph_return = stc_morph.to_original_src(
          src_fs2, subjects_dir=subjects_dir
      )
  
      # test to_original_src method result equality
      for ii in range(2):
          assert_array_equal(
              stc_morph_return.vertices[ii],
              stc_morph_morph.vertices[ii],
          )
  
      # These will not match perfectly because morphing pushes data around
      corr = np.corrcoef(
          stc_morph_return.data[:, 0], stc_morph_morph.data[:, 0]
      )[0, 1]
      assert corr > 0.99, corr
  
      # Degenerate cases
      stc_morph.subject = None  # no .subject provided
      pytest.raises(
          ValueError,
          stc_morph.to_original_src,
          src_fs,
          subject_orig="fsaverage",
          subjects_dir=subjects_dir,
      )
      stc_morph.subject = "sample"
      del src_fs[0]["subject_his_id"]  # no name in src_fsaverage
      pytest.raises(
          ValueError,
          stc_morph.to_original_src,
          src_fs,
          subjects_dir=subjects_dir,
      )
      src_fs[0]["subject_his_id"] = "fsaverage"  # name mismatch
      pytest.raises(
          ValueError,
          stc_morph.to_original_src,
          src_fs,
          subject_orig="foo",
          subjects_dir=subjects_dir,
      )
      src_fs[0]["subject_his_id"] = "sample"
      src = read_source_spaces(fname)  # wrong source space
      pytest.raises(
          RuntimeError,
          stc_morph.to_original_src,
          src,
          subjects_dir=subjects_dir,
      )
  
imports: from pathlib import Path
  from shutil import copytree
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_equal, assert_array_less, assert_equal
  import mne
  from mne import SourceEstimate, add_source_space_distances, compute_source_morph, get_volume_labels_from_src, make_sphere_model, morph_source_spaces, pick_types, read_bem_solution, read_bem_surfaces, read_freesurfer_lut, read_source_spaces, read_trans, setup_source_space, setup_volume_source_space, write_source_spaces
  from mne._fiff.constants import FIFF
  from mne._fiff.pick import _picks_to_idx
  from mne.datasets import testing
  from mne.fixes import _get_img_fdata
  from mne.source_estimate import _get_src_type
  from mne.source_space import compute_distance_to_sensors, get_decimated_surfaces
  from mne.source_space._source_space import _compare_source_spaces
  from mne.surface import _accumulate_normals, _triangle_neighbors
  from mne.utils import _record_warnings, requires_mne, run_subprocess
label_desc: Use image node_id 21 for calling a global function with example usage: test_morphed_source_space_return() without return types