Source code for GWForge.population.user_defined
"""User-defined population distributions from tabulated (xx, yy) priors.
This lets people feed a population produced by an external population-synthesis
code straight into GWForge, without shoehorning it into a parameterised model.
The distribution of any parameter is supplied as a support array ``xx`` and a
(possibly unnormalised) probability-density array ``yy`` in a JSON file with the
structure::
{
"mass_1_source": {"xx": [...], "yy": [...]},
"mass_ratio": {"xx": [...], "yy": [...]},
"a_1": {"xx": [...], "yy": [...]}
}
Each ``(xx, yy)`` pair is turned into a :class:`bilby.core.prior.Interped`
prior, which normalises ``yy`` and samples via inverse-CDF.
"""
import json
import numpy
import bilby
[docs]
def get_xx_yy_from_population_priors(file, parameter):
"""Extract the ``xx`` (support) and ``yy`` (density) arrays for a parameter.
Parameters
----------
file : str
Path to the JSON file of population priors, structured as
``{parameter: {"xx": [...], "yy": [...]}}``.
parameter : str
The parameter name to extract (e.g. ``'mass_1_source'``, ``'mass_ratio'``,
``'a_1'``).
Returns
-------
xx : numpy.ndarray
The support (x-values) of the prior distribution.
yy : numpy.ndarray
The probability density (y-values) of the prior distribution.
"""
with open(file, "r") as f:
priors = json.load(f)
if parameter not in priors:
raise KeyError(
"Parameter '{}' not found in {}. Available: {}".format(
parameter, file, sorted(priors)
)
)
xx = numpy.asarray(priors[parameter]["xx"], dtype=float)
yy = numpy.asarray(priors[parameter]["yy"], dtype=float)
return xx, yy
[docs]
def interped_prior_from_file(file, parameter, name=None):
"""Build a :class:`bilby.core.prior.Interped` prior from a tabulated prior.
Parameters
----------
file : str
Path to the JSON population-priors file.
parameter : str
Key to read from the file.
name : str, optional
Name to give the resulting prior. Defaults to ``parameter``.
Returns
-------
bilby.core.prior.Interped
"""
xx, yy = get_xx_yy_from_population_priors(file, parameter)
if numpy.any(yy < 0):
raise ValueError(
"Probability density 'yy' for '{}' contains negative values".format(
parameter
)
)
return bilby.core.prior.Interped(
xx=xx,
yy=yy,
minimum=numpy.min(xx),
maximum=numpy.max(xx),
name=name or parameter,
)