code: def estimate_snr(evoked, inv, verbose=None):
      r"""Estimate the SNR as a function of time for evoked data.
  
      Parameters
      ----------
      evoked : instance of Evoked
          Evoked instance.
      inv : instance of InverseOperator
          The inverse operator.
      %(verbose)s
  
      Returns
      -------
      snr : ndarray, shape (n_times,)
          The SNR estimated from the whitened data (i.e., GFP of whitened data).
      snr_est : ndarray, shape (n_times,)
          The SNR estimated using the mismatch between the unregularized
          solution and the regularized solution.
  
      Notes
      -----
      ``snr_est`` is estimated by using different amounts of inverse
      regularization and checking the mismatch between predicted and
      measured whitened data.
  
      In more detail, given our whitened inverse obtained from SVD:
  
      .. math::
  
          \tilde{M} = R^\frac{1}{2}V\Gamma U^T
  
      The values in the diagonal matrix :math:`\Gamma` are expressed in terms
      of the chosen regularization :math:`\lambda^2 \sim 1/\rm{SNR}^2`
      and singular values :math:`\lambda_k` as:
  
      .. math::
  
          \gamma_k = \frac{1}{\lambda_k}\frac{\lambda_k^2}{\lambda_k^2 + \lambda^2}
  
      We also know that our predicted data is given by:
  
      .. math::
  
          \hat{x}(t) = G\hat{j}(t)=C^\frac{1}{2}U\Pi w(t)
  
      And thus our predicted whitened data is just:
  
      .. math::
  
          \hat{w}(t) = U\Pi w(t)
  
      Where :math:`\Pi` is diagonal with entries entries:
  
      .. math::
  
          \lambda_k\gamma_k = \frac{\lambda_k^2}{\lambda_k^2 + \lambda^2}
  
      If we use no regularization, note that :math:`\Pi` is just the
      identity matrix. Here we test the squared magnitude of the difference
      between unregularized solution and regularized solutions, choosing the
      biggest regularization that achieves a :math:`\chi^2`-test significance
      of 0.001.
  
      .. versionadded:: 0.9.0
      """  # noqa: E501
      _check_reference(evoked, inv["info"]["ch_names"])
      _check_ch_names(inv, evoked.info)
      inv = prepare_inverse_operator(
          inv, evoked.nave, 1.0 / 9.0, "MNE", copy="non-src"
      )
      sel = _pick_channels_inverse_operator(evoked.ch_names, inv)
      logger.info("Picked %d channels from the data" % len(sel))
      data_white = np.dot(
          inv["whitener"], np.dot(inv["proj"], evoked.data[sel])
      )
      data_white_ef = np.dot(inv["eigen_fields"]["data"], data_white)
      n_ch, n_times = data_white.shape
  
      # Adapted from mne_analyze/regularization.c, compute_regularization
      n_ch_eff = compute_rank_inverse(inv)
      n_zero = n_ch - n_ch_eff
      logger.info(
          "Effective nchan = %d - %d = %d" % (n_ch, n_zero, n_ch_eff)
      )
      del n_ch
      signal = np.sum(
          data_white**2, axis=0
      )  # sum of squares across channels
      snr = signal / n_ch_eff
  
      # Adapted from noise_regularization
      lambda2_est = np.empty(n_times)
      lambda2_est.fill(10.0)
      remaining = np.ones(n_times, bool)
  
      # deal with low SNRs
      bad = snr <= 1
      lambda2_est[bad] = np.inf
      remaining[bad] = False
  
      # parameters
      lambda_mult = 0.99
      sing2 = (inv["sing"] * inv["sing"])[:, np.newaxis]
      val = chi2.isf(1e-3, n_ch_eff)
      for n_iter in range(1000):
          # get_mne_weights (ew=error_weights)
          # (split newaxis creation here for old numpy)
          f = sing2 / (sing2 + lambda2_est[np.newaxis][:, remaining])
          f[inv["sing"] == 0] = 0
          ew = data_white_ef[:, remaining] * (1.0 - f)
          # check condition
          err = np.sum(ew * ew, axis=0)
          remaining[np.where(remaining)[0][err < val]] = False
          if not remaining.any():
              break
          lambda2_est[remaining] *= lambda_mult
      else:
          warn("SNR estimation did not converge")
      snr_est = 1.0 / np.sqrt(lambda2_est)
      snr = np.sqrt(snr)
      return snr, snr_est
  
imports: from copy import deepcopy
  from math import sqrt
  import numpy
  from scipy import linalg
  from scipy.stats import chi2
  from .._fiff.constants import FIFF
  from .._fiff.matrix import _read_named_matrix, _transpose_named_matrix, write_named_matrix
  from .._fiff.open import fiff_open
  from .._fiff.pick import channel_type, pick_channels, pick_info, pick_types
  from .._fiff.proj import _electrode_types, _needs_eeg_average_ref_proj, _read_proj, _write_proj, make_projector
  from .._fiff.tag import find_tag
  from .._fiff.tree import dir_tree_find
  from .._fiff.write import end_block, start_and_end_file, start_block, write_coord_trans, write_float, write_float_matrix, write_int, write_string
  from ..cov import Covariance, _read_cov, _write_cov, compute_whitener, prepare_noise_cov
  from ..epochs import BaseEpochs, EpochsArray
  from ..evoked import Evoked, EvokedArray
  from ..fixes import _safe_svd
  from ..forward import _read_forward_meas_info, _select_orient_forward, compute_depth_prior, compute_orient_prior, convert_forward_solution, is_fixed_orient
  from ..forward.forward import _triage_loose, write_forward_meas_info
  from ..html_templates import _get_html_template
  from ..io import BaseRaw
  from ..source_estimate import _get_src_type, _make_stc
  from ..source_space._source_space import _get_src_nn, _get_vertno, _read_source_spaces_from_tree, _write_source_spaces_to_fid, find_source_space_hemi, label_src_vertno_sel
  from ..surface import _normal_orth
  from ..time_frequency.tfr import _check_tfr_complex
  from ..transforms import _ensure_trans, transform_surface_to
  from ..utils import _check_compensation_grade, _check_depth, _check_fname, _check_option, _check_src_normal, _validate_type, _verbose_safe_false, check_fname, logger, repr_html, verbose, warn
  from ._eloreta import _compute_eloreta
label_desc: Use image node_id 26 for calling a global function with example usage: estimate_snr(evoked, inv, verbose) and returns: snr,  snr_est