Waveform Generator
Helper functions for generating waveforms from surrogate models and computing remnant properties via surfinBH.
- gw_remnant.gw_utils.waveform_generator.generate_nrhybsur3dq8(gwsurrogate_module, q, chi1=[0, 0, 0], chi2=[0, 0, 0], modes=None, times=None, f_low=0.003, dt=0.1)[source]
Generate NRHybSur3dq8 waveform.
Generates gravitational waveform using the NRHybSur3dq8 surrogate model for aligned-spin binary black hole mergers. The waveform is aligned such that t=0 corresponds to the peak amplitude of the (2,2) mode.
- Parameters:
gwsurrogate_module – The gwsurrogate module imported by the user
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 10)chi1 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for primary BH. Default is [0, 0, 0]chi2 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for secondary BH. Default is [0, 0, 0]modes (
list[tuple[int,int]] |None) – List of (l,m) mode tuples to generate. If None, defaults to [(2,2), (2,1), (3,1), (3,2), (3,3), (4,2), (4,3), (4,4)]times (
ndarray|None) – Time array in geometric units (M). If None, defaults to np.arange(-5000.0, 50.0, 0.1)f_low (
float) – Starting orbital frequency in geometric units. Default is 3e-3dt (
float) – Time step for waveform generation in units of M. Default is 0.1
- Returns:
- (times, waveform_dict) where:
times: Time array aligned so peak is at t=0
waveform_dict: Dictionary {(l,m): h_lm(t)} with complex waveforms
- Return type:
- Raises:
ValueError – If q is outside valid range [1, 10]
Example
>>> import gwsurrogate >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> times, h = wg.generate_nrhybsur3dq8( ... gwsurrogate, ... q=3.0, ... chi1=[0, 0, 0.5], ... modes=[(2,2), (3,3)] ... )
- gw_remnant.gw_utils.waveform_generator.generate_bhptnrsur1dq1e4(bhptsur_module, q, modes=None, times=None)[source]
Generate BHPTNRSur1dq1e4 waveform.
Generates waveform using the BHPTNRSur1dq1e4 surrogate model, which combines black hole perturbation theory with numerical relativity for extreme and intermediate mass ratio inspirals.
- Parameters:
bhptsur_module – The BHPTNRSur1dq1e4 module imported by the user
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 10000)modes (
list[tuple[int,int]] |None) – List of (l,m) mode tuples to generate. If None, defaults to [(2,2), (2,1), (3,1), (3,2), (3,3), (4,2), (4,3), (4,4)]times (
ndarray|None) – Time array in geometric units (M). If None, defaults to np.arange(-5000.0, 50.0, 0.1)
- Returns:
- (times, waveform_dict) where:
times: Time array aligned so peak is at t=0
waveform_dict: Dictionary {(l,m): h_lm(t)} with complex waveforms
- Return type:
- Raises:
ValueError – If q is outside valid range
Example
>>> import sys >>> sys.path.append('/path/to/BHPTNRSurrogate/surrogates') >>> import BHPTNRSur1dq1e4 as bhptsur >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> times, h = wg.generate_bhptnrsur1dq1e4( ... bhptsur, ... q=100.0, ... modes=[(2,2)] ... )
- gw_remnant.gw_utils.waveform_generator.generate_bhptnrsur2dq1e3(bhptsur_module, q, spin, modes=None, times=None)[source]
Generate BHPTNRSur2dq1e3 waveform.
Generates waveform using the BHPTNRSur2dq1e3 surrogate model, which combines black hole perturbation theory with numerical relativity for spinning intermediate and extreme mass ratio inspirals.
- Parameters:
bhptsur_module – The BHPTNRSur2dq1e3 module imported by the user
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 1000)spin (
float) – Dimensionless spin of the primary black hole (-0.8 <= spin <= 0.8)modes (
list[tuple[int,int]] |None) – List of (l,m) mode tuples to generate. If None, defaults to [(2,2), (2,1), (3,1), (3,2), (3,3), (4,2), (4,3), (4,4)]times (
ndarray|None) – Time array in geometric units (M). If None, defaults to np.arange(-5000.0, 50.0, 0.1)
- Returns:
- (times, waveform_dict) where:
times: Time array aligned so peak is at t=0
waveform_dict: Dictionary {(l,m): h_lm(t)} with complex waveforms
- Return type:
- Raises:
ValueError – If q is outside valid range
Example
>>> import sys >>> sys.path.append('/path/to/BHPTNRSurrogate/surrogates') >>> import BHPTNRSur2dq1e3 as bhptsur >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> times, h = wg.generate_bhptnrsur2dq1e3( ... bhptsur, ... q=100.0, ... spin=0.5, ... modes=[(2,2)] ... )
- gw_remnant.gw_utils.waveform_generator.generate_nrsur7dq4(gwsurrogate_module, q, chi1=[0, 0, 0], chi2=[0, 0, 0], modes=None, times=None, f_low=0.0, dt=0.1)[source]
Generate NRSur7dq4 waveform.
Generates a gravitational waveform using the NRSur7dq4 surrogate model for generically precessing binary black hole mergers. The waveform is in the inertial frame and aligned so that t=0 is the peak amplitude of the (2,2) mode. Because the binary precesses, all m modes are returned directly from the surrogate (the aligned-spin negative-m symmetry does not apply).
- Parameters:
gwsurrogate_module – The loaded NRSur7dq4 gwsurrogate model
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 4)chi1 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for primary BH. Default is [0, 0, 0]chi2 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for secondary BH. Default is [0, 0, 0]modes (
list[tuple[int,int]] |None) – List of (l,m) mode tuples to keep. If None, all modes returned by the surrogate (up to l=4, all m) are kept.times (
ndarray|None) – Output time array in geometric units (M). If None, defaults to np.arange(-4000.0, 50.0, 0.1)f_low (
float) – Starting orbital frequency in geometric units; 0 uses the full surrogate length. Default is 0.0dt (
float) – Time step for waveform generation in units of M. Default is 0.1
- Returns:
- (times, waveform_dict) where:
times: Time array aligned so peak is at t=0
waveform_dict: Dictionary {(l,m): h_lm(t)} with complex waveforms
- Return type:
- Raises:
ValueError – If q is outside valid range [1, 4]
Example
>>> import gwsurrogate >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> sur = gwsurrogate.LoadSurrogate('NRSur7dq4') >>> times, h = wg.generate_nrsur7dq4( ... sur, ... q=3.0, ... chi1=[0.5, 0.0, 0.3], ... chi2=[0.0, 0.4, -0.2] ... )
- gw_remnant.gw_utils.waveform_generator.compute_nrsur3dq8_remnant(surfinbh_module, q, chi1=[0, 0, 0], chi2=[0, 0, 0], fit_name='NRSur3dq8Remnant', print_output=True)[source]
Compute remnant properties using NRSur3dq8Remnant surrogate.
Predicts final mass, dimensionless spin, and kick velocity of the remnant black hole using the NRSur3dq8Remnant fit.
- Parameters:
surfinbh_module – The surfinBH module imported by the user
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 10)chi1 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for primary BH. Default is [0, 0, 0]chi2 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for secondary BH. Default is [0, 0, 0]fit_name (
str) – Name of the remnant fit to use. Default is ‘NRSur3dq8Remnant’. Other options include ‘NRSur7dq4Remnant’ for precessing systemsprint_output (
bool) – Whether to print remnant properties. Default is True Prints the final properties
- Returns:
- Dictionary containing:
’final_mass’: Final mass in units of total mass M
’final_mass_err’: Uncertainty in final mass
’final_spin’: Final dimensionless spin magnitude
’final_spin_z’: z-component of final spin
’final_spin_err’: Uncertainty in final spin magnitude
’kick_velocity’: Kick velocity magnitude in units of c
’kick_velocity_err’: Uncertainty in kick velocity magnitude
’final_spin_vector’: Full spin vector [sx, sy, sz]
’kick_velocity_vector’: Full kick velocity vector [vx, vy, vz]
- Return type:
- Raises:
ValueError – If q is outside valid range [1, 10]
Example
>>> import surfinBH >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> remnant = wg.compute_nrsur3dq8_remnant( ... surfinBH, ... q=3.0, ... chi1=[0, 0, 0.7] ... ) >>> print(f"Final mass: {remnant['final_mass']:.4f} M") >>> print(f"Final spin: {remnant['final_spin']:.4f}") >>> print(f"Kick velocity: {remnant['kick_velocity']*299792.458:.1f} km/s")
- gw_remnant.gw_utils.waveform_generator.compute_nrsur7dq4_remnant(surfinbh_module, q, chi1=[0, 0, 0], chi2=[0, 0, 0], fit_name='NRSur7dq4Remnant', print_output=True)[source]
Compute remnant properties using the NRSur7dq4Remnant surrogate.
Predicts the final mass, dimensionless spin vector, and kick velocity vector of the remnant black hole for generically precessing binaries using the NRSur7dq4Remnant fit. The full spin and kick vectors are returned (and printed), which matters for precessing systems.
- Parameters:
surfinbh_module – The loaded NRSur7dq4Remnant surfinBH fit
q (
float) – Mass ratio q = m1/m2, where m1 >= m2 (1 <= q <= 4)chi1 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for primary BH. Default is [0, 0, 0]chi2 (
list[float]) – Dimensionless spin vector [sx, sy, sz] for secondary BH. Default is [0, 0, 0]fit_name (
str) – Name of the remnant fit. Default is ‘NRSur7dq4Remnant’print_output (
bool) – Whether to print the remnant summary. Default is True
- Returns:
- Dictionary containing:
’final_mass’: Final mass in units of total mass M
’final_mass_err’: Uncertainty in final mass
’final_spin’: Final dimensionless spin magnitude
’final_spin_z’: z-component of final spin
’final_spin_vector’: Full spin vector [sx, sy, sz]
’final_spin_err’: Uncertainty in final spin magnitude
’kick_velocity’: Kick velocity magnitude in units of c
’kick_velocity_vector’: Full kick velocity vector [vx, vy, vz]
’kick_velocity_err’: Uncertainty in kick velocity magnitude
- Return type:
- Raises:
ValueError – If q is outside valid range [1, 4]
Example
>>> import surfinBH >>> from gw_remnant.gw_utils import waveform_generator as wg >>> >>> fit = surfinBH.LoadFits('NRSur7dq4Remnant') >>> remnant = wg.compute_nrsur7dq4_remnant( ... fit, q=3.0, ... chi1=[0.5, 0.0, 0.3], chi2=[0.0, 0.4, -0.2]) >>> print(remnant['final_spin_vector'])