code: def _compute_residual(forward, evoked, X, active_set, info):
      # OK, picking based on row_names is safe
      sel = [
          forward["sol"]["row_names"].index(c) for c in info["ch_names"]
      ]
      residual = evoked.copy().pick(info["ch_names"])
      r_tmp = residual.copy()
  
      r_tmp.data = np.dot(
          forward["sol"]["data"][sel, :][:, active_set], X
      )
  
      # Take care of proj
      active_projs = list()
      non_active_projs = list()
      for p in evoked.info["projs"]:
          if p["active"]:
              active_projs.append(p)
          else:
              non_active_projs.append(p)
  
      if len(active_projs) > 0:
          with r_tmp.info._unlock():
              r_tmp.info["projs"] = deactivate_proj(
                  active_projs, copy=True, verbose=False
              )
          r_tmp.apply_proj(verbose=False)
          r_tmp.add_proj(
              non_active_projs, remove_existing=False, verbose=False
          )
  
      residual.data -= r_tmp.data
  
      return residual
  
imports: import numpy
  from .._fiff.proj import deactivate_proj
  from ..dipole import Dipole
  from ..fixes import _safe_svd
  from ..forward import is_fixed_orient
  from ..minimum_norm.inverse import _check_reference, _log_exp_var, _prepare_forward, combine_xyz
  from ..source_estimate import SourceEstimate, _BaseSourceEstimate, _make_stc
  from ..utils import _check_depth, _check_option, _validate_type, check_random_state, logger, sum_squared, verbose, warn
  from .mxne_optim import _Phi, groups_norm2, iterative_mixed_norm_solver, iterative_tf_mixed_norm_solver, mixed_norm_solver, norm_epsilon_inf, norm_l2inf, tf_mixed_norm_solver
label_desc: Use image node_id 5 for calling a global function with example usage: _compute_residual(forward, evoked, X, active_set, info) and returns: residual