How To Search for QPOs with BayesPSD

This notebook is a demonstration for how to use the code in this package to search for quasi-periodic oscillations (QPOs) in X-ray data of bursts.

This code requires

  • python 2.7 or later (not really tested with python 3)
  • numpy
  • scipy
  • matplotlib

Recommended

Basics

The module contains both the code to do Bayesian inference on bursty time series, as well as some basic class definitions that are useful for time series analysis in general, and for Fermi/GBM data in particular.

Let's start with a simple time series in a data file. This is actually a magnetar bursts from a source called SGR J1550-5418, but that's not important right now. I've made things easy for you here: the data are individual photon events and energies only from the part of the observation where the burst was observed. We'll have a look at more complicated data and how to automate the steps outlined below later.

For now, let's import some code and load the time series.


In [1]:
%matplotlib inline
import matplotlib.pyplot as plt

## this is just to make plots prettier
## comment out if you don't have seaborn
import seaborn as sns 
sns.set()
########################################

import numpy as np

NOTE: You need to have the directory where you saved the BayesPSD code in your PYTHONPATH variable for the following to work! If you haven't set your variable externally, you can do it in the following way:


In [2]:
import sys
sys.path.append("/Users/danielahuppenkothen/work/repositories/BayesPSD")

Be aware that you need to replace the directory structure with your own, and that you need to add the path to the directory in which the BayesPSD folder is located. In my case, that's in my repositories folder in my work directory on my home folder, but it will be different for you! Also, when importing below, bayespsd needs to be written exactly as the name of the folder (it's case sensitive!).

Now we can import functions and classes from that package:


In [3]:
from BayesPSD import Lightcurve, PowerSpectrum

The data are saved in a simple text file:


In [4]:
## the directory where we've stored the data
datadir = "../data/" 

data = np.loadtxt(datadir+"090122283_+071.87300_eventfile.dat")
print("Data shape : " + str(data.shape))


Data shape : (13001, 2)

The result is a numpy-array with 130001 rows and 2 columns. Each row is a photon, the first column contains the photon arrival times, the second column the energies.

For now, let's not care about the energies (don't worry, we'll get back to that later!). Let's make a light curve and plot it:


In [5]:
timestep = 0.001 ##the time resolution for the light curve
lc = Lightcurve(data[:,0], timestep=timestep)

plt.figure()
plt.plot(lc.time, lc.counts)


Out[5]:
[<matplotlib.lines.Line2D at 0x111e80e10>]

There you go, it's a burst. The class Lightcurve has several useful attributes. Have a look at the code if you're interested. It works both with time tagges arrival times (in which case it takes a value timestep for the output time resolution) or with counts, in which case you should use the keyword times for time bins and counts for the counts per bin.

The next step is to make a periodogram. This is easy if we already have a Lightcurve object. Note that we'll use loglog for the figure rather than plot, because the spectrum is better plotted on a log-log scale.


In [6]:
ps = PowerSpectrum(lc, norm="leahy")

plt.loglog(ps.freq[1:], ps.ps[1:], lw=2, linestyle="steps-mid")


Out[6]:
[<matplotlib.lines.Line2D at 0x111f47e50>]

The PowerSpectrum class comes with three normalizations built-in: leahy for the Leahy normalization, rms for a rms-normalized periodogram and variance for a periodogram that is normalized to the total variance.

For most purposes here, the Leahy normalization (default) is probably what you want, but the other options are there if you want them.

ML/MAP Fitting

So far, we haven't actually done any analysis. Let's first talk about models. All parametric models are saved in the model parametricmodels.py.


In [7]:
from BayesPSD import pl, bpl, const, qpo

We can now, for example, fit one of these models to the data. This kind of fitting is implemented in the class PerMaxLike, which, despite its name actually usually does maximum-a-posteriori estimates rather than maximum likelihood estimates.


In [8]:
from BayesPSD import PerMaxLike

psfit = PerMaxLike(ps, obs=True, fitmethod="bfgs")

PerMaxLike takes a PowerSpectrum object. The variable obs controls whether output plots and logs are produced (set True if you want those!) and fitmethod sets one of the optimization algorithms specified in scipy.optimize. My recommendation is to set to bfgs unless you have a good reason not to.

In order to actually fit a model to the periodogram, we'll need to specify what model, and will also have to set starting guesses for the parameters. Note that the number of parameters. Look at the function definitions for details about the different models. In the case below, we'll use a simple power law model, which takes the power law index, the log(amplitude) and log(background).

The actual fitting is implemented in method mlest. For details on all parameters this method takes, see the documentation. Below are the most important ones. Again, we can set whether the code should produce plots and be verbose, and we can set whether the periodogram we use is the simple Fourier transform of a light curve (m=1) or whether it is the average of several periodograms (or frequency bins). If map is True, the code will produce the maximum-a-posteriori estimate, otherwise it'll return a Maximum Likelihood estimate.


In [9]:
## starting parameters
pars = [2,10,np.log(2.0)]

fitparams = psfit.mlest(pl, pars, obs=True, m=1, map=True)


Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.02036338  0.0781775   0.0117943 ]
 [ 0.0781775   0.31121761  0.041365  ]
 [ 0.0117943   0.041365    0.01405316]]
The best-fit model parameters plus errors are:
Parameter 0: 2.08723748958 +/- 0.142700328632
Parameter 1: 11.1100661977 +/- 0.557868814871
Parameter 2: 0.457427143928 +/- 0.118546023877
The Akaike Information Criterion of the power law model is: 887.00711241.
The figure-of-merit function for this model is: 359.736396168 and the fit for 368.0 dof is 0.977544554804.
Fitting statistics: 
 -- number of frequencies: 371
 -- Deviance [-2 log L] D = 1762.01422482
 -- Highest data/model outlier 2I/S = 13.5363506735
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 7.5281022425
    at frequency f_max = 452.284946234
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 5.91861983855
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 4.02380352683
    at frequency f_max = 8.73655913974
 -- Summed Residuals S = 741.99999352
 -- Expected S ~ 2226.0 +- 66.7233092704
 -- KS test p-value (use with caution!) p = 0.685345492809
 -- merit function (SSE) M = 359.736396168

The fitting routine returns a dictionary with lots of interesting and useful information. Let's have a look at the dictionary keys:


In [10]:
print(fitparams.keys())


['maxind', 'smooth3', 'smooth5', 'merit', 'result', 'popt', 's11maxfreq', 'maxpow', 's5maxfreq', 's5max', 's3max', 's11max', 's3maxfreq', 'bindict', 'maxfreq', 'bic', 'sexp', 'smooth11', 'ssd', 'ksp', 'err', 'deviance', 'cov', 'dof', 'mfit', 'sobs', 'model', 'aic']

Here are the most interesting ones:


In [11]:
print("The best-fit parameters are " + str(fitparams["popt"]))
print("The covariance matrix for the parameters is: " + str(fitparams["cov"]))
print("The MAP estimate (or Maximum Likelihood estimate) is %.3f"%fitparams["result"])
print("The deviance (-2*log(maximum likelihood)) is %.3f"%fitparams["deviance"])
print("The Akaike Information Criterion is %.3f."%fitparams["aic"])
print("The Bayesian Information Criterion is %.3f."%fitparams["bic"])


The best-fit parameters are [  2.08723749  11.1100662    0.45742714]
The covariance matrix for the parameters is: [[ 0.02036338  0.0781775   0.0117943 ]
 [ 0.0781775   0.31121761  0.041365  ]
 [ 0.0117943   0.041365    0.01405316]]
The MAP estimate (or Maximum Likelihood estimate) is 881.007
The deviance (-2*log(maximum likelihood)) is 1762.014
The Akaike Information Criterion is 887.007.
The Bayesian Information Criterion is 1994.007.

A side note: likelihoods, priors and posteriors are implemented in Posterior and its subclasses. Currently (fairly uninformative) priors are hard-coded. If you need different priors, my suggestion is to fork the repository and implement them in a separate branch. Or you could subclass Posterior to make your own.

Bayesian QPO Detection

So now comes the fun bit: we can do the actual QPO search! Most of that is implemented in the class Bayes. Its constructor takes a PowerSpectrum object and various parameters:


In [12]:
from BayesPSD import Bayes

bb = Bayes(ps, namestr='demo', plot=True, m=1)

The variable namestr allows you do set a string identifier for all output plots and text files. This is especially useful if you run many bursts and need to save each in its own separate file.

The variable plot controls whether the code produces output plots for diagnostic purposes. This is usually a useful feature to leave on.

Finally, the periodogram we just produced above is a simple Fourier transform of a single light curve. However, in some applications, you might want to average periodograms or frequency bins, in which case the statistical distributions used in the likelihood need to change. Set m to the number of periodograms or frequency bins averaged.

There will be two steps: First, we need to make some statement about what kind of model to use for the broadband noise (that annoying lower-law-shaped component in the plot above). In the second step we'll use that broadband noise model to infer the presence of a QPO.

Note that unless you care in detail whether you are using the parsimonious model, you can skip step (1) and just use a more complex model. We'll demonstrate the functionality here anyway.


In [13]:
## the two noise models
model1 = pl
model2 = bpl

## input parameters for both
par1 = [1.,4.,np.log(2.0)]
par2 = [1.,3.,2.,3., np.log(2.0)]

## parameters for the MCMC run
nchain = 200 ## number of emcee walkers
niter = 200 ## number of iterations per chain
nsim = 100 ## number of simulations to run

psfit, fakeper, summary = bb.choose_noise_model(model1, par1,
                                               model2, par2, 
                                               fitmethod="bfgs",
                                               nchain = nchain, niter = niter,
                                               nsim = nsim, writefile=True)


Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.03253482  0.13130155  0.01009341]
 [ 0.13130155  0.54188035  0.03744738]
 [ 0.01009341  0.03744738  0.00901978]]
The best-fit model parameters plus errors are:
Parameter 0: 2.08723754207 +/- 0.180374112506
Parameter 1: 11.1100663176 +/- 0.736125223821
Parameter 2: 0.457427265489 +/- 0.0949725030814
The Akaike Information Criterion of the power law model is: 887.00711241.
The figure-of-merit function for this model is: 359.736373665 and the fit for 368.0 dof is 0.977544493654.
Fitting statistics: 
 -- number of frequencies: 371
 -- Deviance [-2 log L] D = 1762.01422482
 -- Highest data/model outlier 2I/S = 13.5363495029
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 7.52810159015
    at frequency f_max = 452.284946234
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 5.91861932672
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 4.0238035013
    at frequency f_max = 8.73655913974
 -- Summed Residuals S = 741.999976503
 -- Expected S ~ 2226.0 +- 66.7233092704
 -- KS test p-value (use with caution!) p = 0.685345233619
 -- merit function (SSE) M = 359.736373665
Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.38054755  0.23509512  0.68112036  1.2383846  -0.01812769]
 [ 0.23509512  0.31074405  0.23346897  0.53388234 -0.02790734]
 [ 0.68112036  0.23346897  1.52872923  2.53538571 -0.00838119]
 [ 1.2383846   0.53388234  2.53538571  4.39645654 -0.03488924]
 [-0.01812769 -0.02790734 -0.00838119 -0.03488924  0.00595677]]
The best-fit model parameters plus errors are:
Parameter 0: 1.18492034413 +/- 0.6168853646
Parameter 1: 9.05996213796 +/- 0.557444211711
Parameter 2: 2.87967378908 +/- 1.23641790086
Parameter 3: 3.32810167723 +/- 2.09677288761
Parameter 4: 0.610094126788 +/- 0.077180137587
The Akaike Information Criterion of the power law model is: 888.151939903.
The figure-of-merit function for this model is: 358.350560945 and the fit for 366.0 dof is 0.979099893291.
Fitting statistics: 
 -- number of frequencies: 371
 -- Deviance [-2 log L] D = 1756.30387981
 -- Highest data/model outlier 2I/S = 14.5414216556
    at frequency f_max = 187.499999999
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 7.03906642037
    at frequency f_max = 452.284946234
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 5.53651404424
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 5.03531944576
    at frequency f_max = 8.73655913974
 -- Summed Residuals S = 741.999930018
 -- Expected S ~ 3710.0 +- 86.1394218694
 -- KS test p-value (use with caution!) p = 0.518561094036
 -- merit function (SSE) M = 358.350560945
The Likelihood Ratio for models pl and bpl is: LRT = 5.71034501353
<--- self.ps len MCMC: 372
mcobs topt: [  2.08723754  11.11006632   0.45742727]
mcobs tcov: [[ 0.03253482  0.13130155  0.01009341]
 [ 0.13130155  0.54188035  0.03744738]
 [ 0.01009341  0.03744738  0.00901978]]
The ensemble acceptance rate is: 0.646325
The autocorrelation times are: [ 23.54990158  12.81215611  29.15341812]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.09518111987.
Good Rhat. Hoorah!
The Rhat value for parameter 1 is: 1.10106429535.
Good Rhat. Hoorah!
The Rhat value for parameter 2 is: 1.10659599425.
Good Rhat. Hoorah!
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
Covariance matrix (after simulations): 

[[ 0.01654201  0.06365105  0.0091727 ]
 [ 0.06365105  0.25685428  0.03106237]
 [ 0.0091727   0.03106237  0.0132707 ]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 2.03574384026	0.128614149052	1.83318355387	2.25262983255

theta[1] 	 10.9084371816	0.506801594856	10.0975273838	11.7674673239

theta[2] 	 0.422416327409	0.115197089507	0.225359315393	0.601404532612

N: 3
simulated srat: [741.99999342808269, 741.99999701474133, 741.99997618024986, 742.00000794061634, 741.99999116648235, 742.00002183269498, 742.00000451022265, 742.00000499005102, 741.99997801021755, 742.00000772310113, 741.99999766586961, 741.99999814792943, 742.00000933502906, 742.00000737025903, 742.0000133285929, 742.00000743530109, 741.9999910876636, 741.99996242770726, 741.9999948632651, 741.99999533233517, 742.00000961306796, 742.00000467850066, 741.99997603993711, 741.99998751102555, 742.00000639805012, 741.99995729178681, 741.99999657444198, 742.0000067680827, 741.99999697625458, 742.00002127608991, 742.00000091153254, 742.00000292217715, 741.99998883475928, 741.99998520086831, 742.00001072135933, 742.00000355302882, 742.00000102815022, 742.00000546631804, 741.999980234536, 741.99999643842739, 742.00000294043014, 742.0000220424979, 741.99998821638621, 741.99999981579549, 741.99999742065597, 741.99999442407648, 741.99999182143472, 742.00000571831004, 741.99998584433661, 741.99998159838822, 742.00000603120554, 742.00003234668839, 741.99999470702983, 741.99998113074753, 742.00001359252906, 741.99999176406948, 741.99999955477233, 742.00003527756076, 741.99999012669241, 742.00001700157634, 741.99999245197932, 742.00000034130994, 742.00001904070689, 742.00002492476347, 742.00001056881877, 741.99997839944376, 741.99996975368242, 741.99999653387113, 741.99999706559868, 742.00005730331782, 742.00003734811492, 742.00001581071251, 742.00000501693751, 741.99998576120265, 742.00000927966425, 741.99999245004028, 741.99997564917396, 741.99998537147007, 741.99998402459869, 741.99997432221483, 742.00001154054269, 741.99999638107079, 742.0000118074696, 741.99999064701944, 741.99996914799908, 742.00002362164423, 742.00004660150535, 742.00007695183842, 741.99998347429539, 741.99999727665966, 741.99998440690388, 741.99997265564275, 742.00000853210111, 741.99999475573645, 741.9999972610226, 742.00004074480557, 741.99994893260418, 742.00000460195281, 741.99998262165695, 742.00000812101007]
observed srat: 741.999976503
p(LRT) = 0.02
KSP(obs) = 0.685345233619
mean(sim_ksp) = 0.672121858396
Merit(obs) = 359.736373665
mean(sim_merit) = 370.537686219
Srat(obs) = 741.999976503
mean(sim_srat) = 741.999999911
Bayesian p-value for maximum power P_max =  0.31 +/- 0.0462493243194
Bayesian p-value for deviance D =  0.51 +/- 0.0499899989998
Bayesian p-value for KS test: 0.53 +/- 0.0499099188539
Bayesian p-value for Merit function: 0.61 +/- 0.048774993593
Bayesian p-value for the np.sum of residuals: 0.9 +/- 0.03
Bayesian p-value for Likelihood Ratio: 0.02 +/- 0.014

Running this code will print a lot of diagnostics on the screen (and also to a log file): the results of the MAP fitting for both models, mean, standard deviations and quantiles for the three parameters and more.

It also returns a bunch of objects useful for further analysis:

  • psfit contains a PerMaxLike object. In its attributes plfit and bplfit it contains summary dictionaries for the power law and bent power law models, respectively, with results from the initial MAP fit on the data, as we've created when we did the fitting by hand above
  • fakeper contains the list of all fake periodograms created during the simulation stage
  • summary is a dictionary with the results printed at the very end of the analysis.

You should also have a couple of plots, all starting with whatever string you gave it for variable namestr above (in my case "demo"):

  • demo_ps_fit.png shows the periodogram and the MAP fits for the two broadband noise models
  • demo_scatter.png shows a triangle plot of the posterior distributions of the parameters for model 1. This can quite useful for diagnosing how well behaved the posterior distribution is, and whether there are correlations between parameters
  • demo_quantiles.png shows the 80% quantiles for all parameters and all Markov chains/walkers. This plot is more useful for Metropolis-Hastings than it is for emcee.
  • demo_rhat.png plots $\hat{R}$ for all parameters in model 1. $\hat{R}$ is another quantity for diagnosing convergence. It compares the variance within Markov chains to the variance between Markov chains. In general, well-mixed chains will have $\hat{R} \approx 1$. If it's much larger than 1.2, I'd start worrying a bit (and perhaps either increase the number of chains (in emcee) or the number of samples (in both MH and emcee).
  • demo_lrt.png shows a histogram of the posterior distribution of the likelihood ratios constructed from model 1, together with the observed value.

In the very end, the code will print to the screen a bunch of posterior predictive p-values; the most important one here is the one for the likelihood ratio. What we've done in this part of the analysis is essentially this:

  1. compute MAP estimates for both models chosen to compare for the data
  2. compute the likelihood ratio of both models for the data
  3. pick parameter sets from the posterior PDF for model 1 via MCMC
  4. from nsim randomly picked parameter sets, simulate a periodogram for each
  5. fit all nsim fake periodograms with both models, compute the likelihood ratio for each
  6. build a posterior distribution for the likelihood ratio of both models under the null hypothesis that model 1 is actually representative of the data
  7. compute how many samples in the distribution lie above the value computed for the data and divide by the total number of samples for the p-value.

This number essentially tells you what likelihood ratio would be expected if the data were generated from model 1. If the observed likelihood ratio is an outlier with respect to the derived distribution, this could be taken as an indicator that the data are unlikely to be generated. However, it is explicitly not an indicator that the data were instead generated from model 2. Strictly speaking, this conclusion is not supported by the test we've done, although we will use it in a way that might seem to imply it. There could be other reasons for why the likelihood ratio we have observed is an outlier with respect to the distributions derived from the posterior sample: we could have simply picked two models that don't particularly describe the data very well, so that neither is an appropriate model for the data. Or perhaps our statistical distributions aren't quite what we expected them to be (which can be the case for dead time), which can also have an effect.

In conclusion, be wary of any results you derive from the analysis above. Model comparison is always tricky, but for QPO detection, having a model that is a reasonable approximation of the broadband shape of the periodogram is good enough. So you can rightfully skip this step and just use the more complex model (usually a bent power law) and get away with it.

Now that we've got that out of the way, let's do the actual QPO fitting. There's a method for that, too!


In [14]:
noise_model = bpl
par = [1,3,2,3,np.log(2.0)]
nchain = 200
niter = 1000
nsim = 1000

results = bb.find_periodicity(noise_model, par, 
                             nchain=nchain, niter=niter, nsim=nsim)


Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.38054755  0.23509512  0.68112036  1.2383846  -0.01812769]
 [ 0.23509512  0.31074405  0.23346897  0.53388234 -0.02790734]
 [ 0.68112036  0.23346897  1.52872923  2.53538571 -0.00838119]
 [ 1.2383846   0.53388234  2.53538571  4.39645654 -0.03488924]
 [-0.01812769 -0.02790734 -0.00838119 -0.03488924  0.00595677]]
The best-fit model parameters plus errors are:
Parameter 0: 1.18492034413 +/- 0.6168853646
Parameter 1: 9.05996213796 +/- 0.557444211711
Parameter 2: 2.87967378908 +/- 1.23641790086
Parameter 3: 3.32810167723 +/- 2.09677288761
Parameter 4: 0.610094126788 +/- 0.077180137587
The Akaike Information Criterion of the power law model is: 888.151939903.
The figure-of-merit function for this model is: 358.350560945 and the fit for 366.0 dof is 0.979099893291.
Fitting statistics: 
 -- number of frequencies: 371
 -- Deviance [-2 log L] D = 1756.30387981
 -- Highest data/model outlier 2I/S = 14.5414216556
    at frequency f_max = 187.499999999
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 7.03906642037
    at frequency f_max = 452.284946234
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 5.53651404424
    at frequency f_max = 450.940860213
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 5.03531944576
    at frequency f_max = 8.73655913974
 -- Summed Residuals S = 741.999930018
 -- Expected S ~ 3710.0 +- 86.1394218694
 -- KS test p-value (use with caution!) p = 0.518561094036
 -- merit function (SSE) M = 358.350560945
<--- self.ps len MCMC: 372
mcobs topt: [ 1.18492034  9.05996214  2.87967379  3.32810168  0.61009413]
mcobs tcov: [[ 0.38054755  0.23509512  0.68112036  1.2383846  -0.01812769]
 [ 0.23509512  0.31074405  0.23346897  0.53388234 -0.02790734]
 [ 0.68112036  0.23346897  1.52872923  2.53538571 -0.00838119]
 [ 1.2383846   0.53388234  2.53538571  4.39645654 -0.03488924]
 [-0.01812769 -0.02790734 -0.00838119 -0.03488924  0.00595677]]
The ensemble acceptance rate is: 0.265945
The autocorrelation times are: [ 87.14363632  87.708177    67.33088917  87.80633997  82.48530557]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.56582961781.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 1 is: 1.49555695924.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 2 is: 1.37042034466.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 3 is: 1.35636239871.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 4 is: 1.19467447802.
Good Rhat. Hoorah!
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
I am on parameter: 3
I am on parameter: 4
Covariance matrix (after simulations): 

[[  4.27069290e-01   8.26545242e-01   1.88412379e-02   8.39625621e-01
    5.58051348e-03]
 [  8.26545242e-01   2.66904104e+00  -6.95728719e-01   3.69014163e-01
   -1.09202533e-02]
 [  1.88412379e-02  -6.95728719e-01   2.03971637e+00   2.15136260e+00
    3.68022585e-02]
 [  8.39625621e-01   3.69014163e-01   2.15136260e+00   1.98470984e+01
   -9.22563797e-02]
 [  5.58051348e-03  -1.09202533e-02   3.68022585e-02  -9.22563797e-02
    1.65535521e-02]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 1.59867603897	0.653503752605	0.504217486407	2.7502821198

theta[1] 	 10.5688562412	1.63371591541	8.86686815403	14.2699014684

theta[2] 	 3.05827095119	1.42818282109	1.18128152329	6.16855860316

theta[3] 	 4.20979592682	4.45499710276	0.563163662466	10.9239224591

theta[4] 	 0.555460969588	0.128660286376	0.33115354113	0.745492693374

N: 5
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 1.3440860215Hz is p = 0.194 +/- 0.0125045591686
The corresponding value of the T_R statistic at frequency f = 187.499999999 is 2I/S = 14.5414216556
The upper limit on the T_R statistic is 2I/S = 17.1290156156
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 1 is P = 309.087452568
The upper limit on the rms amplitude at 40.0Hz for a binning of 1 is rms = 0.15419454559
The upper limit on the power at 70.0Hz for a binning of 1 is P = 89.6876344944
The upper limit on the rms amplitude at 70.0Hz for a binning of 1 is rms = 0.0830605129244
The upper limit on the power at 100.0Hz for a binning of 1 is P = 43.487218418
The upper limit on the rms amplitude at 100.0Hz for a binning of 1 is rms = 0.0578374502164
The upper limit on the power at 300.0Hz for a binning of 1 is P = 15.2596627344
The upper limit on the rms amplitude at 300.0Hz for a binning of 1 is rms = 0.0342610596791
The upper limit on the power at 500.0Hz for a binning of 1 is P = 14.231801415
The upper limit on the rms amplitude at 500.0Hz for a binning of 1 is rms = 0.0330870662798
The upper limit on the power at 1000.0Hz for a binning of 1 is P = 14.231801415
The upper limit on the rms amplitude at 1000.0Hz for a binning of 1 is rms = 0.0330870662798
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 4.0322580645Hz is p = 0.295 +/- 0.0144213383568
The corresponding value of the T_R statistic at frequency f = [ 448.25268817] is 2I/S = 6.4078037666
The upper limit on the T_R statistic is 2I/S = 7.58117229252
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 3 is P = 132.696704116
The upper limit on the rms amplitude at 40.0Hz for a binning of 3 is rms = 0.101031870111
The upper limit on the power at 70.0Hz for a binning of 3 is P = 33.0862333241
The upper limit on the rms amplitude at 70.0Hz for a binning of 3 is rms = 0.0504489332997
The upper limit on the power at 100.0Hz for a binning of 3 is P = 16.4536026243
The upper limit on the rms amplitude at 100.0Hz for a binning of 3 is rms = 0.0355761400426
The upper limit on the power at 300.0Hz for a binning of 3 is P = 5.62936869193
The upper limit on the rms amplitude at 300.0Hz for a binning of 3 is rms = 0.0208093335049
The upper limit on the power at 500.0Hz for a binning of 3 is P = 5.25196051774
The upper limit on the rms amplitude at 500.0Hz for a binning of 3 is rms = 0.0200996756915
The upper limit on the power at 1000.0Hz for a binning of 3 is P = 5.24931147397
The upper limit on the rms amplitude at 1000.0Hz for a binning of 3 is rms = 0.0200946060003
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 6.72043010749Hz is p = 0.142 +/- 0.0110379345894
The corresponding value of the T_R statistic at frequency f = [ 450.94086021] is 2I/S = 5.25321775542
The upper limit on the T_R statistic is 2I/S = 5.85663371472
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 5 is P = 107.662706067
The upper limit on the rms amplitude at 40.0Hz for a binning of 5 is rms = 0.0910041022184
The upper limit on the power at 70.0Hz for a binning of 5 is P = 23.8636923272
The upper limit on the rms amplitude at 70.0Hz for a binning of 5 is rms = 0.0428447037632
The upper limit on the power at 100.0Hz for a binning of 5 is P = 11.9817495804
The upper limit on the rms amplitude at 100.0Hz for a binning of 5 is rms = 0.0303590685734
The upper limit on the power at 300.0Hz for a binning of 5 is P = 3.89881697363
The upper limit on the rms amplitude at 300.0Hz for a binning of 5 is rms = 0.0173178808742
The upper limit on the power at 500.0Hz for a binning of 5 is P = 3.62852927156
The upper limit on the rms amplitude at 500.0Hz for a binning of 5 is rms = 0.0167068140671
The upper limit on the power at 1000.0Hz for a binning of 5 is P = 3.62852927156
The upper limit on the rms amplitude at 1000.0Hz for a binning of 5 is rms = 0.0167068140671
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 9.40860215049Hz is p = 0.555 +/- 0.0157154382694
The corresponding value of the T_R statistic at frequency f = [ 320.56451613] is 2I/S = 3.81963906421
The upper limit on the T_R statistic is 2I/S = 4.8975825447
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 7 is P = 63.7936627864
The upper limit on the rms amplitude at 40.0Hz for a binning of 7 is rms = 0.0700514441659
The upper limit on the power at 70.0Hz for a binning of 7 is P = 18.7338157892
The upper limit on the rms amplitude at 70.0Hz for a binning of 7 is rms = 0.0379613323399
The upper limit on the power at 100.0Hz for a binning of 7 is P = 9.00217936349
The upper limit on the rms amplitude at 100.0Hz for a binning of 7 is rms = 0.0263149261001
The upper limit on the power at 300.0Hz for a binning of 7 is P = 2.93972821525
The upper limit on the rms amplitude at 300.0Hz for a binning of 7 is rms = 0.0150377172348
The upper limit on the power at 500.0Hz for a binning of 7 is P = 2.72574372369
The upper limit on the rms amplitude at 500.0Hz for a binning of 7 is rms = 0.0144800757639
The upper limit on the power at 1000.0Hz for a binning of 7 is P = 2.72574372369
The upper limit on the rms amplitude at 1000.0Hz for a binning of 7 is rms = 0.0144800757639
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 13.440860215Hz is p = 0.204 +/- 0.0127429980774
The corresponding value of the T_R statistic at frequency f = [ 444.22043011] is 2I/S = 3.72017926193
The upper limit on the T_R statistic is 2I/S = 4.11701363724
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 10 is P = 92.3622723247
The upper limit on the rms amplitude at 40.0Hz for a binning of 10 is rms = 0.0842899174209
The upper limit on the power at 70.0Hz for a binning of 10 is P = 13.0994452231
The upper limit on the rms amplitude at 70.0Hz for a binning of 10 is rms = 0.0317434974844
The upper limit on the power at 100.0Hz for a binning of 10 is P = 6.57711598664
The upper limit on the rms amplitude at 100.0Hz for a binning of 10 is rms = 0.0224929322004
The upper limit on the power at 300.0Hz for a binning of 10 is P = 2.14016920268
The upper limit on the rms amplitude at 300.0Hz for a binning of 10 is rms = 0.0128307599232
The upper limit on the power at 500.0Hz for a binning of 10 is P = 1.99180075662
The upper limit on the rms amplitude at 500.0Hz for a binning of 10 is rms = 0.012378022573
The upper limit on the power at 1000.0Hz for a binning of 10 is P = 1.99180075662
The upper limit on the rms amplitude at 1000.0Hz for a binning of 10 is rms = 0.012378022573
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 20.1612903225Hz is p = 0.13 +/- 0.0106348483769
The corresponding value of the T_R statistic at frequency f = [ 242.60752688] is 2I/S = 3.30174077612
The upper limit on the T_R statistic is 2I/S = 3.55482668086
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 15 is P = 115.157350296
The upper limit on the rms amplitude at 40.0Hz for a binning of 15 is rms = 0.0941183176384
The upper limit on the power at 70.0Hz for a binning of 15 is P = 12.1144076324
The upper limit on the rms amplitude at 70.0Hz for a binning of 15 is rms = 0.0305266688354
The upper limit on the power at 100.0Hz for a binning of 15 is P = 6.54309543328
The upper limit on the rms amplitude at 100.0Hz for a binning of 15 is rms = 0.0224346837136
The upper limit on the power at 300.0Hz for a binning of 15 is P = 1.59174883254
The upper limit on the rms amplitude at 300.0Hz for a binning of 15 is rms = 0.0110653611729
The upper limit on the power at 500.0Hz for a binning of 15 is P = 1.46547219722
The upper limit on the rms amplitude at 500.0Hz for a binning of 15 is rms = 0.0106173739953
The upper limit on the power at 1000.0Hz for a binning of 15 is P = 1.46547219722
The upper limit on the rms amplitude at 1000.0Hz for a binning of 15 is rms = 0.0106173739953
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 26.88172043Hz is p = 0.06 +/- 0.00750999334221
The corresponding value of the T_R statistic at frequency f = [ 323.25268817] is 2I/S = 3.18607853041
The upper limit on the T_R statistic is 2I/S = 3.24542745043
bintemplate[0]: 13755.7601905
The upper limit on the power at 40.0Hz for a binning of 20 is P = 54.3362155606
The upper limit on the rms amplitude at 40.0Hz for a binning of 20 is rms = 0.0646506681271
The upper limit on the power at 70.0Hz for a binning of 20 is P = 12.5901572485
The upper limit on the rms amplitude at 70.0Hz for a binning of 20 is rms = 0.0311203090361
The upper limit on the power at 100.0Hz for a binning of 20 is P = 5.24106690716
The upper limit on the rms amplitude at 100.0Hz for a binning of 20 is rms = 0.0200788195086
The upper limit on the power at 300.0Hz for a binning of 20 is P = 1.25904974191
The upper limit on the rms amplitude at 300.0Hz for a binning of 20 is rms = 0.00984123875065
The upper limit on the power at 500.0Hz for a binning of 20 is P = 1.17385386084
The upper limit on the rms amplitude at 500.0Hz for a binning of 20 is rms = 0.00950244446623
The upper limit on the power at 1000.0Hz for a binning of 20 is P = 1.17385386084
The upper limit on the rms amplitude at 1000.0Hz for a binning of 20 is rms = 0.00950244446623
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 40.322580645Hz is p = 0.515 +/- 0.0158042715745
The corresponding value of the T_R statistic at frequency f = [ 323.25268817] is 2I/S = 2.43708994441
The upper limit on the T_R statistic is 2I/S = 2.84861906453
bintemplate[0]: 13755.7601905
The upper limit on the power at 70.0Hz for a binning of 30 is P = 16.1211549927
The upper limit on the rms amplitude at 70.0Hz for a binning of 30 is rms = 0.0352148952234
The upper limit on the power at 100.0Hz for a binning of 30 is P = 3.57119902437
The upper limit on the rms amplitude at 100.0Hz for a binning of 30 is rms = 0.016574305936
The upper limit on the power at 300.0Hz for a binning of 30 is P = 0.868771048164
The upper limit on the rms amplitude at 300.0Hz for a binning of 30 is rms = 0.00817487260858
The upper limit on the power at 500.0Hz for a binning of 30 is P = 0.799849694126
The upper limit on the rms amplitude at 500.0Hz for a binning of 30 is rms = 0.00784390843573
The upper limit on the power at 1000.0Hz for a binning of 30 is P = 0.799849694126
The upper limit on the rms amplitude at 1000.0Hz for a binning of 30 is rms = 0.00784390843573
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 67.2043010749Hz is p = 0.687 +/- 0.0146639353517
The corresponding value of the T_R statistic at frequency f = [ 403.89784946] is 2I/S = 2.13099691433
The upper limit on the T_R statistic is 2I/S = 2.49087698991
bintemplate[0]: 13755.7601905
The upper limit on the power at 70.0Hz for a binning of 50 is P = 3.03739953656
The upper limit on the rms amplitude at 70.0Hz for a binning of 50 is rms = 0.0152854871756
The upper limit on the power at 100.0Hz for a binning of 50 is P = 3.03739953656
The upper limit on the rms amplitude at 100.0Hz for a binning of 50 is rms = 0.0152854871756
The upper limit on the power at 300.0Hz for a binning of 50 is P = 0.510076739376
The upper limit on the rms amplitude at 300.0Hz for a binning of 50 is rms = 0.00626391828328
The upper limit on the power at 500.0Hz for a binning of 50 is P = 0.463582913825
The upper limit on the rms amplitude at 500.0Hz for a binning of 50 is rms = 0.0059716182179
The upper limit on the power at 1000.0Hz for a binning of 50 is P = 0.463582913825
The upper limit on the rms amplitude at 1000.0Hz for a binning of 50 is rms = 0.0059716182179
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 94.0860215049Hz is p = 0.468 +/- 0.0157789733506
The corresponding value of the T_R statistic at frequency f = [ 282.93010753] is 2I/S = 2.08277193773
The upper limit on the T_R statistic is 2I/S = 2.33393394651
bintemplate[0]: 13755.7601905
The upper limit on the power at 100.0Hz for a binning of 70 is P = 1.03746251769
The upper limit on the rms amplitude at 100.0Hz for a binning of 70 is rms = 0.00893335374051
The upper limit on the power at 300.0Hz for a binning of 70 is P = 0.341863807746
The upper limit on the rms amplitude at 300.0Hz for a binning of 70 is rms = 0.0051280811207
The upper limit on the power at 500.0Hz for a binning of 70 is P = 0.315366324211
The upper limit on the rms amplitude at 500.0Hz for a binning of 70 is rms = 0.0049253373505
The upper limit on the power at 1000.0Hz for a binning of 70 is P = 0.315366324211
The upper limit on the rms amplitude at 1000.0Hz for a binning of 70 is rms = 0.0049253373505
ninetyfiveperlim: 950
The posterior p-value for the maximum residual power for a binning of 134.40860215Hz is p = 0.599 +/- 0.0154983547514
The corresponding value of the T_R statistic at frequency f = [ 269.48924731] is 2I/S = 1.84428180035
The upper limit on the T_R statistic is 2I/S = 2.13006697032
bintemplate[0]: 13755.7601905
The upper limit on the power at 300.0Hz for a binning of 100 is P = 0.135154300331
The upper limit on the rms amplitude at 300.0Hz for a binning of 100 is rms = 0.00322435801995
The upper limit on the power at 500.0Hz for a binning of 100 is P = 0.12457079964
The upper limit on the rms amplitude at 500.0Hz for a binning of 100 is rms = 0.00309554021183
The upper limit on the power at 1000.0Hz for a binning of 100 is P = 0.12457079964
The upper limit on the rms amplitude at 1000.0Hz for a binning of 100 is rms = 0.00309554021183
Bayesian p-value for maximum power P_max =  0.194 +/- 0.0125045591686
Bayesian p-value for maximum power P_max =  0.433 +/- 0.0156687906362
Bayesian p-value for maximum power P_max =  0.538 +/- 0.0157656588825
Bayesian p-value for maximum power P_max =  0.515 +/- 0.0158042715745
Bayesian p-value for deviance D =  0.508 +/- 0.0158093643136
Bayesian p-value for KS test: 0.7 +/- 0.0144913767462
Bayesian p-value for Merit function: 0.533 +/- 0.0157769135131
Bayesian p-value for the np.sum of residuals: 0.848 +/- 0.0113532374237

Much like the choose_noise_model method above, this code prints a bunch of useful information to the screen (and a log file) and makes some figures.

Most importantly, it prints a bunch of blocks that start with "The posterior p-value for the maximum residual power [...]". Each of these blocks details the results for the binned periodogram at the specified frequency. The rationale behind this is that QPOs can be narrow or broad: a single QPO might be spread out over several frequency bins, or it might be so coherent it is mostly concentrated in one bin (although even then, sampling will usually cause it to be spread over two adjacent bins). So in searching for QPOs in various frequency bins, we do not risk missing signals that may be broader than the native frequency resolution. Of course, the fact that we've searched more than one periodgram needs to be taken into account when computing the number of trials: while strictly speaking, the binned periodograms are not statistically independent of each other, the conservative assumption to make is that they are, and multiply the number of trials by 7 (the number of frequency bins searched).

Note that after that initial statement, which includes the frequency bin width as well as the posterior p-value (uncorrected for the number of trials in general, including the frequency binning, but it does take into account the fact that we searched many frequencies per periodogram), it also prints $T_{R,j} = \max_j{2I_j/S_j}$, where $I_j$ is the power at frequency $j$ and $S_j$ is the model power spectrum at frequency $j$. Finally, it also prints the upper limit (actually, strictly speaking we show the sensitivity) the fractional rms amplitude that we could have detected at a few useful frequencies. Note that this sensitivity depends on frequency, because the broadband noise depends on frequency and changes the sensitivity at various frequencies.

Again, this method produces two different plots:

  • demo_scatter.png, which is the same plot as produced during the model comparison step, but for whatever model was used for finding QPOs
  • demo_maxpow.png shows the posterior distribution for four different frequency bins. Actually, what it shows are the data at the native time resolution as well as for three different Wiener filter smoothed periodograms (which I thought might be useful at some point, but don't really use in practice).

Usually, when searching for QPOs, I will do the search with nsim=1000 and derive p-values up to $10^{-3}$ to conserve computation. Then I will pick all light curves that have a p-value (corrected for number of trials) of $<10^{-2}$ in at least two or more frequency bins, and re-run those with however many simulations are required to be confident the detection is real. For example, if I had 250 bursts, each of which I decided to run once (for the full light curve), and decided that I'll report any signal that has a posterior predictive p-value, corrected for the number of trials, of $10^{-2}$, then I would have to re-run those bursts that have candidate signals with at least $\frac{10^{-2}}{250 \times 7 \times 100}$ simulations, $250$ for the number of bursts, $7$ for the number of frequency bins, and then another factor of $100$ to make sure I have enough simulations to actually trace out the tail of the distribution sufficiently. This can be a very large number, in which case memory can become an issue. If it does, move to a bigger computer, or let me know!

Running Several Bursts at Once

The code above will work well for the occasional burst, but for large data sets, you'd want to automate it. Of course, you could do that yourself, but for various useful corner cases, there's some code set up that will make things simple.

Especially for Fermi/GBM data, the following code will be useful. Below will be two cases:

  1. Data that comes out of my Fermi/GBM processing pipeline
  2. Data that is stored in an ascii text file (the file format either needs to match the one below, or you'll need to change the code to something that matches your file name structure).

At the heart of this is a set of classes called Burst and GBMBurst that define useful methods for bursts (and can easily be extended). In particular, class Burst has a method that runs the Bayesian QPO search automatically.

What you're going to need for the following analysis are

  1. the data files with the TTE data; this must contain in the first column photon arrival times, in the second (optionally) photon energies or channels
  2. a file that has at least three columns:
    • the identifier for the observations (e.g. the Fermi/GBM trigger ID)
    • the burst start times in the same format as the TTE photon arrival times (seconds since trigger works pretty well)
    • the burst duration in seconds

Using the Burst class to simplify things

For a single light curve, like the one used above, we can make a GBMBurst object as done below. When creating this object, it will automatically create a light curve and periodogram up to whatever Nyquist frequency is specified. It is also possible to specify the normalization of the periodogram, the fluence of the burst and the peak energy for various purposes.


In [28]:
from BayesPSD import GBMBurst

## load data
data = np.loadtxt('../data/090122283_+071.87300_eventfile.dat')
times = data[:,0] ## photon arrival times
events = data[:,1] ## photon energies

## we can get ObsID and start time from the file name in this case
## for others, we might need to read it from a file

#split filename into components and get ObsID and start time
fsplit = "090122283_+071.87300_eventfile.dat".split("_")
print(fsplit)
bid = fsplit[0] ##ObsID
bst = np.float(fsplit[1]) ## burst start time

## let's pretend we know the burst duration
blen = 0.1

## we're going to search between 8 and 200 keV
energies = [8.0, 200.0]

## We want to search up to 4096 Hz:
fnyquist = 4096.

## How much of the burst duration do we want to 
## add on either side of the burst?
addfrac = 0.2

## create GBMBurst object; note the confusing syntax:
## - energies contains energy ranges to use
## - events actually contains the list of photon energies
burst = GBMBurst(bid=bid, bstart=bst, blength=blen,
                energies=energies, photons=times, events=events, 
                instrument="gbm", fnyquist=fnyquist, addfrac=addfrac)


['090122283', '+071.87300', 'eventfile.dat']

Note that for convenience, the code adds 20% of the burst duration on either side of the light curve, to make sure the light curve goes back to the background on either side (anything can cause funny effects in the Fourier transform!).

We can now look at the light curve:


In [17]:
lc = burst.lc

plt.figure()
plt.plot(lc.time, lc.counts)


Out[17]:
[<matplotlib.lines.Line2D at 0x1170b2250>]

Or the periodogram:


In [18]:
ps = burst.ps

plt.figure()
plt.loglog(ps.freq[1:], ps.ps[1:], lw=2, linestyle="steps-mid")


Out[18]:
[<matplotlib.lines.Line2D at 0x1170d95d0>]

Or we can run the entire Bayesian QPO search:


In [19]:
namestr = "%s_%.3f_test"%(bid, bst) ## a string identifier for output files
nchain = 500 ## number of emcee walkers
niter = 100 ## number of iterations in the Markov chain
nsim = 100 ## number of simulations

m = 1 ## periodogram not averaged
fitmethod = "bfgs" ## use BFGS for optimization

burst.bayesian_analysis(namestr = namestr,
                       nchain = nchain,
                       niter = niter,
                       nsim = nsim,
                       m = 1, fitmethod = fitmethod)


Approximating covariance from BFGS: 
Covariance (empirical): [[  4.63587196e-04  -6.18747667e-04   7.70553015e-07]
 [ -6.18747667e-04   1.58317577e-02   1.04012294e-03]
 [  7.70553015e-07   1.04012294e-03   2.39010755e-04]]
The best-fit model parameters plus errors are:
Parameter 0: 2.4895265847 +/- 0.0215310751265
Parameter 1: 11.335737436 +/- 0.125824312696
Parameter 2: 0.658734924935 +/- 0.015459972663
The Akaike Information Criterion of the power law model is: 980.029232656.
The figure-of-merit function for this model is: 493.754632446 and the fit for 569.0 dof is 0.867758580749.
Fitting statistics: 
 -- number of frequencies: 572
 -- Deviance [-2 log L] D = 1948.05846531
 -- Highest data/model outlier 2I/S = 9.8405327097
    at frequency f_max = 1175.90226876
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 6.3619557368
    at frequency f_max = 2970.13612565
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 4.90526698463
    at frequency f_max = 2977.28446771
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 3.8519658305
    at frequency f_max = 67.9092495637
 -- Summed Residuals S = 1143.99998053
 -- Expected S ~ 3432.0 +- 82.8492607088
 -- KS test p-value (use with caution!) p = 0.82274373875
 -- merit function (SSE) M = 493.754632446
Approximating covariance from BFGS: 
Covariance (empirical): [[  4.15633920e-01   1.36883368e+00   1.34032187e+00   1.24116216e-01
    1.17988697e-03]
 [  1.36883368e+00   4.62907253e+00   1.99313207e+00   3.62866740e-01
    4.13200229e-03]
 [  1.34032187e+00   1.99313207e+00   1.24815974e+02  -6.94579098e-03
    4.26679524e-02]
 [  1.24116216e-01   3.62866740e-01  -6.94579098e-03   1.44249638e-01
   -1.78917548e-04]
 [  1.17988697e-03   4.13200229e-03   4.26679524e-02  -1.78917548e-04
    1.40240601e-03]]
The best-fit model parameters plus errors are:
Parameter 0: 2.02635073053 +/- 0.644696766248
Parameter 1: 9.74324826581 +/- 2.15152795206
Parameter 2: 7.65771440363 +/- 11.1721069416
Parameter 3: 4.4681168449 +/- 0.37980210325
Parameter 4: 0.665638990701 +/- 0.0374487117095
The Akaike Information Criterion of the power law model is: 983.547689942.
The figure-of-merit function for this model is: 490.370263994 and the fit for 567.0 dof is 0.864850553781.
Fitting statistics: 
 -- number of frequencies: 572
 -- Deviance [-2 log L] D = 1947.09537988
 -- Highest data/model outlier 2I/S = 9.78244782688
    at frequency f_max = 1175.90226876
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 6.31880307429
    at frequency f_max = 2970.13612565
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 4.87199208168
    at frequency f_max = 2977.28446771
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 3.54580472767
    at frequency f_max = 67.9092495637
 -- Summed Residuals S = 1143.07278964
 -- Expected S ~ 5720.0 +- 106.957935657
 -- KS test p-value (use with caution!) p = 0.668729737959
 -- merit function (SSE) M = 490.370263994
The Likelihood Ratio for models pl and bpl is: LRT = 0.963085428343
<--- self.ps len MCMC: 573
mcobs topt: [  2.48952658  11.33573744   0.65873492]
mcobs tcov: [[  4.63587196e-04  -6.18747667e-04   7.70553015e-07]
 [ -6.18747667e-04   1.58317577e-02   1.04012294e-03]
 [  7.70553015e-07   1.04012294e-03   2.39010755e-04]]
The ensemble acceptance rate is: 0.64376
The autocorrelation times are: [ 4.45445764  4.07877174  0.06641862]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.20679208311.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 1 is: 1.20105800627.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 2 is: 1.20715890237.
*** HIGH Rhat! Check results! ***
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
Covariance matrix (after simulations): 

[[  1.44463371e-01   4.84798256e-01   1.01823281e-03]
 [  4.84798256e-01   1.76183458e+00   1.45803816e-03]
 [  1.01823281e-03   1.45803816e-03   1.83964269e-03]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 2.62506959168	0.380079572405	2.07087045064	3.31021927918

theta[1] 	 11.7799664576	1.32732789516	9.87416660285	14.1585766483

theta[2] 	 0.660678861875	0.042890627205	0.590038772074	0.731825660822

N: 3
simulated srat: [1144.0000053096715, 1143.9996939658199, 1144.0000004132194, 1143.9999902076602, 1144.0000236061971, 1144.0000397314532, 1143.9999977298012, 1144.0000143768643, 1143.9999904073366, 1144.0001969039781, 1144.000003046548, 1144.0000564674824, 1144.0000147574699, 1143.9999908953937, 1144.0000057951343, 1143.9999935323988, 1144.0000028002278, 1144.0000551595547, 1143.9999909006042, 1144.0000329028214, 1144.0000116312319, 1144.0000032777552, 1144.0000217989962, 1144.0000184743483, 1144.0000943291689, 1144.0000109260072, 1144.0000135135133, 1144.0000026693792, 1144.0000068439444, 1144.0000086954215, 1144.0000109613036, 1143.999997960078, 1144.000015542224, 1144.0000261101873, 1143.9999940372629, 1144.0000070460569, 1143.9999912450253, 1143.9999751381797, 1143.9999657760463, 1143.9999864647582, 1144.0000202186261, 1143.9999796902684, 1144.000029811463, 1143.9999492421086, 1144.000461509004, 1144.0000138479518, 1143.9999888659813, 1144.0000133264934, 1144.0000868895991, 1144.0000239660312, 1144.0000386421236, 1144.0000202137098, 1143.9999724284198, 1143.9999780908647, 1144.0000001307208, 1143.999989846774, 1143.999966423504, 1144.0000005488978, 1144.0000061261155, 1144.0000091373495, 1144.0000384930347, 1144.0000383919332, 1143.9999890014224, 1143.999995876474, 1144.0000099727845, 1144.0000114466493, 1144.0001762260945, 1144.0000166888822, 1144.000003451355, 1144.0000202579581, 1143.9999398092807, 1144.0000411493602, 1143.9999967343497, 1144.0000119029569, 1144.000012595628, 1144.0001651041671, 1144.0000231140982, 1144.0000127495193, 1144.0000071687105, 1144.0000090264684, 1144.0000000984905, 1144.0000026911089, 1144.0000064652318, 1143.9999714211197, 1143.9999931077525, 1143.9999876842942, 1144.000025749089, 1144.0000313780658, 1143.9999764726774, 1144.0000057483671, 1144.000007337728, 1144.0000010068684, 1143.9997264163787, 1144.0000338302029, 1143.9999901913657, 1144.0000551441885, 1144.0000173443632, 1144.0000320031054, 1143.9999782708564, 1143.9999860977703]
observed srat: 1143.99998053
p(LRT) = 0.39
KSP(obs) = 0.82274373875
mean(sim_ksp) = 0.668995293672
Merit(obs) = 493.754632446
mean(sim_merit) = 557.270718372
Srat(obs) = 1143.99998053
mean(sim_srat) = 1144.00001158
Bayesian p-value for maximum power P_max =  0.98 +/- 0.014
Bayesian p-value for deviance D =  0.46 +/- 0.0498397431775
Bayesian p-value for KS test: 0.31 +/- 0.0462493243194
Bayesian p-value for Merit function: 0.92 +/- 0.0271293199325
Bayesian p-value for the np.sum of residuals: 0.87 +/- 0.0336303434416
Bayesian p-value for Likelihood Ratio: 0.39 +/- 0.048774993593
Approximating covariance from BFGS: 
Covariance (empirical): [[  2.41628321e-01   8.82811490e-01   2.49181787e-03]
 [  8.82811490e-01   3.36232570e+00   7.84873814e-03]
 [  2.49181787e-03   7.84873814e-03   1.83644196e-03]]
The best-fit model parameters plus errors are:
Parameter 0: 2.4895296253 +/- 0.491557037047
Parameter 1: 11.3357493125 +/- 1.83366455398
Parameter 2: 0.658734904837 +/- 0.0428537275337
The Akaike Information Criterion of the power law model is: 980.029232656.
The figure-of-merit function for this model is: 493.754679746 and the fit for 569.0 dof is 0.867758663877.
Fitting statistics: 
 -- number of frequencies: 572
 -- Deviance [-2 log L] D = 1948.05846531
 -- Highest data/model outlier 2I/S = 9.84053300039
    at frequency f_max = 1175.90226876
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 6.36195587241
    at frequency f_max = 2970.13612565
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 4.90526708915
    at frequency f_max = 2977.28446771
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 3.85196785447
    at frequency f_max = 67.9092495637
 -- Summed Residuals S = 1144.00001897
 -- Expected S ~ 3432.0 +- 82.8492607088
 -- KS test p-value (use with caution!) p = 0.822741204655
 -- merit function (SSE) M = 493.754679746
<--- self.ps len MCMC: 573
mcobs topt: [  2.48952963  11.33574931   0.6587349 ]
mcobs tcov: [[  2.41628321e-01   8.82811490e-01   2.49181787e-03]
 [  8.82811490e-01   3.36232570e+00   7.84873814e-03]
 [  2.49181787e-03   7.84873814e-03   1.83644196e-03]]
The ensemble acceptance rate is: 0.64804
The autocorrelation times are: [-0.22235179 -0.94448544  1.75839868]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.21583340685.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 1 is: 1.21020349264.
*** HIGH Rhat! Check results! ***
The Rhat value for parameter 2 is: 1.20698059716.
*** HIGH Rhat! Check results! ***
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
Covariance matrix (after simulations): 

[[  1.44850955e-01   4.82219101e-01   1.62134884e-03]
 [  4.82219101e-01   1.74265526e+00   4.28160199e-03]
 [  1.62134884e-03   4.28160199e-03   1.87004648e-03]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 2.63414496321	0.380589093121	2.08060697836	3.3126864125

theta[1] 	 11.8134450445	1.32008348485	9.90320854464	14.1696787317

theta[2] 	 0.662411591842	0.0432436015875	0.591233028138	0.733007556768

N: 3
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 7.14834205934Hz is p = 0.99 +/- 0.00994987437107
The corresponding value of the T_R statistic at frequency f = 1175.90226876 is 2I/S = 9.84053300039
The upper limit on the T_R statistic is 2I/S = 19.5248309807
bintemplate[0]: 3516.78401352
The upper limit on the power at 40.0Hz for a binning of 1 is P = 95.6280644613
The upper limit on the rms amplitude at 40.0Hz for a binning of 1 is rms = 0.246484899911
The upper limit on the power at 70.0Hz for a binning of 1 is P = 37.1173509532
The upper limit on the rms amplitude at 70.0Hz for a binning of 1 is rms = 0.153562835487
The upper limit on the power at 100.0Hz for a binning of 1 is P = 25.3480709588
The upper limit on the rms amplitude at 100.0Hz for a binning of 1 is rms = 0.126902475233
The upper limit on the power at 300.0Hz for a binning of 1 is P = 17.4459798649
The upper limit on the rms amplitude at 300.0Hz for a binning of 1 is rms = 0.105279865016
The upper limit on the power at 500.0Hz for a binning of 1 is P = 17.0743945838
The upper limit on the rms amplitude at 500.0Hz for a binning of 1 is rms = 0.104152642429
The upper limit on the power at 1000.0Hz for a binning of 1 is P = 16.9571463446
The upper limit on the rms amplitude at 1000.0Hz for a binning of 1 is rms = 0.103794423274
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 21.445026178Hz is p = 0.44 +/- 0.049638694584
The corresponding value of the T_R statistic at frequency f = [ 2962.9877836] is 2I/S = 6.36195212
The upper limit on the T_R statistic is 2I/S = 8.60184947931
bintemplate[0]: 3516.78401352
The upper limit on the power at 40.0Hz for a binning of 3 is P = 97.7153767651
The upper limit on the rms amplitude at 40.0Hz for a binning of 3 is rms = 0.249160441318
The upper limit on the power at 70.0Hz for a binning of 3 is P = 13.982626385
The upper limit on the rms amplitude at 70.0Hz for a binning of 3 is rms = 0.0942523121129
The upper limit on the power at 100.0Hz for a binning of 3 is P = 10.2185145995
The upper limit on the rms amplitude at 100.0Hz for a binning of 3 is rms = 0.0805733685856
The upper limit on the power at 300.0Hz for a binning of 3 is P = 6.59747873139
The upper limit on the rms amplitude at 300.0Hz for a binning of 3 is rms = 0.0647420781111
The upper limit on the power at 500.0Hz for a binning of 3 is P = 6.43216377474
The upper limit on the rms amplitude at 500.0Hz for a binning of 3 is rms = 0.0639258016461
The upper limit on the power at 1000.0Hz for a binning of 3 is P = 6.38816577539
The upper limit on the rms amplitude at 1000.0Hz for a binning of 3 is rms = 0.0637067903012
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 35.7417102967Hz is p = 0.79 +/- 0.0407308237088
The corresponding value of the T_R statistic at frequency f = [ 1683.43455497] is 2I/S = 4.41938129315
The upper limit on the T_R statistic is 2I/S = 6.00917790378
bintemplate[0]: 3516.78401352
The upper limit on the power at 40.0Hz for a binning of 5 is P = 21.8769541026
The upper limit on the rms amplitude at 40.0Hz for a binning of 5 is rms = 0.117893826479
The upper limit on the power at 70.0Hz for a binning of 5 is P = 21.8769541026
The upper limit on the rms amplitude at 70.0Hz for a binning of 5 is rms = 0.117893826479
The upper limit on the power at 100.0Hz for a binning of 5 is P = 7.47294420486
The upper limit on the rms amplitude at 100.0Hz for a binning of 5 is rms = 0.0689038527076
The upper limit on the power at 300.0Hz for a binning of 5 is P = 3.99850005618
The upper limit on the rms amplitude at 300.0Hz for a binning of 5 is rms = 0.0504018165413
The upper limit on the power at 500.0Hz for a binning of 5 is P = 3.91131031583
The upper limit on the rms amplitude at 500.0Hz for a binning of 5 is rms = 0.0498492665416
The upper limit on the power at 1000.0Hz for a binning of 5 is P = 3.87973973994
The upper limit on the rms amplitude at 1000.0Hz for a binning of 5 is rms = 0.0496476769819
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 50.0383944154Hz is p = 0.9 +/- 0.03
The corresponding value of the T_R statistic at frequency f = [ 2955.83944154] is 2I/S = 3.67925868316
The upper limit on the T_R statistic is 2I/S = 5.27490103201
bintemplate[0]: 3516.78401352
The upper limit on the power at 70.0Hz for a binning of 7 is P = 9.95867839019
The upper limit on the rms amplitude at 70.0Hz for a binning of 7 is rms = 0.0795423631873
The upper limit on the power at 100.0Hz for a binning of 7 is P = 9.95867839019
The upper limit on the rms amplitude at 100.0Hz for a binning of 7 is rms = 0.0795423631873
The upper limit on the power at 300.0Hz for a binning of 7 is P = 3.30580260762
The upper limit on the rms amplitude at 300.0Hz for a binning of 7 is rms = 0.0458285477218
The upper limit on the power at 500.0Hz for a binning of 7 is P = 3.19743270563
The upper limit on the rms amplitude at 500.0Hz for a binning of 7 is rms = 0.0450711191899
The upper limit on the power at 1000.0Hz for a binning of 7 is P = 3.16935971731
The upper limit on the rms amplitude at 1000.0Hz for a binning of 7 is rms = 0.044872824085
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 71.4834205934Hz is p = 1.0 +/- 0.0
The corresponding value of the T_R statistic at frequency f = [ 2219.56020942] is 2I/S = 2.95684952634
The upper limit on the T_R statistic is 2I/S = 4.56070778753
bintemplate[0]: 3516.78401352
The upper limit on the power at 100.0Hz for a binning of 10 is P = 4.77305494554
The upper limit on the rms amplitude at 100.0Hz for a binning of 10 is rms = 0.0550675624392
The upper limit on the power at 300.0Hz for a binning of 10 is P = 2.55388772413
The upper limit on the rms amplitude at 300.0Hz for a binning of 10 is rms = 0.040280841642
The upper limit on the power at 500.0Hz for a binning of 10 is P = 2.50346894874
The upper limit on the rms amplitude at 500.0Hz for a binning of 10 is rms = 0.0398812480316
The upper limit on the power at 1000.0Hz for a binning of 10 is P = 2.4784214617
The upper limit on the rms amplitude at 1000.0Hz for a binning of 10 is rms = 0.0396812383189
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 107.22513089Hz is p = 0.96 +/- 0.0195959179423
The corresponding value of the T_R statistic at frequency f = [ 3970.90401396] is 2I/S = 2.82566342346
The upper limit on the T_R statistic is 2I/S = 3.97907057678
bintemplate[0]: 3516.78401352
The upper limit on the power at 300.0Hz for a binning of 15 is P = 2.03706625656
The upper limit on the rms amplitude at 300.0Hz for a binning of 15 is rms = 0.0359749511945
The upper limit on the power at 500.0Hz for a binning of 15 is P = 1.9348329241
The upper limit on the rms amplitude at 500.0Hz for a binning of 15 is rms = 0.0350606021365
The upper limit on the power at 1000.0Hz for a binning of 15 is P = 1.9151753674
The upper limit on the rms amplitude at 1000.0Hz for a binning of 15 is rms = 0.03488204272
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 142.966841187Hz is p = 0.99 +/- 0.00994987437107
The corresponding value of the T_R statistic at frequency f = [ 1147.30890052] is 2I/S = 2.57322369626
The upper limit on the T_R statistic is 2I/S = 3.7134066305
bintemplate[0]: 3516.78401352
The upper limit on the power at 300.0Hz for a binning of 20 is P = 1.70884322739
The upper limit on the rms amplitude at 300.0Hz for a binning of 20 is rms = 0.0329494937845
The upper limit on the power at 500.0Hz for a binning of 20 is P = 1.67510729529
The upper limit on the rms amplitude at 500.0Hz for a binning of 20 is rms = 0.0326226285393
The upper limit on the power at 1000.0Hz for a binning of 20 is P = 1.65898438663
The upper limit on the rms amplitude at 1000.0Hz for a binning of 20 is rms = 0.0324652525286
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 214.45026178Hz is p = 1.0 +/- 0.0
The corresponding value of the T_R statistic at frequency f = [ 1719.17626527] is 2I/S = 2.28598485855
The upper limit on the T_R statistic is 2I/S = 3.16100367771
bintemplate[0]: 3516.78401352
The upper limit on the power at 300.0Hz for a binning of 30 is P = 1.19502631354
The upper limit on the rms amplitude at 300.0Hz for a binning of 30 is rms = 0.0275541088741
The upper limit on the power at 500.0Hz for a binning of 30 is P = 1.13505206282
The upper limit on the rms amplitude at 500.0Hz for a binning of 30 is rms = 0.0268537862147
The upper limit on the power at 1000.0Hz for a binning of 30 is P = 1.12412718607
The upper limit on the rms amplitude at 1000.0Hz for a binning of 30 is rms = 0.0267242398864
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 357.417102967Hz is p = 1.0 +/- 0.0
The corresponding value of the T_R statistic at frequency f = [ 2505.4938918] is 2I/S = 2.15800911064
The upper limit on the T_R statistic is 2I/S = 2.80057183665
bintemplate[0]: 3516.78401352
The upper limit on the power at 500.0Hz for a binning of 50 is P = 0.787894196751
The upper limit on the rms amplitude at 500.0Hz for a binning of 50 is rms = 0.0223733793753
The upper limit on the power at 1000.0Hz for a binning of 50 is P = 0.776087552143
The upper limit on the rms amplitude at 1000.0Hz for a binning of 50 is rms = 0.0222051133708
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 500.383944154Hz is p = 0.96 +/- 0.0195959179423
The corresponding value of the T_R statistic at frequency f = [ 1504.72600349] is 2I/S = 2.1731965991
The upper limit on the T_R statistic is 2I/S = 2.63172341611
bintemplate[0]: 3516.78401352
The upper limit on the power at 1000.0Hz for a binning of 70 is P = 0.615307064116
The upper limit on the rms amplitude at 1000.0Hz for a binning of 70 is rms = 0.0197716806211
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 714.834205934Hz is p = 0.75 +/- 0.0433012701892
The corresponding value of the T_R statistic at frequency f = [ 2148.07678883] is 2I/S = 2.1244884381
The upper limit on the T_R statistic is 2I/S = 2.47645971653
bintemplate[0]: 3516.78401352
The upper limit on the power at 1000.0Hz for a binning of 100 is P = 0.461887913328
The upper limit on the rms amplitude at 1000.0Hz for a binning of 100 is rms = 0.0171303381079
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 1429.66841187Hz is p = 0.25 +/- 0.0433012701892
The corresponding value of the T_R statistic at frequency f = [ 1433.2425829] is 2I/S = 2.07264714604
The upper limit on the T_R statistic is 2I/S = 2.19040828949
bintemplate[0]: 3516.78401352
Bayesian p-value for maximum power P_max =  0.99 +/- 0.00994987437107
Bayesian p-value for maximum power P_max =  0.88 +/- 0.0324961536185
Bayesian p-value for maximum power P_max =  0.88 +/- 0.0324961536185
Bayesian p-value for maximum power P_max =  0.93 +/- 0.0255147016443
Bayesian p-value for deviance D =  0.49 +/- 0.0499899989998
Bayesian p-value for KS test: 0.33 +/- 0.047021271782
Bayesian p-value for Merit function: 0.97 +/- 0.0170587221092
Bayesian p-value for the np.sum of residuals: 0.28 +/- 0.0448998886413

And then it goes through the entire analysis above.

Running Many Bursts

I've provided you with two files:

  • sgr1550_burstdata.dat has some burst IDs, start times and durations as specified above
  • 090122037a_tte_combined.dat contains the photon arrival times and energies needed to run the bursts in the file above.

The following defines some (simple) code that will read in sgr1550_burstdata.dat.


In [20]:
def read_burstdata(filename, datadir="./"):
    """
    Run Bayesian QPO search on all bursts in file filename. 
    
    Parameters
    ----------
    filename: string
        Name of a file with minimal burst data. Needs to have columns:
        1. ObsID
        2. MET trigger time
        3. Seconds since trigger
        4. Burst duration in seconds
        Note that this is the way my file is currently set up. You can change 
        this by changing the indices of the columns read out below.
    
    datadir: string
        Directory where the data (including the file in filename) is located.
    """
    
    ## read in data
    ## type needs to be string, otherwise code fails on ObsID column, 
    ## which doesn't purely consist of numbers
    data  = np.loadtxt(datadir+filename, dtype=np.string_)
    
    ## ObsIDs are in first column, need to remain string
    obsids = data[:,0]
    
    ## trigger time is in second column, should be float
    trigtime = data[:,1].astype("float64")
    
    ## start time in seconds since trigger is in third column,
    ## should be float
    bstart = data[:,2].astype("float64")
    
    ## burst duration in seconds is in fourth column,
    ## should be float
    blength = data[:,3].astype("float64")
    
    
    return obsids, trigtime, bstart, blength

Now run the function above on the example file:


In [23]:
## now run the function above on the example file
obsids, trigtime, bstart, blength = read_burstdata("sgr1550_burstdata.dat", datadir="../data/")

Next, we'll need to load the data, snip out the parts of the light curve that have bursts and make a GBMBurst object, so that we can then easily run the QPO search.

We'll loop over the ObsIDs first, because if there is more than one burst in a single observation, it makes no sense reading in the data several times! Then we'll find all bursts that have this ObsIDs, and for those bursts, we make GBMBurst objects with the data.


In [24]:
## empty list to store all burst objects in
allbursts = []

## which energy range do we want to run over?
energies = [8.,200.]

## what's the Nyquist frequency supposed to be?
## This depends on the time resolution of your instrument
## and the frequencies where you expect QPOs to appear
fnyquist = 4096.

## get the unique set of ObsIDs
obsid_set = np.unique(obsids)

## loop over all ObsIDs
for o in obsid_set:
    ## this filename structure should reflect what your data files look like
    ## mine all look like ObsID_tte_combined.dat
    ## and contain TTE data (seconds since trigger) and photon energies
    datafile = datadir+"%s_tte_combined.dat"%o
    data = np.loadtxt(datafile)
    times = data[:,0]
    events = data[:,1]
    
    ## find all bursts in this observation
    bst = bstart[obsids == o]
    blen = blength[obsids == o]
    ttrig = trigtime[obsids == o]
    print(len(bst))
    
    ## loop over all bursts
    for s,l in zip(bst, blen):
        burst = GBMBurst(bid=o, bstart=s, blength=l,
                        energies=energies, photons=times, events=events, 
                        instrument="gbm", fnyquist=fnyquist)

        allbursts.append(burst)


8

Now that we have all bursts in a list, running the Bayesian QPO search is easy:


In [26]:
nchain = 500 ## number of chains
niter = 200 ## number of iterations per chain
nsim = 100 ## number of simulations, small to make it run fast for demo purposes
fitmethod = "bfgs" ## scipy.optimize minimization algorithm

## we'll just run 1 burst for brevity; delete [:1] if you want to run 
## on all bursts
for burst in allbursts[:1]:
    ## identifier for the output
    namestr = "%s_%.3f"%(burst.bid, burst.blen)
    
    ## run Bayesian analysis
    burst.bayesian_analysis(namestr = namestr,
                       nchain = nchain,
                       niter = niter,
                       nsim = nsim,
                       m = 1, fitmethod = fitmethod)


Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.21975713  0.89956171  0.01743839]
 [ 0.89956171  3.89602763  0.0628207 ]
 [ 0.01743839  0.0628207   0.00605623]]
The best-fit model parameters plus errors are:
Parameter 0: 1.56734124133 +/- 0.468782602388
Parameter 1: 8.16380494438 +/- 1.97383576589
Parameter 2: 0.609911688411 +/- 0.0778218149677
The Akaike Information Criterion of the power law model is: 429.807823525.
The figure-of-merit function for this model is: 208.647616242 and the fit for 248.0 dof is 0.841321033233.
Fitting statistics: 
 -- number of frequencies: 251
 -- Deviance [-2 log L] D = 847.615647051
 -- Highest data/model outlier 2I/S = 9.90945355874
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 8.19938171276
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 6.55444979164
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 3.6250099474
    at frequency f_max = 203.174603175
 -- Summed Residuals S = 501.999998702
 -- Expected S ~ 1506.0 +- 54.881690936
 -- KS test p-value (use with caution!) p = 0.587186834955
 -- merit function (SSE) M = 208.647616242
Approximating covariance from BFGS: 
Covariance (empirical): [[1 0 0 0 0]
 [0 1 0 0 0]
 [0 0 1 0 0]
 [0 0 0 1 0]
 [0 0 0 0 1]]
The best-fit model parameters plus errors are:
Parameter 0: 1.0 +/- 1.0
Parameter 1: 3.26937622391 +/- 1.0
Parameter 2: 2.0 +/- 1.0
Parameter 3: 3.0 +/- 1.0
Parameter 4: 0.728301638804 +/- 1.0
The Akaike Information Criterion of the power law model is: 1e+16.
The figure-of-merit function for this model is: 443.395364939 and the fit for 246.0 dof is 1.80242018268.
Fitting statistics: 
 -- number of frequencies: 251
 -- Deviance [-2 log L] D = 881.520093216
 -- Highest data/model outlier 2I/S = 8.99240846403
    at frequency f_max = 479.492063492
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 8.95877142011
    at frequency f_max = 40.6349206349
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 8.87572416139
    at frequency f_max = 40.6349206349
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 8.67367602384
    at frequency f_max = 40.6349206349
 -- Summed Residuals S = 514.772337982
 -- Expected S ~ 2510.0 +- 70.8519583357
 -- KS test p-value (use with caution!) p = 0.885109873285
 -- merit function (SSE) M = 443.395364939
The Likelihood Ratio for models pl and bpl is: LRT = -33.904446165
<--- self.ps len MCMC: 252
mcobs topt: [ 1.56734124  8.16380494  0.60991169]
mcobs tcov: [[ 0.21975713  0.89956171  0.01743839]
 [ 0.89956171  3.89602763  0.0628207 ]
 [ 0.01743839  0.0628207   0.00605623]]
The ensemble acceptance rate is: 0.63361
The autocorrelation times are: [ 42.92494614  39.69613022  21.51705029]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.10873688759.
Good Rhat. Hoorah!
The Rhat value for parameter 1 is: 1.10957746715.
Good Rhat. Hoorah!
The Rhat value for parameter 2 is: 1.10749488371.
Good Rhat. Hoorah!
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
Covariance matrix (after simulations): 

[[  7.84640593e-01   2.48905177e+00   1.46509432e-02]
 [  2.48905177e+00   8.24935889e+00   4.23682599e-02]
 [  1.46509432e-02   4.23682599e-02   4.57260045e-03]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 2.99915047166	0.885794980144	1.84110208024	4.62990641189

theta[1] 	 13.4026139218	2.87215535753	9.63700076828	18.7401732006

theta[2] 	 0.652231977191	0.0676206679079	0.541153153303	0.763219342803

N: 3
simulated srat: [501.99989435501539, 502.00000348240303, 502.00001745598934, 501.9999934557863, 501.99998388768154, 501.99980502309739, 502.0000054041202, 501.99997209813034, 502.00000097709272, 502.00000774314657, 501.99999501865875, 502.00001729235288, 502.00002745037455, 502.00000352962843, 502.00003059504155, 501.99988867051184, 502.00000263933765, 502.00001734144195, 501.99997793312497, 501.99992133707883, 501.99993098194858, 501.99993142888434, 501.99999134867352, 502.00003868767681, 502.00000270391297, 501.99999524598297, 502.00000249817981, 502.00000444824656, 501.99997196704254, 499.20126449398373, 501.99999998971759, 501.99996442015072, 502.00000128181603, 501.99998956952993, 502.00000525110647, 501.7642375509256, 502.00000303001121, 501.93822145565576, 501.99999701028491, 501.99999756114187, 502.00000199182807, 501.9998647947956, 501.99999232748729, 502.00000702370681, 501.99998521173325, 502.00001046942248, 501.99999448599186, 501.99994101808676, 502.00000453345916, 502.00001576388775, 502.00000667256313, 502.00001728731502, 501.99999383198679, 502.00000260541731, 502.00004972576005, 502.00000884970279, 502.00000630628847, 501.99997610312499, 501.99999733322954, 502.00000494889338, 501.99998859798825, 502.00000240599951, 502.00001748884233, 501.99998939349234, 501.99999764488143, 502.00001050025224, 502.00000098609416, 502.00000308509561, 501.99999453262518, 501.99998730568683, 502.00002213065682, 502.00002566000205, 502.00000206834261, 502.00000495819313, 501.99995233722427, 502.00001855176862, 501.99999455414269, 501.99999777630308, 502.43860115351345, 501.99998867052443, 501.99998996962552, 502.00001262079422, 502.00001185880734, 495.20970897196509, 502.00000478507172, 502.00000002558329, 502.0000216616873, 502.00000408790856, 502.00001872600558, 502.00000896854556, 501.99999948469042, 502.00001860394292, 496.02660774280486, 501.99993203576918, 501.99999742663317, 502.00000439586938, 501.27632096879654, 502.00000792647825, 502.00001389669274, 507.08360263619414]
observed srat: 501.999998702
p(LRT) = 0.91
KSP(obs) = 0.587186834955
mean(sim_ksp) = 0.660342414927
Merit(obs) = 208.647616242
mean(sim_merit) = 243.662778366
Srat(obs) = 501.999998702
mean(sim_srat) = 501.889378845
Bayesian p-value for maximum power P_max =  0.82 +/- 0.0384187454246
Bayesian p-value for deviance D =  0.52 +/- 0.0499599839872
Bayesian p-value for KS test: 0.63 +/- 0.0482804308183
Bayesian p-value for Merit function: 0.87 +/- 0.0336303434416
Bayesian p-value for the np.sum of residuals: 0.56 +/- 0.049638694584
Bayesian p-value for Likelihood Ratio: 0.91 +/- 0.0286181760425
Approximating covariance from BFGS: 
Covariance (empirical): [[ 0.22794932  0.93814112  0.01783722]
 [ 0.93814112  4.056118    0.06682878]
 [ 0.01783722  0.06682878  0.00604562]]
The best-fit model parameters plus errors are:
Parameter 0: 1.56733893705 +/- 0.477440384358
Parameter 1: 8.16379526726 +/- 2.01398063569
Parameter 2: 0.609911509022 +/- 0.0777535842575
The Akaike Information Criterion of the power law model is: 429.807823525.
The figure-of-merit function for this model is: 208.647611077 and the fit for 248.0 dof is 0.841321012407.
Fitting statistics: 
 -- number of frequencies: 251
 -- Deviance [-2 log L] D = 847.615647051
 -- Highest data/model outlier 2I/S = 9.90945475976
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [3] 2I/S = 8.19938270652
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [5] 2I/S = 6.55445058603
    at frequency f_max = 3080.12698413
 -- Highest smoothed data/model outlier for smoothing factor [11] 2I/S = 3.62500745667
    at frequency f_max = 203.174603175
 -- Summed Residuals S = 502.000002432
 -- Expected S ~ 1506.0 +- 54.881690936
 -- KS test p-value (use with caution!) p = 0.587186534016
 -- merit function (SSE) M = 208.647611077
<--- self.ps len MCMC: 252
mcobs topt: [ 1.56733894  8.16379527  0.60991151]
mcobs tcov: [[ 0.22794932  0.93814112  0.01783722]
 [ 0.93814112  4.056118    0.06682878]
 [ 0.01783722  0.06682878  0.00604562]]
The ensemble acceptance rate is: 0.63365
The autocorrelation times are: [ 30.68048606  26.71874375   3.73300032]
Computing Rhat. The closer to 1, the better!
The Rhat value for parameter 0 is: 1.10514576275.
Good Rhat. Hoorah!
The Rhat value for parameter 1 is: 1.10477864396.
Good Rhat. Hoorah!
The Rhat value for parameter 2 is: 1.09662349421.
Good Rhat. Hoorah!
I am on parameter: 0
I am on parameter: 1
I am on parameter: 2
Covariance matrix (after simulations): 

[[  7.79311831e-01   2.47031808e+00   1.47468959e-02]
 [  2.47031808e+00   8.18140509e+00   4.26209750e-02]
 [  1.47468959e-02   4.26209750e-02   4.63422017e-03]]
-- Posterior Summary of Parameters: 

parameter 	 mean 		 sd 		 5% 		 95% 

---------------------------------------------

theta[0] 	 3.00118174428	0.882781987544	1.84681537364	4.64723058725

theta[1] 	 13.3990631501	2.86030125652	9.63555735835	18.774875186

theta[2] 	 0.652411840928	0.0680747664751	0.540993411937	0.764756019713

N: 3
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 16.253968254Hz is p = 0.86 +/- 0.0346987031458
The corresponding value of the T_R statistic at frequency f = 3080.12698413 is 2I/S = 9.90945475976
The upper limit on the T_R statistic is 2I/S = 17.2627288709
bintemplate[0]: 133.460739162
The upper limit on the power at 40.0Hz for a binning of 1 is P = 193.564616937
The upper limit on the rms amplitude at 40.0Hz for a binning of 1 is rms = 0.652239787594
The upper limit on the power at 70.0Hz for a binning of 1 is P = 61.6178586315
The upper limit on the rms amplitude at 70.0Hz for a binning of 1 is rms = 0.367999816745
The upper limit on the power at 100.0Hz for a binning of 1 is P = 37.4704174595
The upper limit on the rms amplitude at 100.0Hz for a binning of 1 is rms = 0.28697136764
The upper limit on the power at 300.0Hz for a binning of 1 is P = 17.861863147
The upper limit on the rms amplitude at 300.0Hz for a binning of 1 is rms = 0.198133394665
The upper limit on the power at 500.0Hz for a binning of 1 is P = 15.6422452967
The upper limit on the rms amplitude at 500.0Hz for a binning of 1 is rms = 0.185414565479
The upper limit on the power at 1000.0Hz for a binning of 1 is P = 14.5762799875
The upper limit on the rms amplitude at 1000.0Hz for a binning of 1 is rms = 0.178985418938
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 48.7619047619Hz is p = 0.87 +/- 0.0336303434416
The corresponding value of the T_R statistic at frequency f = [ 3080.12698413] is 2I/S = 5.002911099
The upper limit on the T_R statistic is 2I/S = 7.82941552213
bintemplate[0]: 133.460739162
The upper limit on the power at 70.0Hz for a binning of 3 is P = 23.5341991976
The upper limit on the rms amplitude at 70.0Hz for a binning of 3 is rms = 0.22742804295
The upper limit on the power at 100.0Hz for a binning of 3 is P = 23.5341991976
The upper limit on the rms amplitude at 100.0Hz for a binning of 3 is rms = 0.22742804295
The upper limit on the power at 300.0Hz for a binning of 3 is P = 7.12764446647
The upper limit on the rms amplitude at 300.0Hz for a binning of 3 is rms = 0.125160507643
The upper limit on the power at 500.0Hz for a binning of 3 is P = 5.97436725142
The upper limit on the rms amplitude at 500.0Hz for a binning of 3 is rms = 0.114588295544
The upper limit on the power at 1000.0Hz for a binning of 3 is P = 5.57252838212
The upper limit on the rms amplitude at 1000.0Hz for a binning of 3 is rms = 0.110667588415
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 81.2698412698Hz is p = 0.95 +/- 0.0217944947177
The corresponding value of the T_R statistic at frequency f = [ 3015.11111111] is 2I/S = 3.70318848961
The upper limit on the T_R statistic is 2I/S = 5.51893098868
bintemplate[0]: 133.460739162
The upper limit on the power at 100.0Hz for a binning of 5 is P = 8.63907196887
The upper limit on the rms amplitude at 100.0Hz for a binning of 5 is rms = 0.137793219573
The upper limit on the power at 300.0Hz for a binning of 5 is P = 4.30260785051
The upper limit on the rms amplitude at 300.0Hz for a binning of 5 is rms = 0.0972434110371
The upper limit on the power at 500.0Hz for a binning of 5 is P = 3.60643120721
The upper limit on the rms amplitude at 500.0Hz for a binning of 5 is rms = 0.0890293346792
The upper limit on the power at 1000.0Hz for a binning of 5 is P = 3.36386087674
The upper limit on the rms amplitude at 1000.0Hz for a binning of 5 is rms = 0.0859831426967
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 113.777777778Hz is p = 0.67 +/- 0.047021271782
The corresponding value of the T_R statistic at frequency f = [ 3080.12698413] is 2I/S = 3.61737814924
The upper limit on the T_R statistic is 2I/S = 4.63395180535
bintemplate[0]: 133.460739162
The upper limit on the power at 300.0Hz for a binning of 7 is P = 3.3083543479
The upper limit on the rms amplitude at 300.0Hz for a binning of 7 is rms = 0.085270794865
The upper limit on the power at 500.0Hz for a binning of 7 is P = 2.73038571244
The upper limit on the rms amplitude at 500.0Hz for a binning of 7 is rms = 0.0774651387376
The upper limit on the power at 1000.0Hz for a binning of 7 is P = 2.52855117885
The upper limit on the rms amplitude at 1000.0Hz for a binning of 7 is rms = 0.0745470008662
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 162.53968254Hz is p = 0.91 +/- 0.0286181760425
The corresponding value of the T_R statistic at frequency f = [ 820.82539683] is 2I/S = 2.95603838252
The upper limit on the T_R statistic is 2I/S = 4.00241520986
bintemplate[0]: 133.460739162
The upper limit on the power at 300.0Hz for a binning of 10 is P = 2.95802225095
The upper limit on the rms amplitude at 300.0Hz for a binning of 10 is rms = 0.0806296955488
The upper limit on the power at 500.0Hz for a binning of 10 is P = 2.05220640184
The upper limit on the rms amplitude at 500.0Hz for a binning of 10 is rms = 0.0671590927598
The upper limit on the power at 1000.0Hz for a binning of 10 is P = 1.91417399349
The upper limit on the rms amplitude at 1000.0Hz for a binning of 10 is rms = 0.0648612041969
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 243.80952381Hz is p = 0.7 +/- 0.0458257569496
The corresponding value of the T_R statistic at frequency f = [ 2933.84126984] is 2I/S = 2.77410023424
The upper limit on the T_R statistic is 2I/S = 3.4396277902
bintemplate[0]: 133.460739162
The upper limit on the power at 300.0Hz for a binning of 15 is P = 1.76023737091
The upper limit on the rms amplitude at 300.0Hz for a binning of 15 is rms = 0.0621985012877
The upper limit on the power at 500.0Hz for a binning of 15 is P = 1.47542495322
The upper limit on the rms amplitude at 500.0Hz for a binning of 15 is rms = 0.0569446415817
The upper limit on the power at 1000.0Hz for a binning of 15 is P = 1.37618714777
The upper limit on the rms amplitude at 1000.0Hz for a binning of 15 is rms = 0.0549962465807
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 325.079365079Hz is p = 0.68 +/- 0.0466476151588
The corresponding value of the T_R statistic at frequency f = [ 2933.84126984] is 2I/S = 2.61094027678
The upper limit on the T_R statistic is 2I/S = 3.08222925991
bintemplate[0]: 133.460739162
The upper limit on the power at 500.0Hz for a binning of 20 is P = 1.20706426093
The upper limit on the rms amplitude at 500.0Hz for a binning of 20 is rms = 0.051506198516
The upper limit on the power at 1000.0Hz for a binning of 20 is P = 1.03453823868
The upper limit on the rms amplitude at 1000.0Hz for a binning of 20 is rms = 0.0476834396273
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 487.619047619Hz is p = 0.14 +/- 0.0346987031458
The corresponding value of the T_R statistic at frequency f = [ 2933.84126984] is 2I/S = 2.68475423727
The upper limit on the T_R statistic is 2I/S = 2.89251034728
bintemplate[0]: 133.460739162
The upper limit on the power at 500.0Hz for a binning of 30 is P = 0.914703124193
The upper limit on the rms amplitude at 500.0Hz for a binning of 30 is rms = 0.044836776609
The upper limit on the power at 1000.0Hz for a binning of 30 is P = 0.853179743775
The upper limit on the rms amplitude at 1000.0Hz for a binning of 30 is rms = 0.0433026594563
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 812.698412698Hz is p = 0.32 +/- 0.0466476151588
The corresponding value of the T_R statistic at frequency f = [ 3258.92063492] is 2I/S = 2.34149395087
The upper limit on the T_R statistic is 2I/S = 2.62999830417
bintemplate[0]: 133.460739162
The upper limit on the power at 1000.0Hz for a binning of 50 is P = 0.609618212389
The upper limit on the rms amplitude at 1000.0Hz for a binning of 50 is rms = 0.0366035551144
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 1137.77777778Hz is p = 0.52 +/- 0.0499599839872
The corresponding value of the T_R statistic at frequency f = [ 2283.68253968] is 2I/S = 2.08849382236
The upper limit on the T_R statistic is 2I/S = 2.34412907965
bintemplate[0]: 133.460739162
ninetyfiveperlim: 95
The posterior p-value for the maximum residual power for a binning of 1625.3968254Hz is p = 0.84 +/- 0.0366606055596
The corresponding value of the T_R statistic at frequency f = [ 1633.52380952] is 2I/S = 1.84690327275
The upper limit on the T_R statistic is 2I/S = 2.23176904164
bintemplate[0]: 133.460739162
Bayesian p-value for maximum power P_max =  0.86 +/- 0.0346987031458
Bayesian p-value for maximum power P_max =  0.74 +/- 0.0438634243989
Bayesian p-value for maximum power P_max =  0.72 +/- 0.0448998886413
Bayesian p-value for maximum power P_max =  0.96 +/- 0.0195959179423
Bayesian p-value for deviance D =  0.6 +/- 0.0489897948557
Bayesian p-value for KS test: 0.6 +/- 0.0489897948557
Bayesian p-value for Merit function: 0.89 +/- 0.0312889756943
Bayesian p-value for the np.sum of residuals: 0.5 +/- 0.05

And we're done with the basic QPO search for burst light curves! For convenience, I've made a script that takes the code below and allows you to run it directly from the command line:

`shell> python run_bursts.py -f "sgr1550_burstdata.dat" -d "../data/"`