code: def _apply_morph_data(morph, stc_from):
      """Morph a source estimate from one subject to another."""
      if (
          stc_from.subject is not None
          and stc_from.subject != morph.subject_from
      ):
          raise ValueError(
              "stc.subject (%s) != morph.subject_from (%s)"
              % (stc_from.subject, morph.subject_from)
          )
      _check_option(
          "morph.kind", morph.kind, ("surface", "volume", "mixed")
      )
      if morph.kind == "surface":
          _validate_type(
              stc_from,
              _BaseSurfaceSourceEstimate,
              "stc_from",
              "volume source estimate when using a surface morph",
          )
      elif morph.kind == "volume":
          _validate_type(
              stc_from,
              _BaseVolSourceEstimate,
              "stc_from",
              "surface source estimate when using a volume morph",
          )
      else:
          assert morph.kind == "mixed"  # can handle any
          _validate_type(
              stc_from,
              _BaseSourceEstimate,
              "stc_from",
              "source estimate when using a mixed source morph",
          )
  
      # figure out what to actually morph
      do_vol = not isinstance(stc_from, _BaseSurfaceSourceEstimate)
      do_surf = not isinstance(stc_from, _BaseVolSourceEstimate)
  
      vol_src_offset = 2 if do_surf else 0
      from_surf_stop = sum(
          len(v) for v in stc_from.vertices[:vol_src_offset]
      )
      to_surf_stop = sum(
          len(v) for v in morph.vertices_to[:vol_src_offset]
      )
      from_vol_stop = stc_from.data.shape[0]
      vertices_to = morph.vertices_to
      if morph.kind == "mixed":
          vertices_to = vertices_to[
              0 if do_surf else 2 : None if do_vol else 2
          ]
      to_vol_stop = sum(len(v) for v in vertices_to)
  
      mesg = "Ori × Time" if stc_from.data.ndim == 3 else "Time"
      data_from = np.reshape(
          stc_from.data, (stc_from.data.shape[0], -1)
      )
      n_times = data_from.shape[1]  # oris treated as times
      data = np.empty((to_vol_stop, n_times), stc_from.data.dtype)
      to_used = np.zeros(data.shape[0], bool)
      from_used = np.zeros(data_from.shape[0], bool)
      if do_vol:
          stc_from_vertices = stc_from.vertices[vol_src_offset:]
          vertices_from = morph._vol_vertices_from
          for ii, (v1, v2) in enumerate(
              zip(vertices_from, stc_from_vertices)
          ):
              _check_vertices_match(v1, v2, "volume[%d]" % (ii,))
          from_sl = slice(from_surf_stop, from_vol_stop)
          assert not from_used[from_sl].any()
          from_used[from_sl] = True
          to_sl = slice(to_surf_stop, to_vol_stop)
          assert not to_used[to_sl].any()
          to_used[to_sl] = True
          # Loop over time points to save memory
          if (
              morph.vol_morph_mat is None
              and n_times
              >= _VOL_MAT_CHECK_RATIO * (to_vol_stop - to_surf_stop)
          ):
              warn(
                  "Computing a sparse volume morph matrix will save time over "
                  "directly morphing, calling morph.compute_vol_morph_mat(). "
                  "Consider (re-)saving your instance to disk to avoid "
                  "subsequent recomputation."
              )
              morph.compute_vol_morph_mat()
          if morph.vol_morph_mat is None:
              logger.debug("Using individual volume morph")
              data[to_sl, :] = morph._morph_vols(
                  data_from[from_sl], mesg
              )
          else:
              logger.debug("Using sparse volume morph matrix")
              data[to_sl, :] = morph.vol_morph_mat @ data_from[from_sl]
      if do_surf:
          for hemi, v1, v2 in zip(
              ("left", "right"),
              morph.src_data["vertices_from"],
              stc_from.vertices[:2],
          ):
              _check_vertices_match(v1, v2, "%s hemisphere" % (hemi,))
          from_sl = slice(0, from_surf_stop)
          assert not from_used[from_sl].any()
          from_used[from_sl] = True
          to_sl = slice(0, to_surf_stop)
          assert not to_used[to_sl].any()
          to_used[to_sl] = True
          data[to_sl] = morph.morph_mat * data_from[from_sl]
      assert to_used.all()
      assert from_used.all()
      data.shape = (data.shape[0],) + stc_from.data.shape[1:]
      klass = stc_from.__class__
      stc_to = klass(
          data,
          vertices_to,
          stc_from.tmin,
          stc_from.tstep,
          morph.subject_to,
      )
      return stc_to
  
imports: import copy
  import os.path
  import warnings
  import numpy
  from scipy import sparse
  from .fixes import _get_img_fdata
  from .morph_map import read_morph_map
  from .parallel import parallel_func
  from .source_estimate import _BaseSourceEstimate, _BaseSurfaceSourceEstimate, _BaseVolSourceEstimate, _get_ico_tris
  from .source_space._source_space import SourceSpaces, _ensure_src, _grid_interp
  from .surface import _compute_nearest, mesh_edges, read_surface
  from .utils import BunchConst, ProgressBar, _check_fname, _check_option, _custom_lru_cache, _ensure_int, _import_h5io_funcs, _import_nibabel, _validate_type, check_version, fill_doc, get_subjects_dir, logger, use_log_level, verbose, warn
  from .utils import warn
label_desc: Use image node_id 24 for calling a global function with example usage: _apply_morph_data(morph, stc_from) and returns: stc_to