Analyzing GRB 080916C

Alt text (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.

3ML provides utilities to reduce time series data to plugins in a correct and statistically justified way (e.g., background fitting of Poisson data is done with a Poisson likelihood). The approach is generic and can be extended. For more details, see the time series documentation.

[1]:
import warnings

warnings.simplefilter("ignore")
[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
[3]:

silence_warnings() %matplotlib inline from jupyterthemes import jtplot jtplot.style(context="talk", fscale=1, ticks=True, grid=False) set_threeML_style()

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")
13:47:01 INFO      The cache for fermigbrst does not yet exist. We will try to    get_heasarc_table_as_pandas.py:66
                  build it                                                                                         
                                                                                                                   
         INFO      Building cache for fermigbrst                                 get_heasarc_table_as_pandas.py:112
[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)


Properties (0):

(none)


Linked parameters (0):

(none)

Independent variables:

(none)

Linked functions (0):

(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 catalog 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)
13:48:02 INFO      Auto-determined polynomial order: 0                                binned_spectrum_series.py:391
13:48:19 INFO      None 0-order polynomial fit with the mle method                               time_series.py:459
         INFO      Saved fitted background to n3_bkg.h5                                         time_series.py:1064
         INFO      Saved background to n3_bkg.h5                                         time_series_builder.py:471
13:48:20 INFO      Successfully restored fit from n3_bkg.h5                              time_series_builder.py:171
         INFO      Interval set to 1.28-64.257 for n3                                    time_series_builder.py:291
         INFO      Auto-probed noise models:                                                    SpectrumLike.py:491
         INFO      - observation: poisson                                                       SpectrumLike.py:492
         INFO      - background: gaussian                                                       SpectrumLike.py:493
         INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
13:48:23 INFO      Now using 120 bins                                                          SpectrumLike.py:1735
13:48:26 INFO      Auto-determined polynomial order: 1                                binned_spectrum_series.py:391
13:48:44 INFO      None 1-order polynomial fit with the mle method                               time_series.py:459
         INFO      Saved fitted background to n4_bkg.h5                                         time_series.py:1064
         INFO      Saved background to n4_bkg.h5                                         time_series_builder.py:471
13:48:45 INFO      Successfully restored fit from n4_bkg.h5                              time_series_builder.py:171
         INFO      Interval set to 1.28-64.257 for n4                                    time_series_builder.py:291
         INFO      Auto-probed noise models:                                                    SpectrumLike.py:491
         INFO      - observation: poisson                                                       SpectrumLike.py:492
         INFO      - background: gaussian                                                       SpectrumLike.py:493
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
13:48:48 INFO      Auto-determined polynomial order: 1                                binned_spectrum_series.py:391
13:49:06 INFO      None 1-order polynomial fit with the mle method                               time_series.py:459
         INFO      Saved fitted background to b0_bkg.h5                                         time_series.py:1064
         INFO      Saved background to b0_bkg.h5                                         time_series_builder.py:471
         INFO      Successfully restored fit from b0_bkg.h5                              time_series_builder.py:171
         INFO      Interval set to 1.28-64.257 for b0                                    time_series_builder.py:291
13:49:07 INFO      Auto-probed noise models:                                                    SpectrumLike.py:491
         INFO      - observation: poisson                                                       SpectrumLike.py:492
         INFO      - background: gaussian                                                       SpectrumLike.py:493
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
../_images/notebooks_grb080916C_12_42.png
../_images/notebooks_grb080916C_12_43.png
../_images/notebooks_grb080916C_12_44.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)
13:49:08 INFO      sampler set to multinest                                                bayesian_analysis.py:233

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.468 +/- 0.018) x 10^-2 1 / (cm2 keV s)
GRB080916009...alpha -1.080 +/- 0.016
GRB080916009...break_energy (2.18 -0.24 +0.22) x 10^2 keV
GRB080916009...break_scale (2.1 +/- 0.8) x 10^-1
GRB080916009...beta -2.05 -0.06 +0.07

Values of -log(posterior) at the minimum:

-log(posterior)
b0 -1050.300841
n3 -1020.009143
n4 -1011.191114
total -3081.501098

Values of statistical measures:

statistical measures
AIC 6173.172650
BIC 6192.404860
DIC 6178.220344
PDIC 3.572092
log(Z) -1347.282149
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

 no. of live points =  400
 dimensionality =    5
 *****************************************************
 ln(ev)=  -3102.2317930588292      +/-  0.22947579393365405
 Total Likelihood Evaluations:        20754
 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_2.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)
13:51:46 INFO      Created 15 bins via bayesblocks                                       time_series_builder.py:708

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_30_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")
13:51:47 INFO      Created 12 bins via custom                                            time_series_builder.py:708

Now our light curve looks much more acceptable.

[20]:
fig = n3.view_lightcurve(use_binner=True)
../_images/notebooks_grb080916C_33_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)
         INFO      Created 12 bins via custom                                            time_series_builder.py:708
13:51:48 INFO      Interval set to 1.28-64.257 for n3                                    time_series_builder.py:291
         INFO      Created 12 bins via custom                                            time_series_builder.py:708
13:51:49 INFO      Interval set to 1.28-64.257 for n4                                    time_series_builder.py:291
         INFO      Created 12 bins via custom                                            time_series_builder.py:708
13:51:50 INFO      Interval set to 1.28-64.257 for b0                                    time_series_builder.py:291

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)
         INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 107 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.5 -0.6 +0.5) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-5.6 -1.2 +1.3) x 10^-1
grb.spectrum.main.Band.xp (3.4 +/- 0.6) x 10^2 keV
grb.spectrum.main.Band.beta -2.22 +/- 0.27

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval0 -285.728453
n3_interval0 -250.300015
n4_interval0 -268.044501
total -804.072968

Values of statistical measures:

statistical measures
AIC 1616.259251
BIC 1631.668068
DIC 1570.847674
PDIC 2.619610
log(Z) -342.250118
13:52:09 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (5.08 +/- 0.06) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-6.77 -0.07 +0.05) x 10^-1
grb.spectrum.main.Band.xp (4.26 +/- 0.12) x 10^2 keV
grb.spectrum.main.Band.beta -2.251 -0.009 +0.014

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval1 -686.647025
n3_interval1 -647.955528
n4_interval1 -647.261009
total -1981.863563

Values of statistical measures:

statistical measures
AIC 3971.840440
BIC 3987.249257
DIC 3919.407439
PDIC 1.280434
log(Z) -857.093031
13:52:38 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 115 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.83 -0.4 +0.32) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha -1.03 -0.08 +0.07
grb.spectrum.main.Band.xp (4.3 -1.2 +1.3) x 10^2 keV
grb.spectrum.main.Band.beta -1.72 -0.05 +0.07

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval2 -323.759314
n3_interval2 -288.407173
n4_interval2 -311.124608
total -923.291095

Values of statistical measures:

statistical measures
AIC 1854.695504
BIC 1870.104321
DIC 1806.205218
PDIC 2.190793
log(Z) -394.758726
13:53:01 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 109 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (4.2 -0.7 +0.6) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-7.7 -1.3 +1.2) x 10^-1
grb.spectrum.main.Band.xp (1.95 -0.30 +0.25) x 10^2 keV
grb.spectrum.main.Band.beta -1.75 +/- 0.05

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval3 -298.791954
n3_interval3 -241.898805
n4_interval3 -261.818269
total -802.509029

Values of statistical measures:

statistical measures
AIC 1613.131371
BIC 1628.540189
DIC 1575.788757
PDIC 1.308701
log(Z) -344.992194
13:53:26 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.04 -0.12 +0.11) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-9.8 +/- 0.4) x 10^-1
grb.spectrum.main.Band.xp (4.1 +/- 0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.00 +/- 0.10

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval4 -778.453858
n3_interval4 -757.302078
n4_interval4 -746.442279
total -2282.198214

Values of statistical measures:

statistical measures
AIC 4572.509743
BIC 4587.918561
DIC 4528.339492
PDIC 3.662013
log(Z) -985.860142
13:53:49 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.92 -0.14 +0.15) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.77 -0.31 +0.33) x 10^-1
grb.spectrum.main.Band.xp (4.0 +/- 0.4) x 10^2 keV
grb.spectrum.main.Band.beta -2.21 -0.08 +0.09

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval5 -536.807541
n3_interval5 -523.756973
n4_interval5 -527.476385
total -1588.040898

Values of statistical measures:

statistical measures
AIC 3184.195111
BIC 3199.603929
DIC 3134.537195
PDIC 2.095271
log(Z) -684.008522
13:54:11 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (2.06 -0.09 +0.11) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-9.76 -0.28 +0.26) x 10^-1
grb.spectrum.main.Band.xp (3.99 -0.5 +0.35) x 10^2 keV
grb.spectrum.main.Band.beta -2.42 -0.18 +0.28

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval6 -609.230162
n3_interval6 -584.420129
n4_interval6 -576.537805
total -1770.188097

Values of statistical measures:

statistical measures
AIC 3548.489508
BIC 3563.898326
DIC 3499.771709
PDIC 2.314083
log(Z) -762.675757
13:54:32 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.66 +/- 0.11) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha -1.05 +/- 0.05
grb.spectrum.main.Band.xp (4.5 +/- 0.7) x 10^2 keV
grb.spectrum.main.Band.beta -2.41 +/- 0.28

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval7 -662.239009
n3_interval7 -640.942085
n4_interval7 -650.243116
total -1953.424211

Values of statistical measures:

statistical measures
AIC 3914.961736
BIC 3930.370553
DIC 3869.252531
PDIC 3.481362
log(Z) -842.085107
13:54:53 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.55 -0.14 +0.15) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.7 +/- 0.6) x 10^-1
grb.spectrum.main.Band.xp (3.7 -0.7 +0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.10 -0.06 +0.08

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval8 -702.662246
n3_interval8 -697.987601
n4_interval8 -666.507427
total -2067.157275

Values of statistical measures:

statistical measures
AIC 4142.427864
BIC 4157.836681
DIC 4099.387049
PDIC 3.089798
log(Z) -893.409214
13:55:15 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.3 +/- 0.5) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.4 -1.8 +1.7) x 10^-1
grb.spectrum.main.Band.xp (1.14 -0.4 +0.33) x 10^2 keV
grb.spectrum.main.Band.beta -1.86 -0.13 +0.12

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval9 -648.441274
n3_interval9 -616.956564
n4_interval9 -616.265026
total -1881.662864

Values of statistical measures:

statistical measures
AIC 3771.439042
BIC 3786.847860
DIC 3741.215187
PDIC -4.726580
log(Z) -816.269917
13:55:30 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (1.87 -0.29 +0.30) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-8.0 +/- 1.0) x 10^-1
grb.spectrum.main.Band.xp (2.6 -0.4 +0.5) x 10^2 keV
grb.spectrum.main.Band.beta -2.35 -0.24 +0.25

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval10 -460.754693
n3_interval10 -437.725470
n4_interval10 -433.261802
total -1331.741964

Values of statistical measures:

statistical measures
AIC 2671.597243
BIC 2687.006061
DIC 2636.223447
PDIC 2.108867
log(Z) -573.954687
13:55:47 INFO      Range 9-900 translates to channels 5-124                                    SpectrumLike.py:1245
         INFO      Now using 120 bins                                                          SpectrumLike.py:1735
         INFO      Range 9-900 translates to channels 5-123                                    SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      Range 250-30000 translates to channels 1-119                                SpectrumLike.py:1245
         INFO      Now using 119 bins                                                          SpectrumLike.py:1735
         INFO      sampler set to multinest                                                bayesian_analysis.py:233
  analysing data from chains/fit-.txt
Maximum a posteriori probability (MAP) point:

result unit
parameter
grb.spectrum.main.Band.K (3.6 -1.6 +1.4) x 10^-2 1 / (cm2 keV s)
grb.spectrum.main.Band.alpha (-4.3 +/- 2.7) x 10^-1
grb.spectrum.main.Band.xp (1.29 -0.31 +0.30) x 10^2 keV
grb.spectrum.main.Band.beta -2.22 -0.33 +0.32

Values of -log(posterior) at the minimum:

-log(posterior)
b0_interval11 -292.437645
n3_interval11 -272.467129
n4_interval11 -255.854490
total -820.759264

Values of statistical measures:

statistical measures
AIC 1649.631842
BIC 1665.040660
DIC 1615.443595
PDIC -1.917689
log(Z) -352.568117
 *****************************************************
 MultiNest v3.10
 Copyright Farhan Feroz & Mike Hobson
 Release Jul 2015

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

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

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

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

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

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

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

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

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

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

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

 no. of live points =  500
 dimensionality =    4
 *****************************************************
 ln(ev)=  -811.81809157081102      +/-  0.14560703417623524
 Total Likelihood Evaluations:        12518
 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, 20], step=False)
../_images/notebooks_grb080916C_41_0.png
../_images/notebooks_grb080916C_41_1.png
../_images/notebooks_grb080916C_41_2.png
../_images/notebooks_grb080916C_41_3.png
../_images/notebooks_grb080916C_41_4.png
../_images/notebooks_grb080916C_41_5.png
../_images/notebooks_grb080916C_41_6.png
../_images/notebooks_grb080916C_41_7.png
../_images/notebooks_grb080916C_41_8.png
../_images/notebooks_grb080916C_41_9.png
../_images/notebooks_grb080916C_41_10.png
../_images/notebooks_grb080916C_41_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_43_13.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.