Last modified: 22 December 2024

How do I create an XSPEC table model?


[NOTE]
Note

CIAO 4.16 has added experimental support for creating XSPEC table model files, and the CXC welcomes feedback on the interface and its capabilities using the Sherpa GitHub Issues page.

The structure of a XSPEC table model is described at the "The File Format for XSPEC Table Models" page. As this is an experimental interface the logic is not provided as part of the sherpa.astro.ui module - which is automatically loaded when the sherpa application is started - but must be loaded explicitly from the sherpa.astro.io.xstable module.

The following example creates an additive table model that represents a gaussian model where the only parameters are the line position and the normalization.

>>> import numpy as np
>>> from sherpa.astro.io import xstable
>>> from sherpa.astro.xspec import XSgaussian

We shall use the XSPEC gaussian model sherpa.astro.xspec.XSgaussian to create the template models.

>>> mdl = XSgaussian()
>>> print(mdl)
gaussian
   Param        Type          Value          Min          Max      Units
   -----        ----          -----          ---          ---      -----
   gaussian.LineE thawed          6.5            0        1e+06        keV
   gaussian.Sigma thawed          0.1            0           20        keV
   gaussian.norm thawed            1            0        1e+24

The models will be evaluated over the 0.1 to 2 keV range, with a bin spacing of 0.01 keV (note that the last bin ends at 1.99 and not 2.0 keV thanks to the behavior of numpy.arange).

>>> egrid = np.arange(0.1, 2, 0.01)
>>> elo = egrid[:-1]
>>> ehi = egrid[1:]
>>> emid = (elo + ehi) / 2

The table model will interpolate over the line position over the range of 0 to 2.4 inclusive, with a spacing of 0.1 keV:

>>> linepos = np.arange(0, 2.5, 0.1)
>>> minval = linepos[0]
>>> maxval = linepos[-1]

The model is evaluated over the grid defined by elo and ehi for each element of linepos, which is used to set the sherpa.astro.xspec.XSgaussian.LineE parameter:

>>> models = []
>>> for lp in linepos:
...     mdl.linee = lp
...     ymodel = mdl(elo, ehi)
...     models.append(ymodel)
...

This model has a single interpolated parameter which we call "pos". Note that the delta parameter - here set to 0.01 - is only used by Sherpa to decide if the parameter is frozen (value is negative) or not, but is used by the optimiser in XSPEC. The values field is set to those used to generate the spectral models.

>>> param = xstable.Param("pos", 1, 0.01, minval, maxval,
...                       values=linepos)

With this we can create the necessary information to create the table model (make_xstable_model) and then write it out as a FITS file (write_xstable_model):

>>> hdus = xstable.make_xstable_model("gaussy", elo, ehi, params=[param],
...                                   spectra=models)
>>> xstable.write_xstable_model("example.mod", hdus, clobber=True)