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 in your browser.

  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"""
  9
 10import bilby
 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
 80time_delay = ifos[0].time_delay_from_geocenter(
 81    injection_parameters["ra"],
 82    injection_parameters["dec"],
 83    injection_parameters["geocent_time"],
 84)
 85
 86injection_parameters["H1_time"] = injection_parameters["geocent_time"] + time_delay
 87
 88# For this analysis, we implement the standard BBH priors defined, except for
 89# the definition of the time prior, which is defined as uniform about the
 90# injected value.
 91# We change the mass boundaries to be more targeted for the source we
 92# injected.
 93# We define a prior in the time at the Hanford interferometer
 94priors = bilby.gw.prior.BBHPriorDict()
 95
 96priors["H1_time"] = bilby.core.prior.Uniform(
 97    minimum=injection_parameters["H1_time"] - 0.1,
 98    maximum=injection_parameters["H1_time"] + 0.1,
 99    name="H1_time",
100    latex_label="$t_H$",
101    unit="$s$",
102)
103
104# Initialise the likelihood by passing in the interferometer data (ifos) and
105# the waveoform generator, as well the priors.
106# The explicit distance marginalization is turned on to improve
107# convergence, and the posterior is recovered by the conversion function.
108likelihood = bilby.gw.GravitationalWaveTransient(
109    interferometers=ifos,
110    waveform_generator=waveform_generator,
111    priors=priors,
112    distance_marginalization=True,
113    phase_marginalization=False,
114    time_marginalization=False,
115    reference_frame="H1L1",
116    time_reference="H1",
117)
118
119# Run sampler. In this case we're going to use the `dynesty` sampler
120# Note that the `nlive`, `naccept`, and `sample` parameters are specified
121# to ensure sufficient convergence of the analysis.
122# We set `npool=16` to parallelize the analysis over 16 cores.
123# The conversion function will determine the distance posterior in post processing
124result = bilby.run_sampler(
125    likelihood=likelihood,
126    priors=priors,
127    sampler="dynesty",
128    nlive=1000,
129    naccept=60,
130    sample="acceptance-walk",
131    npool=16,
132    injection_parameters=injection_parameters,
133    outdir=outdir,
134    label=label,
135    conversion_function=bilby.gw.conversion.generate_all_bbh_parameters,
136    result_class=bilby.gw.result.CBCResult,
137    rstate=random.rng,
138)
139
140# Plot the inferred waveform superposed on the actual data.
141result.plot_waveform_posterior(n_samples=1000)
142
143# Make a corner plot.
144result.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.