docs: def wave_range(bins, cenwave, npix, round='round'):
      """Get the wavelength range covered by the given number of pixels
      centered on the given wavelength.
  
      Parameters
      ----------
      bins : ndarray
          Wavelengths of pixel centers. Must be in the same units as
          ``cenwave``.
  
      cenwave : float
          Central wavelength of range. Must be in the same units as ``bins``.
  
      npix : int
          Number of pixels in range, centered on ``cenwave``.
  
      round : {'round', 'min', 'max', `None`}, optional
          How to deal with pixels at the edges of the wavelength range. All
          of the options, except `None`, will return wavelength ends that
          correpsonds to pixel edges. Defaults to ``'round'``.
  
              * ``'round'`` - A wavelength range is returned such that the
                ends are pixel edges and the range spans exactly ``npix`` pixels.
                Ends that fall in the center of bins are rounded up to the nearest
                pixel edge.
              * ``'min'`` - The returned wavelength range is shrunk so that
                it includes an integer number of pixels and the ends fall on pixel
                edges. May not span exactly ``npix`` pixels.
              * ``'max'`` - The returned wavelength range is expanded so that
                it includes an integer number of pixels and the ends fall on pixel
                edges. May not span exactly ``npix`` pixels.
              * `None` - An exact wavelength range is returned.
                The wavelength ends returned may not correspond to pixel edges,
                but will cover exactly ``npix`` pixels.
  
      Returns
      -------
      waverange : tuple of floats
          The range of wavelengths spanned by ``npix`` centered on ``cenwave``.
  
      Raises
      ------
      ValueError
          If ``round`` is not an allowed value.
  
      pysynphot.exceptions.OverlapError
          If ``cenwave`` is not within ``bins``, or the returned ``waverange``
          would exceed the limits of ``bins``.
  
      """
      # make sure that the round keyword is valid
      if round not in (None,'round','min','max'):
          raise ValueError("round keyword must be one of (None,'round','min','max')")
  
      # make sure cenwave is within binset
      if cenwave < bins[0]:
          raise exceptions.OverlapError("cenwave is not within binset. Min = %f" % bins[0])
      elif cenwave > bins[-1]:
          raise exceptions.OverlapError("cenwave is not within binset. Max = %f" % bins[-1])
  
      # first figure out what index the central wavelength falls at
      diff = cenwave - bins
      ind = np.where(np.abs(diff) == np.abs(diff).min())[0][0]
  
      # now figure out the fractional index
      if diff[ind] < 0:
          frac_ind = float(ind) + diff[ind] / (bins[ind] - bins[ind-1])
      elif diff[ind] > 0:
          frac_ind = float(ind) + diff[ind] / (bins[ind+1] - bins[ind])
      else:
          frac_ind = float(ind)
  
      # then figure out the fractional indices of the ends
      frac_ind1 = frac_ind - npix/2.
      frac_ind2 = frac_ind + npix/2.
  
      # check ends
      if frac_ind1 < -0.5:
          raise exceptions.OverlapError("Lower wavelength range is below allowed binset.")
  
      if frac_ind2 > bins.shape[0] - 0.5:
          raise exceptions.OverlapError("Upper wavelength range is above allowed binset.")
  
      frac1, int1 = np.modf(frac_ind1)
      frac2, int2 = np.modf(frac_ind2)
  
      # translate ends to wavelength
      if round is None:
          # translate ends directly to wavelength without regard to bin edges
          f, i = frac1, int(int1)
  
          wave1 = bins[i] + frac1 * (bins[i+1] - bins[i])
  
          f, i = frac2, int(int2)
  
          wave2 = bins[i] + frac2 * (bins[i+1] - bins[i])
  
      elif round == 'round':
          # calculate lower end of wavelength range
          f, i = frac1, int(int1)
  
          if f >= 0:
              # end is somewhere greater than binset[0] so we can just
              # interpolate between two neighboring values going with upper edge
              wave1 = bins[i:i+2].mean()
          else:
              # end is below the lowest binset value, but not by enough to
              # trigger an exception
              wave1 = bins[0] - (bins[0:2].mean() - bins[0])
  
          # calculate upper end of wavelength range
          f, i = frac2, int(int2)
  
          if i < bins.shape[0] - 1:
              # end is somewhere below binset[-1] so we can just interpolate
              # between two neighboring values, going with the upper edge.
              wave2 = bins[i:i+2].mean()
          else:
              # end is above highest binset value but not by enough to
              # trigger an exception
              wave2 = bins[-1] + (bins[-1] - bins[-2:].mean())
  
      elif round == 'min':
          # calculate lower end of wavelength range
          f, i = frac1, int(int1)
  
          if f <= 0.5 and i < bins.shape[0] - 1:
              # not at the lowest possible edge and pixel i included
              wave1 = bins[i:i+2].mean()
          elif f > 0.5 and i < bins.shape[0] - 2:
              # not at the lowest possible edge and pixel i not included
              wave1 = bins[i+1:i+3].mean()
          elif f == -0.5:
              # at the lowest possible edge
              wave1 = bins[0] - (bins[0:2].mean() - bins[0])
  
          # calculate upper end of wavelength range
          f, i = frac2, int(int2)
  
          if f >= 0.5 and i < bins.shape[0] - 1:
              # not out at the end and pixel i included
              wave2 = bins[i:i+2].mean()
          elif f < 0.5 and i < bins.shape[0]:
              # not out at end and pixel i not included
              wave2 = bins[i-1:i+1].mean()
          elif f == 0.5 and i == bins.shape[0] - 1:
              # at the very end
              wave2 = bins[-1] + (bins[-1] - bins[-2:].mean())
  
      elif round == 'max':
          # calculate lower end of wavelength range
          f, i = frac1, int(int1)
  
          if f < 0.5 and i < bins.shape[0]:
              # not at the lowest possible edge and pixel i included
              wave1 = bins[i-1:i+1].mean()
          elif f >= 0.5 and i < bins.shape[0] - 1:
              # not at the lowest possible edge and pixel i not included
              wave1 = bins[i:i+2].mean()
          elif f == -0.5:
              # at the lowest possible edge
              wave1 = bins[0] - (bins[0:2].mean() - bins[0])
  
          # calculate upper end of wavelength range
          f, i = frac2, int(int2)
  
          if f > 0.5 and i < bins.shape[0] - 2:
              # not out at the end and pixel i included
              wave2 = bins[i+1:i+3].mean()
          elif f <= 0.5 and i < bins.shape[0] - 1:
              # not out at end and pixel i not included
              wave2 = bins[i:i+2].mean()
          elif f == 0.5 and i == bins.shape[0] - 1:
              # at the very end
              wave2 = bins[-1] + (bins[-1] - bins[-2:].mean())
  
      return wave1, wave2