-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1426 from abhisrkckl/bayesian-wip
Bayesian interface for Wideband data (No correlated noise)
- Loading branch information
Showing
10 changed files
with
545 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# %% [markdown] | ||
# # PINT Bayesian Interface Example (Wideband) | ||
|
||
# %% | ||
import corner | ||
import emcee | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
from pint.bayesian import BayesianTiming | ||
from pint.config import examplefile | ||
from pint.fitter import WidebandDownhillFitter | ||
from pint.logging import setup as setup_log | ||
from pint.models import get_model_and_toas | ||
|
||
# %% | ||
# Turn off log messages. They can slow down the processing. | ||
setup_log(level="WARNING") | ||
|
||
# %% | ||
# This is a simulated dataset. | ||
m, t = get_model_and_toas(examplefile("test-wb-0.par"), examplefile("test-wb-0.tim")) | ||
|
||
# %% | ||
# Fit the model to the data to get the parameter uncertainties. | ||
ftr = WidebandDownhillFitter(t, m) | ||
ftr.fit_toas() | ||
m = ftr.model | ||
|
||
# %% | ||
# Now set the priors. | ||
# I am cheating here by setting the priors around the maximum likelihood estimates. | ||
# This is a bad idea for real datasets and can bias the estimates. I am doing this | ||
# here just to make everything finish faster. In the real world, these priors should | ||
# be informed by, e.g. previous (independent) timing solutions, pulsar search results, | ||
# VLBI localization etc. Note that unbounded uniform priors don't work here. | ||
prior_info = {} | ||
for par in m.free_params: | ||
param = getattr(m, par) | ||
param_min = float(param.value - 10 * param.uncertainty_value) | ||
param_max = float(param.value + 10 * param.uncertainty_value) | ||
prior_info[par] = {"distr": "uniform", "pmin": param_min, "pmax": param_max} | ||
|
||
# %% | ||
# Set the EFAC and DMEFAC priors and unfreeze them. | ||
# Don't do this before the fitting step. The fitter doesn't know | ||
# how to deal with noise parameters. | ||
prior_info["EFAC1"] = {"distr": "normal", "mu": 1, "sigma": 0.1} | ||
prior_info["DMEFAC1"] = {"distr": "normal", "mu": 1, "sigma": 0.1} | ||
|
||
m.EFAC1.frozen = False | ||
m.EFAC1.uncertainty_value = 0.01 | ||
m.DMEFAC1.frozen = False | ||
m.DMEFAC1.uncertainty_value = 0.01 | ||
|
||
# %% | ||
# The likelihood function behaves better if `use_pulse_numbers==True`. | ||
bt = BayesianTiming(m, t, use_pulse_numbers=True, prior_info=prior_info) | ||
|
||
# %% | ||
print("Number of parameters = ", bt.nparams) | ||
print("Likelihood method = ", bt.likelihood_method) | ||
|
||
# %% | ||
nwalkers = 25 | ||
sampler = emcee.EnsembleSampler(nwalkers, bt.nparams, bt.lnposterior) | ||
|
||
# %% | ||
# Start the sampler close to the maximul likelihood estimate. | ||
maxlike_params = np.array([param.value for param in bt.params], dtype=float) | ||
maxlike_errors = [param.uncertainty_value for param in bt.params] | ||
start_points = ( | ||
np.repeat([maxlike_params], nwalkers).reshape(bt.nparams, nwalkers).T | ||
+ np.random.randn(nwalkers, bt.nparams) * maxlike_errors | ||
) | ||
|
||
# %% | ||
# ** IMPORTANT!!! ** | ||
# This is used to exclude the following time-consuming steps from the readthedocs build. | ||
# Set this to False while actually using this example. | ||
rtd = True | ||
|
||
# %% | ||
if not rtd: | ||
print("Running emcee...") | ||
chain_length = 1000 | ||
sampler.run_mcmc( | ||
start_points, | ||
chain_length, | ||
progress=True, | ||
) | ||
|
||
samples_emcee = sampler.get_chain(flat=True, discard=100) | ||
|
||
# %% | ||
# Plot the chains to make sure they have converged and the burn-in has been removed properly. | ||
if not rtd: | ||
for idx, param_chain in enumerate(samples_emcee.T): | ||
plt.subplot(bt.nparams, 1, idx + 1) | ||
plt.plot(param_chain) | ||
plt.ylabel(bt.param_labels[idx]) | ||
plt.autoscale() | ||
plt.show() | ||
|
||
# %% | ||
if not rtd: | ||
fig = corner.corner( | ||
samples_emcee, labels=bt.param_labels, quantiles=[0.5], truths=maxlike_params | ||
) | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.