Computing Remnant Properties from NRSur7dq4 Waveforms

This notebook generates waveforms using the NRSur7dq4 surrogate model, computes remnant properties with gw_remnant, and compares against the NRSur7dq4Remnant fit.

Requires pip install gw_remnant[surrogates].

Contact: Tousif Islam [tousifislam24@gmail.com]

1. Setup

[1]:
import warnings
warnings.filterwarnings("ignore", "Wswiglal-redir-stdio")
import numpy as np
import gwsurrogate
import surfinBH
import gwtools
from gw_remnant.gw_remnant_calculator import GWRemnantCalculator
from gw_remnant.gw_utils import waveform_generator
lal.MSUN_SI != Msun
[2]:
sur = gwsurrogate.LoadSurrogate('NRSur7dq4')
fit = surfinBH.LoadFits('NRSur7dq4Remnant')
Loaded NRSur7dq4 model
Loaded NRSur7dq4Remnant fit.
[3]:
def compare_remnants(calc, fit, q, chi1, chi2, omega0):
    """Print a side-by-side comparison of gw_remnant vs NRSur7dq4Remnant."""
    mf, chif, vf, mf_err, chif_err, vf_err = fit.all(q, chi1, chi2, omega0=omega0)

    print(f"{'Property':<25} {'gw_remnant':>15} {'NRSur7dq4Remnant':>20}")
    print("-" * 62)
    print(f"{'Remnant mass [M]':<25} {calc.remnant_mass:>15.6f} {mf:>20.6f}")
    print(f"{'Remnant spin (z)':<25} {calc.remnant_spin:>15.6f} {chif[2]:>20.6f}")
    print(f"{'Remnant |chi|':<25} {np.linalg.norm(calc.remnant_spin_vector):>15.6f} {np.linalg.norm(chif):>20.6f}")
    print(f"{'Kick velocity [c]':<25} {calc.remnant_kick:>15.6f} {np.linalg.norm(vf):>20.6f}")
    print(f"{'Spin vector':<25} {np.array2string(calc.remnant_spin_vector, precision=4):>15}")
    print(f"{'':25} {np.array2string(chif, precision=4):>15}  (NRSur7dq4Remnant)")

2. Non-spinning binary (q = 2)

[4]:
q = 2.0
chi1 = [0, 0, 0]
chi2 = [0, 0, 0]

times, h = waveform_generator.generate_nrsur7dq4(sur, q=q, chi1=chi1, chi2=chi2)
NRSur7dq4 time grid: [-4299.55, 100.45] M
Output time grid: [-4000.00, 49.90] M
[5]:
calc_ns = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
calc_ns.print_remnants()
==================================================
Remnant Properties Summary
==================================================
Mass ratio                    : 2.000
Initial mass                  : 1.00000000 M
Total energy radiated         : 0.03164319 M
Peak luminosity               : 0.00076585
Remnant mass                  : 0.96137688 M
Remnant spin (dimensionless)  : 0.61992975
Remnant spin vector (x,y,z)  : (0.00001354, 0.00003122, 0.61992975)
Remnant kick velocity         : 0.00049130 c
Remnant kick velocity         : 147.29 km/s
Remnant kick vector (x,y,z)  : (-0.00048506, 0.00007767, -0.00000779) c
Remnant displacement (x,y,z) : (-0.01430924, 0.00316052, -0.00027950) M
==================================================
/var/folders/9k/xlxjfz4d2cz1063spty94p0r0000gq/T/ipykernel_23607/3385016684.py:1: UserWarning: Tips: If you are using NR waveforms, ensure that they do not contain junk radiation, as that is known to corrupt the remnant property estimation.
  calc_ns = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
[6]:
omega0 = abs(np.gradient(0.5 * gwtools.phase(h[(2, 2)])) / np.gradient(times))[0]
compare_remnants(calc_ns, fit, q, chi1, chi2, omega0)
Loaded NRSur7dq4 model
Property                       gw_remnant     NRSur7dq4Remnant
--------------------------------------------------------------
Remnant mass [M]                 0.961377             0.961193
Remnant spin (z)                 0.619930             0.623422
Remnant |chi|                    0.619930             0.623422
Kick velocity [c]                0.000491             0.000488
Spin vector               [1.3544e-05 3.1220e-05 6.1993e-01]
                          [ 5.2284e-05 -1.0361e-04  6.2342e-01]  (NRSur7dq4Remnant)

3. Non-precessing (aligned-spin) binary

[7]:
q = 2.0
chi1 = [0, 0, 0.6]
chi2 = [0, 0, -0.3]

times, h = waveform_generator.generate_nrsur7dq4(sur, q=q, chi1=chi1, chi2=chi2)
NRSur7dq4 time grid: [-4299.47, 100.53] M
Output time grid: [-4000.00, 49.90] M
[8]:
calc_np = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
calc_np.print_remnants()
==================================================
Remnant Properties Summary
==================================================
Mass ratio                    : 2.000
Initial mass                  : 1.00000000 M
Total energy radiated         : 0.04418731 M
Peak luminosity               : 0.00101209
Remnant mass                  : 0.94855348 M
Remnant spin (dimensionless)  : 0.78789787
Remnant spin vector (x,y,z)  : (-0.00001578, -0.00002466, 0.78789787)
Remnant kick velocity         : 0.00026158 c
Remnant kick velocity         : 78.42 km/s
Remnant kick vector (x,y,z)  : (-0.00024390, 0.00009340, 0.00001461) c
Remnant displacement (x,y,z) : (-0.00487550, 0.00188224, 0.00061485) M
==================================================
/var/folders/9k/xlxjfz4d2cz1063spty94p0r0000gq/T/ipykernel_23607/3374374379.py:1: UserWarning: Tips: If you are using NR waveforms, ensure that they do not contain junk radiation, as that is known to corrupt the remnant property estimation.
  calc_np = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
[9]:
omega0 = abs(np.gradient(0.5 * gwtools.phase(h[(2, 2)])) / np.gradient(times))[0]
compare_remnants(calc_np, fit, q, chi1, chi2, omega0)
Property                       gw_remnant     NRSur7dq4Remnant
--------------------------------------------------------------
Remnant mass [M]                 0.948553             0.948758
Remnant spin (z)                 0.787898             0.792294
Remnant |chi|                    0.787898             0.792294
Kick velocity [c]                0.000262             0.000287
Spin vector               [-1.5779e-05 -2.4665e-05  7.8790e-01]
                          [-5.8305e-05 -2.7152e-04  7.9229e-01]  (NRSur7dq4Remnant)

4. Precessing binary

[10]:
q = 3.0
chi1 = [0.5, 0.0, 0.3]
chi2 = [0.0, 0.4, -0.2]

times, h = waveform_generator.generate_nrsur7dq4(sur, q=q, chi1=chi1, chi2=chi2)
NRSur7dq4 time grid: [-4304.26, 95.74] M
Output time grid: [-4000.00, 49.90] M
[11]:
calc_p = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
calc_p.print_remnants()
==================================================
Remnant Properties Summary
==================================================
Mass ratio                    : 3.000
Initial mass                  : 1.00000000 M
Total energy radiated         : 0.02909093 M
Peak luminosity               : 0.00066007
Remnant mass                  : 0.96467585 M
Remnant spin (dimensionless)  : 0.68281051
Remnant spin vector (x,y,z)  : (0.21062174, 0.04002432, 0.68281051)
Remnant kick velocity         : 0.00077546 c
Remnant kick velocity         : 232.48 km/s
Remnant kick vector (x,y,z)  : (0.00064341, 0.00014168, 0.00040902) c
Remnant displacement (x,y,z) : (0.02673383, -0.00266597, 0.00121992) M
==================================================
/var/folders/9k/xlxjfz4d2cz1063spty94p0r0000gq/T/ipykernel_23607/4242708690.py:1: UserWarning: Tips: If you are using NR waveforms, ensure that they do not contain junk radiation, as that is known to corrupt the remnant property estimation.
  calc_p = GWRemnantCalculator(time=times, h_dict=h, q=q, chi1=chi1, chi2=chi2)
[12]:
omega0 = abs(np.gradient(0.5 * gwtools.phase(h[(2, 2)])) / np.gradient(times))[0]
compare_remnants(calc_p, fit, q, chi1, chi2, omega0)
Property                       gw_remnant     NRSur7dq4Remnant
--------------------------------------------------------------
Remnant mass [M]                 0.964676             0.964583
Remnant spin (z)                 0.682811             0.689538
Remnant |chi|                    0.715677             0.718883
Kick velocity [c]                0.000775             0.001510
Spin vector               [0.2106 0.04   0.6828]
                          [0.2    0.0365 0.6895]  (NRSur7dq4Remnant)
[ ]: