From 97e20483bced198c7dc7c3e6a9d0dca698d034c5 Mon Sep 17 00:00:00 2001 From: Gregory Ashton <gregory.ashton@ligo.org> Date: Fri, 11 May 2018 15:42:57 +1000 Subject: [PATCH] Adds an exampe of how to use tupak for non-GW PE --- .../other_examples/alternative_likelihoods.py | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 examples/other_examples/alternative_likelihoods.py diff --git a/examples/other_examples/alternative_likelihoods.py b/examples/other_examples/alternative_likelihoods.py new file mode 100644 index 000000000..74acbc277 --- /dev/null +++ b/examples/other_examples/alternative_likelihoods.py @@ -0,0 +1,92 @@ +#!/bin/python +""" +An example of how to use tupak to perform paramater estimation for +non-gravitational wave data +""" +from __future__ import division +import tupak +import numpy as np +import matplotlib.pyplot as plt + +# A few simple setup steps +tupak.utils.setup_logger(log_level="info") +label = 'test' +outdir = 'outdir' + + +# Here is minimum requirement for a Likelihood class needed to run tupak. In +# this case, we setup a GaussianLikelihood, which needs to have a +# log_likelihood and noise_log_likelihood method. Note, in this case we make +# use of the `tupak` waveform_generator to make the signal (more on this later) +# But, one could make this work without the waveform generator. + +class GaussianLikelihood(): + def __init__(self, x, y, waveform_generator): + self.x = x + self.y = y + self.N = len(x) + self.waveform_generator = waveform_generator + + def log_likelihood(self): + sigma = 1 + res = self.y - self.waveform_generator.time_domain_strain() + return -0.5 * (np.sum((res / sigma)**2) + + self.N*np.log(2*np.pi*sigma**2)) + + def noise_log_likelihood(self): + sigma = 1 + return -0.5 * (np.sum((self.y / sigma)**2) + + self.N*np.log(2*np.pi*sigma**2)) + + +# Here we define our signal model, in this case a very basic trig. function +def model(time, A, P): + return A*np.sin(2*np.pi*time/P) + + +# Here we define the injection parameters which we make simulated data with +injection_parameters = dict(A=1.5, P=10) + +# For this example, we'll use standard Gaussian noise +sigma = 1 + +# These lines of code generate the fake data. Note the ** just unpacks the +# contents of the injection_paramsters when calling the model function. +sampling_frequency = 10 +time_duration = 100 +time = np.arange(0, time_duration, 1/sampling_frequency) +N = len(time) +data = model(time, **injection_parameters) + np.random.normal(0, sigma, N) + +# We quickly plot the data to check it looks sensible +fig, ax = plt.subplots() +ax.plot(time, data) +ax.plot(time, model(time, **injection_parameters), '--r') +fig.savefig('{}/data.png'.format(outdir)) + +# Here, we make a `tupak` waveform_generator. In this case, of course, the +# name doesn't make so much sense. But essentially this is an objects that +# can generate a signal. We give it information on how to make the time series +# and the model() we wrote earlier. +waveform_generator = tupak.waveform_generator.WaveformGenerator( + sampling_frequency=sampling_frequency, time_duration=time_duration, + time_domain_source_model=model) + + +# Now lets instantiate a version of out Likelihood, giving it the time, data +# and waveform_generator +likelihood = GaussianLikelihood(time, data, waveform_generator) + +# From hereon, the syntax is exactly equivalent to other tupak examples +# We make a prior +priors = {} +priors['A'] = tupak.prior.Uniform(0, 5, 'A') +priors['P'] = tupak.prior.Uniform(0, 20, 'P') + +# And run sampler +result = tupak.sampler.run_sampler( + likelihood=likelihood, priors=priors, sampler='dynesty', npoints=1000, + walks=10, injection_parameters=injection_parameters, outdir=outdir, + label=label, use_ratio=False) +result.plot_corner() +print(result) -- GitLab