Timeseries and TD Reconstructions¶
Another common plot to understand data is the time domain plot. These are the most intuitive way to understand the data, since they reflect the data as the detector actually sees it. When the waveform reconstruction is plotted on top of this, it helps understand the behavior of the waveform and allows us to draw a connection between it's morphology, the data, and the inferred parameters.
In this example, we'll plot the whitened time domain data for an example analysis, then add a reconstruction from the posterior.
Preliminaries¶
# For the purposes of notebook readability, we'll surpress the various logging messages from gwpy, lal, bilby, etc
import warnings
warnings.filterwarnings("ignore", "Wswiglal-redir-stdio")
import logging
logging.disable(logging.CRITICAL)
import bilby
import ptfp
import numpy as np
from gwpy.timeseries import TimeSeries
import matplotlib.pyplot as plt
ptfp.configuration.set_better_matplotlib_defaults(fontsize=12)
%matplotlib inline
# Loading in components as in the Spectrograms example
result, data_dump, analysis, likelihood = ptfp.bilby_pipe_interface.get_all_analysis_components("/home/rhiannon.udall/PlottingToolsForPEExampleRun/GW150914_bilby_output")
Plotting the Time Domain Data¶
We are interested in the whitened time domain data, since this is easier to read and shows the degree to which early parts of the waveform are supressed by the noise more effectively. This can now be obtained quite simply with bilby from the interferometer, so we start by simply plotting this data.
One difference vs the spectrograms is that for these we also keep the mask applied to the data to determine which values are actually plotted - the data is always passed in and put out with the full set of times - and this mask will be useful for the TD reconstructions later.
fig, (lho_ax, llo_ax) = plt.subplots(2, 1, tight_layout=True)
_, _, lho_mask = ptfp.time_domain_plots.plot_time_domain_data(
data_dump.interferometers[0].whitened_time_domain_strain,
times=data_dump.interferometers[0].time_array,
start_time=result.start_time+5.5,
end_time=result.start_time+6.5,
timeseries_plot_kws={'color':'C1','alpha':0.3},
fig_and_ax=(fig, lho_ax)
)
_, _, llo_mask = ptfp.time_domain_plots.plot_time_domain_data(
data_dump.interferometers[1].whitened_time_domain_strain,
times=data_dump.interferometers[1].time_array,
start_time=result.start_time+5.5,
end_time=result.start_time+6.5,
timeseries_plot_kws={'color':'C1','alpha':0.3},
fig_and_ax=(fig, llo_ax)
)
lho_ax.set_ylabel("Whitened Strain")
lho_ax.set_title("Hanford")
llo_ax.set_ylabel("Whitened Strain")
llo_ax.set_title("Livingston")
Text(0.5, 1.0, 'Livingston')
As with the spectrograms example, we'll adjust the time tick labeling:
ptfp.time_domain_plots.force_axis_time_offset(
lho_ax,
new_ticks=np.linspace(-0.5, 0.5, 11),
tick_offset=result.start_time+6
)
ptfp.time_domain_plots.force_axis_time_offset(
llo_ax,
new_ticks=np.linspace(-0.5, 0.5, 11),
tick_offset=result.start_time+6
)
<Axes: title={'center': 'Livingston'}, xlabel='Time [s]', ylabel='Whitened Strain'>
fig
Adding Time Domain Waveform Reconstructions¶
As with the time-frequency tracks, this process is split into two parts since one involves costly waveform computations. The generating function produces all four versions of each waveform - whitened and unwhitened, time and frequency domain. We're only interested in the whitened TD for these purposes, so we'll ignore the others.
_, _, _, lho_whitened_td_posterior = ptfp.waveforms.get_waveform_posterior(
result.posterior,
likelihood.waveform_generator,
data_dump.interferometers[0],
time_window_mask=lho_mask
)
_, _, _, llo_whitened_td_posterior = ptfp.waveforms.get_waveform_posterior(
result.posterior,
likelihood.waveform_generator,
data_dump.interferometers[1],
time_window_mask=llo_mask
)
ptfp.time_domain_plots.plot_time_domain_posterior(
lho_whitened_td_posterior,
times=data_dump.interferometers[0].time_array,
posterior_color='C0',
posterior_label="Signal",
fig_and_ax=(fig, lho_ax)
)
ptfp.time_domain_plots.plot_time_domain_posterior(
llo_whitened_td_posterior,
times=data_dump.interferometers[1].time_array,
posterior_color='C0',
posterior_label="Signal",
fig_and_ax=(fig, llo_ax)
)
/home/rhiannon.udall/.conda/envs/bilby-MRs-testing/lib/python3.11/site-packages/ptfp/time_domain_plots.py:138: RuntimeWarning: All-NaN slice encountered np.nanmedian(posterior, axis=0), /home/rhiannon.udall/.conda/envs/bilby-MRs-testing/lib/python3.11/site-packages/numpy/lib/nanfunctions.py:1563: RuntimeWarning: All-NaN slice encountered return function_base._ureduce(a,
(<Figure size 1687.5x1687.5 with 2 Axes>, <Axes: title={'center': 'Livingston'}, xlabel='Time [s]', ylabel='Whitened Strain'>)
fig