import numpy as np
""" Compute p-value """
from scipy.stats import chi2
from scipy.interpolate import interp1d
[docs]
def p_sigma(dist,df):
"""
Compute p-value from chi2 distribution
Parameters
----------
dist : float
Distance
df : int
Degrees of freedom
Returns
-------
p : float
p-value
"""
ps = np.logspace(-15,0,10000)
#df = 1
chi2s = chi2.isf(ps,df)
p = interp1d(np.sqrt(chi2s),ps, bounds_error=False, fill_value=min(ps))
return 1 - p(dist)
""" Compute mode """
#1D Maximum likelihood value from posterior samples
[docs]
def mode(posterior,bins=30):
"""
Compute mode of a posterior distribution
Parameters
----------
posterior : np.ndarray
Posterior samples
bins : int
Number of bins
Returns
-------
mode : float
Mode of the posterior
"""
bins, param = np.histogram(posterior,bins=bins)
return param[np.argmax(bins)]
[docs]
def modes(posteriors,bins=30):
"""
Compute modes of a set of posterior distributions
Parameters
----------
posterior : np.ndarray
Posterior samples
bins : int
Number of bins
Returns
-------
modes : np.ndarray
Modes of the posteriors
"""
length = np.shape(posteriors)[-1]
modes_c = np.zeros(length)
for i in range(length):
modes_c[i] = mode(posteriors[:,i],bins)
return modes_c
""" Wrap phases around their modes """
[docs]
def wrap_phases(parameters_1,parameters_2,nphases):
"""
Wrap phases around their modes to avoid discontinuities from periodic boundaries
Parameters
----------
parameters_1 : np.ndarray
Posterior samples
parameters_2 : np.ndarray
Posterior samples
nphases : int
Number of phases in the posterior samples.
It is assumed that the first nphases parameters are phases.
Returns
-------
parameters_1_wrap_mod : np.ndarray
Wrapped posterior samples of parameter_1. The phases are wrapped around the modes of parameters_1.
parameters_2_wrap_mod : np.ndarray
Wrapped posterior samples of parameter_2. The phases are wrapped around the modes of parameters_1.
"""
#Wrap phases around their modes
#to avoid discontinuities from periodic boundaries
phases_1 = parameters_1[:,:nphases]
phases_2 = parameters_2[:,:nphases]
mode_1 = modes(phases_1)
mode_2 = modes(phases_2)
phases_1_wrap = np.mod(phases_1 - mode_1 + np.pi,2*np.pi)
phases_2_wrap = np.mod(phases_2 - mode_2 + np.pi,2*np.pi) + mode_2 - mode_1
#Put with rest of parameters
parameters_1_wrap = np.concatenate((phases_1_wrap,parameters_1[:,nphases:]),axis=1)
parameters_2_wrap = np.concatenate((phases_2_wrap,parameters_2[:,nphases:]),axis=1)
mean_1_wrap = np.mean(parameters_1_wrap,axis=0)
mean_2_wrap = np.mean(parameters_2_wrap,axis=0)
#Make sure mean is within 0, 2pi
parameters_1_mod = np.concatenate((np.mod(phases_1_wrap,2*np.pi),parameters_1[:,nphases:]),axis=1)
parameters_2_mod = np.concatenate((np.mod(phases_2_wrap,2*np.pi),parameters_2[:,nphases:]),axis=1)
mean_1_mod = np.mean(parameters_1_mod,axis=0)
mean_2_mod = np.mean(parameters_2_mod,axis=0)
parameters_1_wrap_mod = parameters_1_wrap - mean_1_wrap + mean_1_mod
parameters_2_wrap_mod = parameters_2_wrap - mean_2_wrap + mean_2_mod
return parameters_1_wrap_mod, parameters_2_wrap_mod
[docs]
def wrap_only_phases(phases_1,phases_2):
"""
Wrap phases around their modes to avoid discontinuities from periodic boundaries
Parameters
----------
phases_1 : np.ndarray
Posterior samples of phases
phases_2 : np.ndarray
Posterior samples of phases
Returns
-------
phases_1_wrap : np.ndarray
Wrapped posterior samples of phases_1. The phases are wrapped around the modes of phases_1.
phases_2_wrap_mod : np.ndarray
Wrapped posterior samples of phases_2. The phases are wrapped around the modes of phases_1.
"""
#Wrap phases around their modes
#to avoid discontinuities from periodic boundaries
mode_1 = modes(phases_1)
mode_2 = modes(phases_2)
phases_1_wrap = np.mod(phases_1 - mode_1 + np.pi,2*np.pi)
phases_2_wrap = np.mod(phases_2 - mode_2 + np.pi,2*np.pi) + mode_2 - mode_1
mean_2_wrap = np.mean(phases_2_wrap,axis=0)
#Make sure mean is within 0, 2pi
phases_2_mod = np.mod(phases_2_wrap,2*np.pi)
mean_2_mod = np.mean(phases_2_mod,axis=0)
phases_2_wrap_mod = phases_2_wrap - mean_2_wrap + mean_2_mod
return phases_1_wrap, phases_2_wrap_mod
[docs]
def wrap_phase(phases_1):
"""
Wrap phases around their modes to avoid discontinuities from periodic boundaries
Parameters
----------
phases_1 : np.ndarray
Posterior samples of phases
Returns
-------
phases_1_wrap : np.ndarray
Wrapped posterior samples of phases_1. The phases are wrapped around their modes.
"""
#Wrap phases around their modes
#to avoid discontinuities from periodic boundaries
mode_1 = mode(phases_1)
phases_1_wrap = np.mod(phases_1 - mode_1 + np.pi,2*np.pi)
return phases_1_wrap