code: def qrs_detector(
      sfreq,
      ecg,
      thresh_value=0.6,
      levels=2.5,
      n_thresh=3,
      l_freq=5,
      h_freq=35,
      tstart=0,
      filter_length="10s",
      verbose=None,
  ):
      """Detect QRS component in ECG channels.
  
      QRS is the main wave on the heart beat.
  
      Parameters
      ----------
      sfreq : float
          Sampling rate
      ecg : array
          ECG signal
      thresh_value : float | str
          qrs detection threshold. Can also be "auto" for automatic
          selection of threshold.
      levels : float
          number of std from mean to include for detection
      n_thresh : int
          max number of crossings
      l_freq : float
          Low pass frequency
      h_freq : float
          High pass frequency
      %(tstart_ecg)s
      %(filter_length_ecg)s
      %(verbose)s
  
      Returns
      -------
      events : array
          Indices of ECG peaks.
      """
      win_size = int(round((60.0 * sfreq) / 120.0))
  
      filtecg = filter_data(
          ecg,
          sfreq,
          l_freq,
          h_freq,
          None,
          filter_length,
          0.5,
          0.5,
          phase="zero-double",
          fir_window="hann",
          fir_design="firwin2",
      )
  
      ecg_abs = np.abs(filtecg)
      init = int(sfreq)
  
      n_samples_start = int(sfreq * tstart)
      ecg_abs = ecg_abs[n_samples_start:]
  
      n_points = len(ecg_abs)
  
      maxpt = np.empty(3)
      maxpt[0] = np.max(ecg_abs[:init])
      maxpt[1] = np.max(ecg_abs[init : init * 2])
      maxpt[2] = np.max(ecg_abs[init * 2 : init * 3])
  
      init_max = np.mean(maxpt)
  
      if thresh_value == "auto":
          thresh_runs = np.arange(0.3, 1.1, 0.05)
      elif isinstance(thresh_value, str):
          raise ValueError('threshold value must be "auto" or a float')
      else:
          thresh_runs = [thresh_value]
  
      # Try a few thresholds (or just one)
      clean_events = list()
      for thresh_value in thresh_runs:
          thresh1 = init_max * thresh_value
          numcross = list()
          time = list()
          rms = list()
          ii = 0
          while ii < (n_points - win_size):
              window = ecg_abs[ii : ii + win_size]
              if window[0] > thresh1:
                  max_time = np.argmax(window)
                  time.append(ii + max_time)
                  nx = np.sum(
                      np.diff(
                          (
                              (window > thresh1).astype(np.int64) == 1
                          ).astype(int)
                      )
                  )
                  numcross.append(nx)
                  rms.append(np.sqrt(sum_squared(window) / window.size))
                  ii += win_size
              else:
                  ii += 1
  
          if len(rms) == 0:
              rms.append(0.0)
              time.append(0.0)
          time = np.array(time)
          rms_mean = np.mean(rms)
          rms_std = np.std(rms)
          rms_thresh = rms_mean + (rms_std * levels)
          b = np.where(rms < rms_thresh)[0]
          a = np.array(numcross)[b]
          ce = time[b[a < n_thresh]]
  
          ce += n_samples_start
          if ce.size > 0:  # We actually found an event
              clean_events.append(ce)
  
      if clean_events:
          # pick the best threshold; first get effective heart rates
          rates = np.array(
              [
                  60.0 * len(cev) / (len(ecg) / float(sfreq))
                  for cev in clean_events
              ]
          )
  
          # now find heart rates that seem reasonable (infant through adult
          # athlete)
          idx = np.where(np.logical_and(rates <= 160.0, rates >= 40.0))[
              0
          ]
          if idx.size > 0:
              ideal_rate = np.median(
                  rates[idx]
              )  # get close to the median
          else:
              ideal_rate = 80.0  # get close to a reasonable default
  
          idx = np.argmin(np.abs(rates - ideal_rate))
          clean_events = clean_events[idx]
      else:
          clean_events = np.array([])
  
      return clean_events
  
file_path: mne-python/mne/preprocessing/ecg.py
imports: import numpy
  from .._fiff.meas_info import create_info
  from .._fiff.pick import _picks_to_idx, pick_channels, pick_types
  from ..annotations import _annotations_starts_stops
  from ..epochs import BaseEpochs, Epochs
  from ..evoked import Evoked
  from ..filter import filter_data
  from ..io import BaseRaw, RawArray
  from ..utils import int_like, logger, sum_squared, verbose, warn
label_desc: Use image node_id 1 for calling a global function with example usage: qrs_detector(sfreq, ecg, thresh_value, levels, n_thresh, l_freq, h_freq, tstart, filter_length, verbose) and returns: clean_events