Providing Waveform Data

gw_remnant requires two inputs to compute remnant properties:

  1. A time array – 1-D NumPy array in geometric units (M)

  2. A waveform dictionary – mapping (l, m) mode tuples to complex strain time series

Custom waveforms

You can pass waveforms generated by any method. The only requirement is that the dictionary keys are (l, m) tuples and the values are complex NumPy arrays matching the time array in length:

import numpy as np
from gw_remnant.gw_remnant_calculator import GWRemnantCalculator

time = np.arange(-5000, 50, 0.1)  # geometric units (M)

h_dict = {
    (2, 2):  h22,   # complex array, same length as time
    (2, -2): h2m2,
    (3, 3):  h33,
    (3, -3): h3m3,
    # ... add more modes as available
}

calc = GWRemnantCalculator(time, h_dict, q=4.0)

Built-in waveform generators

The package ships helper functions that generate waveforms from popular surrogate models. The surrogate packages are not bundled – you import them yourself and pass the module to the generator:

NRHybSur3dq8

Aligned-spin model valid for mass ratios 1 <= q <= 10:

import gwsurrogate
from gw_remnant.gw_utils import waveform_generator as wg

times, h_dict = wg.generate_nrhybsur3dq8(
    gwsurrogate, q=3.0, chi1=[0, 0, 0.5]
)

BHPTNRSur1dq1e4

Non-spinning model valid for 1 <= q <= 10 000:

import BHPTNRSur1dq1e4 as bhptsur
from gw_remnant.gw_utils import waveform_generator as wg

times, h_dict = wg.generate_bhptnrsur1dq1e4(bhptsur, q=100.0)

BHPTNRSur2dq1e3

Spinning model valid for 1 <= q <= 1000 and |chi| <= 0.8:

import BHPTNRSur2dq1e3 as bhptsur
from gw_remnant.gw_utils import waveform_generator as wg

times, h_dict = wg.generate_bhptnrsur2dq1e3(
    bhptsur, q=100.0, spin=0.5
)

Tips

  • Time should be in geometric units where G = c = 1 and masses are in units of total mass M.

  • The (2, 2) mode is required for the peak-time alignment used internally.

  • Including higher-order modes improves the accuracy of radiated energy and momentum estimates.