Data¤
This guide covers the different ways to get gravitational-wave data into Jim.
All detector data in Jim lives inside Detector objects. Jim ships with convenience constructors for common detectors — LIGO Hanford (get_H1), LIGO Livingston (get_L1), Virgo (get_V1), Einstein Telescope (get_ET), and Cosmic Explorer (get_CE):
from jimgw.core.single_event.detector import get_H1, get_L1, get_V1
H1 = get_H1()
L1 = get_L1()
V1 = get_V1()
You can also retrieve all presets at once as a dictionary with get_detector_preset():
from jimgw.core.single_event.detector import get_detector_preset
detectors = get_detector_preset() # {"H1": ..., "L1": ..., "V1": ..., "ET": ..., "CE": ...}
H1 = detectors["H1"]
Note that get_ET() returns a list of three GroundBased2G objects (one for each of ET's triangular arms), while all others return a single detector.
Once you have a detector, you need to attach strain data and a PSD to it.
Loading Data¤
Fetch from GWOSC¤
Use Data.from_gwosc() to download public strain data from the Gravitational Wave Open Science Center:
from jimgw.core.single_event.data import Data
gps_start = 1126259446
gps_end = 1126259478
data = Data.from_gwosc("H1", gps_start, gps_end)
H1.set_data(data)
Load from File¤
Use Data.from_file() to read a locally saved .npz file. The file must contain the keys td (time-domain strain), dt (time step in seconds), and start_time (GPS start time):
data = Data.from_file("path/to/data.npz")
H1.set_data(data)
Construct from Frequency-Domain Arrays¤
Use Data.from_fd() when you already have frequency-domain strain (e.g. from your own pipeline). The frequency array must form a valid rfft grid:
import jax.numpy as jnp
duration = 4.0
sampling_frequency = 2048.0
n = int(duration * sampling_frequency)
frequencies = jnp.fft.rfftfreq(n, 1.0 / sampling_frequency)
fd_strain = jnp.zeros(len(frequencies), dtype=jnp.complex128) # replace with your data
data = Data.from_fd(fd_strain, frequencies, start_time=0.0)
H1.set_data(data)
Warning
The frequency array must come from jnp.fft.rfftfreq. Internally, from_fd reconstructs the full rfft grid and asserts it matches yours exactly. jnp.linspace produces floating-point values via a different arithmetic path, so the equality check will fail even for a nominally identical grid.
PSD¤
Before you can evaluate a likelihood, each detector also needs a power spectral density (PSD).
Default GWTC-2 ASD¤
The simplest approach downloads and sets the default GWTC-2 ASD for the detector:
H1.load_and_set_psd()
Load from a text file¤
load_and_set_psd also accepts paths to two-column whitespace-separated text files (frequency, PSD or ASD):
# From a PSD file (units: Hz^{-1})
H1.load_and_set_psd(psd_file="path/to/psd.txt")
# From an ASD file (units: Hz^{-1/2}) — squared internally to give PSD
H1.load_and_set_psd(asd_file="path/to/asd.txt")
Construct from arrays¤
Use set_psd with a PowerSpectrum object when you already have PSD values and frequencies as arrays:
import jax.numpy as jnp
from jimgw.core.single_event.data import PowerSpectrum
psd_values = jnp.array(...) # PSD in Hz^{-1}
frequencies = jnp.array(...) # Frequencies in Hz
H1.set_psd(PowerSpectrum(psd_values, frequencies))
Load from a .npz file¤
If you have a previously saved PowerSpectrum, reload it with PowerSpectrum.from_file. The file must contain values and frequencies arrays:
H1.set_psd(PowerSpectrum.from_file("path/to/psd.npz"))
Injecting a Simulated Signal¤
For testing and validation, you can inject a waveform directly into a detector. Set the PSD and frequency bounds first, then call inject_signal.
import jax
from jimgw.core.single_event.waveform import RippleIMRPhenomD
gps_time = 1126259462.0
H1.load_and_set_psd()
waveform = RippleIMRPhenomD(f_ref=20.0)
injection_params = {
"M_c": 28.0, "eta": 0.24,
"s1_z": 0.0, "s2_z": 0.0,
"d_L": 440.0, "t_c": 0.0,
"phase_c": 0.0, "iota": 0.0,
"psi": 0.3, "ra": 1.5, "dec": 0.5,
}
H1.inject_signal(
duration=4.0,
sampling_frequency=2048.0,
trigger_time=gps_time,
waveform_model=waveform,
parameters=injection_params,
f_min=20.0,
f_max=1024.0,
rng_key=jax.random.key(0),
)
Set is_zero_noise=True to get a noiseless injection.