docs: def cutout(self, data, fill_value=0., copy=False):
          """
          Create a cutout from the input data over the mask bounding box,
          taking any edge effects into account.
  
          Parameters
          ----------
          data : array_like
              A 2D array on which to apply the aperture mask.
  
          fill_value : float, optional
              The value is used to fill pixels where the aperture mask
              does not overlap with the input ``data``.  The default is 0.
  
          copy : bool, optional
              If `True` then the returned cutout array will always be hold
              a copy of the input ``data``.  If `False` and the mask is
              fully within the input ``data``, then the returned cutout
              array will be a view into the input ``data``.  In cases
              where the mask partially overlaps or has no overlap with the
              input ``data``, the returned cutout array will always hold a
              copy of the input ``data`` (i.e. this keyword has no
              effect).
  
          Returns
          -------
          result : `~numpy.ndarray`
              A 2D array cut out from the input ``data`` representing the
              same cutout region as the aperture mask.  If there is a
              partial overlap of the aperture mask with the input data,
              pixels outside of the data will be assigned to
              ``fill_value``.  `None` is returned if there is no overlap
              of the aperture with the input ``data``.
          """
  
          data = np.asanyarray(data)
          if data.ndim != 2:
              raise ValueError('data must be a 2D array.')
  
          partial_overlap = False
          if self.bbox.ixmin < 0 or self.bbox.iymin < 0:
              partial_overlap = True
  
          if not partial_overlap:
              # try this for speed -- the result may still be a partial
              # overlap, in which case the next block will be triggered
              if copy:
                  cutout = np.copy(data[self.bbox.slices])
              else:
                  cutout = data[self.bbox.slices]
  
          if partial_overlap or (cutout.shape != self.shape):
              slices_large, slices_small = self._overlap_slices(data.shape)
  
              if slices_small is None:
                  return None    # no overlap
  
              # cutout is a copy
              cutout = np.zeros(self.shape, dtype=data.dtype)
              cutout[:] = fill_value
              cutout[slices_small] = data[slices_large]
  
              if isinstance(data, u.Quantity):
                  cutout = u.Quantity(cutout, unit=data.unit)
  
          return cutout