docs: def find_center(self, image, threshold=0.1, verbose=True):
          """
          Find the center of a galaxy.
  
          If the algorithm is successful the (x, y) coordinates in this
          `~photutils.isophote.EllipseGeometry` (i.e. the ``x0`` and
          ``y0`` attributes) instance will be modified.
  
          The isophote fit algorithm requires an initial guess for the
          galaxy center (x, y) coordinates and these coordinates must be
          close to the actual galaxy center for the isophote fit to work.
          This method provides can provide an initial guess for the galaxy
          center coordinates.  See the **Notes** section below for more
          details.
  
          Parameters
          ----------
          image : 2D `~numpy.ndarray`
              The image array.  Masked arrays are not recognized here. This
              assumes that centering should always be done on valid pixels.
          threshold : float, optional
              The centerer threshold.  To turn off the centerer, set this
              to a large value (i.e. >> 1).  The default is 0.1.
          verbose : bool, optional
              Whether to print object centering information.  The default is
              `True`.
  
          Notes
          -----
          The centerer function scans a 10x10 window centered on the (x,
          y) coordinates in the `~photutils.isophote.EllipseGeometry`
          instance passed to the constructor of the
          `~photutils.isophote.Ellipse` class.  If any of the
          `~photutils.isophote.EllipseGeometry` (x, y) coordinates are
          `None`, the center of the input image frame is used.  If the
          center acquisition is successful, the
          `~photutils.isophote.EllipseGeometry` instance is modified in
          place to reflect the solution of the object centerer algorithm.
  
          In some cases the object centerer algorithm may fail even though
          there is enough signal-to-noise to start a fit (e.g. objects
          with very high ellipticity).  In those cases the sensitivity of
          the algorithm can be decreased by decreasing the value of the
          object centerer threshold parameter.  The centerer works by
          looking where a quantity akin to a signal-to-noise ratio is
          maximized within the 10x10 window.  The centerer can thus be
          shut off entirely by setting the threshold to a large value
          (i.e. >> 1; meaning no location inside the search window will
          achieve that signal-to-noise ratio).
          """
  
          self._centerer_mask_half_size = len(IN_MASK) / 2
          self.centerer_threshold = threshold
  
          # number of pixels in each mask
          sz = len(IN_MASK)
          self._centerer_ones_in = np.ma.masked_array(np.ones(shape=(sz, sz)),
                                                      mask=IN_MASK)
          self._centerer_ones_out = np.ma.masked_array(np.ones(shape=(sz, sz)),
                                                       mask=OUT_MASK)
          self._centerer_in_mask_npix = np.sum(self._centerer_ones_in)
          self._centerer_out_mask_npix = np.sum(self._centerer_ones_out)
  
          # Check if center coordinates point to somewhere inside the frame.
          # If not, set then to frame center.
          shape = image.shape
          _x0 = self.x0
          _y0 = self.y0
          if (_x0 is None or _x0 < 0 or _x0 >= shape[1] or _y0 is None or
                  _y0 < 0 or _y0 >= shape[0]):
              _x0 = shape[1] / 2
              _y0 = shape[0] / 2
  
          max_fom = 0.
          max_i = 0
          max_j = 0
  
          # scan all positions inside window
          window_half_size = 5
          for i in range(int(_x0 - window_half_size),
                         int(_x0 + window_half_size) + 1):
              for j in range(int(_y0 - window_half_size),
                             int(_y0 + window_half_size) + 1):
  
                  # ensure that it stays inside image frame
                  i1 = int(max(0, i - self._centerer_mask_half_size))
                  j1 = int(max(0, j - self._centerer_mask_half_size))
                  i2 = int(min(shape[1] - 1, i + self._centerer_mask_half_size))
                  j2 = int(min(shape[0] - 1, j + self._centerer_mask_half_size))
  
                  window = image[j1:j2, i1:i2]
  
                  # averages in inner and outer regions.
                  inner = np.ma.masked_array(window, mask=IN_MASK)
                  outer = np.ma.masked_array(window, mask=OUT_MASK)
                  inner_avg = np.sum(inner) / self._centerer_in_mask_npix
                  outer_avg = np.sum(outer) / self._centerer_out_mask_npix
  
                  # standard deviation and figure of merit
                  inner_std = np.std(inner)
                  outer_std = np.std(outer)
                  stddev = np.sqrt(inner_std**2 + outer_std**2)
  
                  fom = (inner_avg - outer_avg) / stddev
  
                  if fom > max_fom:
                      max_fom = fom
                      max_i = i
                      max_j = j
  
          # figure of merit > threshold: update geometry with new coordinates.
          if max_fom > threshold:
              self.x0 = float(max_i)
              self.y0 = float(max_j)
  
              if verbose:
                  log.info("Found center at x0 = {0:5.1f}, y0 = {1:5.1f}"
                           .format(self.x0, self.y0))
          else:
              if verbose:
                  log.info('Result is below the threshold -- keeping the '
                           'original coordinates.')