Source code for bxa.sherpa.priors
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
"""
BXA (Bayesian X-ray Analysis) for Sherpa
Copyright: Johannes Buchner (C) 2013-2015
Priors
"""
from math import log10, erf
import numpy
from . import invgauss
[docs]
def create_jeffreys_prior_for(parameter):
"""deprecated name for create_loguniform_prior_for"""
return create_loguniform_prior_for(parameter)
[docs]
def create_gaussian_prior_for(parameter, mean, std):
"""
Use for informed variables.
The Gaussian prior weights by a Gaussian in the parameter. If you
would like the logarithm of the parameter to be weighted by
a Gaussian, create a ancillary parameter (see create_jeffreys_prior_for).
:param parameter: Parameter to create a prior for. E.g. xspowerlaw.mypowerlaw.PhoIndex
:param mean: Mean of the Gaussian
:param std: Standard deviation of the Gaussian
"""
import scipy.stats
lo = parameter.min
hi = parameter.max
rv = scipy.stats.norm(mean, std)
xlo = rv.cdf(lo)
xhi = rv.cdf(hi)
def gauss_transform(x):
return rv.ppf(x * (xhi - xlo) + xlo)
return gauss_transform
[docs]
def prior_from_file(filename, parameter):
"""
Read a custom prior distribution from a file.
The file should have two columns: cumulative probability
and value, in ascii format. The cumulative probability
has to be equally spaced and should exclude 0 and 1.
Returns a sherpa parameter, a list with that parameter inside,
and the prior function.
If the file only constains a single value, that value is returned
along with two empty lists.
"""
dist = numpy.loadtxt(filename)
if numpy.shape(dist) == ():
parameter.val = float(dist)
return float(dist), [], []
distz = numpy.array(list(dist[:, 1]) + [dist[-1,1]]*2)
#deltax = dist[1,0] - dist[0,0]
n = len(dist)
def custom_priorf(x):
assert x >= 0
assert x <= 1
i = int(numpy.floor(x*n))
r = distz[i] + (distz[i + 1] - distz[i]) * (x * n - i)
return r
return parameter, [parameter], [custom_priorf]
[docs]
def create_prior_function(priors = [], parameters = None):
"""
Combine the prior transformations into a single function.
This assumes factorized (independent) priors.
:param priors: individual prior transforms to combine into one function.
If priors is empty, uniform priors are used on all passed parameters
:param parameters: If priors is empty, specify the list of parameters.
Uniform priors will be created for them.
"""
if priors == []:
functions = []
assert parameters is not None, "you need to pass the parameters if you want automatic uniform priors"
thawedparmins = [p.min for p in parameters]
thawedparmaxes = [p.max for p in parameters]
for low, high in zip(thawedparmins, thawedparmaxes):
functions.append(lambda x: x * (high - low) + low)
else:
functions = priors
def prior_function(cube, ndim, nparams):
for i in range(ndim):
cube[i] = functions[i](cube[i])
return prior_function