Analyzing GRB 080916C

[Alt text](https://astrobites.org/wp-content/uploads/2014/10/NASAGRBwhoa-1024x576.jpg ” (NASA/Swift/Cruz deWilde)”) (NASA/Swift/Cruz deWilde)

To demonstrate the capabilities and features of 3ML in, we will go through a time-integrated and time-resolved analysis. This example serves as a standard way to analyze Fermi-GBM data with 3ML as well as a template for how you can design your instrument’s analysis pipeline with 3ML if you have similar data.

[2]:
%%capture
import matplotlib.pyplot as plt
import numpy as np

np.seterr(all="ignore")


from threeML import *
from threeML.io.package_data import get_path_of_data_file

Examining the catalog

As with Swift and Fermi-LAT, 3ML provides a simple interface to the on-line Fermi-GBM catalog. Let’s get the information for GRB 080916C.

[4]:
gbm_catalog = FermiGBMBurstCatalog()
gbm_catalog.query_sources("GRB080916009")
[4]:
Table length=1
nameradectrigger_timet90
objectfloat64float64float64float64
GRB080916009119.800-56.60054725.008861362.977

To aid in quickly replicating the catalog analysis, and thanks to the tireless efforts of the Fermi-GBM team, we have added the ability to extract the analysis parameters from the catalog as well as build an astromodels model with the best fit parameters baked in. Using this information, one can quickly run through the catalog an replicate the entire analysis with a script. Let’s give it a try.

[5]:
grb_info = gbm_catalog.get_detector_information()["GRB080916009"]

gbm_detectors = grb_info["detectors"]
source_interval = grb_info["source"]["fluence"]
background_interval = grb_info["background"]["full"]
best_fit_model = grb_info["best fit model"]["fluence"]
model = gbm_catalog.get_model(best_fit_model, "fluence")["GRB080916009"]
[6]:
model
[6]:
Model summary:

N
Point sources 1
Extended sources 0
Particle sources 0


Free parameters (5):

value min_value max_value unit
GRB080916009.spectrum.main.SmoothlyBrokenPowerLaw.K 0.012255 0.0 None keV-1 s-1 cm-2
GRB080916009.spectrum.main.SmoothlyBrokenPowerLaw.alpha -1.130424 -1.5 2.0
GRB080916009.spectrum.main.SmoothlyBrokenPowerLaw.break_energy 309.2031 10.0 None keV
GRB080916009.spectrum.main.SmoothlyBrokenPowerLaw.break_scale 0.3 0.0 10.0
GRB080916009.spectrum.main.SmoothlyBrokenPowerLaw.beta -2.096931 -5.0 -1.6


Fixed parameters (3):
(abridged. Use complete=True to see all fixed parameters)


Linked parameters (0):

(none)

Independent variables:

(none)

Downloading the data

We provide a simple interface to download the Fermi-GBM data. Using the information from the catalog that we have extracted, we can download just the data from the detectors that were used for the catalog analysis. This will download the CSPEC, TTE and instrument response files from the on-line database.

[7]:
dload = download_GBM_trigger_data("bn080916009", detectors=gbm_detectors)

Let’s first examine the catalof fluence fit. Using the TimeSeriesBuilder, we can fit the background, set the source interval, and create a 3ML plugin for the analysis. We will loop through the detectors, set their appropriate channel selections, and ensure there are enough counts in each bin to make the PGStat profile likelihood valid.

  • First we use the CSPEC data to fit the background using the background selections. We use CSPEC because it has a longer duration for fitting the background.

  • The background is saved to an HDF5 file that stores the polynomial coefficients and selections which we can read in to the TTE file later.

  • The light curve is plotted.

  • The source selection from the catalog is set and DispersionSpectrumLike plugin is created.

  • The plugin has the standard GBM channel selections for spectral analysis set.

[8]:
fluence_plugins = []
time_series = {}
for det in gbm_detectors:

    ts_cspec = TimeSeriesBuilder.from_gbm_cspec_or_ctime(
        det, cspec_or_ctime_file=dload[det]["cspec"], rsp_file=dload[det]["rsp"]
    )

    ts_cspec.set_background_interval(*background_interval.split(","))
    ts_cspec.save_background(f"{det}_bkg.h5", overwrite=True)

    ts_tte = TimeSeriesBuilder.from_gbm_tte(
        det,
        tte_file=dload[det]["tte"],
        rsp_file=dload[det]["rsp"],
        restore_background=f"{det}_bkg.h5",
    )

    time_series[det] = ts_tte

    ts_tte.set_active_time_interval(source_interval)

    ts_tte.view_lightcurve(-40, 100)

    fluence_plugin = ts_tte.to_spectrumlike()

    if det.startswith("b"):

        fluence_plugin.set_active_measurements("250-30000")

    else:

        fluence_plugin.set_active_measurements("9-900")

    fluence_plugin.rebin_on_background(1.0)

    fluence_plugins.append(fluence_plugin)
../_images/notebooks_grb080916C_12_9.png
../_images/notebooks_grb080916C_12_10.png
../_images/notebooks_grb080916C_12_11.png

Setting up the fit

Let’s see if we can reproduce the results from the catalog.

Set priors for the model

We will fit the spectrum using Bayesian analysis, so we must set priors on the model parameters.

[9]:
model.GRB080916009.spectrum.main.shape.alpha.prior = Truncated_gaussian(
    lower_bound=-1.5, upper_bound=1, mu=-1, sigma=0.5
)
model.GRB080916009.spectrum.main.shape.beta.prior = Truncated_gaussian(
    lower_bound=-5, upper_bound=-1.6, mu=-2.25, sigma=0.5
)
model.GRB080916009.spectrum.main.shape.break_energy.prior = Log_normal(mu=2, sigma=1)
model.GRB080916009.spectrum.main.shape.break_energy.bounds = (None, None)
model.GRB080916009.spectrum.main.shape.K.prior = Log_uniform_prior(
    lower_bound=1e-3, upper_bound=1e1
)
model.GRB080916009.spectrum.main.shape.break_scale.prior = Log_uniform_prior(
    lower_bound=1e-4, upper_bound=10
)

Clone the model and setup the Bayesian analysis class

Next, we clone the model we built from the catalog so that we can look at the results later and fit the cloned model. We pass this model and the DataList of the plugins to a BayesianAnalysis class and set the sampler to MultiNest.

[10]:
new_model = clone_model(model)

bayes = BayesianAnalysis(new_model, DataList(*fluence_plugins))

# share spectrum gives a linear speed up when
# spectrumlike plugins have the same RSP input energies
bayes.set_sampler("multinest", share_spectrum=True)

Examine at the catalog fitted model

We can quickly examine how well the catalog fit matches the data. There appears to be a discrepancy between the data and the model! Let’s refit to see if we can fix it.

[11]:
fig = display_spectrum_model_counts(bayes, min_rate=20, step=False)
../_images/notebooks_grb080916C_18_0.png

Run the sampler

We let MultiNest condition the model on the data

[12]:
bayes.sampler.setup(n_live_points=400)
bayes.sample()
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
GRB080916009...K (1.471 -0.017 +0.018) x 10^-2 1 / (cm2 keV s)
GRB080916009...alpha -1.073 +/- 0.016
GRB080916009...break_energy (2.18 +/- 0.24) x 10^2 keV
GRB080916009...break_scale (2.0 +/- 0.8) x 10^-1
GRB080916009...beta -2.12 +/- 0.09

Values of -log(posterior) at the minimum:

-log(posterior)
b0 -1052.086785
n3 -1022.899816
n4 -1014.404375
total -3089.390976

Values of statistical measures:

statistical measures
AIC 6188.952407
BIC 6208.184617
DIC 6176.314762
PDIC 4.363974
log(Z) -1347.914956
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  400
 dimensionality =    5
 *****************************************************
 ln(ev)=  -3103.6888854516783      +/-  0.22543751094307246
 Total Likelihood Evaluations:        22632
 Sampling finished. Exiting MultiNest

Now our model seems to match much better with the data!

[13]:
bayes.restore_median_fit()
fig = display_spectrum_model_counts(bayes, min_rate=20)
../_images/notebooks_grb080916C_22_0.png

But how different are we from the catalog model? Let’s plot our fit along with the catalog model. Luckily, 3ML can handle all the units for is

[14]:
conversion = u.Unit("keV2/(cm2 s keV)").to("erg2/(cm2 s keV)")
energy_grid = np.logspace(1, 4, 100) * u.keV
vFv = (energy_grid ** 2 * model.get_point_source_fluxes(0, energy_grid)).to(
    "erg2/(cm2 s keV)"
)
[15]:
fig = plot_spectra(bayes.results, flux_unit="erg2/(cm2 s keV)")
ax = fig.get_axes()[0]
_ = ax.loglog(energy_grid, vFv, color="blue", label="catalog model")
../_images/notebooks_grb080916C_25_3.png

Time Resolved Analysis

Now that we have examined fluence fit, we can move to performing a time-resolved analysis.

Selecting a temporal binning

We first get the brightest NaI detector and create time bins via the Bayesian blocks algorithm. We can use the fitted background to make sure that our intervals are chosen in an unbiased way.

[16]:
n3 = time_series["n3"]
[17]:
n3.create_time_bins(0, 60, method="bayesblocks", use_background=True, p0=0.2)

Sometimes, glitches in the GBM data cause spikes in the data that the Bayesian blocks algorithm detects as fast changes in the count rate. We will have to remove those intervals manually.

...note In the future, 3ML will provide an automated method to remove these unwanted spikes.
[18]:
fig = n3.view_lightcurve(use_binner=True)
../_images/notebooks_grb080916C_31_0.png
[19]:
bad_bins = []
for i, w in enumerate(n3.bins.widths):

    if w < 5e-2:
        bad_bins.append(i)


edges = [n3.bins.starts[0]]

for i, b in enumerate(n3.bins):

    if i not in bad_bins:
        edges.append(b.stop)

starts = edges[:-1]
stops = edges[1:]


n3.create_time_bins(starts, stops, method="custom")

Now our light curve looks much more acceptable.

[20]:
fig = n3.view_lightcurve(use_binner=True)
../_images/notebooks_grb080916C_34_0.png

The time series objects can read time bins from each other, so we will map these time bins onto the other detectors’ time series and create a list of time plugins for each detector and each time bin created above.

[21]:
time_resolved_plugins = {}

for k, v in time_series.items():
    v.read_bins(n3)
    time_resolved_plugins[k] = v.to_spectrumlike(from_bins=True)

Setting up the model

For the time-resolved analysis, we will fit the classic Band function to the data. We will set some principled priors.

[22]:
band = Band()
band.alpha.prior = Truncated_gaussian(lower_bound=-1.5, upper_bound=1, mu=-1, sigma=0.5)
band.beta.prior = Truncated_gaussian(lower_bound=-5, upper_bound=-1.6, mu=-2, sigma=0.5)
band.xp.prior = Log_normal(mu=2, sigma=1)
band.xp.bounds = (0, None)
band.K.prior = Log_uniform_prior(lower_bound=1e-10, upper_bound=1e3)
ps = PointSource("grb", 0, 0, spectral_shape=band)
band_model = Model(ps)

Perform the fits

One way to perform Bayesian spectral fits to all the intervals is to loop through each one. There can are many ways to do this, so find an analysis pattern that works for you.

[23]:
models = []
results = []
analysis = []
for interval in range(12):

    # clone the model above so that we have a separate model
    # for each fit

    this_model = clone_model(band_model)

    # for each detector set up the plugin
    # for this time interval

    this_data_list = []
    for k, v in time_resolved_plugins.items():

        pi = v[interval]

        if k.startswith("b"):
            pi.set_active_measurements("250-30000")
        else:
            pi.set_active_measurements("9-900")

        pi.rebin_on_background(1.0)

        this_data_list.append(pi)

    # create a data list

    dlist = DataList(*this_data_list)

    # set up the sampler and fit

    bayes = BayesianAnalysis(this_model, dlist)

    # get some speed with share spectrum
    bayes.set_sampler("multinest", share_spectrum=True)
    bayes.sampler.setup(n_live_points=500)
    bayes.sample()

    # at this stage we coudl also
    # save the analysis result to
    # disk but we will simply hold
    # onto them in memory

    analysis.append(bayes)
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.25 -0.23 +0.24) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-6.3 +/- 0.6) x 10^-1
grb.spectrum.main.Band.xp (3.3 +/- 0.4) x 10^2 keV
grb.spectrum.main.Band.beta -1.93 +/- 0.07

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval0 -280.690141
n3_interval0 -245.000952
n4_interval0 -261.357150
total -787.048243

Values of statistical measures:

statistical measures
AIC 1582.209801
BIC 1597.618619
DIC 1560.910648
PDIC 2.236160
log(Z) -344.198508
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (4.32 -0.17 +0.12) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.22 -0.4 +0.28) x 10^-1
grb.spectrum.main.Band.xp (5.6 -0.4 +0.6) x 10^2 keV
grb.spectrum.main.Band.beta -2.24 -0.14 +0.13

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval1 -665.122593
n3_interval1 -634.820545
n4_interval1 -638.542875
total -1938.486013

Values of statistical measures:

statistical measures
AIC 3885.085340
BIC 3900.494157
DIC 3860.375694
PDIC 3.153052
log(Z) -845.107457
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.08 +/- 0.27) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-9.5 -0.8 +1.0) x 10^-1
grb.spectrum.main.Band.xp (3.7 +/- 0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.00 -0.12 +0.11

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval2 -318.135818
n3_interval2 -282.864448
n4_interval2 -305.659843
total -906.660109

Values of statistical measures:

statistical measures
AIC 1821.433532
BIC 1836.842350
DIC 1803.023151
PDIC 3.007453
log(Z) -396.550802
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.2 -0.5 +0.4) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.6 +/- 1.0) x 10^-1
grb.spectrum.main.Band.xp (2.9 +/- 0.5) x 10^2 keV
grb.spectrum.main.Band.beta -1.97 -0.09 +0.12

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval3 -292.062386
n3_interval3 -237.242619
n4_interval3 -257.066680
total -786.371685

Values of statistical measures:

statistical measures
AIC 1580.856685
BIC 1596.265502
DIC 1561.276530
PDIC 2.407588
log(Z) -343.686462
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.06 +/- 0.12) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-9.7 +/- 0.4) x 10^-1
grb.spectrum.main.Band.xp (4.0 +/- 0.4) x 10^2 keV
grb.spectrum.main.Band.beta -2.08 -0.12 +0.13

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval4 -773.490612
n3_interval4 -751.308052
n4_interval4 -741.210096
total -2266.008759

Values of statistical measures:

statistical measures
AIC 4540.130833
BIC 4555.539651
DIC 4520.853301
PDIC 3.755171
log(Z) -986.936394
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.34 -0.09 +0.11) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.08 -0.29 +0.24) x 10^-1
grb.spectrum.main.Band.xp (2.96 -0.14 +0.12) x 10^2 keV
grb.spectrum.main.Band.beta -1.892 -0.012 +0.014

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval5 -533.205509
n3_interval5 -519.687792
n4_interval5 -522.312908
total -1575.206209

Values of statistical measures:

statistical measures
AIC 3158.525733
BIC 3173.934550
DIC 3137.981508
PDIC 1.793461
log(Z) -688.635715
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.01 -0.12 +0.13) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-9.9 +/- 0.5) x 10^-1
grb.spectrum.main.Band.xp (4.2 +/- 0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.57 +/- 0.27

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval6 -607.148020
n3_interval6 -577.853516
n4_interval6 -570.994628
total -1755.996165

Values of statistical measures:

statistical measures
AIC 3520.105644
BIC 3535.514461
DIC 3496.283180
PDIC 2.944686
log(Z) -764.469196
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.69 -0.11 +0.10) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha -1.03 +/- 0.05
grb.spectrum.main.Band.xp (4.2 -0.5 +0.6) x 10^2 keV
grb.spectrum.main.Band.beta -2.50 +/- 0.28

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval7 -659.155256
n3_interval7 -635.201343
n4_interval7 -644.342367
total -1938.698966

Values of statistical measures:

statistical measures
AIC 3885.511247
BIC 3900.920065
DIC 3863.616047
PDIC 3.157185
log(Z) -844.043595
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.57 -0.13 +0.12) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.2 +/- 0.6) x 10^-1
grb.spectrum.main.Band.xp (3.6 -0.4 +0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.52 +/- 0.26

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval8 -696.676882
n3_interval8 -693.538083
n4_interval8 -661.227129
total -2051.442095

Values of statistical measures:

statistical measures
AIC 4110.997505
BIC 4126.406323
DIC 4090.275746
PDIC 3.126589
log(Z) -893.159352
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.7 -1.0 +1.8) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.3 -2.8 +5) x 10^-1
grb.spectrum.main.Band.xp (1.3 -0.7 +0.6) x 10^2 keV
grb.spectrum.main.Band.beta -2.2 -0.4 +0.5

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval9 -646.859516
n3_interval9 -615.271222
n4_interval9 -614.041530
total -1876.172268

Values of statistical measures:

statistical measures
AIC 3760.457850
BIC 3775.866668
DIC 3603.647429
PDIC -142.374494
log(Z) -817.658991
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.3 -0.7 +0.6) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-7.3 -1.8 +2.0) x 10^-1
grb.spectrum.main.Band.xp (2.1 -0.6 +0.7) x 10^2 keV
grb.spectrum.main.Band.beta -2.09 -0.30 +0.27

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval10 -457.385159
n3_interval10 -433.754129
n4_interval10 -429.043591
total -1320.182879

Values of statistical measures:

statistical measures
AIC 2648.479073
BIC 2663.887891
DIC 2627.671543
PDIC -1.826170
log(Z) -575.593587
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.2 +/- 1.3) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-4.6 -2.4 +2.6) x 10^-1
grb.spectrum.main.Band.xp (1.30 -0.27 +0.28) x 10^2 keV
grb.spectrum.main.Band.beta -2.25 -0.33 +0.32

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval11 -289.578909
n3_interval11 -268.934023
n4_interval11 -252.495857
total -811.008790

Values of statistical measures:

statistical measures
AIC 1630.130894
BIC 1645.539711
DIC 1613.250130
PDIC 0.751176
log(Z) -353.409802
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -792.54635272331518      +/-  0.18926356928624652
 Total Likelihood Evaluations:        16944
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1945.9318317790173      +/-  0.21570673051081790
 Total Likelihood Evaluations:        22820
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -913.09196475243277      +/-  0.18923355638944594
 Total Likelihood Evaluations:        20502
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -791.36732294892602      +/-  0.18023014465256723
 Total Likelihood Evaluations:        17885
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -2272.5050274618675      +/-  0.19372856144644462
 Total Likelihood Evaluations:        21957
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1585.6423308780916      +/-  0.20945418610903552
 Total Likelihood Evaluations:        19238
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1760.2553756497773      +/-  0.19382761154824582
 Total Likelihood Evaluations:        20349
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1943.4822000601039      +/-  0.19140667486601343
 Total Likelihood Evaluations:        20510
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -2056.5754093346027      +/-  0.18861062055863564
 Total Likelihood Evaluations:        18912
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1882.7294028109061      +/-  0.15746457790614471
 Total Likelihood Evaluations:        12185
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -1325.3532127547080      +/-  0.16878427385616979
 Total Likelihood Evaluations:        15427
 Sampling finished. Exiting MultiNest
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -813.75614219966621      +/-  0.14628358087285478
 Total Likelihood Evaluations:        12665
 Sampling finished. Exiting MultiNest

Examine the fits

Now we can look at the fits in count space to make sure they are ok.

[24]:
for a in analysis:
    a.restore_median_fit()
    _ = display_spectrum_model_counts(a, min_rate=[20, 20, -99], step=False)
../_images/notebooks_grb080916C_42_0.png
../_images/notebooks_grb080916C_42_1.png
../_images/notebooks_grb080916C_42_2.png
../_images/notebooks_grb080916C_42_3.png
../_images/notebooks_grb080916C_42_4.png
../_images/notebooks_grb080916C_42_5.png
../_images/notebooks_grb080916C_42_6.png
../_images/notebooks_grb080916C_42_7.png
../_images/notebooks_grb080916C_42_8.png
../_images/notebooks_grb080916C_42_9.png
../_images/notebooks_grb080916C_42_10.png
../_images/notebooks_grb080916C_42_11.png

Finally, we can plot the models together to see how the spectra evolve with time.

[25]:
fig = plot_spectra(
    *[a.results for a in analysis[::1]],
    flux_unit="erg2/(cm2 s keV)",
    fit_cmap="viridis",
    contour_cmap="viridis",
    contour_style_kwargs=dict(alpha=0.1),
)
../_images/notebooks_grb080916C_44_14.png

This example can serve as a template for performing analysis on GBM data. However, as 3ML provides an abstract interface and modular building blocks, similar analysis pipelines can be built for any time series data.