PyXspec basics – fitting models to data#

Learning Goals#

By the end of this tutorial, you will be able to:

  • Load X-ray a spectrum and response into PyXspec.

  • Define and fit models to X-ray spectra and evaluate their quality.

  • Calculate parameter errors and confidence contours.

  • Use PyXspec and matplotlib to visualize spectra and model fits.

Introduction#

This example uses some very old spectral data. It’s much simpler than more modern observations and so can be used to better illustrate the basics of XSPEC analysis.

The data in question is a 20 ks EXOSAT ‘Medium-Energy’ (ME) observation of the 6-second period X-ray pulsar 1E1048.1-5937 by EXOSAT, taken in June 1985.

In this example, we’ll conduct a general investigation of the spectrum from the Medium Energy instrument, i.e. follow the same sort of steps as the original investigators (Seward F. D., Charles P. A., Smale A. P. 1986).

The ME spectrum and corresponding response matrix were obtained from the HEASARC and are available either as part of a large collection of example data or directly from the URLs defined in the Global Setup: Constants section.

Inputs#

  • EXOSAT-ME spectrum file for 1E1048.1-5937 - s54405.pha

  • Corresponding EXOSAT-ME response file - s54405.rsp

Outputs#

  • Various diagnostic plots showing data, models, and residuals

  • Best-fit model parameters with uncertainties

  • Flux measurements and confidence ranges

  • Upper limit on iron emission line equivalent width

Runtime#

As of 28th May 2026, this notebook takes ~1-minute to run to completion on Fornax using the ‘small’ server with 8GB RAM/2 cores.

Imports#

import contextlib
import os
from time import sleep
from typing import Optional, Tuple
from urllib.request import urlretrieve

import numpy as np
import xspec as xs
from astropy.units import Quantity
from matplotlib import pyplot as plt
from matplotlib.ticker import FuncFormatter
from scipy.stats import chi2

Global Setup#

Functions#

Hide code cell source

def plot_fit_residual_spec(
    plot_data: dict,
    sp_color: str = "navy",
    mod_color: str = "firebrick",
    res_color: str = "navy",
    x_lims: Optional[Tuple[float, float]] = None,
    y_lims: Optional[Tuple[float, float]] = None,
    inst_name: Optional[str] = None,
    stepped_model: bool = True,
    mod_expr: Optional[str] = None,
):
    """
    A convenience function used to plot the spectrum, fitted model, and residuals, at
    various points in this demonstration. The required input is a dictionary of
    the style constructed in various subsections of the 'alternative spectral models'
    section.

    Limited customization of the output figure is offered, but this is not intended
    as a truly general-purpose plotting function, more as a possible inspiration
    for your own versions.

    :param dict plot_data: Dictionary containing all information necessary to produce
        the fitted spectrum and residual visualization.
    :param str sp_color: Matplotlib color to use for the spectral data points.
    :param str mod_color: Matplotlib color to use for the fitted model staircase line.
    :param str res_color: Matplotlib color to use for the residual data points.
    :param Optional[Tuple[float, float]] x_lims: Optional limits on which parts
        of the x-axis to plot. Must be a two-element tuple containing the lower and
        then the upper limit.
    :param Optional[Tuple[float, float]] y_lims: Optional limits on which parts
        of the y-axis to plot. Must be a two-element tuple containing the lower and
        then the upper limit.
    :param str inst_name: Optionally, a mission/instrument name to add to the
        legend label given to the spectral data points.
    :param bool stepped_model: Controls whether the fitted model is plotted as a
        staircase (to match XSPEC's plotting style) or as a smooth line. Default is
        True, resulting in a staircase.
    :param str mod_expr: Optionally, the 'expression' of the fitted model - to be
        added to its legend label.
    """

    # Some basic checks to make sure the plot data is in the right format
    # These are what we need
    req_ents = [
        "energy",
        "energy_delta",
        "rate",
        "rate_err",
        "model",
        "residual",
        "residual_err",
        "energy_step",
    ]
    # Raise an error before we get started plotting if any entries are missing
    if any([en not in plot_data for en in req_ents]):
        raise KeyError(
            f"Plot data must contain the following keys: f{', '.join(req_ents)}"
        )

    # Basic validity check on any axis limits
    if x_lims is not None and (len(x_lims) != 2 or np.diff(x_lims) < 0):
        raise ValueError(
            "Passed x-axis limits must be a two-element tuple, with the first "
            "entry less than the second."
        )
    if y_lims is not None and (len(y_lims) != 2 or np.diff(y_lims) < 0):
        raise ValueError(
            "Passed y-axis limits must be a two-element tuple, with the first "
            "entry less than the second."
        )

    # Determine what the label for spectrum data points should be based on input
    #  instrument name
    sp_label = "Spectral data" if inst_name is None else f"{inst_name} data"

    # Same as above, but for the model label
    mod_label = "Fitted model" if mod_expr is None else f"Fitted model ({mod_expr})"

    fig, ax_arr = plt.subplots(
        nrows=2, figsize=(7, 6), height_ratios=(3, 1.5), sharex=True
    )
    # Shrink the vertical gap between the panels to zero
    fig.subplots_adjust(hspace=0)

    # First axis (the large, top-most one) is where we will plot the spectrum
    #  data points, and fitted model lines.
    spec_ax = ax_arr[0]
    # Turn minor axis ticks on, and configure the direction they point, and that
    #  they also appear on the top and right sides of the plot.
    spec_ax.minorticks_on()
    spec_ax.tick_params(which="both", direction="in", top=True, right=True)

    # First we plot the spectrum data points, including the count rate uncertainty,
    #  and the size of each energy bin as error bars.
    spec_ax.errorbar(
        plot_data["energy"],
        plot_data["rate"],
        xerr=plot_data["energy_delta"],
        yerr=plot_data["rate_err"],
        fmt="+",
        capsize=1.5,
        label=sp_label,
        color=sp_color,
    )

    # If the user has requested that the model fit be shown as a 'stepped' line (i.e.
    #  what the standard XSPEC plots look like), we have to use the 'stairs' method
    #  rather than the standard 'plot' method.
    if stepped_model:
        spec_ax.stairs(
            plot_data["model"],
            plot_data["energy_step"],
            baseline=None,
            fill=False,
            color=mod_color,
            alpha=0.8,
            label=mod_label,
            linewidth=1.4,
            zorder=3,
        )
    # Otherwise, the model will be plotted as a smooth line.
    else:
        spec_ax.plot(
            plot_data["energy"],
            plot_data["model"],
            color=mod_color,
            label=mod_label,
            alpha=0.8,
            linewidth=1.4,
            zorder=3,
        )

    # We allow the user to set specific x and y axis limits when they call this
    #  function - if they have passed limits, we enforce them here (the residual
    #  axis will inherit the limits as well, because we set sharex=True when
    #  we defined the figure.
    if x_lims is not None:
        spec_ax.set_xlim(x_lims)
    if y_lims is not None:
        spec_ax.set_ylim(y_lims)

    # We just assume the user wants a logged y-scale, which I don't think is too
    #  restrictive.
    spec_ax.set_yscale("log")
    # Alter the formatting of the labels so that they are 0.1, 0.01, 0.001 etc.
    spec_ax.yaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))
    # And make sure to set the y-axis label
    spec_ax.set_ylabel(
        r"Spectrum [$\frac{\rm{ct}}{\rm{s} \: \rm{cm}^{2} \: \rm{keV}}$]", fontsize=15
    )

    spec_ax.legend(fontsize=14)

    res_ax = ax_arr[1]
    res_ax.minorticks_on()
    res_ax.tick_params(which="both", direction="in", top=True, right=True)

    res_ax.errorbar(
        plot_data["energy"],
        plot_data["residual"],
        xerr=plot_data["energy_delta"],
        yerr=plot_data["residual_err"],
        fmt="+",
        capsize=1.5,
        color=res_color,
    )
    res_ax.axhline(0, color="goldenrod", linestyle="dashed")

    res_ax.set_xlabel("Energy [keV]", fontsize=15)
    res_ax.set_ylabel(
        r"Residuals [$\frac{\rm{ct}}{\rm{s} \: \rm{cm}^{2} \: \rm{keV}}$]", fontsize=15
    )

    res_ax.set_xscale("log")
    res_ax.xaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))
    res_ax.xaxis.set_minor_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))

    plt.show()

Constants#

Hide code cell source

SRC_NAME = "1E1048.1-5937"

EXOSAT_ME_SP_BASE_URL = "https://nasa-heasarc.s3.amazonaws.com/exosat/data/me/spectra"
DEMO_SPEC_URL = os.path.join(EXOSAT_ME_SP_BASE_URL, "s54405.pha.Z")
DEMO_RESP_URL = os.path.join(EXOSAT_ME_SP_BASE_URL, "s54405.rsp.Z")

Configuration#

Hide code cell source

# ------------- Setting how many cores we can use --------------
# We use a service called CircleCI to execute, test, and validate these notebooks
#  as we're writing and maintaining them. Unfortunately we have to treat the
#  determination of the number of cores we can use differently, as the
#  'os.cpu_count()' call will return the number of cores of the host machine, rather
#  than the number that have actually been allocated to us.
if "CIRCLECI" in os.environ and bool(os.environ["CIRCLECI"]):
    # Here we read the CPU quota (total CPU time allowed) and the CPU period (how
    #  long the scheduling window is) from a cgroup (a linux kernel feature) file.
    # Dividing one by t'other provides the number of cores we've been allocated.
    with open("/sys/fs/cgroup/cpu.max", "r") as cpu_maxo:
        quota, period = cpu_maxo.read().strip().split()
        NUM_CORES = int(quota) // int(period)

# If you, the reader, are running this notebook yourself, this is the
#  part that is relevant to you - you can override the default number of cores
#  used by setting this variable to an integer value.
else:
    NUM_CORES = None

# Determines the number of CPU cores available
total_cores = os.cpu_count()

# If NUM_CORES is None, then we use the number of cores returned by 'os.cpu_count()'
if NUM_CORES is None:
    NUM_CORES = total_cores
# Otherwise, NUM_CORES has been overridden (either by the user, or because we're
#  running on CircleCI, and we do a validity check.
elif not isinstance(NUM_CORES, int):
    raise TypeError(
        "If manually overriding 'NUM_CORES', you must set it to an integer value."
    )
elif isinstance(NUM_CORES, int) and NUM_CORES > total_cores:
    raise ValueError(
        f"If manually overriding 'NUM_CORES', the value must be less than or "
        f"equal to the total available cores ({total_cores})."
    )
# --------------------------------------------------------------

# -------------- Set paths and create directories --------------
if os.path.exists("../../../_data"):
    ROOT_DATA_DIR = "../../../_data/PyXSPEC/EXOSAT"
else:
    ROOT_DATA_DIR = "PyXSPEC/EXOSAT"

# Ensure that the specified directory exists
ROOT_DATA_DIR = os.path.abspath(ROOT_DATA_DIR)

# Make sure the download directory exists.
os.makedirs(ROOT_DATA_DIR, exist_ok=True)
# --------------------------------------------------------------

# ------------- Download demonstration data files --------------
# Download the spectrum and response required for this demonstration.
#  The return value is unimportant, and we only capture it in a variable to
#  avoid Jupyter notebooks from printing it, as these are the last lines of the cell.
# The EXOSAT-ME spectrum
ret = urlretrieve(
    DEMO_SPEC_URL, os.path.join(ROOT_DATA_DIR, os.path.basename(DEMO_SPEC_URL))
)
# The accompanying EXOSAT-ME response
ret = urlretrieve(
    DEMO_RESP_URL, os.path.join(ROOT_DATA_DIR, os.path.basename(DEMO_RESP_URL))
)
# --------------------------------------------------------------

1. Loading a spectrum into PyXspec#

The spectral files we need for this demonstration were downloaded in the Global Setup: Configuration section.

We can read our spectrum file into a PyXspec Spectrum object, assigning it to the exo_me_specvariable. Most PyXspec operations don’t involve direct interaction with individual spectrum objects, but we will use it to ignore some channels later in this tutorial.

The spectrum file we are using for this demonstration has not been downloaded to the same directory as the notebook, so we will briefly change our working directory as we load it.

Of course, we could pass the full spectrum path rather than changing directories, but the ‘RESPFILE’ entry in the spectrum’s header is a path relative to the location of the spectrum file.

As such, if we didn’t change directories, PyXspec would have been unable to find and automatically load the response file (though we could instead pass a response file path to the optional respfile argument of the Spectrum constructor).

with contextlib.chdir(ROOT_DATA_DIR):
    exo_me_spec = xs.Spectrum("s54405.pha")
Creating a $HOME/.xspec directory for you
***Warning: Unrecognized grouping for channel(s). It/they will be reset to 1.
  HOWEVER NOTE: Resets only occurred for channels of bad quality
Warning: RMF CHANTYPE keyword (UNKNOWN) is not consistent with that in spectrum (PHA)

1 spectrum  in use
 
Spectral Data File: s54405.pha  Spectrum 1
Net count rate (cts/s) for Spectrum:1  3.783e+00 +/- 1.367e-01
 Assigned to Data Group 1 and Plot Group 1
  Noticed Channels:  1-125
  Telescope: EXOSAT Instrument: ME  Channel Type: PHA
  Exposure Time: 2.358e+04 sec
 Using fit statistic: chi
 Using Response (RMF) File            s54405.rsp for Source 1
***Warning: POISSERR keyword is missing or of wrong format, assuming FALSE.

2. Visualizing the data#

One of the first things most users will want to do at this stage - even before fitting a model - is to look at their data (something we strongly encourage as a first step of any analysis).

XSPEC can plot a wide variety of different information, all related in some way to the underlying spectral data, fitted model(s), fit statistics, and the instrument used to collect the data.

Even though we’re using the Python interface to XSPEC and will be creating visualizations using Matplotlib, we can still take advantage of XSPEC’s backend plotting functionality by retrieving the data necessary to create a particular figure from PyXspec.

The exact visualization information that can be retrieved from PyXspec will depend on what you’re plotting, but here follow some examples of what can be fetched:

  • X and Y data points.

  • X and Y uncertainties.

  • Axis labels.

  • Plot title.

What plots can XSPEC generate?#

To list the types of plots that PyXspec can generate, we can run:

xs.Plot("?")
plot data/models/fits etc
    Syntax: plot commands:
	background     chain          chisq          contour        counts         
	data           delchi         dem            edata          eedata         
	eemodel        eeufspec       efficiency     emodel         eqw            
	eufspec        fitstat        foldmodel      goodness       icounts        
	insensitivity  integprob      lcounts        ldata          ledata         
	leedata        margin         model          polangle       polfrac        
	ratio          residuals      sensitivity    sum            ufspec         
	
    Multi-panel plots are created by entering multiple options e.g. data fitstat

Setting XSPEC’s plot device#

Before we actually plot something, we need to set the ‘plot device’ that XSPEC’s graphic library outputs to. When running XSPEC ‘traditionally’ (i.e. through the command line), then your choice of plot device will control whether a figure is written to a file or displayed in a window (and what technology/file format is utilized).

In this demonstration we don’t really want either of those things to happen, as we’re going to use the Python module matplotlib to do our own plotting. As such, we set the plot device to “/null”, which means that XSPEC won’t output figures at all:

xs.Plot.device = "/null"

Danger

Skipping this step could result in many files being written to your current directory, or the wholesale failure of all plotting in your notebook.

Plotting a spectrum#

The data plot option produces the most important of all XSPEC visualizations – a spectrum!

By default, spectra will be plotted as a function of instrument channel, which is the most fundamental indication of an X-ray event’s energy (said event hopefully corresponding to a photon, as opposed to a particle, hitting the detector).

On the other hand, if an instrument response has been loaded along with the spectral data (we made sure of that Section 1), then we can plot the spectrum as a function of energy (considerably more useful).

Note, however, that this won’t happen automatically just because a response is available; we have to specify the units of the energy axis explicitly:

xs.Plot.xAxis = "keV"

As we’ve already mentioned, we’re going to use the Python module matplotlib to construct our figures and visualizations. Compared to using XSPEC’s intrinsic plotting functionality, this will give us a great deal of flexibility and much finer control over the final figure.

Our first task is to use PyXspec to produce the rate, energy, and uncertainty information that make up a spectrum visualization, then to retrieve the data to pass to matplotlib.

Here we call the Plot method, passing “data” to specify which type of plot XSPEC should produce (in this case a spectrum). Note that preparing and retrieving the data necessary to visualize a PyXspec plot with Matplotlib are two distinct steps:

  1. Running Plot("data") will recalcuate plot quantities based on the current data, noticed channels, model fit (if any), etc.

  2. Calling Plot.x() or Plot.y() will fetch the most current calculated quantities.

You will also notice that PyXspec very handily provides the axis labels and title that it would use if it were making the plot itself, we store those too:

xs.Plot("data")

spec_plot_data = {
    "energy": np.array(xs.Plot.x()),
    "energy_delta": np.array(xs.Plot.xErr()),
    "rate": np.array(xs.Plot.y()),
    "rate_err": np.array(xs.Plot.yErr()),
    "x_label": xs.Plot.labels()[0],
    "y_label": xs.Plot.labels()[1],
    "title": xs.Plot.labels()[2],
}

Tip

If you’re working in a Jupyter notebook, and are likely to be making multiple versions of XSPEC plots, we recommend storing plot data in a dictionary, as we have demonstrated above.

This helps reduce the risk of accidentally re-using variable names and overwriting their existing values, or using plot data from a previous figure. As Jupyter notebooks can be run out of order, or have cells re-executed, this is an important consideration.

All that information can now be used to construct a figure showing the spectrum, prior to any fitting or energy limits, whilst making some small customizations to improve the appearance and clarity of the plot.

In this particular case, this includes:

  • Logging the energy axis; plt.xscale("log")

  • Configuring axis ticks to point inwards and be present on the top and right of the figure; plt.tick_params(which="both", direction="in", top=True, right=True)

  • Removing labels from minor ticks on the energy axis if the values are below 1 keV, to avoid colliding labels; ax.xaxis.set_minor_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp) if inp >= 1 else ""))

Hide code cell source

plt.figure(figsize=(7, 4.5))
plt.minorticks_on()
plt.tick_params(which="both", direction="in", top=True, right=True)

plt.errorbar(
    spec_plot_data["energy"],
    spec_plot_data["rate"],
    xerr=spec_plot_data["energy_delta"],
    yerr=spec_plot_data["rate_err"],
    fmt="+",
    label="EXOSAT-ME data",
    color="navy",
)

plt.xscale("log")

ax = plt.gca()
ax.xaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))
ax.xaxis.set_minor_formatter(
    FuncFormatter(lambda inp, _: "{:g}".format(inp) if inp >= 1 else "")
)

plt.xlabel(spec_plot_data["x_label"], fontsize=15)
plt.ylabel(spec_plot_data["y_label"], fontsize=15)

plt.title(spec_plot_data["title"], fontsize=16)

plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
../../../_images/340da92a990e8441721aa422e368baecd3c82c88089d48dd20189682f43ae76a.png

3. Defining and fitting models#

We are now ready to fit the data with a model.

Models in XSPEC are specified using the model command, followed by an algebraic expression of a combination of component models.

There are two basic kinds of model components – additive and multiplicative:

  • Additive components – Represent X-Ray sources of different kinds (e.g., a bremsstrahlung continuum) and, after being convolved with the instrument response, prescribe the number of counts per energy bin.

  • Multiplicative components – Represent phenomena that modify the observed X-Radiation (e.g. reddening or an absorption edge). They apply an energy-dependent multiplicative factor to the source radiation before the result is convolved with the instrumental response.

More generally, XSPEC allows three types of modifying components:

  • The multiplicative type mentioned above.

  • Convolutions, which apply a convolution operator to an input model calculated from another model (e.g. cgflux, which we use in Section 5).

  • Mixing models, which perform transformations on the available spectra (e.g. modeling cross-talk between spatial regions of a detector/source).

Since there must be a source, there must be at least one additive component model, but there is no restriction on the number of modifying components.

Setting up a model object#

Given the fairly low quality of our data, as shown by the plot above, we’ll choose an absorbed power law. To set it up, we define an instance of the PyXspec Model class and assign it to a variable - abs_pl_mod:

abs_pl_mod = xs.Model("tbabs(powerlaw)")
========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    1.00000      +/-  0.0          
   2    2   powerlaw   PhoIndex            1.00000      +/-  0.0          
   3    2   powerlaw   norm                1.00000      +/-  0.0          
________________________________________________________________________

tbvabs Version 2.3
Cosmic absorption with grains and H2, modified from
Wilms, Allen, & McCray, 2000, ApJ 542, 914-924
Questions: Joern Wilms
joern.wilms@sternwarte.uni-erlangen.de
joern.wilms@fau.de

http://pulsar.sternwarte.uni-erlangen.de/wilms/research/tbabs/

PLEASE NOTICE:
To get the model described by the above paper
you will also have to set the abundances:
   abund wilm

Note that this routine ignores the current cross section setting
as it always HAS to use the Verner cross sections as a baseline.

Fit statistic  : Chi-Squared              4.867896e+08     using 125 bins.

Test statistic : Chi-Squared              4.867896e+08     using 125 bins.
 Null hypothesis probability of 0.000000e+00 with 122 degrees of freedom
 Current data and model not fit yet.

Ignoring bad channels#

We are not quite ready to fit the data (and obtain a better \(\chi^2\)), because some of the 125 PHA bins should not be included in the fitting:

  • Some are below the lower discriminator of the instrument and therefore do not contain valid data.

  • Some have imperfect background subtraction at the margins of the pass band.

  • Some may not contain enough counts for \(\chi^2\) to be strictly meaningful.

To find out which channels to discard (ignore in XSPEC terminology), consult mission-specific documentation that will include information about discriminator settings, background subtraction problems, and other issues.

For the mature missions in the HEASARC archives, this information may have already been encoded in the headers of the spectral files as a list of bad channels. To remove the bad channels from the spectrum that we previously read into exo_me_spec, we can use:

xs.AllData.ignore("bad")
ignore:    40 channels ignored from  source number 1
Fit statistic  : Chi-Squared              4.867277e+08     using 85 bins.

Test statistic : Chi-Squared              4.867277e+08     using 85 bins.
 Null hypothesis probability of 0.000000e+00 with 82 degrees of freedom
 Current data and model not fit yet.

Note

PyXspec doesn’t allow us to ignore “bad” channels for individual spectra, only for all loaded spectra. AllData is a special data manager object which allows us to perform operations on all current spectra.

Renormalizing the model to our data#

The current statistic is \(\chi^2\), and is huge for the initial, default, model parameter values – mostly because the power law normalization is two orders of magnitude too large. This particular problem is easily fixed using the renorm method:

xs.Fit.renorm()
Fit statistic  : Chi-Squared                  796.59     using 85 bins.

Test statistic : Chi-Squared                  796.59     using 85 bins.
 Null hypothesis probability of 1.46e-117 with 82 degrees of freedom
 Current data and model not fit yet.

Visualizing the spectrum and renormalized model#

To show off our renormalized, but not yet fit, model, we’ll use PyXspec and matplotlib together to produce a two-panel figure. The top panel will show the spectral data and the current state of the model, and the bottom panel will show \(\Delta\chi^2\) values given the sign of the corresponding residual value.

Just like in Section 2, we can use the PyXspec Plot manager object to calculate the information necessary to plot our spectrum, model, and signed \(\Delta\chi^2\).

Passing two choices to the Plot object generates a plot with vertically stacked ‘plot windows’ (up to a maximum of six panels). The plot data calculated for each plot option can be accessed by passing an index to the plotWindow=... argument of Plot’s various methods.

Tip

Remember that XSPEC (and thus PyXspec) uses ‘one-based indexing’ (as opposed to Python’s zero-based indexing), so to retrieve the data relevant to the bottom panel, we need to pass plotWindow=2, and plotWindow=1 for the top panel.

We read out the spectral rates and errors, energy bin centers and half-widths, the current rates of the model at each energy bin center, and the signed \(\Delta\chi^2\) values calculated for the bottom panel – storing them in a dictionary. Additionally, the axis labels that XSPEC would have used are stored in the same dictionary.

In this instance we’re going to imitate the appearance of an XSPEC fitted spectrum plot, so rather than plotting the model as a smooth line, we’ll display it as a staircase. This being a visual reminder that the model is only evaluated at the centers of the energy bins.

To support the staircased model line, we calculate the upper and lower edges of each energy bin by subtracting the energy bin half-widths from the energy bin centers and appending a final bin edge representing the last energy bin center plus its half-width:

xs.Plot("data chi")

rn_mod_plot_data = {
    "energy": np.array(xs.Plot.x(plotWindow=1)),
    "energy_delta": np.array(xs.Plot.xErr(plotWindow=1)),
    "rate": np.array(xs.Plot.y(plotWindow=1)),
    "rate_err": np.array(xs.Plot.yErr(plotWindow=1)),
    "model": np.array(xs.Plot.model(plotWindow=1)),
    "signed_chisq": np.array(xs.Plot.y(plotWindow=2)),
    "x_label": xs.Plot.labels(plotWindow=1)[0],
    "y_label": xs.Plot.labels(plotWindow=1)[1],
    "chisq_label": xs.Plot.labels(plotWindow=2)[1],
}

rn_mod_plot_data["energy_step"] = np.append(
    rn_mod_plot_data["energy"] - rn_mod_plot_data["energy_delta"],
    rn_mod_plot_data["energy"][-1] + rn_mod_plot_data["energy_delta"][-1],
)
***Warning: Fit is not current.

Attention

We get a warning that the fit is not current because no fit has been performed yet (renormalizing doesn’t count, the reason for which will become obvious when you see the figure).

As a brief aside, we can examine the XSPEC-generated label for the y-axis of the upcoming figure’s lower panel, as we won’t actually be using it in our visualization.

We’re discarding the default label for practical purposes, as it is too long for the small amount of space we give to the lower panel.

However, as you can see, the meanings of the original and our replacement are equivalent. You will also notice that XSPEC produces LaTeX-formatted labels suitable for use with matplotlib:

rn_mod_plot_data["chisq_label"]
'sign(data-model) $\\times$ $\\Delta$ $\\chi$$^{2}$'

Finally, we can make our visualization:

Hide code cell source

fig, ax_arr = plt.subplots(nrows=2, figsize=(7, 6), height_ratios=(3, 1.5), sharex=True)
# Shrink the vertical gap between the panels to zero
fig.subplots_adjust(hspace=0)

spec_ax = ax_arr[0]
spec_ax.minorticks_on()
spec_ax.tick_params(which="both", direction="in", top=True, right=True)

spec_ax.errorbar(
    rn_mod_plot_data["energy"],
    rn_mod_plot_data["rate"],
    xerr=rn_mod_plot_data["energy_delta"],
    yerr=rn_mod_plot_data["rate_err"],
    fmt="+",
    capsize=1.5,
    label="EXOSAT-ME data",
    color="navy",
)

spec_ax.stairs(
    rn_mod_plot_data["model"],
    rn_mod_plot_data["energy_step"],
    baseline=None,
    fill=False,
    color="firebrick",
    alpha=0.8,
    label="Renormalized model",
    linewidth=1.4,
)

spec_ax.set_xscale("log")
spec_ax.xaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))
spec_ax.xaxis.set_minor_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))

spec_ax.set_yscale("log")
spec_ax.yaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))

spec_ax.set_ylabel(rn_mod_plot_data["y_label"], fontsize=15)

spec_ax.legend(fontsize=14)

chi_ax = ax_arr[1]
chi_ax.minorticks_on()
chi_ax.tick_params(which="both", direction="in", top=True, right=True)

chi_ax.stairs(
    rn_mod_plot_data["signed_chisq"],
    rn_mod_plot_data["energy_step"],
    baseline=None,
    fill=False,
    color="navy",
    linewidth=1.4,
)

chi_ax.axhline(0, color="goldenrod", linestyle="dashed")

chi_ax.set_xlabel(rn_mod_plot_data["x_label"], fontsize=15)
chi_ax.set_ylabel(
    r"$\frac{\rm{Residual}}{|\rm{Residual}|} \: \times \: \Delta\chi^2$", fontsize=15
)

plt.show()
../../../_images/a81f9ac98ebfb551060ffd0356949d6cd00ff58b82c6ead3c7a02acb61db71c2.png

Ignoring channels based on energy#

Forty channels were rejected in a previous section because they were flagged as bad – but do we need to ignore any more?

The renormalized model figure shows the result of plotting the data and the model (in the upper window) and the contributions to \(\chi^2\) (in the lower window).

We see that above about 15 keV the signal-to-noise becomes small. We also see, when comparing with our initial spectrum figure, which bad channels were ignored.

Although visual inspection is not the most rigorous method for deciding which channels to ignore, it’s good enough for now and will at least prevent us from getting grossly misleading fit results. To ignore energies above 15 keV:

exo_me_spec.ignore("15.0-**")
    78 channels (48-125) ignored in spectrum #     1

Fit statistic  : Chi-Squared                  718.42     using 45 bins.

Test statistic : Chi-Squared                  718.42     using 45 bins.
 Null hypothesis probability of 5.53e-124 with 42 degrees of freedom
 Current data and model not fit yet.

Caution

Note that ignore (and notice) interpret integers as channel numbers and real numbers as energies - it can be confusing when you think you’ve ignored everything above 8 keV but instead find you only have 8 channels.

Also, the double star (**) is a special indicator which just means the extreme value in the spectrum - in this case the upper extreme, but if we instead ran ignore("**-15.0") we’d ignore everything up to 15 keV.

Preparing to fit the model#

We are now ready to fit the data. Fitting is initiated by the command xs.Fit.perform().

As the fit proceeds, the screen displays the status of the fit for each iteration until either the fit converges to the minimum \(\chi^2\), or the maximum number of iterations is exceeded.

The current maximum number of iterations can be found like this:

print(xs.Fit.nIterations)
10

We can also set a new maximum number of iterations using the same Fit attribute:

xs.Fit.nIterations = 50

Performing the model fit#

xs.Fit.perform()
                                   Parameters
Chi-Squared  |beta|/N    Lvl          1:nH    2:PhoIndex        3:norm
451.747      150.716      -3     0.0934254       1.60966    0.00387228
413.31       63193.6      -3      0.272618       2.30612    0.00909560
54.0828      28059.8      -4      0.521485       2.14066     0.0121325
43.8345      4672.39      -5      0.556743       2.23842     0.0130769
43.8215      131.89       -6      0.543800       2.23583     0.0130241
43.8214      0.582959     -7      0.542814       2.23549     0.0130166
========================================
 Variances and Principal Axes
                 1        2        3  
 4.7777E-08| -0.0025  -0.0151   0.9999  
 2.3010E-03|  0.3979  -0.9173  -0.0128  
 8.8416E-02|  0.9174   0.3978   0.0083  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   7.478e-02   3.143e-02   6.623e-04
   3.143e-02   1.593e-02   3.194e-04
   6.623e-04   3.194e-04   6.532e-06
------------------------------------

========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    0.542814     +/-  0.273463     
   2    2   powerlaw   PhoIndex            2.23549      +/-  0.126210     
   3    2   powerlaw   norm                1.30166E-02  +/-  2.55587E-03  
________________________________________________________________________


Fit statistic  : Chi-Squared                   43.82     using 45 bins.

Test statistic : Chi-Squared                   43.82     using 45 bins.
 Null hypothesis probability of 3.94e-01 with 42 degrees of freedom
451.747      150.716      -3     0.0934254       1.60966    0.00387228
413.31       63193.6      -3      0.272618       2.30612    0.00909560
54.0828      28059.8      -4      0.521485       2.14066     0.0121325
43.8345      4672.39      -5      0.556743       2.23842     0.0130769
43.8215      131.89       -6      0.543800       2.23583     0.0130241
43.8214      0.582959     -7      0.542814       2.23549     0.0130166
========================================
 Variances and Principal Axes
                 1        2        3  
 4.7777E-08| -0.0025  -0.0151   0.9999  
 2.3010E-03|  0.3979  -0.9173  -0.0128  
 8.8416E-02|  0.9174   0.3978   0.0083  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   7.478e-02   3.143e-02   6.623e-04
   3.143e-02   1.593e-02   3.194e-04
   6.623e-04   3.194e-04   6.532e-06
------------------------------------

========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    0.542814     +/-  0.273463     
   2    2   powerlaw   PhoIndex            2.23549      +/-  0.126210     
   3    2   powerlaw   norm                1.30166E-02  +/-  2.55587E-03  
________________________________________________________________________


Fit statistic  : Chi-Squared                   43.82     using 45 bins.

Test statistic : Chi-Squared                   43.82     using 45 bins.
 Null hypothesis probability of 3.94e-01 with 42 degrees of freedom

Interpreting the output of an XSPEC fit#

There is a fair amount of information here, so we will unpack it a bit at a time.

State of the fit at each iteration [first section]#

XSPEC writes out one line after each fit iteration, containing the following:

  • Two obvious columns:

    • Chi-Squared

    • Parameters

  • As well as two less obvious columns related to fit convergence:

    • |beta|/N – At each step in the fit a numerical derivative of the statistic with respect to the parameters is calculated. We call the vector of these derivatives ‘beta’.

    • Lvl – A measure of the Levenberg–Marquardt algorithm’s (the default XSPEC fitting method) ‘damping parameter’ indicating how the fit is converging (it should generally decrease).

At the best-fit the normalization of beta should be zero, so XSPEC displays |beta| divided by the number of parameters (N) as a check of that.

The actual default convergence criterion is when the fit statistic does not change significantly between iterations, so bear in mind that it is possible for the fit to end while |beta| is still significantly different from zero.

Note

For the first iteration only the powerlaw normalization is varied.

While not strictly necessary this simple model, for more complicated models only varying the norms on the first iteration helps the fit proper get started in a reasonable region of parameter space.

Fitting statistics [second section]#

Once the fit has finished its iterations, PyXspec writes out the “Variances and Principal Axes” and “Covariance Matrix” tables. These are both based on the second derivatives of the fit statistic with respect to the parameters. Generally, the larger these second derivatives, the better determined the parameter (think of the case of a parabola in 1-D).

The “Covariance Matrix” table is the inverse of the matrix of second derivatives.

The “Variances and Principal Axes” section is based on an eigenvector decomposition of the second derivative matrix and indicates which parameters are correlated. We can see that in this case that the first eigenvector depends almost entirely on the powerlaw normalization, while the other two are combinations of the nH and powerlaw PhoIndex. This tells us that the normalization is independent, but that the other two parameters are correlated.

Best-fit model parameters and error estimates [third section]#

After the “Covariance Matrix” section, the next table shows the best-fit model parameters and their error estimates. The latter are just the square roots of the covariance matrix’s diagonal elements (i.e. the variance elements) – as such they implicitly assume that the parameter space is multidimensional Gaussian with all parameters independent.

We already know that in this case the parameters are not independent, so these error estimates should only be considered guidelines to help us determine the true errors later.

Final statistic values [fourth section]#

The fourth and final section displays the statistic values at the end of the fit.

PyXspec defines a fit statistic, used to determine the best-fit parameters and errors, and test statistic, used to decide whether this model and parameters provide a good fit to the data.

By default, both statistics are \(\chi^2\) – when the test statistic is \(\chi^2\), we can also calculate the null hypothesis probability (as you can see in the fit output).

The null hypothesis probability is the likelihood of getting a value of \(\chi^2\) as large or larger than observed if the model is correct, and if this probability is small, then the model is not a good fit.

Examining goodness of fit without a null hypothesis probability#

The null hypothesis probability can be calculated analytically for the \(\chi^2\) statistic and, if you haven’t selected a different test statistic, XSPEC will do so during model fits, as we saw in the last section.

Unfortunately, there is no way to analytically calculate the null hypothesis probability for some of the other test statistics that XSPEC offers, so we need another way to determine the meaning of the statistic value.

PyXspec has a built-in function that will perform simulations of the data based on the current model and parameters, then compare the statistic values of the simulation to that calculated for the real data. If the observed statistic is larger than the values calculated for the simulated data, then the implication is that the real data do not come from the current model.

Before we run the Fit.goodness(...) function, we will make our first use of XSPEC’s parallelization capabilities, intended to improve the performance of certain tasks by utilizing multiple cores (many-core CPUs are now almost ubiquitous). This demonstration notebook determined the number of cores available in the Global Setup: Configuration section, and stored the number in the NUM_CORES constant.

Here we specifically set the goodness function to use all available cores:

xs.Xset.parallel.goodness = NUM_CORES

Now we can run the command, which will display a one-line message passing judgement on the current model’s goodness (or lack thereof); it also returns the percentage of simulations that had a smaller test statistic than the observed data. While we’re at it, we retrieve the distribution of simulation test statistics for later use:

cur_lt_stat_perc = xs.Fit.goodness(1000)
# This just splits off the XSPEC output from the other output we show below
print("--------------------------------------------------------------------", "\n")
cur_test_stat = xs.Fit.testStatistic

# The 'previousGoodnessSims' attribute returns a list of strings - they
#  must be converted to floats before we make a histogram.
goodness_dist = np.array(xs.Fit.previousGoodnessSims).astype(float)
goodness_dist[:20]
58.80% of realizations are < best test statistic 43.82  (nosim)  (fit)
--------------------------------------------------------------------
--------------------------------------------------------------------
array([17.8307483 , 19.62602409, 20.76426273, 21.30913168, 21.83650857,
       22.01511059, 22.18381599, 23.12378947, 23.28502316, 23.48332704,
       23.58972276, 23.59922549, 23.77314561, 24.32848021, 24.38381696,
       24.69270837, 24.69909351, 24.79786295, 25.23509332, 25.45735167])

Warning

We retrieve the goodness-of-fit distribution in the same cell as the call to the goodness() method to ensure that no other fit or goodness calculation has been run in between this goodness call and the retrieval.

This might happen if, for instance, you are running the notebook out of order - as the goodness-of-fit distribution is stored in the global fit manager, rather than a unique model object, it could be overridden.

Approximately 60% of the simulations give a statistic value less than that observed, consistent with this being a good fit. We might now want to plot a histogram of the \(\chi^2\) values from the simulations, with the observed statistic value shown as a vertical line, for context.

It is entirely possible to retrieve the bin centers and probability density values from PyXspec and use them with matplotlib to reconstruct the histogram that XSPEC would make – just as we’ve been doing for other visualizations.

Taking that route for a histogram is a little awkward, however, so why don’t we instead directly use the goodness-of-fit value distribution to construct and plot a histogram.

We actually already retrieved the goodness-of-fit distribution, in the same cell we ran the goodness() method, so creating a histogram is straightforward:

Hide code cell source

plt.figure(figsize=(6, 5.5))
plt.minorticks_on()
plt.tick_params(which="both", direction="in", top=True, right=True)

plt.hist(
    goodness_dist,
    bins=20,
    density=True,
    ec="teal",
    histtype="step",
    hatch="/",
    linewidth=3,
    label=r"Simulation $\chi^{2}$",
)

plt.axvline(
    cur_test_stat,
    linestyle="dashed",
    color="goldenrod",
    linewidth=2,
    label=r"Data $\chi^{2}$",
)

plt.xlabel(r"$\chi^2$", fontsize=15)
plt.ylabel("Probability Density", fontsize=15)

plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
../../../_images/218b29cb5f7ff36510096fa12059d06656e45a50b7b78a8feb2c64d167938eac.png

Examining fit residuals#

So the statistic implies the fit is good, but it is still always a good idea to look at the data and residuals to check for any systematic differences that may not be caught by the test.

We pull the relevant information out of PyXspec in a similar manner to our earlier plot of the renormalized, unfit, model earlier, though here we pass “data resid” rather than “data chi”:

xs.Plot("data resid")

fit_pl_plot_data = {
    "energy": np.array(xs.Plot.x(plotWindow=1)),
    "energy_delta": np.array(xs.Plot.xErr(plotWindow=1)),
    "rate": np.array(xs.Plot.y(plotWindow=1)),
    "rate_err": np.array(xs.Plot.yErr(plotWindow=1)),
    "model": np.array(xs.Plot.model(plotWindow=1)),
    "residual": np.array(xs.Plot.y(plotWindow=2)),
    "residual_err": np.array(xs.Plot.yErr(plotWindow=2)),
}

fit_pl_plot_data["energy_step"] = np.append(
    fit_pl_plot_data["energy"] - fit_pl_plot_data["energy_delta"],
    fit_pl_plot_data["energy"][-1] + fit_pl_plot_data["energy_delta"][-1],
)

We can now visualize our data, fitted model, and residuals by calling a convenience function that was defined in the Global Setup: Functions section. Said function contains plotting code that is quite similar to what we wrote for the last spectrum figure, but seeing as we’ll be wanting to make a few of these plots, it is neater to put into a function:

plot_fit_residual_spec(
    fit_pl_plot_data, inst_name="EXOSAT-ME", mod_expr=abs_pl_mod.expression
)
../../../_images/9b14bffe91e37a4ac3d88db7fbe28b359900342cfcbbc011fbd4b448c51fd8a9.png

4. Error analysis#

Now that we think we have an acceptable model, we need to determine how well the parameters are constrained.

You may recall that the output at the end of XSPEC’s fitting process (see this summary of its contents) shows the best-fitting parameter values, and approximations to their errors. Those errors should be regarded only as indications of the parameter uncertainties and should absolutely not be quoted in publications.

XSPEC’s error() method#

The true errors, i.e. the confidence ranges, are obtained using the Fit.error() method.

We want to run error() on all three parameters of our model, which is an intrinsically parallel operation, so we can once again use PyXspec’s support for multiple cores and run the error estimations in parallel.

The numbers 1, 2, 3 refer to the IDs assigned to each parameter by XSPEC. You can check which ID goes with which parameter by passing the IDs to our model object:

print(abs_pl_mod(1).name, abs_pl_mod(2).name, abs_pl_mod(3).name)
nH PhoIndex norm

Now we run the error calculation:

xs.Xset.parallel.error = NUM_CORES
xs.Fit.error("1-3")
 Parameter   Confidence Range (2.706)
     1     0.107662      1.01753    (-0.43511,0.474755)
     2      2.03713      2.44776    (-0.198347,0.212282)
     3   0.00953337    0.0181336    (-0.00348297,0.0051173)

Examining the output of the error() method we see that for the first parameter, the column density of absorbing hydrogen atoms, the 90% confidence range is 0.110–1.018.

More usefully, we can dynamically retrieve error values calculated for specific parameters from the XSPEC model object:

# Can access the nH parameter instance by passing its ID to the model
print(abs_pl_mod(1).error, "\n")

# Or by accessing the nH attribute of the model's TBabs attribute
print(abs_pl_mod.TBabs.nH.error)
(0.10766234087236387, 1.017527160754112, 'FFFFFFFFF') 

(0.10766234087236387, 1.017527160754112, 'FFFFFFFFF')

The first entry in the returned tuple is the lower confidence limit, the second is the upper confidence limit, and the third is the nine-letter error string that indicates whether the error calculation was successful (FFFFFFFFF means that we’re all good; see the ‘error’ entry in the XSPEC tclout API reference for full information).

Tip

When you pass only a set of parameters to error(), and no other arguments, you are determining the 90% confidence interval - a \(\Delta\chi^{2}\) of 2.706.

It is of course possible to tell XSPEC to calculate a different confidence level. You can pass a delta fit statistic calculated from a one degree of freedom \(\chi^2\) distribution (see the next section for an easy way to do this in Python) to the error() method. For the 68.3% (\(1\sigma\)) confidence levels of all three parameters we would use error("1.0 1-3"), for 95.5% (\(2\sigma\)) - error("4.034 1-3"), and for 99.7% (\(3\sigma\)) - error("9.0 1-3")

You might ask why these better error calculations are not performed automatically, as part of the standard fitting process – the answer to that question is that they entail further fitting. When the model is simple (as in our example), this requires little CPU time, but for complicated models the extra time can be quite considerable.

The error for each parameter is determined by allowing all other, unfrozen, model parameters to vary freely, and if model parameters are uncorrelated then this error is all we need to know.

Remember, though, that we have an indication from the fit process’s output covariance matrix that the hydrogen column density and photon index parameters are correlated!

Running steppar to explore parameter correlations#

To further investigate the possible correlation between hydrogen column density and power law photon index, we can use the PyXspec Fit manager object’s steppar(...) method to run a grid over these two parameters, calculating a joint confidence region.

When we call steppar, we’re going to make it construct a two-dimensional parameter grid for nH and PhoIndex:

  • The nH dimension will consist of 25 evenly spaced points between 0.0 and 1.5.

  • The PhoIndex dimension will consist of 25 evenly spaced points between 1.5 and 3.0.

This is another operation that can benefit greatly from parallelization, so we make sure to configure PyXspec to use all available cores:

xs.Xset.parallel.steppar = NUM_CORES
xs.Fit.steppar("1 0.0 1.5 25 2 1.5 3.0 25")

# See the warning below
sleep(5)

Hide code cell output

     Chi-Squared    Delta               nH      PhoIndex
                 Chi-Squared             1             2

          162.65      118.83    0           0    0         1.5
          171.47      127.65    1        0.06    0         1.5
          180.61      136.79    2        0.12    0         1.5
          190.05      146.22    3        0.18    0         1.5
          199.75      155.93    4        0.24    0         1.5
          209.71      165.89    5         0.3    0         1.5
           219.9      176.08    6        0.36    0         1.5
           230.3      186.48    7        0.42    0         1.5
           240.9      197.08    8        0.48    0         1.5
          251.68      207.86    9        0.54    0         1.5
          262.62       218.8   10         0.6    0         1.5
          273.72       229.9   11        0.66    0         1.5
          284.95      241.13   12        0.72    0         1.5
          296.31      252.49   13        0.78    0         1.5
          307.77      263.95   14        0.84    0         1.5
          319.34      275.52   15         0.9    0
    1.5
             331      287.18   16        0.96    0         1.5
          342.73      298.91   17        1.02    0         1.5
          354.53      310.71   18        1.08    0         1.5
           366.4      322.58   19        1.14    0         1.5
          378.31      334.49   20         1.2    0         1.5
          390.27      346.45   21        1.26    0         1.5
          402.26      358.44   22        1.32    0         1.5
          414.28      370.46   23        1.38    0         1.5
          426.32       382.5   24        1.44    0         1.5
          438.38      394.56   25         1.5    0         1.5
          399.23      355.41   25         1.5    1        1.56
          387.44      343.62   24        1.44    1        1.56
          375.68      331.86   23        1.38    1        1.56
          363.96      320.14   22        1.32    1        1.56
          352.28      308.46   21        1.26    1        1.56
          340.66      296.84   20         1.2    1        1.56
          329.11      285.29   19        1.14    1        1.56
          317.62       273.8   18        1.08    1        1.56
          306.22       262.4   17        1.02    1        1.56
          294.91      251.08   16        0.96    1        1.56
           283.7      239.87   15         0.9    1        1.56
           272.6      228.78   14        0.84    1        1.56
          261.63       217.8   13        0.78    1        1.56
          250.79      206.97   12        0.72    1        1.56
          240.11      196.29   11        0.66    1        1.56
          229.59      185.77   10         0.6    1        1.56
          219.25      175.43    9        0.54    1        1.56
          209.11      165.29    8        0.48    1        1.56
          199.18      155.35    7        0.42    1        1.56
          189.47      145.65    6        0.36    1        1.56
          180.02       136.2    5         0.3    1        1.56
          170.83      127.01    4        0.24    1        1.56
          161.93      118.11    3        0.18    1        1.56
          153.34      109.52    2        0.12    1        1.56
          145.09      101.26    1        0.06    1        1.56
          137.19      93.364    0           0    1        1.56
          114.89      71.069    0           0    2        1.62
          121.81      77.985    1        0.06    2        1.62
          129.12      85.298    2        0.12    2        1.62
           136.8      92.983    3        0.18    2        1.62
          144.84      101.02    4        0.24    2        1.62
           153.2      109.37    5         0.3    2        1.62
          161.86      118.04    6        0.36    2        1.62
           170.8      126.98    7        0.42    2        1.62
          180.01      136.19    8        0.48    2        1.62
          189.46      145.64    9        0.54    2        1.62
          199.14      155.31   10         0.6    2        1.62
          209.02       165.2   11        0.66    2        1.62
           219.1      175.28   12        0.72    2        1.62
          229.37      185.54   13        0.78    2        1.62
          239.79      195.97   14        0.84    2        1.62
          250.37      206.55   15         0.9    2        1.62
          261.08      217.26   16        0.96    2        1.62
          271.92       228.1   17        1.02    2        1.62
          282.88      239.06   18        1.08    2        1.62
          293.94      250.12   19        1.14    2        1.62
           305.1      261.28   20         1.2    2        1.62
          316.34      272.51   21        1.26    2        1.62
          327.65      283.83   22        1.32    2        1.62
          339.03      295.21   23        1.38    2        1.62
          350.46      306.64   24        1.44    2        1.62
          361.95      318.13   25         1.5    2        1.62
           326.6      282.78   25         1.5    3        1.68
          315.46      271.64   24        1.44    3        1.68
          304.39      260.57   23        1.38    3        1.68
          293.39      249.57   22        1.32    3        1.68
          282.48      238.66   21        1.26    3        1.68
          271.67      227.85   20         1.2    3        1.68
          260.97      217.15   19        1.14    3        1.68
          250.38      206.56   18        1.08    3        1.68
          239.91      196.09   17        1.02    3        1.68
          229.59      185.77   16        0.96    3        1.68
          219.42       175.6   15         0.9    3        1.68
          209.41      165.59   14        0.84    3        1.68
          199.59      155.76   13        0.78    3        1.68
          189.95      146.13   12        0.72    3        1.68
          180.52       136.7   11        0.66    3        1.68
          171.32       127.5   10         0.6    3        1.68
          162.36      118.54    9        0.54    3        1.68
          153.65      109.83    8        0.48    3        1.68
          145.23      101.41    7        0.42    3        1.68
           137.1      93.276    6        0.36    3        1.68
          129.29      85.464    5         0.3    3        1.68
          121.81      77.992    4        0.24    3        1.68
           114.7      70.882    3        0.18    3        1.68
          107.98      64.158    2        0.12    3        1.68
          101.67      57.845    1        0.06    3        1.68
          95.793      51.971    0           0    3        1.68
          79.913      36.092    0           0    4        1.74
          84.692      40.871    1        0.06    4        1.74
           89.95      46.128    2        0.12    4        1.74
          95.658      51.837    3        0.18    4        1.74
          101.79       57.97    4        0.24    4        1.74
          108.33      64.504    5         0.3    4        1.74
          115.23      71.413    6        0.36    4        1.74
           122.5      78.675    7        0.42    4        1.74
          130.09      86.268    8        0.48    4        1.74
          137.99      94.173    9        0.54    4        1.74
          146.19      102.37   10         0.6    4        1.74
          154.66      110.84   11        0.66    4        1.74
          163.38      119.56   12        0.72    4        1.74
          172.34      128.52   13        0.78    4        1.74
          181.52       137.7   14        0.84    4        1.74
          190.91      147.09   15         0.9    4        1.74
          200.49      156.67   16        0.96    4        1.74
          210.24      166.42   17        1.02    4        1.74
          220.16      176.34   18        1.08    4        1.74
          230.24      186.42   19        1.14    4        1.74
          240.45      196.63   20         1.2    4        1.74
          250.79      206.97   21        1.26    4        1.74
          261.25      217.43   22        1.32    4        1.74
          271.82      227.99   23        1.38    4        1.74
          282.48      238.66   24        1.44    4        1.74
          293.23      249.41   25         1.5    4        1.74
          261.91      218.09   25         1.5    5         1.8
          251.58      207.76   24        1.44    5         1.8
          241.37      197.55   23        1.38    5         1.8
          231.27      187.45   22        1.32    5         1.8
           221.3      177.48   21        1.26    5         1.8
          211.48      167.66   20         1.2    5         1.8
           201.8      157.98   19        1.14    5         1.8
          192.29      148.47   18        1.08    5         1.8
          182.96      139.14   17        1.02    5         1.8
          173.82      129.99   16        0.96    5         1.8
          164.88      121.06   15         0.9    5         1.8
          156.16      112.33   14        0.84    5         1.8
          147.67      103.85   13        0.78    5         1.8
          139.43      95.613   12        0.72    5         1.8
          131.47      87.645   11        0.66    5         1.8
          123.78      79.963   10         0.6    5         1.8
          116.41      72.584    9        0.54    5         1.8
          109.35      65.529    8        0.48    5         1.8
          102.64      58.819    7        0.42    5         1.8
          96.296      52.475    6        0.36    5         1.8
           90.34      46.519    5         0.3    5         1.8
          84.796      40.975    4        0.24    5         1.8
           79.69      35.868    3        0.18    5         1.8
          75.046      31.224    2        0.12    5         1.8
          70.892      27.071    1        0.06    5         1.8
          67.257      23.436    0           0    5         1.8
          57.817      13.996    0           0    6        1.86
          60.264      16.443    1        0.06    6        1.86
          63.269      19.448    2        0.12    6        1.86
          66.802      22.981    3        0.18    6        1.86
          70.836      27.015    4        0.24    6        1.86
          75.344      31.523    5         0.3    6        1.86
            80.3      36.479    6        0.36    6        1.86
           85.68      41.859    7        0.42    6        1.86
           91.46      47.639    8        0.48    6        1.86
          97.618      53.797    9        0.54    6        1.86
          104.13      60.311   10         0.6    6        1.86
          110.98      67.161   11        0.66    6        1.86
          118.15      74.328   12        0.72    6        1.86
          125.61      81.793   13        0.78    6        1.86
          133.36      89.538   14        0.84    6        1.86
          141.37      97.545   15         0.9    6        1.86
          149.62       105.8   16        0.96    6        1.86
          158.11      114.29   17        1.02    6        1.86
          166.81      122.99   18        1.08    6        1.86
          175.71      131.89   19        1.14    6        1.86
          184.81      140.98   20         1.2    6        1.86
          194.07      150.25   21        1.26    6        1.86
          203.51      159.68   22        1.32    6        1.86
          213.09      169.27   23        1.38    6        1.86
          222.81      178.99   24        1.44    6        1.86
          232.67      188.85   25         1.5    6        1.86
          205.56      161.74   25         1.5    7        1.92
          196.22       152.4   24        1.44    7        1.92
          187.02       143.2   23        1.38    7        1.92
          177.99      134.17   22        1.32    7        1.92
          169.14      125.32   21        1.26    7        1.92
          160.47      116.65   20         1.2    7        1.92
             152      108.18   19        1.14    7        1.92
          143.74      99.923   18        1.08    7        1.92
          135.72      91.896   17        1.02    7        1.92
          127.93      84.112   16        0.96    7        1.92
          120.41      76.587   15         0.9    7        1.92
          113.16      69.336   14        0.84    7        1.92
           106.2      62.377   13        0.78    7        1.92
          99.549      55.727   12        0.72    7        1.92
          93.228      49.406   11        0.66    7        1.92
          87.254      43.432   10         0.6    7        1.92
          81.648      37.826    9        0.54    7        1.92
          76.431      32.609    8        0.48    7        1.92
          71.625      27.803    7        0.42    7        1.92
          67.253      23.432    6        0.36    7        1.92
           63.34      19.518    5         0.3    7        1.92
           59.91      16.089    4        0.24    7        1.92
          56.991      13.169    3        0.18    7        1.92
          54.609      10.787    2        0.12    7        1.92
          52.792      8.9709    1        0.06    7        1.92
          51.572      7.7507    0           0    7        1.92
          48.487      4.6652    0           0    8        1.98
          48.447      4.6257    1        0.06    8        1.98
           49.04      5.2188    2        0.12    8        1.98
          50.235       6.414    3        0.18    8        1.98
          52.004      8.1823    4        0.24    8        1.98
          54.317      10.496    5         0.3    8        1.98
          57.149      13.327    6        0.36    8        1.98
          60.473      16.651    7        0.42    8        1.98
          64.265      20.443    8        0.48    8        1.98
            68.5      24.679    9        0.54    8        1.98
          73.157      29.336   10         0.6    8        1.98
          78.213      34.392   11        0.66    8        1.98
          83.648      39.826   12        0.72    8        1.98
           89.44      45.619   13        0.78    8        1.98
          95.572      51.751   14        0.84    8        1.98
          102.02      58.203   15         0.9    8        1.98
          108.78      64.958   16        0.96    8        1.98
          115.82      71.999   17        1.02    8        1.98
          123.13      79.309   18        1.08    8        1.98
           130.7      86.874   19        1.14    8        1.98
           138.5      94.678   20         1.2    8        1.98
          146.53      102.71   21        1.26    8        1.98
          154.77      110.95   22        1.32    8        1.98
          163.21      119.38   23        1.38    8        1.98
          171.83      128.01   24        1.44    8        1.98
          180.63      136.81   25         1.5    8        1.98
          157.89      114.07   25         1.5    9        2.04
          149.68      105.86   24        1.44    9        2.04
          141.66      97.843   23        1.38    9        2.04
          133.86      90.036   22        1.32    9        2.04
          126.27      82.451   21        1.26    9        2.04
          118.92      75.101   20         1.2    9        2.04
          111.82      68.001   19        1.14    9        2.04
          104.99      61.166   18        1.08    9        2.04
          98.432      54.611   17        1.02    9        2.04
          92.174      48.352   16        0.96    9        2.04
          86.228      42.407   15         0.9    9        2.04
          80.614      36.792   14        0.84    9        2.04
          75.348      31.527   13        0.78    9        2.04
          70.451       26.63   12        0.72    9        2.04
          65.942      22.121   11        0.66    9        2.04
          61.842       18.02   10         0.6    9        2.04
          58.171       14.35    9        0.54    9        2.04
          54.954      11.132    8        0.48    9        2.04
          52.212      8.3909    7        0.42    9        2.04
          49.971      6.1496    6        0.36    9        2.04
          48.255      4.4337    5         0.3    9        2.04
          47.091      3.2696    4        0.24    9        2.04
          46.506      2.6845    3        0.18    9        2.04
          46.528      2.7067    2        0.12    9        2.04
          47.187      3.3658    1        0.06    9        2.04
          48.514      4.6923    0           0    9        2.04
          51.594      7.7723    0           0   10         2.1
          48.959      5.1373    1        0.06   10         2.1
          47.024      3.2029    2        0.12   10         2.1
           45.76      1.9381    3        0.18   10         2.1
          45.135      1.3133    4        0.24   10         2.1
          45.122      1.3001    5         0.3   10         2.1
          45.692      1.8707    6        0.36   10         2.1
           46.82      2.9986    7        0.42   10         2.1
           48.48      4.6582    8        0.48   10         2.1
          50.646      6.8249    9        0.54   10         2.1
          53.296       9.475   10         0.6   10         2.1
          56.407      12.586   11        0.66   10         2.1
          59.956      16.135   12        0.72   10         2.1
          63.922      20.101   13        0.78   10         2.1
          68.286      24.464   14        0.84   10         2.1
          73.026      29.205   15         0.9   10         2.1
          78.125      34.304   16        0.96   10         2.1
          83.565      39.744   17        1.02   10         2.1
          89.328      45.506   18        1.08   10         2.1
          95.396      51.575   19        1.14   10         2.1
          101.76      57.934   20         1.2   10         2.1
          108.39      64.568   21        1.26   10         2.1
          115.28      71.461   22        1.32   10         2.1
          122.42      78.601   23        1.38   10         2.1
          129.79      85.972   24        1.44   10         2.1
          137.38      93.563   25         1.5   10         2.1
          119.12      75.299   25         1.5   11        2.16
          112.19      68.365   24        1.44   11        2.16
          105.49      61.673   23        1.38   11        2.16
          99.058      55.237   22        1.32   11        2.16
          92.891      49.069   21        1.26   11        2.16
          87.008      43.186   20         1.2   11        2.16
          81.424      37.603   19        1.14   11        2.16
          76.156      32.335   18        1.08   11        2.16
          71.221      27.399   17        1.02   11        2.16
          66.634      22.812   16        0.96   11        2.16
          62.415      18.593   15         0.9   11        2.16
          58.581      14.759   14        0.84   11        2.16
          55.152      11.331   13        0.78   11        2.16
          52.149      8.3273   12        0.72   11        2.16
          49.591      5.7696   11        0.66   11        2.16
          47.501      3.6793   10         0.6   11        2.16
            45.9      2.0788    9        0.54   11        2.16
          44.813     0.99132    8        0.48   11        2.16
          44.262     0.44082    7        0.42   11        2.16
          44.274     0.45224    6        0.36   11        2.16
          44.873      1.0514    5         0.3   11        2.16
          46.087      2.2651    4        0.24   11        2.16
          47.942       4.121    3        0.18   11        2.16
          50.469      6.6478    2        0.12   11        2.16
          53.697      9.8752    1        0.06   11        2.16
          57.655      13.834    0           0   11        2.16
          66.617      22.795    0           0   12        2.22
          61.325      17.503    1        0.06   12        2.22
          56.793      12.971    2        0.12   12        2.22
           52.99      9.1688    3        0.18   12        2.22
          49.887      6.0658    4        0.24   12        2.22
          47.455       3.634    5         0.3   12        2.22
          45.667      1.8456    6        0.36   12        2.22
          44.495     0.67374    7        0.42   12        2.22
          43.914    0.092541    8        0.48   12        2.22
          43.898    0.076938    9        0.54   12        2.22
          44.424      0.6027   10         0.6   12        2.22
          45.468      1.6464   11        0.66   12        2.22
          47.007      3.1854   12        0.72   12        2.22
          49.019       5.198   13        0.78   12        2.22
          51.484      7.6628   14        0.84   12        2.22
          54.381       10.56   15         0.9   12        2.22
           57.69      13.869   16        0.96   12        2.22
          61.393      17.572   17        1.02   12        2.22
          65.471      21.649   18        1.08   12        2.22
          69.906      26.085   19        1.14   12        2.22
          74.682       30.86   20         1.2   12        2.22
          79.782       35.96   21        1.26   12        2.22
           85.19      41.368   22        1.32   12        2.22
          90.891      47.069   23        1.38   12        2.22
           96.87      53.049   24        1.44   12        2.22
          103.11      59.293   25         1.5   12        2.22
          89.373      45.551   25         1.5   13        2.28
          83.849      40.028   24        1.44   13        2.28
          78.613      34.792   23        1.38   13        2.28
          73.678      29.856   22        1.32   13        2.28
          69.059      25.238   21        1.26   13        2.28
          64.772      20.951   20         1.2   13        2.28
          60.834      17.012   19        1.14   13        2.28
           57.26      13.439   18        1.08   13        2.28
          54.069      10.248   17        1.02   13        2.28
          51.278      7.4565   16        0.96   13        2.28
          48.906      5.0844   15         0.9   13        2.28
          46.972      3.1505   14        0.84   13        2.28
          45.496      1.6746   13        0.78   13        2.28
          44.499      0.6775   12        0.72   13        2.28
          44.002     0.18036   11        0.66   13        2.28
          44.027     0.20526   10         0.6   13        2.28
          44.596     0.77498    9        0.54   13        2.28
          45.734       1.913    8        0.48   13        2.28
          47.465      3.6437    7        0.42   13        2.28
          49.814      5.9921    6        0.36   13        2.28
          52.806      8.9842    5         0.3   13        2.28
          56.468      12.647    4        0.24   13        2.28
          60.828      17.007    3        0.18   13        2.28
          65.915      22.094    2        0.12   13        2.28
          71.757      27.936    1        0.06   13        2.28
          78.386      34.564    0           0   13        2.28
          92.861       49.04    0           0   14        2.34
          84.899      41.078    1        0.06   14        2.34
          77.746      33.925    2        0.12   14        2.34
          71.373      27.552    3        0.18   14        2.34
           65.75      21.929    4        0.24   14        2.34
           60.85      17.029    5         0.3   14        2.34
          56.645      12.824    6        0.36   14        2.34
          53.109      9.2879    7        0.42   14        2.34
          50.216      6.3948    8        0.48   14        2.34
          47.941      4.1196    9        0.54   14        2.34
           46.26      2.4382   10         0.6   14        2.34
          45.148       1.327   11        0.66   14        2.34
          44.585     0.76313   12        0.72   14        2.34
          44.546     0.72459   13        0.78   14        2.34
          45.011      1.1899   14        0.84   14        2.34
           45.96      2.1383   15         0.9   14        2.34
          47.371      3.5498   16        0.96   14        2.34
          49.226      5.4047   17        1.02   14        2.34
          51.506      7.6843   18        1.08   14        2.34
          54.192       10.37   19        1.14   14        2.34
          57.267      13.445   20         1.2   14        2.34
          60.713      16.892   21        1.26   14        2.34
          64.515      20.694   22        1.32   14        2.34
          68.656      24.835   23        1.38   14        2.34
          73.121        29.3   24        1.44   14        2.34
          77.895      34.074   25         1.5   14        2.34
          68.676      24.854   25         1.5   15         2.4
          64.677      20.856   24        1.44   15         2.4
          61.009      17.188   23        1.38   15         2.4
          57.687      13.866   22        1.32   15         2.4
          54.727      10.906   21        1.26   15         2.4
          52.145      8.3234   20         1.2   15         2.4
          49.957      6.1356   19        1.14   15         2.4
          48.181      4.3597   18        1.08   15         2.4
          46.835      3.0136   17        1.02   15         2.4
          45.937      2.1155   16        0.96   15         2.4
          45.506      1.6846   15         0.9   15         2.4
          45.562      1.7405   14        0.84   15         2.4
          46.125      2.3032   13        0.78   15         2.4
          47.215      3.3936   12        0.72   15         2.4
          48.855      5.0333   11        0.66   15         2.4
          51.066      7.2441   10         0.6   15         2.4
           53.87      10.049    9        0.54   15         2.4
          57.293      13.471    8        0.48   15         2.4
          61.356      17.535    7        0.42   15         2.4
          66.086      22.265    6        0.36   15         2.4
          71.508      27.687    5         0.3   15         2.4
          77.648      33.826    4        0.24   15         2.4
          84.532      40.711    3        0.18   15         2.4
          92.189      48.368    2        0.12   15         2.4
          100.65      56.825    1        0.06   15         2.4
          109.93      66.113    0           0   15         2.4
          129.49      85.668    0           0   16        2.46
          118.89      75.068    1        0.06   16        2.46
          109.14      65.317    2        0.12   16        2.46
          100.21      56.384    3        0.18   16        2.46
          92.065      48.244    4        0.24   16        2.46
          84.689      40.868    5         0.3   16        2.46
          78.052       34.23    6        0.36   16        2.46
          72.127      28.305    7        0.42   16        2.46
          66.889      23.068    8        0.48   16        2.46
          62.314      18.493    9        0.54   16        2.46
          58.379      14.558   10         0.6   16        2.46
           55.06      11.238   11        0.66   16        2.46
          52.334      8.5124   12        0.72   16        2.46
          50.179      6.3579   13        0.78   16        2.46
          48.575      4.7537   14        0.84   16        2.46
            47.5      3.6788   15         0.9   16        2.46
          46.934       3.113   16        0.96   16        2.46
          46.858      3.0369   17        1.02   16        2.46
          47.253      3.4313   18        1.08   16        2.46
          48.099      4.2777   19        1.14   16        2.46
           49.38      5.5581   20         1.2   16        2.46
          51.077      7.2552   21        1.26   16        2.46
          53.173      9.3519   22        1.32   16        2.46
          55.653      11.832   23        1.38   16        2.46
          58.501       14.68   24        1.44   16        2.46
            61.7      17.879   25         1.5   16        2.46
           56.95      13.129   25         1.5   17        2.52
          54.571      10.749   24        1.44   17        2.52
          52.564      8.7423   23        1.38   17        2.52
          50.945      7.1236   22        1.32   17        2.52
          49.731      5.9091   21        1.26   17        2.52
          48.937      5.1152   20         1.2   17        2.52
           48.58       4.759   19        1.14   17        2.52
          48.679       4.858   18        1.08   17        2.52
          49.252      5.4302   17        1.02   17        2.52
          50.316      6.4941   16        0.96   17        2.52
           51.89      8.0687   15         0.9   17        2.52
          53.995      10.174   14        0.84   17        2.52
           56.65      12.829   13        0.78   17        2.52
          59.877      16.055   12        0.72   17        2.52
          63.695      19.874   11        0.66   17        2.52
          68.127      24.306   10         0.6   17        2.52
          73.196      29.375    9        0.54   17        2.52
          78.924      35.102    8        0.48   17        2.52
          85.334      41.512    7        0.42   17        2.52
           92.45      48.629    6        0.36   17        2.52
           100.3      56.476    5         0.3   17        2.52
           108.9       65.08    4        0.24   17        2.52
          118.29      74.466    3        0.18   17        2.52
          128.48       84.66    2        0.12   17        2.52
          139.51       95.69    1        0.06   17        2.52
           151.4      107.58    0           0   17        2.52
          175.55      131.73    0           0   18        2.58
          162.39      118.57    1        0.06   18        2.58
           150.1      106.28    2        0.12   18        2.58
          138.67      94.844    3        0.18   18        2.58
          128.05      84.228    4        0.24   18        2.58
          118.23      74.409    5         0.3   18        2.58
          109.18      65.362    6        0.36   18        2.58
          100.88      57.063    7        0.42   18        2.58
          93.307      49.486    8        0.48   18        2.58
          86.431      42.609    9        0.54   18        2.58
          80.231      36.409   10         0.6   18        2.58
          74.685      30.864   11        0.66   18        2.58
          69.773      25.951   12        0.72   18        2.58
          65.471      21.649   13        0.78   18        2.58
          61.759      17.938   14        0.84   18        2.58
          58.617      14.796   15         0.9   18        2.58
          56.025      12.204   16        0.96   18        2.58
          53.964      10.142   17        1.02   18        2.58
          52.414      8.5922   18        1.08   18        2.58
          51.357      7.5354   19        1.14   18        2.58
          50.775      6.9538   20         1.2   18        2.58
          50.651      6.8299   21        1.26   18        2.58
          50.968      7.1466   22        1.32   18        2.58
          51.709      7.8874   23        1.38   18        2.58
          52.858      9.0362   24        1.44   18        2.58
          54.399      10.577   25         1.5   18        2.58
          54.015      10.193   25         1.5   19        2.64
          53.327      9.5058   24        1.44   19        2.64
          53.051      9.2295   23        1.38   19        2.64
          53.201        9.38   22        1.32   19        2.64
          53.795      9.9736   21        1.26   19        2.64
          54.848      11.027   20         1.2   19        2.64
          56.378      12.556   19        1.14   19        2.64
          58.401       14.58   18        1.08   19        2.64
          60.936      17.115   17        1.02   19        2.64
          64.002       20.18   16        0.96   19        2.64
          67.616      23.794   15         0.9   19        2.64
          71.798      27.976   14        0.84   19        2.64
          76.567      32.746   13        0.78   19        2.64
          81.944      38.123   12        0.72   19        2.64
          87.949      44.128   11        0.66   19        2.64
          94.604      50.782   10         0.6   19        2.64
          101.93      58.107    9        0.54   19        2.64
          109.95      66.125    8        0.48   19        2.64
          118.68      74.858    7        0.42   19        2.64
          128.15      84.328    6        0.36   19        2.64
          138.38      94.559    5         0.3   19        2.64
           149.4      105.58    4        0.24   19        2.64
          161.22       117.4    3        0.18   19        2.64
          173.88      130.06    2        0.12   19        2.64
           187.4      143.58    1        0.06   19        2.64
           201.8      157.98    0           0   19        2.64
          230.02       186.2    0           0   20         2.7
          214.41      170.59    1        0.06   20         2.7
          199.69      155.87    2        0.12   20         2.7
          185.84      142.02    3        0.18   20         2.7
          172.83      129.01    4        0.24   20         2.7
          160.64      116.81    5         0.3   20         2.7
          149.24      105.42    6        0.36   20         2.7
          138.61      94.794    7        0.42   20         2.7
          128.74       84.92    8        0.48   20         2.7
           119.6      75.774    9        0.54   20         2.7
          111.16      67.334   10         0.6   20         2.7
           103.4      59.578   11        0.66   20         2.7
          96.308      52.487   12        0.72   20         2.7
           89.86      46.039   13        0.78   20         2.7
          84.036      40.214   14        0.84   20         2.7
          78.814      34.993   15         0.9   20         2.7
          74.178      30.356   16        0.96   20         2.7
          70.106      26.285   17        1.02   20         2.7
          66.582       22.76   18        1.08   20         2.7
          63.586      19.765   19        1.14   20         2.7
          61.102       17.28   20         1.2   20         2.7
          59.112       15.29   21        1.26   20         2.7
          57.599      13.777   22        1.32   20         2.7
          56.546      12.725   23        1.38   20         2.7
          55.939      12.117   24        1.44   20         2.7
           55.76      11.939   25         1.5   20         2.7
          59.592      15.771   25         1.5   21        2.76
          60.646      16.825   24        1.44   21        2.76
          62.146      18.325   23        1.38   21        2.76
          64.107      20.286   22        1.32   21        2.76
          66.546      22.724   21        1.26   21        2.76
          69.478      25.656   20         1.2   21        2.76
           72.92      29.098   19        1.14   21        2.76
          76.889      33.068   18        1.08   21        2.76
          81.403      37.582   17        1.02   21        2.76
           86.48      42.659   16        0.96   21        2.76
          92.137      48.315   15         0.9   21        2.76
          98.393      54.571   14        0.84   21        2.76
          105.27      61.445   13        0.78   21        2.76
          112.78      68.956   12        0.72   21        2.76
          120.94      77.123   11        0.66   21        2.76
          129.79      85.967   10         0.6   21        2.76
          139.33      95.508    9        0.54   21        2.76
          149.59      105.77    8        0.48   21        2.76
          160.58      116.76    7        0.42   21        2.76
          172.34      128.52    6        0.36   21        2.76
          184.88      141.06    5         0.3   21        2.76
          198.22       154.4    4        0.24   21        2.76
          212.39      168.57    3        0.18   21        2.76
           227.4      183.58    2        0.12   21        2.76
          243.29      199.47    1        0.06   21        2.76
          260.08      216.26    0           0   21        2.76
          291.83      248.01    0           0   22        2.82
          273.91      230.09    1        0.06   22        2.82
          256.89      213.07    2        0.12   22        2.82
          240.75      196.93    3        0.18   22        2.82
          225.46      181.63    4        0.24   22        2.82
          210.99      167.17    5         0.3   22        2.82
          197.34      153.52    6        0.36   22        2.82
          184.48      140.65    7        0.42   22        2.82
          172.38      128.56    8        0.48   22        2.82
          161.03      117.21    9        0.54   22        2.82
           150.4      106.58   10         0.6   22        2.82
          140.49      96.667   11        0.66   22        2.82
          131.26      87.437   12        0.72   22        2.82
           122.7      78.875   13        0.78   22        2.82
          114.78      70.963   14        0.84   22        2.82
           107.5       63.68   15         0.9   22        2.82
          100.83      57.009   16        0.96   22        2.82
          94.754      50.933   17        1.02   22        2.82
          89.253      45.432   18        1.08   22        2.82
          84.311       40.49   19        1.14   22        2.82
          79.911       36.09   20         1.2   22        2.82
          76.036      32.215   21        1.26   22        2.82
          72.669      28.848   22        1.32   22        2.82
          69.796      25.974   23        1.38   22        2.82
          67.398      23.577   24        1.44   22        2.82
          65.463      21.641   25         1.5   22        2.82
          73.317      29.496   25         1.5   23        2.88
          76.138      32.317   24        1.44   23        2.88
          79.435      35.614   23        1.38   23        2.88
          83.223      39.402   22        1.32   23        2.88
          87.517      43.696   21        1.26   23        2.88
          92.334      48.512   20         1.2   23        2.88
          97.689      53.867   19        1.14   23        2.88
           103.6      59.777   18        1.08   23        2.88
          110.08      66.258   17        1.02   23        2.88
          117.15      73.327   16        0.96   23        2.88
          124.82      81.001   15         0.9   23        2.88
          133.12      89.299   14        0.84   23        2.88
          142.06      98.237   13        0.78   23        2.88
          151.66      107.83   12        0.72   23        2.88
          161.93      118.11   11        0.66   23        2.88
           172.9      129.08   10         0.6   23        2.88
          184.59      140.76    9        0.54   23        2.88
             197      153.18    8        0.48   23        2.88
          210.18      166.35    7        0.42   23        2.88
          224.12       180.3    6        0.36   23        2.88
          238.86      195.04    5         0.3   23        2.88
          254.41      210.59    4        0.24   23        2.88
          270.79      226.97    3        0.18   23        2.88
          288.03      244.21    2        0.12   23        2.88
          306.14      262.32    1        0.06   23        2.88
          325.15      281.33    0           0   23        2.88
           359.9      316.07    0           0   24        2.94
          339.84      296.02    1        0.06   24        2.94
          320.68      276.86    2        0.12   24        2.94
          302.39      258.57    3        0.18   24        2.94
          284.96      241.13    4        0.24   24        2.94
          268.35      224.53    5         0.3   24        2.94
          252.56      208.74    6        0.36   24        2.94
          237.57      193.75    7        0.42   24        2.94
          223.35      179.53    8        0.48   24        2.94
          209.89      166.07    9        0.54   24        2.94
          197.17      153.35   10         0.6   24        2.94
          185.17      141.35   11        0.66   24        2.94
          173.87      130.05   12        0.72   24        2.94
          163.26      119.43   13        0.78   24        2.94
          153.31      109.49   14        0.84   24        2.94
          144.01      100.19   15         0.9   24        2.94
          135.35      91.524   16        0.96   24        2.94
           127.3      83.474   17        1.02   24        2.94
          119.84      76.023   18        1.08   24        2.94
          112.98      69.154   19        1.14   24        2.94
          106.67      62.851   20         1.2   24        2.94
          100.92      57.098   21        1.26   24        2.94
          95.701      51.879   22        1.32   24        2.94
          91.001       47.18   23        1.38   24        2.94
          86.806      42.984   24        1.44   24        2.94
          83.099      39.278   25         1.5   24        2.94
          94.745      50.924   25         1.5   25           3
          99.335      55.514   24        1.44   25           3
          104.43      60.605   23        1.38   25           3
          110.03      66.211   22        1.32   25           3
          116.17      72.347   21        1.26   25           3
          122.85      79.028   20         1.2   25           3
          130.09       86.27   19        1.14   25           3
          137.91      94.088   18        1.08   25           3
          146.32       102.5   17        1.02   25           3
          155.33      111.51   16        0.96   25           3
          164.98      121.15   15         0.9   25           3
          175.26      131.43   14        0.84   25           3
          186.19      142.37   13        0.78   25           3
           197.8      153.98   12        0.72   25           3
           210.1      166.28   11        0.66   25           3
          223.11      179.29   10         0.6   25           3
          236.84      193.02    9        0.54   25           3
          251.31      207.49    8        0.48   25           3
          266.54      222.72    7        0.42   25           3
          282.55      238.73    6        0.36   25           3
          299.36      255.53    5         0.3   25           3
          316.97      273.15    4        0.24   25           3
          335.42       291.6    3        0.18   25           3
          354.72       310.9    2        0.12   25           3
          374.89      331.07    1        0.06   25           3
          395.94      352.12    0           0   25           3
    1.5
             331      287.18   16        0.96    0         1.5
          342.73      298.91   17        1.02    0         1.5
          354.53      310.71   18        1.08    0         1.5
           366.4      322.58   19        1.14    0         1.5
          378.31      334.49   20         1.2    0         1.5
          390.27      346.45   21        1.26    0         1.5
          402.26      358.44   22        1.32    0         1.5
          414.28      370.46   23        1.38    0         1.5
          426.32       382.5   24        1.44    0         1.5
          438.38      394.56   25         1.5    0         1.5
          399.23      355.41   25         1.5    1        1.56
          387.44      343.62   24        1.44    1        1.56
          375.68      331.86   23        1.38    1        1.56
          363.96      320.14   22        1.32    1        1.56
          352.28      308.46   21        1.26    1        1.56
          340.66      296.84   20         1.2    1        1.56
          329.11      285.29   19        1.14    1        1.56
          317.62       273.8   18        1.08    1        1.56
          306.22       262.4   17        1.02    1        1.56
          294.91      251.08   16        0.96    1        1.56
           283.7      239.87   15         0.9    1        1.56
           272.6      228.78   14        0.84    1        1.56
          261.63       217.8   13        0.78    1        1.56
          250.79      206.97   12        0.72    1        1.56
          240.11      196.29   11        0.66    1        1.56
          229.59      185.77   10         0.6    1        1.56
          219.25      175.43    9        0.54    1        1.56
          209.11      165.29    8        0.48    1        1.56
          199.18      155.35    7        0.42    1        1.56
          189.47      145.65    6        0.36    1        1.56
          180.02       136.2    5         0.3    1        1.56
          170.83      127.01    4        0.24    1        1.56
          161.93      118.11    3        0.18    1        1.56
          153.34      109.52    2        0.12    1        1.56
          145.09      101.26    1        0.06    1        1.56
          137.19      93.364    0           0    1        1.56
          114.89      71.069    0           0    2        1.62
          121.81      77.985    1        0.06    2        1.62
          129.12      85.298    2        0.12    2        1.62
           136.8      92.983    3        0.18    2        1.62
          144.84      101.02    4        0.24    2        1.62
           153.2      109.37    5         0.3    2        1.62
          161.86      118.04    6        0.36    2        1.62
           170.8      126.98    7        0.42    2        1.62
          180.01      136.19    8        0.48    2        1.62
          189.46      145.64    9        0.54    2        1.62
          199.14      155.31   10         0.6    2        1.62
          209.02       165.2   11        0.66    2        1.62
           219.1      175.28   12        0.72    2        1.62
          229.37      185.54   13        0.78    2        1.62
          239.79      195.97   14        0.84    2        1.62
          250.37      206.55   15         0.9    2        1.62
          261.08      217.26   16        0.96    2        1.62
          271.92       228.1   17        1.02    2        1.62
          282.88      239.06   18        1.08    2        1.62
          293.94      250.12   19        1.14    2        1.62
           305.1      261.28   20         1.2    2        1.62
          316.34      272.51   21        1.26    2        1.62
          327.65      283.83   22        1.32    2        1.62
          339.03      295.21   23        1.38    2        1.62
          350.46      306.64   24        1.44    2        1.62
          361.95      318.13   25         1.5    2        1.62
           326.6      282.78   25         1.5    3        1.68
          315.46      271.64   24        1.44    3        1.68
          304.39      260.57   23        1.38    3        1.68
          293.39      249.57   22        1.32    3        1.68
          282.48      238.66   21        1.26    3        1.68
          271.67      227.85   20         1.2    3        1.68
          260.97      217.15   19        1.14    3        1.68
          250.38      206.56   18        1.08    3        1.68
          239.91      196.09   17        1.02    3        1.68
          229.59      185.77   16        0.96    3        1.68
          219.42       175.6   15         0.9    3        1.68
          209.41      165.59   14        0.84    3        1.68
          199.59      155.76   13        0.78    3        1.68
          189.95      146.13   12        0.72    3        1.68
          180.52       136.7   11        0.66    3        1.68
          171.32       127.5   10         0.6    3        1.68
          162.36      118.54    9        0.54    3        1.68
          153.65      109.83    8        0.48    3        1.68
          145.23      101.41    7        0.42    3        1.68
           137.1      93.276    6        0.36    3        1.68
          129.29      85.464    5         0.3    3        1.68
          121.81      77.992    4        0.24    3        1.68
           114.7      70.882    3        0.18    3        1.68
          107.98      64.158    2        0.12    3        1.68
          101.67      57.845    1        0.06    3        1.68
          95.793      51.971    0           0    3        1.68
          79.913      36.092    0           0    4        1.74
          84.692      40.871    1        0.06    4        1.74
           89.95      46.128    2        0.12    4        1.74
          95.658      51.837    3        0.18    4        1.74
          101.79       57.97    4        0.24    4        1.74
          108.33      64.504    5         0.3    4        1.74
          115.23      71.413    6        0.36    4        1.74
           122.5      78.675    7        0.42    4        1.74
          130.09      86.268    8        0.48    4        1.74
          137.99      94.173    9        0.54    4        1.74
          146.19      102.37   10         0.6    4        1.74
          154.66      110.84   11        0.66    4        1.74
          163.38      119.56   12        0.72    4        1.74
          172.34      128.52   13        0.78    4        1.74
          181.52       137.7   14        0.84    4        1.74
          190.91      147.09   15         0.9    4        1.74
          200.49      156.67   16        0.96    4        1.74
          210.24      166.42   17        1.02    4        1.74
          220.16      176.34   18        1.08    4        1.74
          230.24      186.42   19        1.14    4        1.74
          240.45      196.63   20         1.2    4        1.74
          250.79      206.97   21        1.26    4        1.74
          261.25      217.43   22        1.32    4        1.74
          271.82      227.99   23        1.38    4        1.74
          282.48      238.66   24        1.44    4        1.74
          293.23      249.41   25         1.5    4        1.74
          261.91      218.09   25         1.5    5         1.8
          251.58      207.76   24        1.44    5         1.8
          241.37      197.55   23        1.38    5         1.8
          231.27      187.45   22        1.32    5         1.8
           221.3      177.48   21        1.26    5         1.8
          211.48      167.66   20         1.2    5         1.8
           201.8      157.98   19        1.14    5         1.8
          192.29      148.47   18        1.08    5         1.8
          182.96      139.14   17        1.02    5         1.8
          173.82      129.99   16        0.96    5         1.8
          164.88      121.06   15         0.9    5         1.8
          156.16      112.33   14        0.84    5         1.8
          147.67      103.85   13        0.78    5         1.8
          139.43      95.613   12        0.72    5         1.8
          131.47      87.645   11        0.66    5         1.8
          123.78      79.963   10         0.6    5         1.8
          116.41      72.584    9        0.54    5         1.8
          109.35      65.529    8        0.48    5         1.8
          102.64      58.819    7        0.42    5         1.8
          96.296      52.475    6        0.36    5         1.8
           90.34      46.519    5         0.3    5         1.8
          84.796      40.975    4        0.24    5         1.8
           79.69      35.868    3        0.18    5         1.8
          75.046      31.224    2        0.12    5         1.8
          70.892      27.071    1        0.06    5         1.8
          67.257      23.436    0           0    5         1.8
          57.817      13.996    0           0    6        1.86
          60.264      16.443    1        0.06    6        1.86
          63.269      19.448    2        0.12    6        1.86
          66.802      22.981    3        0.18    6        1.86
          70.836      27.015    4        0.24    6        1.86
          75.344      31.523    5         0.3    6        1.86
            80.3      36.479    6        0.36    6        1.86
           85.68      41.859    7        0.42    6        1.86
           91.46      47.639    8        0.48    6        1.86
          97.618      53.797    9        0.54    6        1.86
          104.13      60.311   10         0.6    6        1.86
          110.98      67.161   11        0.66    6        1.86
          118.15      74.328   12        0.72    6        1.86
          125.61      81.793   13        0.78    6        1.86
          133.36      89.538   14        0.84    6        1.86
          141.37      97.545   15         0.9    6        1.86
          149.62       105.8   16        0.96    6        1.86
          158.11      114.29   17        1.02    6        1.86
          166.81      122.99   18        1.08    6        1.86
          175.71      131.89   19        1.14    6        1.86
          184.81      140.98   20         1.2    6        1.86
          194.07      150.25   21        1.26    6        1.86
          203.51      159.68   22        1.32    6        1.86
          213.09      169.27   23        1.38    6        1.86
          222.81      178.99   24        1.44    6        1.86
          232.67      188.85   25         1.5    6        1.86
          205.56      161.74   25         1.5    7        1.92
          196.22       152.4   24        1.44    7        1.92
          187.02       143.2   23        1.38    7        1.92
          177.99      134.17   22        1.32    7        1.92
          169.14      125.32   21        1.26    7        1.92
          160.47      116.65   20         1.2    7        1.92
             152      108.18   19        1.14    7        1.92
          143.74      99.923   18        1.08    7        1.92
          135.72      91.896   17        1.02    7        1.92
          127.93      84.112   16        0.96    7        1.92
          120.41      76.587   15         0.9    7        1.92
          113.16      69.336   14        0.84    7        1.92
           106.2      62.377   13        0.78    7        1.92
          99.549      55.727   12        0.72    7        1.92
          93.228      49.406   11        0.66    7        1.92
          87.254      43.432   10         0.6    7        1.92
          81.648      37.826    9        0.54    7        1.92
          76.431      32.609    8        0.48    7        1.92
          71.625      27.803    7        0.42    7        1.92
          67.253      23.432    6        0.36    7        1.92
           63.34      19.518    5         0.3    7        1.92
           59.91      16.089    4        0.24    7        1.92
          56.991      13.169    3        0.18    7        1.92
          54.609      10.787    2        0.12    7        1.92
          52.792      8.9709    1        0.06    7        1.92
          51.572      7.7507    0           0    7        1.92
          48.487      4.6652    0           0    8        1.98
          48.447      4.6257    1        0.06    8        1.98
           49.04      5.2188    2        0.12    8        1.98
          50.235       6.414    3        0.18    8        1.98
          52.004      8.1823    4        0.24    8        1.98
          54.317      10.496    5         0.3    8        1.98
          57.149      13.327    6        0.36    8        1.98
          60.473      16.651    7        0.42    8        1.98
          64.265      20.443    8        0.48    8        1.98
            68.5      24.679    9        0.54    8        1.98
          73.157      29.336   10         0.6    8        1.98
          78.213      34.392   11        0.66    8        1.98
          83.648      39.826   12        0.72    8        1.98
           89.44      45.619   13        0.78    8        1.98
          95.572      51.751   14        0.84    8        1.98
          102.02      58.203   15         0.9    8        1.98
          108.78      64.958   16        0.96    8        1.98
          115.82      71.999   17        1.02    8        1.98
          123.13      79.309   18        1.08    8        1.98
           130.7      86.874   19        1.14    8        1.98
           138.5      94.678   20         1.2    8        1.98
          146.53      102.71   21        1.26    8        1.98
          154.77      110.95   22        1.32    8        1.98
          163.21      119.38   23        1.38    8        1.98
          171.83      128.01   24        1.44    8        1.98
          180.63      136.81   25         1.5    8        1.98
          157.89      114.07   25         1.5    9        2.04
          149.68      105.86   24        1.44    9        2.04
          141.66      97.843   23        1.38    9        2.04
          133.86      90.036   22        1.32    9        2.04
          126.27      82.451   21        1.26    9        2.04
          118.92      75.101   20         1.2    9        2.04
          111.82      68.001   19        1.14    9        2.04
          104.99      61.166   18        1.08    9        2.04
          98.432      54.611   17        1.02    9        2.04
          92.174      48.352   16        0.96    9        2.04
          86.228      42.407   15         0.9    9        2.04
          80.614      36.792   14        0.84    9        2.04
          75.348      31.527   13        0.78    9        2.04
          70.451       26.63   12        0.72    9        2.04
          65.942      22.121   11        0.66    9        2.04
          61.842       18.02   10         0.6    9        2.04
          58.171       14.35    9        0.54    9        2.04
          54.954      11.132    8        0.48    9        2.04
          52.212      8.3909    7        0.42    9        2.04
          49.971      6.1496    6        0.36    9        2.04
          48.255      4.4337    5         0.3    9        2.04
          47.091      3.2696    4        0.24    9        2.04
          46.506      2.6845    3        0.18    9        2.04
          46.528      2.7067    2        0.12    9        2.04
          47.187      3.3658    1        0.06    9        2.04
          48.514      4.6923    0           0    9        2.04
          51.594      7.7723    0           0   10         2.1
          48.959      5.1373    1        0.06   10         2.1
          47.024      3.2029    2        0.12   10         2.1
           45.76      1.9381    3        0.18   10         2.1
          45.135      1.3133    4        0.24   10         2.1
          45.122      1.3001    5         0.3   10         2.1
          45.692      1.8707    6        0.36   10         2.1
           46.82      2.9986    7        0.42   10         2.1
           48.48      4.6582    8        0.48   10         2.1
          50.646      6.8249    9        0.54   10         2.1
          53.296       9.475   10         0.6   10         2.1
          56.407      12.586   11        0.66   10         2.1
          59.956      16.135   12        0.72   10         2.1
          63.922      20.101   13        0.78   10         2.1
          68.286      24.464   14        0.84   10         2.1
          73.026      29.205   15         0.9   10         2.1
          78.125      34.304   16        0.96   10         2.1
          83.565      39.744   17        1.02   10         2.1
          89.328      45.506   18        1.08   10         2.1
          95.396      51.575   19        1.14   10         2.1
          101.76      57.934   20         1.2   10         2.1
          108.39      64.568   21        1.26   10         2.1
          115.28      71.461   22        1.32   10         2.1
          122.42      78.601   23        1.38   10         2.1
          129.79      85.972   24        1.44   10         2.1
          137.38      93.563   25         1.5   10         2.1
          119.12      75.299   25         1.5   11        2.16
          112.19      68.365   24        1.44   11        2.16
          105.49      61.673   23        1.38   11        2.16
          99.058      55.237   22        1.32   11        2.16
          92.891      49.069   21        1.26   11        2.16
          87.008      43.186   20         1.2   11        2.16
          81.424      37.603   19        1.14   11        2.16
          76.156      32.335   18        1.08   11        2.16
          71.221      27.399   17        1.02   11        2.16
          66.634      22.812   16        0.96   11        2.16
          62.415      18.593   15         0.9   11        2.16
          58.581      14.759   14        0.84   11        2.16
          55.152      11.331   13        0.78   11        2.16
          52.149      8.3273   12        0.72   11        2.16
          49.591      5.7696   11        0.66   11        2.16
          47.501      3.6793   10         0.6   11        2.16
            45.9      2.0788    9        0.54   11        2.16
          44.813     0.99132    8        0.48   11        2.16
          44.262     0.44082    7        0.42   11        2.16
          44.274     0.45224    6        0.36   11        2.16
          44.873      1.0514    5         0.3   11        2.16
          46.087      2.2651    4        0.24   11        2.16
          47.942       4.121    3        0.18   11        2.16
          50.469      6.6478    2        0.12   11        2.16
          53.697      9.8752    1        0.06   11        2.16
          57.655      13.834    0           0   11        2.16
          66.617      22.795    0           0   12        2.22
          61.325      17.503    1        0.06   12        2.22
          56.793      12.971    2        0.12   12        2.22
           52.99      9.1688    3        0.18   12        2.22
          49.887      6.0658    4        0.24   12        2.22
          47.455       3.634    5         0.3   12        2.22
          45.667      1.8456    6        0.36   12        2.22
          44.495     0.67374    7        0.42   12        2.22
          43.914    0.092541    8        0.48   12        2.22
          43.898    0.076938    9        0.54   12        2.22
          44.424      0.6027   10         0.6   12        2.22
          45.468      1.6464   11        0.66   12        2.22
          47.007      3.1854   12        0.72   12        2.22
          49.019       5.198   13        0.78   12        2.22
          51.484      7.6628   14        0.84   12        2.22
          54.381       10.56   15         0.9   12        2.22
           57.69      13.869   16        0.96   12        2.22
          61.393      17.572   17        1.02   12        2.22
          65.471      21.649   18        1.08   12        2.22
          69.906      26.085   19        1.14   12        2.22
          74.682       30.86   20         1.2   12        2.22
          79.782       35.96   21        1.26   12        2.22
           85.19      41.368   22        1.32   12        2.22
          90.891      47.069   23        1.38   12        2.22
           96.87      53.049   24        1.44   12        2.22
          103.11      59.293   25         1.5   12        2.22
          89.373      45.551   25         1.5   13        2.28
          83.849      40.028   24        1.44   13        2.28
          78.613      34.792   23        1.38   13        2.28
          73.678      29.856   22        1.32   13        2.28
          69.059      25.238   21        1.26   13        2.28
          64.772      20.951   20         1.2   13        2.28
          60.834      17.012   19        1.14   13        2.28
           57.26      13.439   18        1.08   13        2.28
          54.069      10.248   17        1.02   13        2.28
          51.278      7.4565   16        0.96   13        2.28
          48.906      5.0844   15         0.9   13        2.28
          46.972      3.1505   14        0.84   13        2.28
          45.496      1.6746   13        0.78   13        2.28
          44.499      0.6775   12        0.72   13        2.28
          44.002     0.18036   11        0.66   13        2.28
          44.027     0.20526   10         0.6   13        2.28
          44.596     0.77498    9        0.54   13        2.28
          45.734       1.913    8        0.48   13        2.28
          47.465      3.6437    7        0.42   13        2.28
          49.814      5.9921    6        0.36   13        2.28
          52.806      8.9842    5         0.3   13        2.28
          56.468      12.647    4        0.24   13        2.28
          60.828      17.007    3        0.18   13        2.28
          65.915      22.094    2        0.12   13        2.28
          71.757      27.936    1        0.06   13        2.28
          78.386      34.564    0           0   13        2.28
          92.861       49.04    0           0   14        2.34
          84.899      41.078    1        0.06   14        2.34
          77.746      33.925    2        0.12   14        2.34
          71.373      27.552    3        0.18   14        2.34
           65.75      21.929    4        0.24   14        2.34
           60.85      17.029    5         0.3   14        2.34
          56.645      12.824    6        0.36   14        2.34
          53.109      9.2879    7        0.42   14        2.34
          50.216      6.3948    8        0.48   14        2.34
          47.941      4.1196    9        0.54   14        2.34
           46.26      2.4382   10         0.6   14        2.34
          45.148       1.327   11        0.66   14        2.34
          44.585     0.76313   12        0.72   14        2.34
          44.546     0.72459   13        0.78   14        2.34
          45.011      1.1899   14        0.84   14        2.34
           45.96      2.1383   15         0.9   14        2.34
          47.371      3.5498   16        0.96   14        2.34
          49.226      5.4047   17        1.02   14        2.34
          51.506      7.6843   18        1.08   14        2.34
          54.192       10.37   19        1.14   14        2.34
          57.267      13.445   20         1.2   14        2.34
          60.713      16.892   21        1.26   14        2.34
          64.515      20.694   22        1.32   14        2.34
          68.656      24.835   23        1.38   14        2.34
          73.121        29.3   24        1.44   14        2.34
          77.895      34.074   25         1.5   14        2.34
          68.676      24.854   25         1.5   15         2.4
          64.677      20.856   24        1.44   15         2.4
          61.009      17.188   23        1.38   15         2.4
          57.687      13.866   22        1.32   15         2.4
          54.727      10.906   21        1.26   15         2.4
          52.145      8.3234   20         1.2   15         2.4
          49.957      6.1356   19        1.14   15         2.4
          48.181      4.3597   18        1.08   15         2.4
          46.835      3.0136   17        1.02   15         2.4
          45.937      2.1155   16        0.96   15         2.4
          45.506      1.6846   15         0.9   15         2.4
          45.562      1.7405   14        0.84   15         2.4
          46.125      2.3032   13        0.78   15         2.4
          47.215      3.3936   12        0.72   15         2.4
          48.855      5.0333   11        0.66   15         2.4
          51.066      7.2441   10         0.6   15         2.4
           53.87      10.049    9        0.54   15         2.4
          57.293      13.471    8        0.48   15         2.4
          61.356      17.535    7        0.42   15         2.4
          66.086      22.265    6        0.36   15         2.4
          71.508      27.687    5         0.3   15         2.4
          77.648      33.826    4        0.24   15         2.4
          84.532      40.711    3        0.18   15         2.4
          92.189      48.368    2        0.12   15         2.4
          100.65      56.825    1        0.06   15         2.4
          109.93      66.113    0           0   15         2.4
          129.49      85.668    0           0   16        2.46
          118.89      75.068    1        0.06   16        2.46
          109.14      65.317    2        0.12   16        2.46
          100.21      56.384    3        0.18   16        2.46
          92.065      48.244    4        0.24   16        2.46
          84.689      40.868    5         0.3   16        2.46
          78.052       34.23    6        0.36   16        2.46
          72.127      28.305    7        0.42   16        2.46
          66.889      23.068    8        0.48   16        2.46
          62.314      18.493    9        0.54   16        2.46
          58.379      14.558   10         0.6   16        2.46
           55.06      11.238   11        0.66   16        2.46
          52.334      8.5124   12        0.72   16        2.46
          50.179      6.3579   13        0.78   16        2.46
          48.575      4.7537   14        0.84   16        2.46
            47.5      3.6788   15         0.9   16        2.46
          46.934       3.113   16        0.96   16        2.46
          46.858      3.0369   17        1.02   16        2.46
          47.253      3.4313   18        1.08   16        2.46
          48.099      4.2777   19        1.14   16        2.46
           49.38      5.5581   20         1.2   16        2.46
          51.077      7.2552   21        1.26   16        2.46
          53.173      9.3519   22        1.32   16        2.46
          55.653      11.832   23        1.38   16        2.46
          58.501       14.68   24        1.44   16        2.46
            61.7      17.879   25         1.5   16        2.46
           56.95      13.129   25         1.5   17        2.52
          54.571      10.749   24        1.44   17        2.52
          52.564      8.7423   23        1.38   17        2.52
          50.945      7.1236   22        1.32   17        2.52
          49.731      5.9091   21        1.26   17        2.52
          48.937      5.1152   20         1.2   17        2.52
           48.58       4.759   19        1.14   17        2.52
          48.679       4.858   18        1.08   17        2.52
          49.252      5.4302   17        1.02   17        2.52
          50.316      6.4941   16        0.96   17        2.52
           51.89      8.0687   15         0.9   17        2.52
          53.995      10.174   14        0.84   17        2.52
           56.65      12.829   13        0.78   17        2.52
          59.877      16.055   12        0.72   17        2.52
          63.695      19.874   11        0.66   17        2.52
          68.127      24.306   10         0.6   17        2.52
          73.196      29.375    9        0.54   17        2.52
          78.924      35.102    8        0.48   17        2.52
          85.334      41.512    7        0.42   17        2.52
           92.45      48.629    6        0.36   17        2.52
           100.3      56.476    5         0.3   17        2.52
           108.9       65.08    4        0.24   17        2.52
          118.29      74.466    3        0.18   17        2.52
          128.48       84.66    2        0.12   17        2.52
          139.51       95.69    1        0.06   17        2.52
           151.4      107.58    0           0   17        2.52
          175.55      131.73    0           0   18        2.58
          162.39      118.57    1        0.06   18        2.58
           150.1      106.28    2        0.12   18        2.58
          138.67      94.844    3        0.18   18        2.58
          128.05      84.228    4        0.24   18        2.58
          118.23      74.409    5         0.3   18        2.58
          109.18      65.362    6        0.36   18        2.58
          100.88      57.063    7        0.42   18        2.58
          93.307      49.486    8        0.48   18        2.58
          86.431      42.609    9        0.54   18        2.58
          80.231      36.409   10         0.6   18        2.58
          74.685      30.864   11        0.66   18        2.58
          69.773      25.951   12        0.72   18        2.58
          65.471      21.649   13        0.78   18        2.58
          61.759      17.938   14        0.84   18        2.58
          58.617      14.796   15         0.9   18        2.58
          56.025      12.204   16        0.96   18        2.58
          53.964      10.142   17        1.02   18        2.58
          52.414      8.5922   18        1.08   18        2.58
          51.357      7.5354   19        1.14   18        2.58
          50.775      6.9538   20         1.2   18        2.58
          50.651      6.8299   21        1.26   18        2.58
          50.968      7.1466   22        1.32   18        2.58
          51.709      7.8874   23        1.38   18        2.58
          52.858      9.0362   24        1.44   18        2.58
          54.399      10.577   25         1.5   18        2.58
          54.015      10.193   25         1.5   19        2.64
          53.327      9.5058   24        1.44   19        2.64
          53.051      9.2295   23        1.38   19        2.64
          53.201        9.38   22        1.32   19        2.64
          53.795      9.9736   21        1.26   19        2.64
          54.848      11.027   20         1.2   19        2.64
          56.378      12.556   19        1.14   19        2.64
          58.401       14.58   18        1.08   19        2.64
          60.936      17.115   17        1.02   19        2.64
          64.002       20.18   16        0.96   19        2.64
          67.616      23.794   15         0.9   19        2.64
          71.798      27.976   14        0.84   19        2.64
          76.567      32.746   13        0.78   19        2.64
          81.944      38.123   12        0.72   19        2.64
          87.949      44.128   11        0.66   19        2.64
          94.604      50.782   10         0.6   19        2.64
          101.93      58.107    9        0.54   19        2.64
          109.95      66.125    8        0.48   19        2.64
          118.68      74.858    7        0.42   19        2.64
          128.15      84.328    6        0.36   19        2.64
          138.38      94.559    5         0.3   19        2.64
           149.4      105.58    4        0.24   19        2.64
          161.22       117.4    3        0.18   19        2.64
          173.88      130.06    2        0.12   19        2.64
           187.4      143.58    1        0.06   19        2.64
           201.8      157.98    0           0   19        2.64
          230.02       186.2    0           0   20         2.7
          214.41      170.59    1        0.06   20         2.7
          199.69      155.87    2        0.12   20         2.7
          185.84      142.02    3        0.18   20         2.7
          172.83      129.01    4        0.24   20         2.7
          160.64      116.81    5         0.3   20         2.7
          149.24      105.42    6        0.36   20         2.7
          138.61      94.794    7        0.42   20         2.7
          128.74       84.92    8        0.48   20         2.7
           119.6      75.774    9        0.54   20         2.7
          111.16      67.334   10         0.6   20         2.7
           103.4      59.578   11        0.66   20         2.7
          96.308      52.487   12        0.72   20         2.7
           89.86      46.039   13        0.78   20         2.7
          84.036      40.214   14        0.84   20         2.7
          78.814      34.993   15         0.9   20         2.7
          74.178      30.356   16        0.96   20         2.7
          70.106      26.285   17        1.02   20         2.7
          66.582       22.76   18        1.08   20         2.7
          63.586      19.765   19        1.14   20         2.7
          61.102       17.28   20         1.2   20         2.7
          59.112       15.29   21        1.26   20         2.7
          57.599      13.777   22        1.32   20         2.7
          56.546      12.725   23        1.38   20         2.7
          55.939      12.117   24        1.44   20         2.7
           55.76      11.939   25         1.5   20         2.7
          59.592      15.771   25         1.5   21        2.76
          60.646      16.825   24        1.44   21        2.76
          62.146      18.325   23        1.38   21        2.76
          64.107      20.286   22        1.32   21        2.76
          66.546      22.724   21        1.26   21        2.76
          69.478      25.656   20         1.2   21        2.76
           72.92      29.098   19        1.14   21        2.76
          76.889      33.068   18        1.08   21        2.76
          81.403      37.582   17        1.02   21        2.76
           86.48      42.659   16        0.96   21        2.76
          92.137      48.315   15         0.9   21        2.76
          98.393      54.571   14        0.84   21        2.76
          105.27      61.445   13        0.78   21        2.76
          112.78      68.956   12        0.72   21        2.76
          120.94      77.123   11        0.66   21        2.76
          129.79      85.967   10         0.6   21        2.76
          139.33      95.508    9        0.54   21        2.76
          149.59      105.77    8        0.48   21        2.76
          160.58      116.76    7        0.42   21        2.76
          172.34      128.52    6        0.36   21        2.76
          184.88      141.06    5         0.3   21        2.76
          198.22       154.4    4        0.24   21        2.76
          212.39      168.57    3        0.18   21        2.76
           227.4      183.58    2        0.12   21        2.76
          243.29      199.47    1        0.06   21        2.76
          260.08      216.26    0           0   21        2.76
          291.83      248.01    0           0   22        2.82
          273.91      230.09    1        0.06   22        2.82
          256.89      213.07    2        0.12   22        2.82
          240.75      196.93    3        0.18   22        2.82
          225.46      181.63    4        0.24   22        2.82
          210.99      167.17    5         0.3   22        2.82
          197.34      153.52    6        0.36   22        2.82
          184.48      140.65    7        0.42   22        2.82
          172.38      128.56    8        0.48   22        2.82
          161.03      117.21    9        0.54   22        2.82
           150.4      106.58   10         0.6   22        2.82
          140.49      96.667   11        0.66   22        2.82
          131.26      87.437   12        0.72   22        2.82
           122.7      78.875   13        0.78   22        2.82
          114.78      70.963   14        0.84   22        2.82
           107.5       63.68   15         0.9   22        2.82
          100.83      57.009   16        0.96   22        2.82
          94.754      50.933   17        1.02   22        2.82
          89.253      45.432   18        1.08   22        2.82
          84.311       40.49   19        1.14   22        2.82
          79.911       36.09   20         1.2   22        2.82
          76.036      32.215   21        1.26   22        2.82
          72.669      28.848   22        1.32   22        2.82
          69.796      25.974   23        1.38   22        2.82
          67.398      23.577   24        1.44   22        2.82
          65.463      21.641   25         1.5   22        2.82
          73.317      29.496   25         1.5   23        2.88
          76.138      32.317   24        1.44   23        2.88
          79.435      35.614   23        1.38   23        2.88
          83.223      39.402   22        1.32   23        2.88
          87.517      43.696   21        1.26   23        2.88
          92.334      48.512   20         1.2   23        2.88
          97.689      53.867   19        1.14   23        2.88
           103.6      59.777   18        1.08   23        2.88
          110.08      66.258   17        1.02   23        2.88
          117.15      73.327   16        0.96   23        2.88
          124.82      81.001   15         0.9   23        2.88
          133.12      89.299   14        0.84   23        2.88
          142.06      98.237   13        0.78   23        2.88
          151.66      107.83   12        0.72   23        2.88
          161.93      118.11   11        0.66   23        2.88
           172.9      129.08   10         0.6   23        2.88
          184.59      140.76    9        0.54   23        2.88
             197      153.18    8        0.48   23        2.88
          210.18      166.35    7        0.42   23        2.88
          224.12       180.3    6        0.36   23        2.88
          238.86      195.04    5         0.3   23        2.88
          254.41      210.59    4        0.24   23        2.88
          270.79      226.97    3        0.18   23        2.88
          288.03      244.21    2        0.12   23        2.88
          306.14      262.32    1        0.06   23        2.88
          325.15      281.33    0           0   23        2.88
           359.9      316.07    0           0   24        2.94
          339.84      296.02    1        0.06   24        2.94
          320.68      276.86    2        0.12   24        2.94
          302.39      258.57    3        0.18   24        2.94
          284.96      241.13    4        0.24   24        2.94
          268.35      224.53    5         0.3   24        2.94
          252.56      208.74    6        0.36   24        2.94
          237.57      193.75    7        0.42   24        2.94
          223.35      179.53    8        0.48   24        2.94
          209.89      166.07    9        0.54   24        2.94
          197.17      153.35   10         0.6   24        2.94
          185.17      141.35   11        0.66   24        2.94
          173.87      130.05   12        0.72   24        2.94
          163.26      119.43   13        0.78   24        2.94
          153.31      109.49   14        0.84   24        2.94
          144.01      100.19   15         0.9   24        2.94
          135.35      91.524   16        0.96   24        2.94
           127.3      83.474   17        1.02   24        2.94
          119.84      76.023   18        1.08   24        2.94
          112.98      69.154   19        1.14   24        2.94
          106.67      62.851   20         1.2   24        2.94
          100.92      57.098   21        1.26   24        2.94
          95.701      51.879   22        1.32   24        2.94
          91.001       47.18   23        1.38   24        2.94
          86.806      42.984   24        1.44   24        2.94
          83.099      39.278   25         1.5   24        2.94
          94.745      50.924   25         1.5   25           3
          99.335      55.514   24        1.44   25           3
          104.43      60.605   23        1.38   25           3
          110.03      66.211   22        1.32   25           3
          116.17      72.347   21        1.26   25           3
          122.85      79.028   20         1.2   25           3
          130.09       86.27   19        1.14   25           3
          137.91      94.088   18        1.08   25           3
          146.32       102.5   17        1.02   25           3
          155.33      111.51   16        0.96   25           3
          164.98      121.15   15         0.9   25           3
          175.26      131.43   14        0.84   25           3
          186.19      142.37   13        0.78   25           3
           197.8      153.98   12        0.72   25           3
           210.1      166.28   11        0.66   25           3
          223.11      179.29   10         0.6   25           3
          236.84      193.02    9        0.54   25           3
          251.31      207.49    8        0.48   25           3
          266.54      222.72    7        0.42   25           3
          282.55      238.73    6        0.36   25           3
          299.36      255.53    5         0.3   25           3
          316.97      273.15    4        0.24   25           3
          335.42       291.6    3        0.18   25           3
          354.72       310.9    2        0.12   25           3
          374.89      331.07    1        0.06   25           3
          395.94      352.12    0           0   25           3

Warning

We are aware of an unexpected behaviour in PyXspec v2.1.5 where steppar() outputs can spill over into the next cell’s output, particularly when using Jupyter’s ‘run all’ option. Pausing Python’s execution for a few seconds after the steppar call is a crude workaround.

Examining steppar output as a contour plot#

The result of our steppar() run can be understood more clearly by plotting confidence contours.

XSPEC’s (and thus PyXspec’s) default \(\Delta\chi^2\) contour levels are:

  1. 2.30 [\(1\sigma\); 68.3%]

  2. 4.61 [90%]

  3. 9.21 [99%]

The stated confidence levels are valid for a two degree of freedom (i.e. parameter) contour plot.

The contour plotting command we’re about to use expects contour levels to be input as \(\Delta\chi^2\) values, so if we, for instance, want to specify which contours are calculated as confidence levels in fraction/percentage form, we need to perform a quick calculation.

To infer a confidence level (or inversely a p-value) from a \(\chi^2\)-distribution, we have to inverse the cumulative distribution function (CDF). To make this a little simpler, we can just use SciPy’s implementation of the \(\chi^2\)-distribution, and call the ppf(...) method (standing for “percent point function”).

As we want to plot these contours and label them with their confidence levels, we store our chosen percentiles in a dictionary, with keys ready to be used in the legend of the figure we’re about to construct.

The df=2 argument specifies that we want to calculate the \(\Delta\chi^2\) values for a two degree of freedom distribution – this is because we’re calculating a confidence region for both parameters we investigated with steppar():

cont_conf_perc = {r"$1\sigma$": 0.6826, r"$2\sigma$": 0.9554, r"$3\sigma$": 0.9973}

cont_chisq = chi2.ppf(list(cont_conf_perc.values()), df=2).round(2)
cont_chisq
array([ 2.3 ,  6.22, 11.83])

Note

If you wish to calculate \(\Delta\chi^{2}\) values from percentage confidence levels to pass to an XSPEC error() call, remember to set df=1. When you’re using error() to calculate parameter uncertainties, you are not calculating a joint confidence region, no matter how many parameters you told error() to explore.

Now we use PyXspec’s Plot manager to prepare all the information required to create a contour plot using matplotlib. By default XSPEC will include a probability density image as a backdrop to its contour plots, but as we don’t require that for our purposes, we turn it off.

The command we pass to Plot specifies the number of contours, and their levels; as we don’t manually specify a minimum fit statistic (the first argument), the command begins with “,,”.

xs.Plot.addCommand("image off")

xs.Plot(f"contour ,,{len(cont_chisq)},{','.join(cont_chisq.astype(str))}")
xs.Plot.delCommand(1)

steppar_plot_data = {
    "nh": xs.Plot.x(),
    "powerlaw_ind": xs.Plot.y(),
    "contour_height": xs.Plot.z(),
    "contour_level": xs.Plot.contourLevels(),
    "x_label": xs.Plot.labels()[0],
    "y_label": xs.Plot.labels()[1],
}

# Store the current fit statistic value
cur_fit_stat = xs.Fit.statistic

Now that PyXspec has done all the hard work for us, we can use the information we just retrieved to make a nice contour plot:

Hide code cell source

#
plt.figure(figsize=(5.5, 5.5))
plt.minorticks_on()
plt.tick_params(which="both", direction="in", right=True, top=True)

cont_obj = plt.contour(
    steppar_plot_data["nh"],
    steppar_plot_data["powerlaw_ind"],
    steppar_plot_data["contour_height"],
    steppar_plot_data["contour_level"],
    cmap="rainbow",
)
plt.clabel(cont_obj)

plt.xlabel(steppar_plot_data["x_label"], fontsize=15)
plt.ylabel(steppar_plot_data["y_label"], fontsize=15)

fit_point_obj = plt.plot(
    abs_pl_mod.TBabs.nH.values[0],
    abs_pl_mod.powerlaw.PhoIndex.values[0],
    "+",
    color="black",
    markersize=15,
    markeredgewidth=0.8,
)

plt.axvline(
    abs_pl_mod.TBabs.nH.values[0], color="black", linestyle="solid", linewidth=1.2
)
plt.axhline(
    abs_pl_mod.powerlaw.PhoIndex.values[0],
    color="black",
    linestyle="solid",
    linewidth=1.2,
)

cont_handles = cont_obj.legend_elements()[0]

leg_labels = ["Fit result"] + list(cont_conf_perc.keys())
leg_handles = fit_point_obj + cont_handles

plt.legend(leg_handles, leg_labels, fontsize=14, loc=4)

plt.tight_layout()
plt.show()
../../../_images/cda6597878167fe96099c4a083c9780ccfda66cbdbab78837311b10e88ada282.png

5. Flux calculation#

What else can we do with a model fit?

One thing is to derive the flux of the model – the data by themselves only give the instrument-dependent count rate. The model, on the other hand, is an estimate of the true spectrum emitted by the astrophysical object. In PyXspec, the model is defined in physical units independent of the instrument.

Calling the calcFlux() method#

The calcFlux() method of the model manager AllModels (AllModels is the way of operating on all Model objects in the same way as AllData on all Spectrum objects) integrates the current model over an energy range specified by the user (2.0–10.0 keV in this case):

xs.AllModels.calcFlux("2.0 10.0")
 Model Flux 0.0035392 photons (2.2324e-11 ergs/cm^2/s) range (2.0000 - 10.000 keV)

From that calculation we can see that the energy flux is \({\sim}2.2 \times 10^{-11} \: \rm{erg}\:\rm{cm}^{-2}\:s^{-1}\).

When calculating the flux in this manner (i.e. not using the method discussed in the next subsection), we can retrieve the current value from the flux attribute of the spectrum object:

exo_me_spec.flux[0]
2.232356097423783e-11

Note that calcFlux() will integrate only within the energy range of the current response matrix. If the model flux outside this energy range is desired - in effect, an extrapolation beyond the data - then the setEnergies() method should be used.

This method defines a set of energies on which the models will be calculated. The resulting models are then remapped onto the response energies for convolution with the response matrix.

For example, if we want to know the flux of our model in the ROSAT PSPC band of 0.2–2.0 keV, we enter:

xs.AllModels.setEnergies("extend", "low,0.2,100")
xs.AllModels.calcFlux("0.2 2.0")
Models will use response energies extended to:
   Low:  0.2 in 100 log bins

Fit statistic  : Chi-Squared                   43.82     using 45 bins.

Test statistic : Chi-Squared                   43.82     using 45 bins.
 Null hypothesis probability of 3.94e-01 with 42 degrees of freedom
 Current data and model not fit yet.
 Model Flux 0.0043107 photons (8.8204e-12 ergs/cm^2/s) range (0.20000 - 2.0000 keV)

The energy flux, at \({\sim}8.8\times10^{-12} \: \rm{erg}\:\rm{cm}^{-2}\:s^{-1}\) is lower in this band, but the photon flux is higher.

Model energies can be reset to the response energies using xs.AllModels.setEnergies("reset").

Using the cflux model component to calculate flux value and uncertainty#

Calculating the flux is not usually enough, we want its uncertainty as well. The best way to do this is to make use of the cflux model. Suppose further that what we really want is the unabsorbed flux (i.e. what we think the object is emitting prior to the wider Universe getting in the way) then we redefine the model by:

abs_pl_par_vals = (
    abs_pl_mod(1).values[0],
    abs_pl_mod(2).values[0],
    abs_pl_mod(3).values[0],
)

abs_pl_cflux_mod = xs.Model(
    "tbabs*cflux(powerlaw)",
    setPars=(
        abs_pl_par_vals[0],
        0.2,
        2.0,
        -10.3,
        abs_pl_par_vals[1],
        abs_pl_par_vals[2],
    ),
)
========================================================================
Model TBabs<1>*cflux<2>*powerlaw<3> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    0.542778     +/-  0.0          
   2    2   cflux      Emin       keV      0.200000     frozen
   3    2   cflux      Emax       keV      2.00000      frozen
   4    2   cflux      lg10Flux   cgs      -10.3000     +/-  0.0          
   5    3   powerlaw   PhoIndex            2.23548      +/-  0.0          
   6    3   powerlaw   norm                1.30164E-02  +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared                   51.47     using 45 bins.

Test statistic : Chi-Squared                   51.47     using 45 bins.
 Null hypothesis probability of 1.27e-01 with 41 degrees of freedom
 Current data and model not fit yet.

The Emin and Emax parameters are set to the energy range over which we want the flux to be calculated. We also have to fix the normalization of the powerlaw because the normalization of the model will now be determined by the lg10Flux parameter.

abs_pl_cflux_mod.powerlaw.norm.frozen = True
Fit statistic  : Chi-Squared                   51.47     using 45 bins.

Test statistic : Chi-Squared                   51.47     using 45 bins.
 Null hypothesis probability of 1.50e-01 with 42 degrees of freedom
 Current data and model not fit yet.

Now we run the model fit and calculate the uncertainty on parameter four (lg10Flux):

xs.Fit.perform()
xs.Fit.error("4")
 Warning: renorm - no variable model to allow  renormalization
                                   Parameters
Chi-Squared  |beta|/N    Lvl          1:nH    4:lg10Flux    5:PhoIndex
43.8243      151.428      -3      0.534552      -10.2827       2.23148
43.8215      2.54227      -4      0.542443      -10.2795       2.23541
========================================
 Variances and Principal Axes
                 1        4        5  
 3.3544E-05|  0.0637  -0.8010   0.5953  
 3.1291E-03|  0.5102  -0.4865  -0.7092  
 1.0002E-01|  0.8577   0.3489   0.3776  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   7.440e-02   2.915e-02   3.126e-02
   2.915e-02   1.294e-02   1.424e-02
   3.126e-02   1.424e-02   1.585e-02
------------------------------------

========================================================================
Model TBabs<1>*cflux<2>*powerlaw<3> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    0.542443     +/-  0.272755     
   2    2   cflux      Emin       keV      0.200000     frozen
   3    2   cflux      Emax       keV      2.00000      frozen
   4    2   cflux      lg10Flux   cgs      -10.2795     +/-  0.113748     
   5    3   powerlaw   PhoIndex            2.23541      +/-  0.125881     
   6    3   powerlaw   norm                1.30164E-02  frozen
________________________________________________________________________


Fit statistic  : Chi-Squared                   43.82     using 45 bins.

Test statistic : Chi-Squared                   43.82     using 45 bins.
 Null hypothesis probability of 3.94e-01 with 42 degrees of freedom
 Parameter   Confidence Range (2.706)
     4     -10.4579     -10.0806    (-0.178538,0.198762)

This process tells us that the 90% confidence range (the default when error("<par ID>") is called without further arguments) of the 0.2–2.0 keV unabsorbed flux is \({\sim}3.5 — 8.3 \: \times 10^{-11} \: \rm{erg}\:\rm{cm}^{-2}\:s^{-1}\).

Usefully, we can also programmatically retrieve the flux value and just-calculated confidence interval. As cflux is just another component model, we can access its parameters in the same way we would any other:

cur_flux = Quantity(10 ** abs_pl_cflux_mod.cflux.lg10Flux.values[0], "erg cm^-2 s^-1")
cur_flux
\[5.2554855 \times 10^{-11} \; \mathrm{\frac{erg}{s\,cm^{2}}}\]
cur_flux_conf_inter = 10 ** np.array(abs_pl_cflux_mod.cflux.lg10Flux.error[:2])
cur_flux_conf_inter = Quantity(cur_flux_conf_inter, "erg cm^-2 s^-1")
cur_flux_conf_inter
\[[3.4839721 \times 10^{-11},~8.3056757 \times 10^{-11}] \; \mathrm{\frac{erg}{s\,cm^{2}}}\]

6. Testing alternative spectral models#

The absorbed power law fit, as we’ve remarked, is good, and the parameters are constrained. However, unless the purpose of our investigation is merely to measure a photon index, it’s a good idea to check whether alternative models can fit the data just as well.

We also should derive upper limits on components such as iron emission lines and additional continua, which, although not evident in the data nor required for a good fit, are nevertheless important to constrain – though we’ll get to that in Section 7.

Absorbed blackbody model#

First, let’s try an absorbed blackbody:

abs_bb_mod = xs.Model("tbabs*bb")
xs.Fit.perform()
========================================================================
Model TBabs<1>*bbody<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    1.00000      +/-  0.0          
   2    2   bbody      kT         keV      3.00000      +/-  0.0          
   3    2   bbody      norm                1.00000      +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared              3.375927e+09     using 45 bins.

Test statistic : Chi-Squared              3.375927e+09     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 42 degrees of freedom
 Current data and model not fit yet.
                                   Parameters
Chi-Squared  |beta|/N    Lvl          1:nH          2:kT        3:norm
1534.86      63.2544       0      0.338183       3.01571   0.000673480
1523.38      111647        0      0.161649       2.96538   0.000613265
1492.13      170705        0     0.0709727       2.87593   0.000569742
1445.31      204930        0     0.0268499       2.76631   0.000534590
1388.29      227495        0    0.00599150       2.64726   0.000503786
1324.83      244672        0    0.00114251       2.52385   0.000475565
1254.75      259313        0   2.68036e-05       2.39831   0.000449173
1178.12      272733        0   1.09316e-05       2.27155   0.000424348
1094.73      285233        0   3.78841e-06       2.14399   0.000401001
1004.43      296655        0   6.15032e-07       2.01591   0.000379132
907.174      306551        0   2.67839e-07       1.88760   0.000358788
803.296      314244        0   1.18574e-07       1.75950   0.000340062
693.902      318851        0   5.57470e-08       1.63237   0.000323098
581.452      319356        0   4.16219e-09       1.50754   0.000308105
470.506      314775        0   1.58837e-09       1.38738   0.000295357
368.152      304507        0   5.89385e-10       1.27564   0.000285161
282.873      288791        0   2.09421e-10       1.17746   0.000277735
220.712      269031        0   6.50669e-11       1.09775   0.000272993
181.275      247485        0   8.88206e-12       1.03846   0.000270428
158.686      226446        0   3.18562e-12      0.997325   0.000269295
146.336      207545        0   7.66588e-13      0.969936   0.000268951
139.675      191524        0   2.25499e-13      0.952241   0.000268959
135.933      178966        0   1.01576e-13      0.940689   0.000269090
133.569      169442        0   4.54874e-14      0.933018   0.000269407
132.099      159951        0   2.04889e-14      0.926844   0.000269436
130.474      155792        0   9.03629e-15      0.921170   0.000269954
129.487      144815        0   1.40881e-15      0.919024   0.000270668
127.913      133035        0   4.78915e-16      0.916484   0.000272258
126.278      108070        0   9.78465e-17      0.913262   0.000274380
125.939      74833.7       0   3.56453e-17      0.911866   0.000274746
***Warning: Zero alpha-matrix diagonal element for parameter 1
 Parameter 1 is pegged at 3.56453e-17 due to zero or negative pivot element, likely
 caused by the fit being insensitive to the parameter.
124.393      102930        0   3.56453e-17      0.902731   0.000276864
123.808      48243.1      -1   3.56453e-17      0.893755   0.000278515
123.775      4434.48      -2   3.56453e-17      0.891028   0.000278618
123.773      92.193       -3   3.56453e-17      0.890376   0.000278601
***Warning: Zero alpha-matrix diagonal element for parameter 1
 Parameter 1 is pegged at 3.56453e-17 due to zero or negative pivot element, likely
 caused by the fit being insensitive to the parameter.
123.773      3.42057      -3   3.56453e-17      0.890224   0.0002
78596
==============================
 Variances and Principal Axes
                 2        3  
 2.2371E-11| -0.0000   1.0000  
 2.8685E-04|  1.0000   0.0000  
------------------------------

========================
  Covariance Matrix
        1           2   
   2.869e-04   9.352e-09
   9.352e-09   2.268e-11
------------------------

========================================================================
Model TBabs<1>*bbody<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    3.56453E-17  +/-  -1.00000     
   2    2   bbody      kT         keV      0.890224     +/-  1.69367E-02  
   3    2   bbody      norm                2.78596E-04  +/-  4.76190E-06  
________________________________________________________________________


Fit statistic  : Chi-Squared                  123.77     using 45 bins.

Test statistic : Chi-Squared                  123.77     using 45 bins.
 Null hypothesis probability of 5.42e-10 with 42 degrees of freedom
78596
==============================
 Variances and Principal Axes
                 2        3  
 2.2371E-11| -0.0000   1.0000  
 2.8685E-04|  1.0000   0.0000  
------------------------------

========================
  Covariance Matrix
        1           2   
   2.869e-04   9.352e-09
   9.352e-09   2.268e-11
------------------------

========================================================================
Model TBabs<1>*bbody<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    3.56453E-17  +/-  -1.00000     
   2    2   bbody      kT         keV      0.890224     +/-  1.69367E-02  
   3    2   bbody      norm                2.78596E-04  +/-  4.76190E-06  
________________________________________________________________________


Fit statistic  : Chi-Squared                  123.77     using 45 bins.

Test statistic : Chi-Squared                  123.77     using 45 bins.
 Null hypothesis probability of 5.42e-10 with 42 degrees of freedom

Note that the fit process has displayed a warning about the first parameter and its estimated error is -1.

Unsurprisingly, this is a bad sign! It indicates that the fit is unable to constrain the parameter, and it should be considered indeterminate. We can usually interpret this as meaning that the model is not appropriate.

One thing to check in this case is that the model component has any contribution within the energy range being calculated.

The black body fit is obviously not a good one. Not only is \(\chi^2\) large, but the best-fitting N\(_{\rm H}\) is indeterminate.

When diagnosing a seemingly poor model fit, it is often useful to take a look at the residuals (like we already did for the absorbed power law model). To that end, we once again ask PyXspec to provide the necessary plotting data:

xs.Plot("data resid")

fit_bb_plot_data = {
    "energy": np.array(xs.Plot.x(plotWindow=1)),
    "energy_delta": np.array(xs.Plot.xErr(plotWindow=1)),
    "rate": np.array(xs.Plot.y(plotWindow=1)),
    "rate_err": np.array(xs.Plot.yErr(plotWindow=1)),
    "model": np.array(xs.Plot.model(plotWindow=1)),
    "residual": np.array(xs.Plot.y(plotWindow=2)),
    "residual_err": np.array(xs.Plot.yErr(plotWindow=2)),
}

fit_bb_plot_data["energy_step"] = np.append(
    fit_bb_plot_data["energy"] - fit_bb_plot_data["energy_delta"],
    fit_bb_plot_data["energy"][-1] + fit_bb_plot_data["energy_delta"][-1],
)

Now we plot the data, and inspection of the residuals provides another confirmation of our belief that the absorbed blackbody model is not a good choice. The pronounced wave-like shape is indicative of a bad choice of overall continuum:

plot_fit_residual_spec(
    fit_bb_plot_data,
    inst_name="EXOSAT-ME",
    mod_expr=abs_bb_mod.expression,
    sp_color="darkgreen",
    res_color="darkgreen",
    mod_color="darkgrey",
)
../../../_images/3cb312136469b4bf62e1ed267084a7bf675cbc41a09d5054c9e1f31a80b34067.png

Absorbed thermal bremsstrahlung model#

Let’s try thermal bremsstrahlung next, following the same procedure we did for the absorbed blackbody in the last subsection.

First, we define a model instance and run a fit:

abs_br_mod = xs.Model("tbabs*brems")
xs.Fit.perform()
========================================================================
Model TBabs<1>*bremss<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    1.00000      +/-  0.0          
   2    2   bremss     kT         keV      7.00000      +/-  0.0          
   3    2   bremss     norm                1.00000      +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared              4.545115e+07     using 45 bins.

Test statistic : Chi-Squared              4.545115e+07     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 42 degrees of freedom
 Current data and model not fit yet.
                                   Parameters
Chi-Squared  |beta|/N    Lvl          1:nH          2:kT        3:norm
104.367      23.8112      -3      0.273915       6.17368    0.00725005
46.6859      16500.6      -4     0.0365477       5.60244    0.00785592
43.1958      5654.35      -5     0.0169395       5.64498    0.00792029
42.3436      3589.54      -6   0.000210932       5.64193    0.00792328
42.3299      3135.34      -7   9.76410e-05       5.64205    0.00792369
42.327       3123.8       -8   4.10602e-05       5.64202    0.00792372
========================================
 Variances and Principal Axes
                 1        2        3  
 1.8452E-08| -0.0015   0.0006   1.0000  
 1.2724E-02|  0.9784   0.2069   0.0013  
 6.6797E-01| -0.2069   0.9784  -0.0009  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   4.079e-02  -1.327e-01   1.365e-04
  -1.327e-01   6.399e-01  -5.630e-04
   1.365e-04  -5.630e-04   5.433e-07
------------------------------------

========================================================================
Model TBabs<1>*bremss<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.10602E-05  +/-  0.201955     
   2    2   bremss     kT         keV      5.64202      +/-  0.799941     
   3    2   bremss     norm                7.92
372E-03  +/-  7.37090E-04  
________________________________________________________________________


Fit statistic  : Chi-Squared                   42.33     using 45 bins.

Test statistic : Chi-Squared                   42.33     using 45 bins.
 Null hypothesis probability of 4.57e-01 with 42 degrees of freedom
372E-03  +/-  7.37090E-04  
________________________________________________________________________


Fit statistic  : Chi-Squared                   42.33     using 45 bins.

Test statistic : Chi-Squared                   42.33     using 45 bins.
 Null hypothesis probability of 4.57e-01 with 42 degrees of freedom

Now we extract the data necessary to plot the fitted spectrum and residuals:

xs.Plot("data resid")

fit_br_plot_data = {
    "energy": np.array(xs.Plot.x(plotWindow=1)),
    "energy_delta": np.array(xs.Plot.xErr(plotWindow=1)),
    "rate": np.array(xs.Plot.y(plotWindow=1)),
    "rate_err": np.array(xs.Plot.yErr(plotWindow=1)),
    "model": np.array(xs.Plot.model(plotWindow=1)),
    "residual": np.array(xs.Plot.y(plotWindow=2)),
    "residual_err": np.array(xs.Plot.yErr(plotWindow=2)),
}

fit_br_plot_data["energy_step"] = np.append(
    fit_br_plot_data["energy"] - fit_br_plot_data["energy_delta"],
    fit_br_plot_data["energy"][-1] + fit_br_plot_data["energy_delta"][-1],
)

Finally, we make a visualization:

plot_fit_residual_spec(
    fit_br_plot_data, inst_name="EXOSAT-ME", mod_expr=abs_br_mod.expression
)
../../../_images/c5e76091c1072abf4016aec3ff01a65a722676e4e72f02004058a9f4fe0839d5.png

It is clear that the Bremsstrahlung model is a better fit than the blackbody – and is as good as the power law – although it shares the low absorption column.

Absorbed power law model [frozen nH]#

With two models that appear to be good fits to the spectrum (absorbed power law and absorbed Bremsstrahlung), it’s time to scrutinize their parameters in more detail.

From the EXOSAT database on HEASARC, we know that the target in question, 1E1048.1-5937, is almost on the plane of the Galaxy. In fact, the database also provides values for the Galactic N\(_{\rm H}\) based on 21-cm radio observations.

One estimate (though admittedly not the one you will get from the current version of nhtool) puts it at \(4\times10^{22}\) cm\(^{-2}\), which is higher than the 90% confidence upper limit from the power-law fit.

Perhaps, then, the power-law fit is not so good after all. What we can do is fix (freeze in XSPEC terminology) the value of N\(_{\rm H}\) at the Galactic value and refit the power law. Although we won’t get a good fit, the shape of the residuals might give us a clue to what is missing.

We follow a familiar procedure, though here we make sure to freeze the value of the Hydrogen column density at the estimate we’re using:

abs_pl_frz_nh_mod = xs.Model("tbabs*powerlaw")

abs_pl_frz_nh_mod.TBabs.nH = 4.0
abs_pl_frz_nh_mod.TBabs.nH.frozen = True

xs.Fit.perform()
========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    1.00000      +/-  0.0          
   2    2   powerlaw   PhoIndex            1.00000      +/-  0.0          
   3    2   powerlaw   norm                1.00000      +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared              4.859538e+08     using 45 bins.

Test statistic : Chi-Squared              4.859538e+08     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 42 degrees of freedom
 Current data and model not fit yet.

Fit statistic  : Chi-Squared              3.207240e+08     using 45 bins.

Test statistic : Chi-Squared              3.207240e+08     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 42 degrees of freedom
 Current data and model not fit yet.

Fit statistic  : Chi-Squared              3.207240e+08     using 45 bins.

Test statistic : Chi-Squared              3.207240e+08     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 43 degrees of freedom
 Current data and model not fit yet.
                                   Parameters
Chi-Squared  |beta|/N    Lvl    2:PhoIndex        3:norm
1107.58      195.47       -1       1.29283
0.00381578
935.643      40104.6      -1       1.56254    0.00582512
766.041      31426.4      -1       1.80268    0.00873216
622.228      19892.6      -1       2.01612     0.0124867
507.734      12157.1      -1       2.20659     0.0170071
418.397      7544.3       -1       2.37673     0.0221916
416.213      4814.65      -2       3.05221     0.0440337
309.299      7466.95      -3       3.59154     0.0891606
134.291      3400.36      -4       3.57479      0.113292
134.227      66.1577      -5       3.57576      0.112938
134.227      0.0772422    -6       3.57595      0.112962
==============================
 Variances and Principal Axes
                 2        3  
 3.6240E-06| -0.1311   0.9914  
 4.6299E-03|  0.9914   0.1311  
------------------------------

========================
  Covariance Matrix
        1           2   
   4.550e-03   6.011e-04
   6.011e-04   8.308e-05
------------------------

========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.00000      frozen
   2    2   powerlaw   PhoIndex            3.57595      +/-  6.74570E-02  
   3    2   powerlaw   norm                0.112962     +/-  9.11477E-03  
________________________________________________________________________


Fit statistic  : Chi-Squared                  134.23     using 45 bins.

Test statistic : Chi-Squared                  134.23     using 45 bins.
 Null hypothesis probability of 2.58e-11 with 43 degrees of freedom
0.00381578
935.643      40104.6      -1       1.56254    0.00582512
766.041      31426.4      -1       1.80268    0.00873216
622.228      19892.6      -1       2.01612     0.0124867
507.734      12157.1      -1       2.20659     0.0170071
418.397      7544.3       -1       2.37673     0.0221916
416.213      4814.65      -2       3.05221     0.0440337
309.299      7466.95      -3       3.59154     0.0891606
134.291      3400.36      -4       3.57479      0.113292
134.227      66.1577      -5       3.57576      0.112938
134.227      0.0772422    -6       3.57595      0.112962
==============================
 Variances and Principal Axes
                 2        3  
 3.6240E-06| -0.1311   0.9914  
 4.6299E-03|  0.9914   0.1311  
------------------------------

========================
  Covariance Matrix
        1           2   
   4.550e-03   6.011e-04
   6.011e-04   8.308e-05
------------------------

========================================================================
Model TBabs<1>*powerlaw<2> Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.00000      frozen
   2    2   powerlaw   PhoIndex            3.57595      +/-  6.74570E-02  
   3    2   powerlaw   norm                0.112962     +/-  9.11477E-03  
________________________________________________________________________


Fit statistic  : Chi-Squared                  134.23     using 45 bins.

Test statistic : Chi-Squared                  134.23     using 45 bins.
 Null hypothesis probability of 2.58e-11 with 43 degrees of freedom

Then fetching the information necessary to plot a fitted spectrum and residuals:

xs.Plot("data resid")

fit_pl_frz_nh_plot_data = {
    "energy": np.array(xs.Plot.x(plotWindow=1)),
    "energy_delta": np.array(xs.Plot.xErr(plotWindow=1)),
    "rate": np.array(xs.Plot.y(plotWindow=1)),
    "rate_err": np.array(xs.Plot.yErr(plotWindow=1)),
    "model": np.array(xs.Plot.model(plotWindow=1)),
    "residual": np.array(xs.Plot.y(plotWindow=2)),
    "residual_err": np.array(xs.Plot.yErr(plotWindow=2)),
}

fit_pl_frz_nh_plot_data["energy_step"] = np.append(
    fit_pl_frz_nh_plot_data["energy"] - fit_pl_frz_nh_plot_data["energy_delta"],
    fit_pl_frz_nh_plot_data["energy"][-1] + fit_pl_frz_nh_plot_data["energy_delta"][-1],
)

Finally, making a visualization:

plot_fit_residual_spec(
    fit_pl_frz_nh_plot_data,
    inst_name="EXOSAT-ME",
    mod_expr=abs_pl_frz_nh_mod.expression,
)
../../../_images/8f0aa8e60502ebbc5d69614294527bcf8a4d98e26fdc0795388769e7bc7adfef.png

In this version of the absorbed power-law fit, there appears to be an observational surplus of softer photons, perhaps indicating a second continuum component needs to be modeled.

Absorbed power law + blackbody model [frozen nH]#

To investigate this possibility, we can combine what we have with another additive model component; a bbody.

Note that we freeze the temperature parameter of the black body to 2 keV (the canonical temperature for nuclear burning on the surface of a neutron star in a low-mass X-ray binary) using an XSPEC trick that setting the delta for a parameter to zero switches its freeze/thaw status.

We also set the normalization of the component to a small number to start the fit off in a sensible place since we are looking for a small change to the model.

abs_pl_frz_nh_par_vals = (
    abs_pl_frz_nh_mod(1).values[0],
    abs_pl_frz_nh_mod(2).values[0],
    abs_pl_frz_nh_mod(3).values[0],
)

abs_pl_bb_frz_nh_mod = xs.Model(
    "tbabs(powerlaw+bb)",
    setPars=(
        abs_pl_frz_nh_par_vals[0],
        abs_pl_frz_nh_par_vals[1],
        abs_pl_frz_nh_par_vals[2],
        "2.0,0.0",
        1.0e-5,
    ),
)

abs_pl_bb_frz_nh_mod.TBabs.nH.frozen = True
========================================================================
Model TBabs<1>(powerlaw<2> + bbody<3>) Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.00000      +/-  0.0          
   2    2   powerlaw   PhoIndex            3.57595      +/-  0.0          
   3    2   powerlaw   norm                0.112962     +/-  0.0          
   4    3   bbody      kT         keV      2.00000      frozen
   5    3   bbody      norm                1.00000E-05  +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared                  131.04     using 45 bins.

Test statistic : Chi-Squared                  131.04     using 45 bins.
 Null hypothesis probability of 2.41e-11 with 41 degrees of freedom
 Current data and model not fit yet.

Fit statistic  : Chi-Squared                  131.04     using 45 bins.

Test statistic : Chi-Squared                  131.04     using 45 bins.
 Null hypothesis probability of 4.38e-11 with 42 degrees of freedom
 Current data and model not fit yet.

We run the fit of this new two-continua-component model:

xs.Fit.perform()
                                   Parameters
Chi-Squared  |beta|/N    Lvl    2:PhoIndex        3:norm        5:norm
129.066      53855.5      -3       4.47679      0.198877   0.000244340
90.8792      7260.12      -4       4.87139      0.317929   0.000225711
69.2353      84957.5      -5       4.86527      0.350685   0.000229422
69.2346      556.179      -6       4.86485      0.350373   0.000229320
========================================
 Variances and Principal Axes
                 2        3        5  
 1.1861E-10| -0.0003   0.0008   1.0000  
 7.6889E-05|  0.2988  -0.9543   0.0008  
 2.7853E-02|  0.9543   0.2988   0.0001  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   2.537e-02   7.920e-03   2.545e-06
   7.920e-03   2.557e-03   7.303e-07
   2.545e-06   7.303e-07   4.224e-10
------------------------------------

========================================================================
Model TBabs<1>(powerlaw<2> + bbody<3>) Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.00000      frozen
   2    2   powerlaw   PhoIndex            4.86485      +/-  0.159289     
   3    2   powerlaw   norm                0.350373     +/-  5.05636E-02  
   4    3   bbody      kT         keV      2.00000      frozen
   5    3   bbody      norm                2.29320E-04  +/-  2.05526E-05  
________________________________________________________________________


Fit statistic  : Chi-Squared                   69.23     using 45 bins.

Test statistic : Chi-Squared                   69.23     using 45 bins.
 Null hypothesis probability of 5.12e-03 with 42 degrees of freedom
129.066      53855.5      -3       4.47679      0.198877   0.000244340
90.8792      7260.12      -4       4.87139      0.317929   0.000225711
69.2353      84957.5      -5       4.86527      0.350685   0.000229422
69.2346      556.179      -6       4.86485      0.350373   0.000229320
========================================
 Variances and Principal Axes
                 2        3        5  
 1.1861E-10| -0.0003   0.0008   1.0000  
 7.6889E-05|  0.2988  -0.9543   0.0008  
 2.7853E-02|  0.9543   0.2988   0.0001  
----------------------------------------

====================================
  Covariance Matrix
        1           2           3   
   2.537e-02   7.920e-03   2.545e-06
   7.920e-03   2.557e-03   7.303e-07
   2.545e-06   7.303e-07   4.224e-10
------------------------------------

========================================================================
Model TBabs<1>(powerlaw<2> + bbody<3>) Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    4.00000      frozen
   2    2   powerlaw   PhoIndex            4.86485      +/-  0.159289     
   3    2   powerlaw   norm                0.350373     +/-  5.05636E-02  
   4    3   bbody      kT         keV      2.00000      frozen
   5    3   bbody      norm                2.29320E-04  +/-  2.05526E-05  
________________________________________________________________________


Fit statistic  : Chi-Squared                   69.23     using 45 bins.

Test statistic : Chi-Squared                   69.23     using 45 bins.
 Null hypothesis probability of 5.12e-03 with 42 degrees of freedom

The fit is better than the one with just a power law and the fixed Galactic column, but it is still not good. Thawing the black body temperature and fitting does of course improve the fit, but the power law index becomes even steeper.

Now we have two separate additive models contributing to the continuum fit, we might want to examine their individual contributions to this odd model.

To do that, we’re going to make yet another version of a fitted spectrum visualization. This time though we’re going to drop the residual panel, and retrieve/plot both the overall model, and the curves of the individual model components.

For this to work, we have to tell PyXspec to calculate the plotting information for individual additive model components as well as the usual total model:

xs.Plot.add = True

Now we fetch much the same data as we have previously, but this time also use the Plot.addComp(<additive model ID>) method to retrieve the plotting information for the individual model components:

xs.Plot("data")

fit_pl_bb_plot_data = {
    "energy": np.array(xs.Plot.x()),
    "energy_delta": np.array(xs.Plot.xErr()),
    "rate": np.array(xs.Plot.y()),
    "rate_err": np.array(xs.Plot.yErr()),
    "total_model": np.array(xs.Plot.model()),
    "powerlaw_model": np.array(xs.Plot.addComp(1)),
    "bbody_model": np.array(xs.Plot.addComp(2)),
}

fit_pl_bb_plot_data["energy_step"] = np.append(
    fit_pl_bb_plot_data["energy"] - fit_pl_bb_plot_data["energy_delta"],
    fit_pl_bb_plot_data["energy"][-1] + fit_pl_bb_plot_data["energy_delta"][-1],
)

Now we can visualize the spectrum and the two-additive-model fit:

Hide code cell source

plt.figure(figsize=(7, 4.5))
plt.minorticks_on()
plt.tick_params(which="both", direction="in", top=True, right=True)

# Set the colours for each component we're plotting
cur_sp_color = "navy"
cur_tot_mod_color = "firebrick"
cur_pl_mod_color = "darkorchid"
cur_bb_mod_color = "peru"

# Then set the linestyles
cur_tot_mod_ls = "solid"
cur_pl_mod_ls = "dashed"
cur_bb_mod_ls = (0, (3, 1, 1, 1))

# This adds the spectrum data points to the figure
plt.errorbar(
    fit_pl_bb_plot_data["energy"],
    fit_pl_bb_plot_data["rate"],
    xerr=fit_pl_bb_plot_data["energy_delta"],
    yerr=fit_pl_bb_plot_data["rate_err"],
    fmt="+",
    capsize=1.5,
    label="EXOSAT-ME data",
    color=cur_sp_color,
)

# Total model
plt.stairs(
    fit_pl_bb_plot_data["total_model"],
    fit_pl_bb_plot_data["energy_step"],
    baseline=None,
    fill=False,
    color=cur_tot_mod_color,
    alpha=0.8,
    label="Total model",
    linewidth=1.4,
    linestyle=cur_tot_mod_ls,
)

# Power law model component
plt.stairs(
    fit_pl_bb_plot_data["powerlaw_model"],
    fit_pl_bb_plot_data["energy_step"],
    baseline=None,
    fill=False,
    color=cur_pl_mod_color,
    alpha=0.8,
    label="Power law component",
    linewidth=1.4,
    linestyle=cur_pl_mod_ls,
)

# Bremsstrahlung model component
plt.stairs(
    fit_pl_bb_plot_data["bbody_model"],
    fit_pl_bb_plot_data["energy_step"],
    baseline=None,
    fill=False,
    color=cur_bb_mod_color,
    alpha=0.8,
    label="Blackbody component",
    linewidth=1.4,
    linestyle=cur_bb_mod_ls,
)

# Set the axis scales
plt.xscale("log")
plt.yscale("log")

# Here we tell matplotlib how to format the labels it applies to the ticks on
#  each axis; e.g. should we see 10^2 or 100. This configures the tick labels to
#  avoid scientific notation (i.e. 100 instead of 10^2)
plt.gca().xaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))
plt.gca().xaxis.set_minor_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))

plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda inp, _: "{:g}".format(inp)))

# Add the x and y axis labels
plt.xlabel("Energy [keV]", fontsize=15)
plt.ylabel(
    r"Spectrum [$\frac{\rm{ct}}{\rm{s} \: \rm{cm}^{2} \: \rm{keV}}$]", fontsize=15
)

plt.legend(fontsize=14)

plt.tight_layout()
plt.show()
../../../_images/1a20ec744134cfb7cf335a111d7c1516d04b52125a2b5ead7d7a7fa4e24106fb.png

We see that the black body and the power law have changed places, in that the power law provides the soft photons required by the high absorption, while the black body provides the harder photons. We could continue to search for a plausible, well-fitting model, but the data, with their limited signal-to-noise and energy resolution, probably don’t warrant it (the original investigators published only the power law fit).

7. Deriving upper limits on model parameters#

There is one final useful thing to do with the data – derive an upper limit to the presence of a fluorescent iron emission line. We return to our original model and add a gaussian emission line of fixed energy and width then fit to get:

abs_pl_gauss_em_mod = xs.Model(
    "tbabs*(powerlaw + gaussian)", setPars=(1.0, 1.0, 1.0, "6.4,0.0", "0.1,0.0", 1.0e-4)
)
xs.Fit.perform()
========================================================================
Model TBabs<1>(powerlaw<2> + gaussian<3>) Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    1.00000      +/-  0.0          
   2    2   powerlaw   PhoIndex            1.00000      +/-  0.0          
   3    2   powerlaw   norm                1.00000      +/-  0.0          
   4    3   gaussian   LineE      keV      6.40000      frozen
   5    3   gaussian   Sigma      keV      0.100000     frozen
   6    3   gaussian   norm                1.00000E-04  +/-  0.0          
________________________________________________________________________


Fit statistic  : Chi-Squared              4.860175e+08     using 45 bins.

Test statistic : Chi-Squared              4.860175e+08     using 45 bins.
 Null hypothesis probability of 0.000000e+00 with 41 degrees of freedom
 Current data and model not fit yet.
                                   Parameters
Chi-Squared  |beta|/N    Lvl          1:nH    2:PhoIndex        3:norm        6:norm
483.664      64383.4      -3      0.110472       1.68886    0.00411254   9.08293e-05
125.469      46304.6      -2     0.0227476       1.90209    0.00680329   4.22340e-05
50.1442      16662.9      -2     0.0389320       2.01858    0.00888761   1.46605e-05
45.162       5006.78      -2      0.224913       2.10142     0.0102966   2.94637e-05
43.3161      1787.09      -2      0.350888       2.16724     0.0114416   4.04177e-05
42.3952      886.046      -2      0.446271       2.21703     0.0123715   4.85486e-05
42.2332      475.772      -3      0.681918       2.34339     0.0147578   6.98715e-05
41.2583      2042.35      -4      0.759083       2.38050     0.0158460   7.48366e-05
41.2371      318.981      -5      0.760371       2.37988     0.0158781   7.45651e-05
41.2371      0.267079     -6      0.760949       2.38017     0.0158850   7.46081e-05
==================================================
 Variances and Principal Axes
                 1        2        3        6  
 1.2084E-09| -0.0000  -0.0010   0.0353   0.9994  
 7.8196E-08|  0.0033   0.0175  -0.9992   0.0353  
 3.1636E-03|  0.4412  -0.8973  -0.0142  -0.0003  
 1.2907E-01|  0.8974   0.4411   0.0107   0.0001  
--------------------------------------------------

================================================
  Covariance Matrix
        1           2           3           4   
   1.046e-01   4.983e-02   1.218e-03   7.238e-06
   4.983e-02   2.766e-02   6.488e-04   4.766e-06
   1.218e-03   6.488e-04   1.546e-05   1.046e-07
   7.238e-06   4.766e-06   1.046e-07   2.250e-09
------------------------------------------------

========================================================================
Model TBabs<1>(powerlaw<2> + gaussian<3>) Source No.: 1   Active/On
Model Model Component  Parameter  Unit     Value
 par  comp
   1    1   TBabs      nH         10^22    0.760949     +/-  0.323356     
   2    2   powerlaw   PhoIndex            2.38017      +/-  0.166300     
   3    2   powerlaw   norm                1.58850E-02  +/-  3.93169E-03  
   4    3   gaussian   LineE      keV      6.40000      frozen
   5    3   gaussian   Sigma      keV      0.100000     frozen
   6    3   gaussian   norm                7.46081E-05  +/-  4.74292E-05  
________________________________________________________________________


Fit statistic  : Chi-Squared                   41.24     using 45 bins.

Test statistic : Chi-Squared                   41.24     using 45 bins.
 Null hypothesis probability of 4.60e-01 with 41 degrees of freedom

The energy and width have to be frozen because, in the absence of an obvious line in the data, the fit would be completely unable to converge on meaningful values. Besides, our aim is to see how bright a line at 6.4 keV can be and still not ruin the fit. To do this, we fit first and then use the error command to derive the maximum allowable iron line normalization. We then set the normalization at this maximum value with and, finally, derive the equivalent width. That is:

xs.Fit.error("6")
 Parameter   Confidence Range (2.706)
***Warning: Parameter pegged at hard limit: 0
     6            0  0.000151008    (-7.46043e-05,7.6404e-05)

Note that the true minimum value of the gaussian normalization is less than zero, but the error search stopped when the minimum value hit zero, the “hard” lower limit of the parameter.

abs_pl_gauss_em_mod.gaussian.norm = abs_pl_gauss_em_mod.gaussian.norm.error[1]
Fit statistic  : Chi-Squared                   46.06     using 45 bins.

Test statistic : Chi-Squared                   46.06     using 45 bins.
 Null hypothesis probability of 2.71e-01 with 41 degrees of freedom
 Current data and model not fit yet.

The eqwidth() method takes the component number as its argument:

xs.AllModels.eqwidth("3")
Data group number: 1
Additive group equiv width for Component 3:  0.78255 keV
Additive group equiv width for Component 3:  0.78255 keV

About this notebook#

Author: Keith Arnaud, XSPEC Lead, Associate Research Scientist

Author: David Turner, HEASARC Staff Scientist

Updated On: 2026-06-01

Additional Resources#

Support: XSPEC Helpdesk

Original PyXspec Jupyter Notebooks Repository

Full XSPEC walkthrough dataset

XSPEC plot devices

XSPEC plot types

XSPEC convolution models

XSPEC mixing models

Parallelization settings in PyXspec

XSPEC tclout API reference

XSPEC steppar command

Acknowledgements#

References#

Seward F. D., Charles P. A., Smale A. P. (1986) - A 6 Second Periodic X-Ray Source in Carina