code: def _make_projector(
      projs, ch_names, bads=(), include_active=True, inplace=False
  ):
      """Subselect projs based on ch_names and bads.
  
      Use inplace=True mode to modify ``projs`` inplace so that no
      warning will be raised next time projectors are constructed with
      the given inputs. If inplace=True, no meaningful data are returned.
      """
      nchan = len(ch_names)
      if nchan == 0:
          raise ValueError("No channel names specified")
  
      default_return = (np.eye(nchan, nchan), 0, np.empty((nchan, 0)))
  
      #   Check trivial cases first
      if projs is None:
          return default_return
  
      nvec = 0
      nproj = 0
      for p in projs:
          if not p["active"] or include_active:
              nproj += 1
              nvec += p["data"]["nrow"]
  
      if nproj == 0:
          return default_return
  
      #   Pick the appropriate entries
      vecs = np.zeros((nchan, nvec))
      nvec = 0
      nonzero = 0
      bads = set(bads)
      for k, p in enumerate(projs):
          if not p["active"] or include_active:
              if len(p["data"]["col_names"]) != len(
                  np.unique(p["data"]["col_names"])
              ):
                  raise ValueError(
                      "Channel name list in projection item %d"
                      " contains duplicate items" % k
                  )
  
              # Get the two selection vectors to pick correct elements from
              # the projection vectors omitting bad channels
              sel = []
              vecsel = []
              p_set = set(
                  p["data"]["col_names"]
              )  # faster membership access
              for c, name in enumerate(ch_names):
                  if name not in bads and name in p_set:
                      sel.append(c)
                      vecsel.append(p["data"]["col_names"].index(name))
  
              # If there is something to pick, pickit
              nrow = p["data"]["nrow"]
              this_vecs = vecs[:, nvec : nvec + nrow]
              if len(sel) > 0:
                  this_vecs[sel] = p["data"]["data"][:, vecsel].T
  
              # Rescale for better detection of small singular values
              for v in range(p["data"]["nrow"]):
                  psize = np.linalg.norm(this_vecs[:, v])
                  if psize > 0:
                      orig_n = p["data"]["data"].any(axis=0).sum()
                      # Average ref still works if channels are removed
                      # Use relative power to determine if we're in trouble.
                      # 10% loss is hopefully a reasonable threshold.
                      if (
                          psize < 0.9
                          and not inplace
                          and (
                              p["kind"]
                              != FIFF.FIFFV_PROJ_ITEM_EEG_AVREF
                              or len(vecsel) == 1
                          )
                      ):
                          warn(
                              f'Projection vector {repr(p["desc"])} has been '
                              f"reduced to {100 * psize:0.2f}% of its "
                              "original magnitude by subselecting "
                              f"{len(vecsel)}/{orig_n} of the original "
                              "channels. If the ignored channels were bad "
                              "during SSP computation, we recommend "
                              "recomputing proj (via compute_proj_raw "
                              "or related functions) with the bad channels "
                              "properly marked, because computing SSP with bad "
                              "channels present in the data but unmarked is "
                              "dangerous (it can bias the PCA used by SSP). "
                              "On the other hand, if you know that all channels "
                              "were good during SSP computation, you can safely "
                              "use info.normalize_proj() to suppress this "
                              "warning during projection."
                          )
                      this_vecs[:, v] /= psize
                      nonzero += 1
              # If doing "inplace" mode, "fix" the projectors to only operate
              # on this subset of channels.
              if inplace:
                  p["data"]["data"] = this_vecs[sel].T
                  p["data"]["col_names"] = [
                      p["data"]["col_names"][ii] for ii in vecsel
                  ]
                  p["data"]["ncol"] = len(p["data"]["col_names"])
              nvec += p["data"]["nrow"]
  
      #   Check whether all of the vectors are exactly zero
      if nonzero == 0 or inplace:
          return default_return
  
      # Reorthogonalize the vectors
      U, S, _ = _safe_svd(vecs[:, :nvec], full_matrices=False)
  
      # Throw away the linearly dependent guys
      nproj = np.sum((S / S[0]) > 1e-2)
      U = U[:, :nproj]
  
      # Here is the celebrated result
      proj = np.eye(nchan, nchan) - np.dot(U, U.T)
      if nproj >= nchan:  # e.g., 3 channels and 3 projectors
          raise RuntimeError(
              "Application of %d projectors for %d channels "
              "will yield no components." % (nproj, nchan)
          )
  
      return proj, nproj, U
  
imports: import re
  from copy import deepcopy
  from itertools import count
  import numpy
  from ..defaults import _BORDER_DEFAULT, _EXTRAPOLATE_DEFAULT, _INTERPOLATION_DEFAULT
  from ..fixes import _safe_svd
  from ..utils import _check_option, _validate_type, fill_doc, logger, object_diff, verbose, warn
  from .constants import FIFF
  from .pick import _ELECTRODE_CH_TYPES, _electrode_types, pick_info, pick_types
  from .tag import _rename_list, find_tag
  from .tree import dir_tree_find
  from .write import _safe_name_list, end_block, start_block, write_float, write_float_matrix, write_int, write_name_list_sanitized, write_string
label_desc: Use image node_id 6 for calling a global function with example usage: _make_projector(projs, ch_names, bads, include_active, inplace) and returns: proj,  nproj,  U, default_return, default_return, default_return