Source code for beast.fitting.pdf2d

# class to generate 1D PDFs for many objects all with
#  spare or full nD likelihoods on the same grid of models
import math
import numpy as np


[docs] class pdf2d: def __init__( self, gridvals_p1, gridvals_p2, nbins_p1, nbins_p2, logspacing_p1=False, logspacing_p2=False, minval_p1=None, maxval_p1=None, minval_p2=None, maxval_p2=None, ): """ Create an object which can be used to efficiently generate a 2D pdf for an observed object Parameters ---------- gridvals_p1, gridvals_p2 : ndarray 1D `float` array with the values of the quantity for all the grid points nbins_p1, nbins_p2 : int number of bins to use for the 1D pdf logspacing_p1, logspacing_p2 : bool, optional whether to use logarithmic spacing for the bins minval_p1, maxval_p1, minval_p2, maxval_p2 : float, optional override the range for the bins. this can be useful to make sure that the pdfs for different runs have the same bins """ # copy values over self.nbins_p1 = nbins_p1 self.nbins_p2 = nbins_p2 self.n_gridvals = len(gridvals_p1) # same as len(gridvals_p2) self.logspacing_p1 = logspacing_p1 self.logspacing_p2 = logspacing_p2 # grab copies of gridvals that can be edited without messing with originals tgridvals_p1 = np.array(gridvals_p1) tgridvals_p2 = np.array(gridvals_p2) # set bin ranges self.min_val_p1 = tgridvals_p1.min() if minval_p1 is None else minval_p1 self.max_val_p1 = tgridvals_p1.max() if maxval_p1 is None else maxval_p1 self.min_val_p2 = tgridvals_p2.min() if minval_p2 is None else minval_p2 self.max_val_p2 = tgridvals_p2.max() if maxval_p2 is None else maxval_p2 # if log spacing requested, make the transformation if logspacing_p1: self.min_val_p1 = math.log10(self.min_val_p1) self.max_val_p1 = math.log10(self.max_val_p1) tgridvals_p1 = np.log10(tgridvals_p1) if logspacing_p2: self.min_val_p2 = math.log10(self.min_val_p2) self.max_val_p2 = math.log10(self.max_val_p2) tgridvals_p2 = np.log10(tgridvals_p2) # set bin widths if self.nbins_p1 > 1: self.bin_delta_p1 = (self.max_val_p1 - self.min_val_p1) / ( self.nbins_p1 - 1 ) else: self.bin_delta_p1 = 1 if self.nbins_p2 > 1: self.bin_delta_p2 = (self.max_val_p2 - self.min_val_p2) / ( self.nbins_p2 - 1 ) else: self.bin_delta_p2 = 1 # set values for the bin middles/edges self.bin_vals_p1 = ( self.min_val_p1 + np.arange(self.nbins_p1) * self.bin_delta_p1 ) self.bin_edges_p1 = ( self.min_val_p1 + (np.arange(self.nbins_p1 + 1) - 0.5) * self.bin_delta_p1 ) self.bin_vals_p2 = ( self.min_val_p2 + np.arange(self.nbins_p2) * self.bin_delta_p2 ) self.bin_edges_p2 = ( self.min_val_p2 + (np.arange(self.nbins_p2 + 1) - 0.5) * self.bin_delta_p2 ) # get PDF bin associated with each grid val pdf_bin_num_p1 = np.digitize(tgridvals_p1, self.bin_edges_p1) pdf_bin_num_p2 = np.digitize(tgridvals_p2, self.bin_edges_p2) # array to hold indices for each bin pdf_bin_indxs = [ [0 for j in range(self.nbins_p2)] for i in range(self.nbins_p1) ] for i in range(self.nbins_p1): for j in range(self.nbins_p2): # find the indicies for the current bin (cur_bin_indxs,) = np.where( (pdf_bin_num_p1 == (i + 1)) & (pdf_bin_num_p2 == (j + 1)) ) # save them pdf_bin_indxs[i][j] = cur_bin_indxs # transform the bin edges back to linear spacing if log spacing # was asked for if logspacing_p1: self.bin_vals_p1 = np.power(10.0, self.bin_vals_p1) self.bin_edges_p1 = np.power(10.0, self.bin_edges_p1) if logspacing_p2: self.bin_vals_p2 = np.power(10.0, self.bin_vals_p2) self.bin_edges_p2 = np.power(10.0, self.bin_edges_p2) self.pdf_bin_indxs = pdf_bin_indxs
[docs] def gen2d(self, gindxs, weights): """ Compute the 2D posterior PDFs based on the nD probabilities Parameters ---------- gindxs : ndarray 1D `int` array with the indxs of the weights in the full model grid weights : ndarray 1D `float` array with the fit probabilities (likelihood*prior) at each grid point Returns ------- vals_2d : ndarray 2D `float` array giving the bin pPDF values """ _tgrid = np.zeros(self.n_gridvals) _tgrid[gindxs] = weights _vals_2d = np.zeros((self.nbins_p1, self.nbins_p2)) for i in range(self.nbins_p1): for j in range(self.nbins_p2): if len(self.pdf_bin_indxs[i][j]) > 0: _vals_2d[i, j] = np.sum(_tgrid[self.pdf_bin_indxs[i][j]]) return _vals_2d