From bb81835032931d0295f400518044905dcb36873b Mon Sep 17 00:00:00 2001 From: Matthew Pitkin <matthew.pitkin@ligo.org> Date: Thu, 2 Aug 2018 23:16:25 +0100 Subject: [PATCH] radioactive_decay.py: complete example - complete the radioactive decay example to test the Poisson likelihood - refs Monash/tupak!132 --- examples/other_examples/radioactive_decay.py | 69 +++++++++++--------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/examples/other_examples/radioactive_decay.py b/examples/other_examples/radioactive_decay.py index 0767632e0..219f7bc58 100644 --- a/examples/other_examples/radioactive_decay.py +++ b/examples/other_examples/radioactive_decay.py @@ -2,7 +2,7 @@ """ An example of how to use tupak to perform paramater estimation for non-gravitational wave data. In this case, fitting the half-life and -initial radionucleotide number for Carbon 14. +initial radionucleotide number for Lead 214. """ from __future__ import division import tupak @@ -17,56 +17,65 @@ label = 'radioactive_decay' outdir = 'outdir' tupak.utils.check_directory_exists_and_if_not_mkdir(outdir) -NA = 6.02214078e23 # Avagadro's number +# generate a set of counts per minute for Polonium 214 with a half-life of 20 mins +halflife = 20 +N0 = 1.e-19 # initial number of radionucleotides in moles -# generate a set of counts per minute for Carbon 14 with a half-life of -# 5730 years -halflife = 5730. -N0mol = 1. # initial number of radionucleotides in moles -N0 = N0mol * +def decayrate(deltat, halflife, N0): + """ + Get the decay rate of a radioactive substance in a range of time intervals + (in minutes). halflife is in mins. N0 is in moles. + """ + times = np.cumsum(deltat) # get cumulative times + times = np.insert(times, 0, 0.) -# First, we define our "signal model", in this case a simple linear function -def model(time, m, c): - return time * m + c + ln2 = np.log(2.) + NA = 6.02214078e23 # Avagadro's number + rates = (N0*NA*(np.exp(-ln2*(times[0:-1]/halflife)) + - np.exp(-ln2*(times[1:]/halflife)))/deltat) + + return rates -# Now we define the injection parameters which we make simulated data with -injection_parameters = dict(m=0.5, c=0.2) -# For this example, we'll use standard Gaussian noise -sigma = 1 +# Now we define the injection parameters which we make simulated data with +injection_parameters = dict(halflife=halflife, N0=N0) # These lines of code generate the fake data. Note the ** just unpacks the # contents of the injection_parameters when calling the model function. -sampling_frequency = 10 -time_duration = 10 -time = np.arange(0, time_duration, 1/sampling_frequency) -N = len(time) -data = model(time, **injection_parameters) + np.random.normal(0, sigma, N) +sampling_frequency = 1. +time_duration = 30. +time = np.arange(0, time_duration, 1./sampling_frequency) +deltat = np.diff(time) + +rates = decayrate(deltat, **injection_parameters) +# get radioactive counts +counts = np.array([np.random.poisson(rate) for rate in rates]) # We quickly plot the data to check it looks sensible fig, ax = plt.subplots() -ax.plot(time, data, 'o', label='data') -ax.plot(time, model(time, **injection_parameters), '--r', label='signal') +ax.plot(time[0:-1], counts, 'o', label='data') +ax.plot(time[0:-1], decayrate(deltat, **injection_parameters), '--r', label='signal') ax.set_xlabel('time') -ax.set_ylabel('y') +ax.set_ylabel('counts') ax.legend() fig.savefig('{}/{}_data.png'.format(outdir, label)) # Now lets instantiate a version of the Poisson Likelihood, giving it -# the time, data and signal model -likelihood = PoissonLikelihood(time, counts, model) +# the time intervals, counts and rate model +likelihood = PoissonLikelihood(deltat, counts, decayrate) -# From hereon, the syntax is exactly equivalent to other tupak examples -# We make a prior +# Make the prior priors = {} -priors['m'] = tupak.core.prior.Uniform(0, 5, 'm') -priors['c'] = tupak.core.prior.Uniform(-2, 2, 'c') +priors['halflife'] = tupak.core.prior.LogUniform(1e-5, 1e5, 'halflife', + latex_label='$t_{1/2}$') +priors['N0'] = tupak.core.prior.LogUniform(1e-25, 1e-10, 'N0', + latex_label='$N_0$') # And run sampler result = tupak.run_sampler( likelihood=likelihood, priors=priors, sampler='dynesty', npoints=500, - walks=10, injection_parameters=injection_parameters, outdir=outdir, - label=label) + nlive=1000, walks=10, injection_parameters=injection_parameters, + outdir=outdir, label=label) result.plot_corner() -- GitLab