Compact binary coalescence parameter estimation

In this example, we demonstrate how to generate simulated data for a binary black hole coalescence observed by the two LIGO interferometers at Hanford and Livingston for all parameters in the IMRPhenomPv2 waveform model.

The code will take around 8 hours to run.

For testing, you may prefer to run the 4-parameter CBC tutorial.

  1#!/usr/bin/env python
  2"""
  3Tutorial to demonstrate running parameter estimation on a full 15 parameter
  4space for an injected cbc signal. This is the standard injection analysis script
  5one can modify for the study of injected CBC events.
  6
  7This will take many hours to run.
  8"""
  9import bilby
 10import numpy as np
 11from bilby.core.utils import random
 12
 13# Sets seed of bilby's generator "rng" to "123" to ensure reproducibility
 14random.seed(123)
 15
 16# Set the duration and sampling frequency of the data segment that we're
 17# going to inject the signal into
 18duration = 4.0
 19sampling_frequency = 1024.0
 20
 21# Specify the output directory and the name of the simulation.
 22outdir = "outdir"
 23label = "full_15_parameters"
 24bilby.core.utils.setup_logger(outdir=outdir, label=label)
 25
 26
 27# We are going to inject a binary black hole waveform.  We first establish a
 28# dictionary of parameters that includes all of the different waveform
 29# parameters, including masses of the two black holes (mass_1, mass_2),
 30# spins of both black holes (a, tilt, phi), etc.
 31injection_parameters = dict(
 32    mass_1=36.0,
 33    mass_2=29.0,
 34    a_1=0.4,
 35    a_2=0.3,
 36    tilt_1=0.5,
 37    tilt_2=1.0,
 38    phi_12=1.7,
 39    phi_jl=0.3,
 40    luminosity_distance=2000.0,
 41    theta_jn=0.4,
 42    psi=2.659,
 43    phase=1.3,
 44    geocent_time=1126259642.413,
 45    ra=1.375,
 46    dec=-1.2108,
 47)
 48
 49# Fixed arguments passed into the source model
 50waveform_arguments = dict(
 51    waveform_approximant="IMRPhenomXPHM",
 52    reference_frequency=50.0,
 53    minimum_frequency=20.0,
 54)
 55
 56# Create the waveform_generator using a LAL BinaryBlackHole source function
 57# the generator will convert all the parameters
 58waveform_generator = bilby.gw.WaveformGenerator(
 59    duration=duration,
 60    sampling_frequency=sampling_frequency,
 61    frequency_domain_source_model=bilby.gw.source.lal_binary_black_hole,
 62    parameter_conversion=bilby.gw.conversion.convert_to_lal_binary_black_hole_parameters,
 63    waveform_arguments=waveform_arguments,
 64)
 65
 66# Set up interferometers.  In this case we'll use two interferometers
 67# (LIGO-Hanford (H1), LIGO-Livingston (L1). These default to their design
 68# sensitivity
 69ifos = bilby.gw.detector.InterferometerList(["H1", "L1"])
 70ifos.set_strain_data_from_power_spectral_densities(
 71    sampling_frequency=sampling_frequency,
 72    duration=duration,
 73    start_time=injection_parameters["geocent_time"] - 2,
 74)
 75
 76ifos.inject_signal(
 77    waveform_generator=waveform_generator, parameters=injection_parameters
 78)
 79
 80# For this analysis, we implement the standard BBH priors defined, except for
 81# the definition of the time prior, which is defined as uniform about the
 82# injected value.
 83# We change the mass boundaries to be more targeted for the source we
 84# injected.
 85# We define priors in the time at the Hanford interferometer and two
 86# parameters (zenith, azimuth) defining the sky position wrt the two
 87# interferometers.
 88priors = bilby.gw.prior.BBHPriorDict()
 89
 90time_delay = ifos[0].time_delay_from_geocenter(
 91    injection_parameters["ra"],
 92    injection_parameters["dec"],
 93    injection_parameters["geocent_time"],
 94)
 95priors["H1_time"] = bilby.core.prior.Uniform(
 96    minimum=injection_parameters["geocent_time"] + time_delay - 0.1,
 97    maximum=injection_parameters["geocent_time"] + time_delay + 0.1,
 98    name="H1_time",
 99    latex_label="$t_H$",
100    unit="$s$",
101)
102del priors["ra"], priors["dec"]
103priors["zenith"] = bilby.core.prior.Sine(latex_label="$\\kappa$")
104priors["azimuth"] = bilby.core.prior.Uniform(
105    minimum=0, maximum=2 * np.pi, latex_label="$\\epsilon$", boundary="periodic"
106)
107
108# Initialise the likelihood by passing in the interferometer data (ifos) and
109# the waveoform generator, as well the priors.
110# The explicit distance marginalization is turned on to improve
111# convergence, and the posterior is recovered by the conversion function.
112likelihood = bilby.gw.GravitationalWaveTransient(
113    interferometers=ifos,
114    waveform_generator=waveform_generator,
115    priors=priors,
116    distance_marginalization=True,
117    phase_marginalization=False,
118    time_marginalization=False,
119    reference_frame="H1L1",
120    time_reference="H1",
121)
122
123# Run sampler. In this case we're going to use the `dynesty` sampler
124# Note that the `nlive`, `naccept`, and `sample` parameters are specified
125# to ensure sufficient convergence of the analysis.
126# We set `npool=16` to parallelize the analysis over 16 cores.
127# The conversion function will determine the distance posterior in post processing
128result = bilby.run_sampler(
129    likelihood=likelihood,
130    priors=priors,
131    sampler="dynesty",
132    nlive=1000,
133    naccept=60,
134    sample="acceptance-walk",
135    npool=16,
136    injection_parameters=injection_parameters,
137    outdir=outdir,
138    label=label,
139    conversion_function=bilby.gw.conversion.generate_all_bbh_parameters,
140    result_class=bilby.gw.result.CBCResult,
141    rstate=random.rng,
142)
143
144# Plot the inferred waveform superposed on the actual data.
145result.plot_waveform_posterior(n_samples=1000)
146
147# Make a corner plot.
148result.plot_corner()

Running this script will generate data then perform parameter estimation. In doing all of this, it prints information about the matched-filter SNRs in each detector (saved to the log-file). Moreover, it generates a plot for each detector showing the data, amplitude spectral density (ASD) and the signal; here is an example for the Hanford detector:

_images/full_15_parameters_H1_waveform.png

Finally, after running the parameter estimation. It generates a corner plot:

_images/full_15_parameters_corner.png

The solid lines indicate the injection parameters.