code: def _compute_exg_proj(
      mode,
      raw,
      raw_event,
      tmin,
      tmax,
      n_grad,
      n_mag,
      n_eeg,
      l_freq,
      h_freq,
      average,
      filter_length,
      n_jobs,
      ch_name,
      reject,
      flat,
      bads,
      avg_ref,
      no_proj,
      event_id,
      exg_l_freq,
      exg_h_freq,
      tstart,
      qrs_threshold,
      filter_method,
      iir_params,
      return_drop_log,
      copy,
      meg,
      verbose,
  ):
      """Compute SSP/PCA projections for ECG or EOG artifacts."""
      raw = raw.copy() if copy else raw
      del copy
      raw.load_data()  # we will filter it later
  
      if no_proj:
          projs = []
      else:
          projs = cp.deepcopy(raw.info["projs"])
          logger.info(
              "Including %d SSP projectors from raw file" % len(projs)
          )
  
      if avg_ref:
          eeg_proj = make_eeg_average_ref_proj(raw.info)
          projs.append(eeg_proj)
  
      if raw_event is None:
          raw_event = raw
  
      assert mode in ("ECG", "EOG")  # internal function
      logger.info("Running %s SSP computation" % mode)
      if mode == "ECG":
          events, _, _ = find_ecg_events(
              raw_event,
              ch_name=ch_name,
              event_id=event_id,
              l_freq=exg_l_freq,
              h_freq=exg_h_freq,
              tstart=tstart,
              qrs_threshold=qrs_threshold,
              filter_length=filter_length,
          )
      else:  # mode == 'EOG':
          events = find_eog_events(
              raw_event,
              event_id=event_id,
              l_freq=exg_l_freq,
              h_freq=exg_h_freq,
              filter_length=filter_length,
              ch_name=ch_name,
              tstart=tstart,
          )
  
      # Check to make sure we actually got at least one usable event
      if events.shape[0] < 1:
          warn(f"No {mode} events found")
          return ([], events) + (([],) if return_drop_log else ())
  
      logger.info("Computing projector")
      my_info = cp.deepcopy(raw.info)
      my_info["bads"] += bads
  
      # Handler rejection parameters
      if reject is not None:  # make sure they didn't pass None
          if (
              len(
                  pick_types(
                      my_info,
                      meg="grad",
                      eeg=False,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(reject, "grad")
          if (
              len(
                  pick_types(
                      my_info,
                      meg="mag",
                      eeg=False,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(reject, "mag")
          if (
              len(
                  pick_types(
                      my_info,
                      meg=False,
                      eeg=True,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(reject, "eeg")
          if (
              len(
                  pick_types(
                      my_info,
                      meg=False,
                      eeg=False,
                      eog=True,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(reject, "eog")
      if flat is not None:  # make sure they didn't pass None
          if (
              len(
                  pick_types(
                      my_info,
                      meg="grad",
                      eeg=False,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(flat, "grad")
          if (
              len(
                  pick_types(
                      my_info,
                      meg="mag",
                      eeg=False,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(flat, "mag")
          if (
              len(
                  pick_types(
                      my_info,
                      meg=False,
                      eeg=True,
                      eog=False,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(flat, "eeg")
          if (
              len(
                  pick_types(
                      my_info,
                      meg=False,
                      eeg=False,
                      eog=True,
                      ref_meg=False,
                      exclude="bads",
                  )
              )
              == 0
          ):
              _safe_del_key(flat, "eog")
  
      # exclude bad channels from projection
      # keep reference channels if compensation channels are present
      ref_meg = len(my_info["comps"]) > 0
      picks = pick_types(
          my_info,
          meg=True,
          eeg=True,
          eog=True,
          ecg=True,
          ref_meg=ref_meg,
          exclude="bads",
      )
  
      raw.filter(
          l_freq,
          h_freq,
          picks=picks,
          filter_length=filter_length,
          n_jobs=n_jobs,
          method=filter_method,
          iir_params=iir_params,
          l_trans_bandwidth=0.5,
          h_trans_bandwidth=0.5,
          phase="zero-double",
          fir_design="firwin2",
      )
  
      epochs = Epochs(
          raw,
          events,
          None,
          tmin,
          tmax,
          baseline=None,
          preload=True,
          picks=picks,
          reject=reject,
          flat=flat,
          proj=True,
      )
  
      drop_log = epochs.drop_log
      if epochs.events.shape[0] < 1:
          warn("No good epochs found")
          return ([], events) + ((drop_log,) if return_drop_log else ())
  
      if average:
          evoked = epochs.average()
          ev_projs = compute_proj_evoked(
              evoked, n_grad=n_grad, n_mag=n_mag, n_eeg=n_eeg, meg=meg
          )
      else:
          ev_projs = compute_proj_epochs(
              epochs,
              n_grad=n_grad,
              n_mag=n_mag,
              n_eeg=n_eeg,
              n_jobs=n_jobs,
              meg=meg,
          )
  
      for p in ev_projs:
          p["desc"] = mode + "-" + p["desc"]
  
      projs.extend(ev_projs)
      logger.info("Done.")
      return (projs, events) + ((drop_log,) if return_drop_log else ())
  
file_path: mne-python/mne/preprocessing/ssp.py
imports: import copy
  import numpy
  from .._fiff.pick import pick_types
  from .._fiff.reference import make_eeg_average_ref_proj
  from ..epochs import Epochs
  from ..proj import compute_proj_epochs, compute_proj_evoked
  from ..utils import logger, verbose, warn
  from .ecg import find_ecg_events
  from .eog import find_eog_events
label_desc: Use image node_id 2 for calling a global function with example usage: _compute_exg_proj(mode, raw, raw_event, tmin, tmax, n_grad, n_mag, n_eeg, l_freq, h_freq, average, filter_length, n_jobs, ch_name, reject, flat, bads, avg_ref, no_proj, event_id, exg_l_freq, exg_h_freq, tstart, qrs_threshold, filter_method, iir_params, return_drop_log, copy, meg, verbose) and returns: unknown, unknown, unknown