Add a background model to your fit¶
Most of the time, the X-ray spectrum is extracted around the source, and
an additional spectrum is extracted further away to get a representative
X-ray background in the vicinity of your observation. With jaxspec
, this
spectrum is automatically loaded as long as it is defined in the header of
your observation.
To include this in your spectral fitting, you should add a BackgroundModel
to your code as follows. The simplest
approach is equivalent to subtract the background to the observed spectrum when performing the fit.
from jaxspec.model.background import SubtractedBackground
fitter = MCMCFitter(model, prior, obs, background_model=SubtractedBackground())
result_bkg_substracted = fitter.fit(num_chains=16, num_warmup=1000, num_samples=5000, mcmc_kwargs={"progress_bar": True})
result_bkg_substracted.plot_ppc()
The SubtractedBackground
simply account for the observed counts without propagating any kind of dispersion, which
is clearly bad when we want to get spectral parameters with a comprehensive error budget. The simplest way to deal with
it is to consider each background bin as a Poisson realisation of a counting process, which is achieved here using
BackgroundWithError
.
from jaxspec.model.background import BackgroundWithError
fitter = MCMCFitter(model, prior, obs, background_model=BackgroundWithError())
result_bkg_with_spread = fitter.fit(num_chains=16, num_warmup=1000, num_samples=5000, mcmc_kwargs={"progress_bar": True})
result_bkg_with_spread.plot_ppc()
The other way to deal with this is to directly fit a Gaussian process on the folded background spectrum to integrate
energy and bins correlations in a very empiric way. This can be done using a GaussianProcessBackground
. The number of
nodes will drive the flexibility of the Gaussian process, and it should always be lower than the number of channels.
from jaxspec.model.background import GaussianProcessBackground
forward = MCMCFitter(model, prior, obs, background_model=GaussianProcessBackground(e_min=0.3, e_max=8, n_nodes=20))
result_bkg_gp = forward.fit(num_chains=16, num_warmup=1000, num_samples=5000, mcmc_kwargs={"progress_bar": True})
result_bkg_gp.plot_ppc()
This is also possible to use a spectral model that will be folded within the instrument background using a SpectralModelBackground
.
from jaxspec.model.background import SpectralModelBackground
spectral_model_background = Powerlaw()
background_prior = {
"powerlaw_1_alpha": dist.Uniform(0, 5),
"powerlaw_1_norm": dist.LogUniform(1e-8, 1e-3),
}
forward = MCMCFitter(model, prior, obs, background_model=SpectralModelBackground(spectral_model_background, background_prior))
result_bkg_spectral = forward.fit(num_chains=16, num_warmup=1000, num_samples=5000, mcmc_kwargs={"progress_bar": True})
result_bkg_spectral.plot_ppc()
We can compare the results for all these background models using the plot_corner_comparison
function.
from jaxspec.analysis.compare import plot_corner_comparison
plot_corner_comparison(
{
"Background with no spread" : result_bkg_substracted,
"Background with spread" : result_bkg_with_spread,
"Gaussian process background" : result_bkg_gp,
"Spectral background" : result_bkg_spectral
}
)