.. _transient_gw_data:

=====================================
Transient gravitational wave data I/O
=====================================

This document describes how :code:`bilby` handles interferometer data and how
you can load data.

What is used by the likelihood?
-------------------------------

The primary likelihhod for use in transient gravitational wave data analysis
is the `GravitationalWaveTransient <gw_likelihood.html>`_ . This takes
an argument `interferometers` which is a list of
`bilby.gw.detector.Interferometer` objects. These objects know about the
geometry of the detector, the noise properties of the detector, and the
segment of data which is to be analysed. In the following, we'll describe
different ways to initilalse a likelihood for gravitational wave data analysis.

Making an Interferometer
------------------------

To make an empty interferometer, for example the Hanford detector::

   >>> H1 = bilby.gw.detector.get_empty_interferometer('H1')

By default, these will have power spectral densities based on the expected
design sensitivity of the detector. The strain data (i.e. the data about the
segment of interferomer data which we want to analyse) is in an attribute
:code:`H1.strain_data`. The following is a list of ways to set this strain
data.

Setting the strain data
-----------------------

Setting the strain data using gwpy
==================================

The `gwpy <https://gwpy.github.io/>`_ module is the recommended way to read in
and manipulate gravitational wave strain data. For example, here is a snippet
taken from the documentation to obtain the Hanford open date for GW150914::

   >>> from gwpy.timeseries import TimeSeries
   >>> time_series = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478)

Gwpy provides a complete interface for reading any type of data related to
gravitational wave strain data. Once you have created your time series, you can
pass it into your :code:`bilby` interferometer as follows::

   >>> H1.set_strain_data_from_gwpy_time_series(time_series=time_series)


Setting the strain data directly
================================

If you have an array of the frequency-domain strain data, you can set it
directly like this::

   >>> H1.set_strain_data_from_frequency_domain_strain(frequency_domain_strain,
                                                       sampling_frequency=sampling_frequency,
                                                       duration=duration,
                                                       start_time=start_time)

Where the given arguments are things you have already defined in your python
script. If you'd prefer to give the :code:`frequency_array` to which the
data corresponds instead of the :code:`sampling_frequency` and :code:`duration`
this can also be done::

   >>> H1.set_strain_data_from_frequency_domain_strain(frequency_domain_strain,
                                                       sampling_frequency=sampling_frequency,
                                                       duration=duration,
                                                       start_time=start_time)

Setting the strain data to be Gaussian noise
============================================

Often, for testing, you may want to just generate a realization of coloured
Gaussian noise from the power spectral density. This can be done using this
method:

   >>> H1.set_strain_data_from_power_spectral_density

Setting the strain data to be zero noise
========================================

You can also set the strain data without any noise at all

   >>> H1.set_strain_data_from_zero_noise

Injecting a signal
------------------

If you wish to inject a signal into the data, you can use this function:

   >>> bilby.gw.detector.Interferometer.inject_signal

To inject a signal a `bilby.gw.waveform_generator.WaveformGenerator` is required.
This is where you must specify the injection's duration, start-time, waveform.
Additionally, a `parameter_conversion` function can be passed. The default is :code:`parameter_conversion = bilby.gw.conversion.convert_to_lal_binary_black_hole_parameters`.
This expects injection parameters to be provided in the detector-frame, e.g.

.. code-block:: python

    >>> parameters = dict(
        mass_1=36., mass_2=29.,
        a_1=0.4, a_2=0.3, tilt_1=0.5, tilt_2=1.0, phi_12=1.7, phi_jl=0.3,
        luminosity_distance=2000., theta_jn=0.4, psi=2.659,
        phase=1.3, geocent_time=1126259642.413, ra=1.375, dec=-1.2108
        )

