docs: def writefits(self, filename, clobber=True, trimzero=True,
                    binned=False, precision=None, hkeys=None):
          """Write the spectrum to a FITS table.
  
          Primary header in EXT 0. ``FILENAME``,  ``ORIGIN``, and any
          extra keyword(s) from ``hkeys`` will also be added.
  
          Table header and data are in EXT 1. The table has 2 columns,
          i.e., ``WAVELENGTH`` and ``FLUX``. Data are stored in user units.
          Its header also will have these additional keywords:
  
          * ``EXPR`` - Description of the spectrum.
          * ``TDISP1`` and ``TDISP2`` - Columns display format,
            always "G15.7".
          * ``GRFTABLE`` and ``CMPTABLE`` - Graph and component
            table names to use with associated observation mode.
            These are only added if applicable.
  
          If data is already double-precision but user explicitly
          set output precision to single, ``pysynphot.spectrum.syn_epsilon``
          defines the allowed minimum wavelength separation.
          This limit (:math:`3.2 \\times 10^{-4}`) was taken from
          IRAF STSDAS SYNPHOT FAQ.
          Values equal or smaller than this limit are considered as the
          same, and duplicates are ignored, resulting in data loss.
          In the way that this comparison is coded, when such precision clash
          happens, even when no duplicates are detected, the last row is
          always omitted (also data loss). Therefore, it is *not* recommended
          for user to force single-precision when the data is in
          double-precision.
  
          Parameters
          ----------
          filename : str
              Output filename.
  
          clobber : bool
              Overwrite existing file. Default is `True`.
  
          trimzero : bool
              Trim off duplicate rows with flux values of zero from both ends
              of the spectrum. This keeps one row of zero-flux at each end,
              if it exists; However, it does not add a zero-flux row if it
              does not. Default is `True`.
  
          binned : bool
              Write ``self.binwave`` and ``self.binflux`` (binned) dataset,
              instead of ``self.wave`` and ``self.flux`` (native). Using
              this option when object does not have binned data will cause
              an exception to be raised. Default is `False`.
  
          precision : {'s', 'd', `None`}
              Write data out in single (``'s'``) or double (``'d'``)
              precision. Default is `None`, which will enforce native
              precision from ``self.flux``.
  
          hkeys : dict
              Additional keyword(s) to be added to primary FITS header,
              in the format of ``{keyword:(value,comment)}``.
  
          """
          pcodes={'d':'D', 's':'E'}
          if precision is None:
              precision = self.flux.dtype.char
          _precision = precision.lower()[0]
          pcodes = {'d':'D','s':'E','f':'E'}
  
          if clobber:
              try:
                  os.remove(filename)
              except OSError:
                  pass
  
          if binned:
              wave = self.binwave
              flux = self.binflux
          else:
              wave = self.wave
              flux = self.flux
  
          # Add a check for single/double precision clash, so
          # that if written out in single precision, the wavelength table
          # will still be sorted with no duplicates
          # The value of epsilon is taken from the Synphot FAQ.
  
          if wave.dtype == N.float64 and _precision == 's':
              idx = N.where(abs(wave[1:]-wave[:-1]) > syn_epsilon)
          else:
              idx = N.where(wave) #=> idx=[:]
  
          wave = wave[idx]
          flux = flux[idx]
  
          first, last = 0, len(flux)
  
          if trimzero:
              # Keep one zero at each end
              nz = flux.nonzero()[0]
              try:
                  first = max(nz[0] - 1, first)
                  last = min(nz[-1] + 2, last)
              except IndexError:
                  pass
  
          # Construct the columns and HDUlist
          cw = pyfits.Column(name='WAVELENGTH',
                             array=wave[first:last],
                             unit=self.waveunits.name,
                             format=pcodes[_precision])
          cf = pyfits.Column(name='FLUX',
                             array=flux[first:last],
                             unit=self.fluxunits.name,
                             format=pcodes[_precision])
  
          # Make the primary header
          hdu = pyfits.PrimaryHDU()
          hdulist = pyfits.HDUList([hdu])
  
          # User-provided keys are written to the primary header
          # so are filename and origin
          bkeys = dict(filename=(os.path.basename(filename), 'name of file'),
                       origin=('pysynphot', 'Version (%s, %s)' %
                               (__version__, __svn_revision__)))
          # User-values if present may override default values
          if hkeys is not None:
              bkeys.update(hkeys)
  
          # Now update the primary header
          for key, val in bkeys.items():
              hdu.header[key] = val
  
          # Make the extension HDU
          cols = pyfits.ColDefs([cw, cf])
          hdu = pyfits.BinTableHDU.from_columns(cols)
  
          # There are some standard keywords that should be added
          # to the extension header.
          bkeys = dict(expr=(str(self), 'pysyn expression'),
                       tdisp1=('G15.7',),
                       tdisp2=('G15.7',))
  
          try:
              bkeys['grftable'] = (self.bandpass.obsmode.gtname,)
              bkeys['cmptable'] = (self.bandpass.obsmode.ctname,)
          except AttributeError:
              pass  # Not all spectra have these
  
          for key, val in bkeys.items():
              hdu.header[key] = val
  
          # Add the header to the list, and write the file
          hdulist.append(hdu)
          hdulist.writeto(filename)