Quickstart

Install the package, point it at the model files, get a waveform.

1. Install

pip install nrhjsurrogate

The package ships code only. Its runtime dependencies are NumPy, SciPy, h5py and spectools, and pip installs them for you. Everything on this page works with those.

That gives you the NumPy backend. For the compiled one -- which is what section 6 uses -- install the source distribution, and say which backend you want if you do not want the default:

pip install --no-binary nrhjsurrogate nrhjsurrogate          # auto
NRHJ_BACKEND=openmp pip install --no-binary nrhjsurrogate nrhjsurrogate
NRHJ_BACKEND=cuda NRHJ_CUDA_ARCH=sm_75 \
  pip install --no-binary nrhjsurrogate nrhjsurrogate        # NVIDIA GPU

The compile can fail, or succeed without OpenMP and be single-threaded, and neither of those fails the install. So it tells you: once on the first import after installing, and any time you ask —

python -m nrhjsurrogate.compiled_backend

INSTALL.md section 1b has the full table.

2. Get the model files

The model artifacts are HDF5 files distributed separately from the code, because they are tens of megabytes each. Download them and put them in one directory.

For the released action-angle model you need two files:

File What it is
NRHJSur3dq8_AA_v3.h5 the model
NRHJSur3dq8_MR_v3.h5 the merger-ringdown part it uses

The second one is not optional. The model resolves it by name every time it loads, and a directory without it gives a FileNotFoundError rather than a model that quietly stops at the merger.

3. Point the package at them

export NRHJ_MODEL_DIR=/path/to/the/directory

If you already keep LALSuite waveform data in $LAL_DATA_PATH, you can drop the files there instead and set nothing. That directory is searched too. You can also hand a full path straight to the loader.

You can also skip this step. If you have not downloaded anything, the first load fetches what it needs from the deposit into your per-user cache and verifies its SHA-256 before using it. Set NRHJ_AUTO_FETCH=0 if you would rather it never reached the network.

4. A waveform

from nrhjsurrogate import NRHJSurAA

model = NRHJSurAA.load_h5("NRHJSur3dq8_AA_v3")

# Geometric units: time in units of the total mass M, modes are r h/M.
times, modes = model.get_td_waveform_modes_geometric(4.0, 0.3, -0.2)

print(times.shape)                      # (15775,)
print(sorted(modes))
# [(2, 1), (2, 2), (3, 2), (3, 3), (4, 3), (4, 4), (5, 5)]

The three arguments are mass_ratio >= 1 and the two spin components along the orbital angular momentum. The model covers roughly 1 <= mass_ratio <= 8 and spin components from about -0.95 to +1.0. Check any point with model.in_hull(mass_ratio, spin1z, spin2z).

There are four waveform methods: get_td_waveform_modes_geometric and get_td_waveform_geometric in geometric units, get_td_waveform_modes and get_td_waveform in physical ones. The plain model(4.0, 0.3, -0.2) call is retained and returns the same content as one dictionary.

5. A waveform in physical units

import numpy as np

times, modes = model.get_td_waveform_modes(
    mass1=50.0, mass2=12.5, spin1z=0.3, spin2z=-0.2,
    delta_t=1.0 / 4096.0, f_min=30.0, distance=400.0)

h_plus, h_cross = model.get_td_waveform(
    mass1=50.0, mass2=12.5, spin1z=0.3, spin2z=-0.2,
    delta_t=1.0 / 4096.0, f_min=30.0, distance=400.0,
    inclination=np.pi / 3.0)

times                  # seconds, zero at the amplitude peak
modes[(2, 2)]          # strain in the (2, 2) mode

Masses in solar masses, delta_t in seconds, f_min in Hz of the (2, 2) gravitational-wave frequency, distance in Mpc, angles in radians.

Two things catch people out here:

6. Make it fast

model = NRHJSurAA.load_h5("NRHJSur3dq8_AA_v3", backend="kokkos")

On one test machine, with OMP_NUM_THREADS=8, this took 2.2 ms per waveform against 87.5 ms for the default NumPy backend, and the two agreed to 2.2e-08 of the peak on the worst mode. The compiled module is looked for beside the package; set $NRHJ_KOKKOS_DIR to point somewhere else.

This needs a compiled backend that actually has OpenMP. An install that fell back to NumPy, or built Serial-only, will run this line without complaint and give you none of that speedup — python -m nrhjsurrogate.compiled_backend is how you tell which you have.

Next

docs/USAGE.md covers starting frequencies below what the artifact carries, the derived waveform routes, parameter derivatives, the Fisher matrix, and the model's own uncertainty estimate. Runnable versions of everything are in examples/usage/.