code: def _fit_xdawn(
      epochs_data,
      y,
      n_components,
      reg=None,
      signal_cov=None,
      events=None,
      tmin=0.0,
      sfreq=1.0,
      method_params=None,
      info=None,
  ):
      """Fit filters and coefs using Xdawn Algorithm.
  
      Xdawn is a spatial filtering method designed to improve the signal
      to signal + noise ratio (SSNR) of the event related responses. Xdawn was
      originally designed for P300 evoked potential by enhancing the target
      response with respect to the non-target response. This implementation is a
      generalization to any type of event related response.
  
      Parameters
      ----------
      epochs_data : array, shape (n_epochs, n_channels, n_times)
          The epochs data.
      y : array, shape (n_epochs)
          The epochs class.
      n_components : int (default 2)
          The number of components to decompose the signals signals.
      reg : float | str | None (default None)
          If not None (same as ``'empirical'``, default), allow
          regularization for covariance estimation.
          If float, shrinkage is used (0 <= shrinkage <= 1).
          For str options, ``reg`` will be passed as ``method`` to
          :func:`mne.compute_covariance`.
      signal_cov : None | Covariance | array, shape (n_channels, n_channels)
          The signal covariance used for whitening of the data.
          if None, the covariance is estimated from the epochs signal.
      events : array, shape (n_epochs, 3)
          The epochs events, used to correct for epochs overlap.
      tmin : float
          Epochs starting time. Only used if events is passed to correct for
          epochs overlap.
      sfreq : float
          Sampling frequency.  Only used if events is passed to correct for
          epochs overlap.
  
      Returns
      -------
      filters : array, shape (n_channels, n_channels)
          The Xdawn components used to decompose the data for each event type.
          Each row corresponds to one component.
      patterns : array, shape (n_channels, n_channels)
          The Xdawn patterns used to restore the signals for each event type.
      evokeds : array, shape (n_class, n_components, n_times)
          The independent evoked responses per condition.
      """
      if (
          not isinstance(epochs_data, np.ndarray)
          or epochs_data.ndim != 3
      ):
          raise ValueError("epochs_data must be 3D ndarray")
  
      classes = np.unique(y)
  
      # XXX Eventually this could be made to deal with rank deficiency properly
      # by exposing this "rank" parameter, but this will require refactoring
      # the linalg.eigh call to operate in the lower-dimension
      # subspace, then project back out.
  
      # Retrieve or compute whitening covariance
      if signal_cov is None:
          signal_cov = _regularized_covariance(
              np.hstack(epochs_data),
              reg,
              method_params,
              info,
              rank="full",
          )
      elif isinstance(signal_cov, Covariance):
          signal_cov = signal_cov.data
      if not isinstance(signal_cov, np.ndarray) or (
          not np.array_equal(
              signal_cov.shape, np.tile(epochs_data.shape[1], 2)
          )
      ):
          raise ValueError(
              "signal_cov must be None, a covariance instance, "
              "or an array of shape (n_chans, n_chans)"
          )
  
      # Get prototype events
      if events is not None:
          evokeds, toeplitzs = _least_square_evoked(
              epochs_data, events, tmin, sfreq
          )
      else:
          evokeds, toeplitzs = list(), list()
          for c in classes:
              # Prototyped response for each class
              evokeds.append(np.mean(epochs_data[y == c, :, :], axis=0))
              toeplitzs.append(1.0)
  
      filters = list()
      patterns = list()
      for evo, toeplitz in zip(evokeds, toeplitzs):
          # Estimate covariance matrix of the prototype response
          evo = np.dot(evo, toeplitz)
          evo_cov = _regularized_covariance(
              evo, reg, method_params, info, rank="full"
          )
  
          # Fit spatial filters
          try:
              evals, evecs = linalg.eigh(evo_cov, signal_cov)
          except np.linalg.LinAlgError as exp:
              raise ValueError(
                  "Could not compute eigenvalues, ensure "
                  "proper regularization (%s)" % (exp,)
              )
          evecs = evecs[:, np.argsort(evals)[::-1]]  # sort eigenvectors
          evecs /= np.apply_along_axis(np.linalg.norm, 0, evecs)
          _patterns = np.linalg.pinv(evecs.T)
          filters.append(evecs[:, :n_components].T)
          patterns.append(_patterns[:, :n_components].T)
  
      filters = np.concatenate(filters, axis=0)
      patterns = np.concatenate(patterns, axis=0)
      evokeds = np.array(evokeds)
      return filters, patterns, evokeds
  
imports: import numpy
  from scipy import linalg
  from .._fiff.pick import _pick_data_channels, pick_info
  from ..cov import Covariance, _regularized_covariance
  from ..decoding import BaseEstimator, TransformerMixin
  from ..epochs import BaseEpochs
  from ..evoked import Evoked, EvokedArray
  from ..io import BaseRaw
  from ..utils import _check_option, logger
label_desc: Use image node_id 3 for calling a global function with example usage: _fit_xdawn(epochs_data, y, n_components, reg, signal_cov, events, tmin, sfreq, method_params, info) and returns: filters,  patterns,  evokeds