docs: def _find_stars(data, kernel, threshold_eff, min_separation=None,
                  mask=None, exclude_border=False):
      """
      Find stars in an image.
  
      Parameters
      ----------
      data : 2D array_like
          The 2D array of the image.
  
      kernel : `_StarFinderKernel`
          The convolution kernel.
  
      threshold_eff : float
          The absolute image value above which to select sources.  This
          threshold should be the threshold input to the star finder class
          multiplied by the kernel relerr.
  
      mask : 2D bool array, optional
          A boolean mask with the same shape as ``data``, where a `True`
          value indicates the corresponding element of ``data`` is masked.
          Masked pixels are ignored when searching for stars.
  
      exclude_border : bool, optional
          Set to `True` to exclude sources found within half the size of
          the convolution kernel from the image borders.  The default is
          `False`, which is the mode used by IRAF's `DAOFIND`_ and
          `starfind`_ tasks.
  
      Returns
      -------
      objects : list of `_StarCutout`
          A list of `_StarCutout` objects containing the image cutout for
          each source.
  
      .. _DAOFIND: http://stsdas.stsci.edu/cgi-bin/gethelp.cgi?daofind
      .. _starfind: http://stsdas.stsci.edu/cgi-bin/gethelp.cgi?starfind
      """
  
      convolved_data = filter_data(data, kernel.data, mode='constant',
                                   fill_value=0.0, check_normalization=False)
  
      # define a local footprint for the peak finder
      if min_separation is None:   # daofind
          footprint = kernel.mask.astype(np.bool)
      else:
          # define a circular footprint
          idx = np.arange(-min_separation, min_separation + 1)
          xx, yy = np.meshgrid(idx, idx)
          footprint = np.array((xx**2 + yy**2) <= min_separation**2, dtype=int)
  
      # pad the data and convolved image by the kernel x/y radius to allow
      # for detections near the edges
      if not exclude_border:
          ypad = kernel.yradius
          xpad = kernel.xradius
          pad = ((ypad, ypad), (xpad, xpad))
          # mode must be a string for numpy < 0.11
          # (see https://github.com/numpy/numpy/issues/7112)
          mode = str('constant')
          data = np.pad(data, pad, mode=mode, constant_values=[0.])
          if mask is not None:
              mask = np.pad(mask, pad, mode=mode, constant_values=[0.])
          convolved_data = np.pad(convolved_data, pad, mode=mode,
                                  constant_values=[0.])
  
      # find local peaks in the convolved data
      with warnings.catch_warnings():
          # suppress any NoDetectionsWarning from find_peaks
          warnings.filterwarnings('ignore', category=NoDetectionsWarning)
          tbl = find_peaks(convolved_data, threshold_eff, footprint=footprint,
                           mask=mask)
  
      if tbl is None:
          return None
  
      coords = np.transpose([tbl['y_peak'], tbl['x_peak']])
  
      star_cutouts = []
      for (ypeak, xpeak) in coords:
          # now extract the object from the data, centered on the peak
          # pixel in the convolved image, with the same size as the kernel
          x0 = xpeak - kernel.xradius
          x1 = xpeak + kernel.xradius + 1
          y0 = ypeak - kernel.yradius
          y1 = ypeak + kernel.yradius + 1
  
          if x0 < 0 or x1 > data.shape[1]:
              continue    # pragma: no cover
          if y0 < 0 or y1 > data.shape[0]:
              continue    # pragma: no cover
  
          slices = (slice(y0, y1), slice(x0, x1))
          data_cutout = data[slices]
          convdata_cutout = convolved_data[slices]
  
          # correct pixel values for the previous image padding
          if not exclude_border:
              x0 -= kernel.xradius
              x1 -= kernel.xradius
              y0 -= kernel.yradius
              y1 -= kernel.yradius
              xpeak -= kernel.xradius
              ypeak -= kernel.yradius
              slices = (slice(y0, y1), slice(x0, x1))
  
          star_cutouts.append(_StarCutout(data_cutout, convdata_cutout, slices,
                                          xpeak, ypeak, kernel, threshold_eff))
  
      return star_cutouts