Note

This tutorial was generated from a Jupyter notebook that can be downloaded here. If you’d like to reproduce the results in the notebook, or make changes to the code, we recommend downloading this notebook and running it with Jupyter as certain cells (mostly those that change plot styles) are excluded from the tutorials.

Demo - Compare sensitivity curves

This demo shows how you can use LEGWORK to compare different detector sensitivitity curves. We illustrate these sensitivity curves as well as how the SNR of a source changes in different detectors.

[2]:
import legwork
import numpy as np
import astropy.units as u
import matplotlib.pyplot as plt
from matplotlib.colors import TwoSlopeNorm

from copy import copy
[3]:
%config InlineBackend.figure_format = 'retina'

plt.rc('font', family='serif')
plt.rcParams['text.usetex'] = False
fs = 24

# update various fontsizes to match
params = {'figure.figsize': (12, 8),
          'legend.fontsize': fs,
          'axes.labelsize': fs,
          'xtick.labelsize': 0.7 * fs,
          'ytick.labelsize': 0.7 * fs}
plt.rcParams.update(params)

Direct sensitivity curve comparisons

First, we can plot the sensitivity curves directly to see which regimes are better for different detectors. Let’s look at different LISA specifications as well as the TianQin detector.

[4]:
# create new figure
fig, ax = plt.subplots()

# define the frequency range of interest
fr = np.logspace(-4, 0, 1000) * u.Hz

# plot a sensitivity curve for different mission lengths
linewidth = 4
for i, t_obs in enumerate([0.5, 2.0, 4.0]):
    legwork.visualisation.plot_sensitivity_curve(frequency_range=fr, t_obs=t_obs * u.yr,
                                                 fig=fig, ax=ax, show=False, fill=False, linewidth=linewidth,
                                                 color=plt.get_cmap("Blues")((i + 1) * 0.3),
                                                 label=r"LISA ($t_{{\rm obs}} = {{{}}} \, {{\rm yr}}$)".format(t_obs))

# plot the LISA curve with an approximate response function
legwork.visualisation.plot_sensitivity_curve(frequency_range=fr, approximate_R=True,
                                             fig=fig, ax=ax, show=False, fill=False, linewidth=linewidth,
                                             color=plt.get_cmap("Purples")(0.5),
                                             label=r"LISA (approximate $\mathcal{R}(f)$)")

# plot the TianQin curve
legwork.visualisation.plot_sensitivity_curve(frequency_range=fr, instrument="TianQin", label="TianQin",
                                             fig=fig, ax=ax, show=False, linewidth=linewidth,
                                             color=plt.get_cmap("Greens")(0.6), fill=False)

ax.legend(fontsize=0.7*fs)

plt.show()
../_images/demos_CompareSensitivityCurves_5_0.png

SNR in different detectors

But we need not just look at the sensitivity curve, we could also investigate in what regimes of frequency and eccentricity each detector is superior. Let’s compare a LISA to TianQin with a grid of sources across eccentricity and frequency space.

[5]:
# spread out some frequencies and eccentricities
f_orb_s = np.logspace(-4, -1, 200) * u.Hz
ecc_s = np.linspace(0, 0.9, 150)

# turn them into a grid
F, E = np.meshgrid(f_orb_s, ecc_s)

# flatten the grid
F_flat, E_flat = F.flatten(), E.flatten()

# put all of the sources at the same distance with the same mass
m_1 = np.repeat(10, len(F_flat)) * u.Msun
m_2 = np.repeat(10, len(F_flat)) * u.Msun
dist = np.repeat(8, len(F_flat)) * u.kpc

# define a set of sources
sources = legwork.source.Source(m_1=m_1, m_2=m_2, f_orb=F_flat, ecc=E_flat, dist=dist, gw_lum_tol=1e-3)
sources.get_merger_time()
[5]:
$[0.0040682461,~0.0037085677,~0.0033806889,~\dots,~1.6679556 \times 10^{-13},~1.5204897 \times 10^{-13},~1.3860614 \times 10^{-13}] \; \mathrm{Gyr}$
[6]:
# compute the LISA SNR
LISA_snr = copy(sources.get_snr(verbose=True, which_sources=sources.t_merge > 0.1 * u.yr))
Calculating SNR for 26248 sources
        0 sources have already merged
        13486 sources are stationary
                222 sources are stationary and circular
                13264 sources are stationary and eccentric
        12762 sources are evolving
                158 sources are evolving and circular
                12604 sources are evolving and eccentric
[7]:
# compute the TianQin SNR
sources.update_sc_params({"instrument": "TianQin"})
TQ_snr = sources.get_snr(verbose=True, which_sources=sources.t_merge > 0.1 * u.yr)
Calculating SNR for 26248 sources
        0 sources have already merged
        13126 sources are stationary
                216 sources are stationary and circular
                12910 sources are stationary and eccentric
        13122 sources are evolving
                164 sources are evolving and circular
                12958 sources are evolving and eccentric
[10]:
# create a figure
fig, ax = plt.subplots(figsize=(14, 12))
ax.set_xscale("log")
ax.set_xlabel(r"Orbital Frequency, $f_{\rm orb} \, [{\rm Hz}]$")
ax.set_ylabel(r"Eccentricity, $e$")

ratio = np.zeros_like(LISA_snr)
ratio[LISA_snr > 0] = (LISA_snr[LISA_snr > 0] / TQ_snr[LISA_snr > 0])
ratio = ratio.reshape(F.shape)

# make contours of the ratio of SNR
ratio_cont = ax.contourf(F, E, ratio, cmap="PRGn_r",
                         norm=TwoSlopeNorm(vcenter=1.0, vmin=0.0, vmax=3.6), levels=20)

for c in ratio_cont.collections:
    c.set_edgecolor("face")

# add a line when the SNRs are equal
ax.contour(F, E, ratio, levels=[1.0], colors="grey", linewidths=2.0, linestyles="--")

# add a colourbar
cbar = fig.colorbar(ratio_cont, fraction=2/14, pad=0.02,
                    label=r"$\rho_{\rm LISA} / \rho_{\rm TianQin}$",
                    ticks=np.arange(0, 3.5 + 0.5, 0.5))

# annotate which regions suit each detector
ax.annotate("LISA stronger", xy=(0.1, 0.53), xycoords="axes fraction", fontsize=0.7 * fs,
            color=plt.get_cmap("PRGn_r")(1.0),
            bbox=dict(boxstyle="round", facecolor="white", edgecolor="white", alpha=0.5, pad=0.4))
ax.annotate("TianQin stronger", xy=(0.6, 0.73), xycoords="axes fraction", fontsize=0.7 * fs,
            color=plt.get_cmap("PRGn_r")(0.0),
            bbox=dict(boxstyle="round", facecolor="white", edgecolor="white", alpha=0.5, pad=0.4))

# annotate with source details
source_string = r"$m_1 = {{{}}} \, {{ \rm M_{{\odot}}}}$".format(m_1[0].value)
source_string += "\n"
source_string += r"$m_2 = {{{}}} \, {{ \rm M_{{\odot}}}}$".format(m_1[0].value)
source_string += "\n"
source_string += r"$D_L = {{{}}} \, {{ \rm kpc}}$".format(dist[0].value)
ax.annotate(source_string, xy=(0.98, 0.03), xycoords="axes fraction", ha="right", fontsize=0.75*fs,
            bbox=dict(boxstyle="round", facecolor="white", edgecolor="white", alpha=0.5, pad=0.4))

plt.show()
../_images/demos_CompareSensitivityCurves_10_0.png

From this plot we can see that for circular sources at low frequenies LISA produces a stronger SNR. As eccentricity is increases, the range of frequencies at which LISA is superior decreases until at \(e = 0.9\), TianQin is better at every frequency greater than approximately 0.3mHz!