Skip to content

API reference

Generated from the package source and NumPy-style docstrings.

jaxglitches.data

Clean (noise-free) single-exponential glitch signal in the frequency and time domains.

Convention
h_fd[k, c]  =  H_c(f_k)        (frequency domain)
h_td[n, c]  =  h_c(t_n)        (time domain)

where H_c(f) is the analytical Fourier transform of TDI channel c evaluated at discrete frequency f_k (the DC bin is set to zero), and h_c(t) is the corresponding time-domain TDI channel evaluated at time t_n. The channel columns c are [A, E, T] when basis="AET" (default) or [X, Y, Z] when basis="XYZ".

Raw (pre-TDI) signal

The "raw" glitch is the single-link fractional-frequency signal injected on link/MOSA 12, before the TDI Michelson combination is applied:

raw_t(t) = (Deltav / c) * [ -1 + e^{-(t-t0)/tau} (1 + (t-t0)/tau) ]   (t >= t0)

Its analytic Fourier transform is

raw_f(f) = 1 / (i w c) * e^{-i w t0} * Deltav / (-i + tau w)^2 ,  w = 2*pi*f .

compute_TDI applies the TDI transfer functions to a raw frequency-domain signal so that, by construction,

compute_TDI(raw_glitch_f(params, freq), freq, ...) == clean_signal_f(params, freq, ...)

to machine precision. The transfer functions are the frequency-domain delay operators D = e^{-i w T} acting on link 12:

TDI-1:  X = (1 - D^4) raw,                 Y = 2 (D^3 - D) raw,           Z = 0
TDI-2:  X = (1 - D^4)^2 raw,               Y = 2 (-D + D^3 + D^5 - D^7) raw, Z = 0
Unequal arms (numerical orbits)

The *_unequal variants replace the single arm time T by the six per-link light travel times L_ij (frozen at the glitch epoch — see orbits.py), in the lisaorbits ordering ltt = [L_12, L_23, L_31, L_13, L_32, L_21]. With D_ij = e^{-i w L_ij} the link-12 test-mass glitch response is

TDI-1:  X = (1 - D_13 D_31)(1 + D_12 D_21) raw
        Y = 2 D_21 (D_23 D_32 - 1) raw
        Z = 0
TDI-2:  X = (1 - D_12 D_21 D_13 D_31) * X_TDI1
        Y = (1 - D_23 D_32 D_12 D_21) * Y_TDI1
        Z = 0

which reduce exactly to the equal-arm transfer functions when all L_ij = T.

Public API

freq_grid(t_obs, dt) -> (F,) real array clean_signal_f(params, freq, T, tdi, basis) -> (F, 3) complex array clean_signal_t(params, t, T, tdi, basis) -> (N, 3) real array raw_glitch_f(params, freq, T) -> (F,) complex array raw_glitch_t(params, t, T) -> (N,) real array compute_TDI(raw_f, freq, T, tdi, basis) -> (F, 3) complex array clean_signal_f_unequal(params, freq, ltt, tdi, basis) -> (F, 3) complex array clean_signal_t_unequal(params, t, ltt, tdi, basis) -> (N, 3) real array compute_TDI_unequal(raw_f, freq, ltt, tdi, basis) -> (F, 3) complex array

clean_signal_f(params, freq, T=T_ARM_s, tdi=1, basis='AET')

Frequency-domain TDI signal for a single-exponential glitch.

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
 t0     : glitch onset time (s).
 Deltav : velocity-kick amplitude (m/s).
 tau    : exponential decay timescale (s).
required
freq
required
T float
T_ARM_s
tdi int
1
basis str
'AET'

Returns:

Name Type Description
h_fd complex (F, 3), columns [A, E, T] if basis="AET" else [X, Y, Z].

DC bin is zero.

clean_signal_f_unequal(params, freq, ltt, tdi=1, basis='AET')

Frequency-domain TDI signal for a link-12 glitch with unequal arms.

Same conventions as clean_signal_f, but the single arm time T is replaced by the six per-link light travel times frozen at the glitch epoch.

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
required
freq
required
ltt
 [L_12, L_23, L_31, L_13, L_32, L_21] — see orbits.link_ltt.
required
tdi int
1
basis str
'AET'

Returns:

Name Type Description
h_fd complex (F, 3); DC bin is zero.

clean_signal_t(params, t, T=T_ARM_s, tdi=1, basis='AET')

Time-domain TDI signal for a single-exponential glitch.

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
 t0     : glitch onset time (s).
 Deltav : velocity-kick amplitude (m/s).
 tau    : exponential decay timescale (s).
required
t
required
T float
T_ARM_s
tdi int
1
basis str
'AET'

Returns:

Name Type Description
h_td real (N, 3), columns [A, E, T] if basis="AET" else [X, Y, Z].

clean_signal_t_unequal(params, t, ltt, tdi=1, basis='AET')

Time-domain TDI signal for a link-12 glitch with unequal arms.

Exact time-domain counterpart of clean_signal_f_unequal: each TDI channel is a signed sum of shifted copies of the integrated shapelet, with the shifts built from the six frozen light travel times.

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
required
t
required
ltt
 [L_12, L_23, L_31, L_13, L_32, L_21] — see orbits.link_ltt.
required
tdi int
1
basis str
'AET'

Returns:

Name Type Description
h_td real (N, 3).

compute_TDI(raw_f, freq, T=T_ARM_s, tdi=1, basis='AET')

Numerically apply the link-12 TDI combination to a raw frequency-domain glitch.

By construction this reproduces clean_signal_f:

compute_TDI(raw_glitch_f(params, freq), freq, T, tdi, basis)
    == clean_signal_f(params, freq, T, tdi, basis)

The TDI Michelson combination is implemented as frequency-domain delay operators D = e^{-i w T} acting on the single-link signal raw_f.

Parameters:

Name Type Description Default
raw_f complex (F,) single-link signal, e.g. from raw_glitch_f().
required
freq
required
T float
T_ARM_s
tdi int
1
basis output channel basis — "AET" (default) or "XYZ".
'AET'

Returns:

Name Type Description
h_fd complex (F, 3), columns [A, E, T] if basis="AET" else [X, Y, Z].

DC bin is zero.

compute_TDI_unequal(raw_f, freq, ltt, tdi=1, basis='AET')

Apply the unequal-arm link-12 TDI combination to a raw frequency-domain glitch.

By construction: compute_TDI_unequal(raw_glitch_f(params, freq), freq, ltt, tdi, basis) == clean_signal_f_unequal(params, freq, ltt, tdi, basis)

Parameters:

Name Type Description Default
raw_f complex (F,) single-link signal, e.g. from raw_glitch_f().
required
freq
required
ltt
required
tdi int
1
basis "AET" (default) or "XYZ".
'AET'

Returns:

Name Type Description
h_fd complex (F, 3); DC bin is zero.

freq_grid(t_obs=T_OBS_s, dt=DT_s)

Return the one-sided rfft frequency grid for an observation of length t_obs.

raw_glitch_f(params, freq, T=T_ARM_s)

Frequency-domain raw glitch on link 12, before the TDI combination.

Analytic Fourier transform of raw_glitch_t:

raw_f(f) = 1 / (i w c) * e^{-i w t0} * Deltav / (-i + tau w)^2 ,  w = 2*pi*f.

The DC bin is set to zero (the step has an ill-defined zero-frequency value; every TDI transfer function vanishes there anyway).

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
required
freq
required
T float
T_ARM_s

Returns:

Name Type Description
raw_fd complex (F,) single-link signal; DC bin is zero.

raw_glitch_t(params, t, T=T_ARM_s)

Time-domain raw glitch on link 12, before the TDI combination.

This is the single-link fractional-frequency signal (a smooth velocity step in units of c). It is the integrated n=1 shapelet whose time derivative is the acceleration shapelet (delta_t/tau^2) e^{-delta_t/tau}.

Parameters:

Name Type Description Default
params (3,) array [t0 (s), Deltav (m/s), tau (s)].
required
t
required
T float
 the raw single-link signal carries no arm delay).
T_ARM_s

Returns:

Name Type Description
raw_td real (N,) fractional-frequency single-link signal.

jaxglitches.waveform

AET(X, Y, Z)

tdi1_1exp_glitch(t, t0=1.9394221536001746, Deltav=2.22616837 * 10 ** -11, tau=0.79357148, T=T_ARM_s)

tdi2_1exp_glitch(t, t0=1.9394221536001746, Deltav=2.22616837e-11, tau=0.79357148, T=T_ARM_s)

tdi1_1exp_f_glitch(f, t0=1.9394221536001746, Deltav=2.22616837 * 10 ** -11, tau=0.79357148, T=T_ARM_s)

tdi2_1exp_f_glitch(f, t0=1.9394221536001746, Deltav=2.22616837 * 10 ** -11, tau=0.79357148, T=T_ARM_s)

jaxglitches.likelihood

Frequency-domain likelihood for a single single-exponential glitch in stationary noise.

Noise model
n_fd[k, c]  ~  CN(0, S_c(f_k))        for each positive-frequency bin k
E[|n_fd[k,c]|^2] = S_c(f_k)

where S_c is the noise PSD supplied by the caller (not computed here).

Log-likelihood
log p(d | h) = -sum_{k>0, c}  |d[k,c] - h[k,c]|^2 / S_c(f_k)  + const
Matched-filter SNR
SNR  = sqrt( (h|h) )
(a|b) = 2 * Re[ sum_{k>0, c} conj(a[k,c]) b[k,c] / S_c[k] ]
Public API

inner_product(a_fd, b_fd, psd_fd) -> scalar snr(h_fd, psd_fd) -> scalar log_likelihood(data_fd, h_fd, psd_fd) -> scalar make_log_likelihood(data_fd, psd_fd, freq, T, tdi) -> callable(params) make_log_likelihood_unequal(data_fd, psd_fd, freq, ltt, tdi) -> callable(params) fisher_matrix(params, freq, psd_fd, T, tdi) -> (n, n) array fisher_matrix_unequal(params, freq, psd_fd, ltt, tdi) -> (n, n) array

fisher_matrix(params, freq, psd_fd, T=T_ARM_s, tdi=1)

Fisher information matrix in physical parameters [t0, Deltav, tau].

Gamma_ij = (dh/dtheta_i | dh/dtheta_j) = 2 Re[ sum_{k>0,c} conj(dh[k,c,i]) dh[k,c,j] / S_c[k] ]

Parameters:

Name Type Description Default
params (n,) array [t0, Deltav, tau].
required
freq
required
psd_fd (F, 3) noise PSD (must match the tdi generation).
required
T float
T_ARM_s
tdi int
1

Returns:

Name Type Description
Gamma (n, n) real symmetric positive-definite Fisher matrix.

fisher_matrix_unequal(params, freq, psd_fd, ltt, tdi=1)

Fisher information matrix for the unequal-arm (numerical-orbits) template.

Same as fisher_matrix, with the single arm time T replaced by the six per-link light travel times frozen at the glitch epoch.

Parameters:

Name Type Description Default
params (n,) array [t0, Deltav, tau].
required
freq
required
psd_fd (F, 3) noise PSD (must match the tdi generation).
required
ltt
required
tdi int
1

Returns:

Name Type Description
Gamma (n, n) real symmetric positive-definite Fisher matrix.

inner_product(a_fd, b_fd, psd_fd)

Noise-weighted inner product (a|b).

(a|b) = 2 * Re[ sum_{k>0, c} conj(a[k,c]) b[k,c] / S_c[k] ]

The DC bin (index 0) is always excluded.

Parameters:

Name Type Description Default
a_fd complex (F, 3) or (F,) arrays.
required
b_fd complex (F, 3) or (F,) arrays.
required
psd_fd
required

Returns:

Type Description
Scalar float.

log_likelihood(data_fd, h_fd, psd_fd)

Log-likelihood log p(data | h).

Parameters:

Name Type Description Default
data_fd complex (F, 3) observed data.
required
h_fd
required
psd_fd
required

Returns:

Type Description
Scalar float (up to an additive constant independent of h).

log_posterior(data_fd, h_fd, psd_fd, params, t_obs)

Un-normalised log posterior = log_likelihood + log_prior.

Parameters:

Name Type Description Default
data_fd complex (F, 3).
required
h_fd
required
psd_fd
required
params
required
t_obs float
required

make_log_likelihood(data_fd, psd_fd, freq, T=T_ARM_s, tdi=1)

Build a JIT-compiled log_likelihood(params) -> scalar closure.

Parameters:

Name Type Description Default
data_fd complex (F, 3) fixed data array.
required
psd_fd
required
freq
required
T float
T_ARM_s
tdi int
1

Returns:

Name Type Description
log_L callable, log_L(params) -> scalar.

make_log_likelihood_unequal(data_fd, psd_fd, freq, ltt, tdi=1)

Build a JIT-compiled log_likelihood(params) -> scalar closure for the unequal-arm (numerical-orbits) template.

The six light travel times are frozen at the glitch epoch — pass ltt = orbits.link_ltt(t_glitch). Since the arms drift by ~3e-8 s per second, one evaluation per glitch (e.g. at the detection time) is enough for any t0 within the analysis window.

Parameters:

Name Type Description Default
data_fd complex (F, 3) fixed data array.
required
psd_fd
required
freq
required
ltt
  [L_12, L_23, L_31, L_13, L_32, L_21].
required
tdi int
1

Returns:

Name Type Description
log_L callable, log_L(params) -> scalar.

snr(h_fd, psd_fd)

Optimal matched-filter SNR = sqrt( (h|h) ).

jaxglitches.priors

Prior distributions for a single single-exponential glitch.

Parameter vector (3 components, last axis): [t0, Deltav, tau]

t0    : glitch onset time (s)   — uniform over the analysis window
Deltav : velocity-kick amplitude (m/s) — log-uniform
tau   : exponential decay timescale (s)  — log-uniform
Physical model and bounds

These parameters follow the LISA Pathfinder glitch model implemented in the LISA Glitch tool (https://gitlab.in2p3.fr/lisa-simulation/glitch). A glitch is a single-component (n = 1) shapelet in differential acceleration; integrated in time it produces a velocity kick

Delta_v = "equivalent transferred impulse"   (the amplitude here, m/s)
tau     = "equivalent damping time" beta      (s)
t0      = arrival time                        (s)

The bounds below are chosen from the observed LPF population characterised in Baghi et al. 2022 (PRD 105, 042002; arXiv:2112.07490): transferred impulses are mostly in 1e-15 - 1e-13 m/s with a detection floor near 2e-16 m/s, and damping times range from below the sampling time up to a few hours, most under a minute. catalog_generator.py draws from exactly these priors and adds the LPF event rate to synthesise realistic glitch catalogues.

The prior is expressed through its inverse CDF so it can be composed with any sampler that expects unit-hypercube inputs (flowMC, numpyro, etc.). Log-prior functions are also provided for samplers that work directly in parameter space.

Samplers usually explore the sampling coordinates

xi = [t0, log Deltav, log tau]

in which the log-uniform priors on Deltav and tau become flat (their Jacobian cancels). to_sampling/to_physical convert between the two, and log_prior_sampling / sample_prior give the prior and prior draws directly in these coordinates.

log_prior(params, t_obs=T_OBS_s)

Log prior density p(t0, Deltav, tau).

Parameters:

Name Type Description Default
params array of shape (..., 3) = [t0, Deltav, tau].
required
t_obs float
T_OBS_s

Returns:

Type Description
Scalar log-prior value (sum over last axis).

log_prior_sampling(xi, t_obs=T_OBS_s)

Log prior in sampling coordinates [t0, log Deltav, log tau].

The physical prior is uniform in t0 and log-uniform in Deltav and tau; in these log coordinates its Jacobian cancels, so the prior is flat inside the box. Returns 0.0 inside the prior support and -inf outside. Accepts a single (3,) vector or a batch (..., 3) (then the result has shape (...,)).

prior_bounds(t_obs=T_OBS_s)

Return (lower, upper) bound arrays of shape (3,) for box-constrained samplers.

prior_inverse_cdf(u, t_obs=T_OBS_s)

Map unit-hypercube samples to glitch parameters.

Parameters:

Name Type Description Default
u
required
t_obs observation window length (s); upper bound for t0.
T_OBS_s

Returns:

Name Type Description
params array of shape (..., 3) = [t0, Deltav, tau].

sample_prior(key, n, t_obs=T_OBS_s)

Draw n samples from the prior, returned in sampling coordinates [t0, log Deltav, log tau] with shape (n, 3).

Uses prior_inverse_cdf on uniform-hypercube draws, so the samples follow the exact prior (uniform t0, log-uniform Deltav and tau).

sampling_bounds(t_obs=T_OBS_s)

Return (lower, upper) bound arrays of shape (3,) in sampling coordinates.

to_physical(xi)

Sampling -> physical coordinates (inverse of to_sampling), on the last axis:

[t0, log Deltav, log tau]  ->  [t0, Deltav, tau]

Accepts a single (3,) vector or a batch (..., 3).

to_sampling(params)

Physical -> sampling coordinates, on the last axis:

[t0, Deltav, tau]  ->  [t0, log Deltav, log tau]

Accepts a single (3,) vector or a batch (..., 3).

jaxglitches.orbits

Numerical LISA orbits (lisaorbits) -> per-link light travel times for unequal-arm TDI.

Frozen-arm approximation

Glitches last seconds to minutes, while the LISA arm lengths breathe on month timescales (dL/dt ~ 10 m/s, i.e. a light-travel-time drift of ~3e-8 s per second). Over the duration of one glitch the six one-way light travel times L_ij are therefore constant to excellent accuracy, but they are not equal to each other: the Keplerian constellation shows inter-link differences of ~30 ms. We freeze the six delays at the glitch epoch and build the TDI response with those constant, unequal delays.

Public API

default_orbits(**kwargs) -> lisaorbits.KeplerianOrbits instance link_ltt(t, orbits) -> (6,) [scalar t] or (N, 6) light travel times (s) equal_arm_ltt(T) -> (6,) constant array (for testing/reduction checks)

default_orbits(**kwargs)

Return a lisaorbits.KeplerianOrbits instance (imported lazily).

Keyword arguments are forwarded to KeplerianOrbits, e.g. L=2.5e9 (mean arm length, m), lambda1, m_init1 (initial constellation phase angles, rad).

equal_arm_ltt(T=T_ARM_s)

(6,) array with all links set to the same travel time T (s).

Feeding this to the unequal-arm functions must reproduce the equal-arm functions exactly — useful as a reduction check.

Light travel times of the six LISA links at epoch(s) t.

Parameters:

Name Type Description Default
t
 For a glitch, pass the glitch onset epoch (the frozen-arm
 approximation evaluates the orbits once per glitch).
required
orbits lisaorbits.Orbits instance or None — defaults to KeplerianOrbits().
None

Returns:

Name Type Description
ltt (6,) array if t is scalar, else (N, 6) — L_ij in seconds,

ordered as LINKS = (12, 23, 31, 13, 32, 21).

jaxglitches.catalog_generator

Realistic glitch-population catalogue generator.

run_catalog(t_obs) returns a realistic population of LISA glitches over an observation window of t_obs seconds, reproducing the pipeline of the LISA Glitch tool (https://gitlab.in2p3.fr/lisa-simulation/glitch, sampler/) and the LISA Pathfinder statistics of Baghi et al. 2022 (arXiv:2112.07490):

  • Arrival times are a homogeneous Poisson process. The rate is estimated the same way LISA Glitch does it — lambda = 1 / mean(interarrivals) from the LPF interval catalogue — giving lambda ~ 4.97e-5 /s (~4.3 events/day) for ordinary runs, with cold runs about ten times more active. lambda is the total event rate; each event is then assigned one of the six test-mass injection points uniformly (as in sampler/sample_lpf.py).

  • Parameters (Delta_v, tau) are drawn from the empirical LPF glitch catalogue (the effective_glitch_parameters files that the tool's normalizing flow was trained on), by Gaussian-kernel resampling in (log tau, log|Delta_v|) space. This reproduces the true, highly non-uniform LPF population — damping times clustered below a minute with a long tail to a few hours, and velocity kicks around ~3e-13 m/s — instead of a flat prior. Glitch polarity (the sign of Delta_v) is randomised, as in the tool.

Mapping to the LISA Glitch model

Glitches are single-component (n = 1) integrated exponential shapelets (IntegratedShapeletGlitch): s(t) = level * [1 - (1 + dt/beta) e^{-dt/beta}], which asymptotes to level. Hence the tool's level is exactly this package's velocity kick Delta_v and its beta is the decay time tau — the same shape as :func:jaxglitches.waveform.tdi1_1exp_glitch.

The per-event parameters use the bounds and coordinate transforms of :mod:priors; only the population shape comes from the LPF catalogue.

expected_count(t_obs, run_type='ordinary', rate=None)

Expected number of glitches over t_obs seconds: lambda * t_obs.

run_catalog(t_obs, key=None, run_type='ordinary', rate=None, inj_points=INJ_POINTS, smooth=True, signed=True, sort=True)

Generate a realistic glitch catalogue over an observation window.

Parameters:

Name Type Description Default
t_obs float
required
key
     used for reproducibility; pass an explicit key for a new draw.
None
run_type str
'ordinary'
rate
None
inj_points injection-point names to draw from (default: the six ``tm_ij``).
INJ_POINTS
smooth bool
True
signed bool
True
sort bool
True

Returns:

Name Type Description
catalog dict with entries

"n_glitches" : int, number of events drawn (~ Poisson(rate * t_obs)). "t0" : (N,) arrival times (s), uniform on [0, t_obs]. "Deltav" : (N,) velocity kicks (m/s), signed if signed. "tau" : (N,) damping times (s). "params" : (N, 3) physical parameters [t0, Deltav, tau]. "xi" : (N, 3) sampling coordinates [t0, log|Deltav|, log tau]. "inj_idx" : (N,) integer index into inj_points. "inj_point" : list[str] of length N, injection-point name per event. "t_obs" : the observation window (s). "rate" : the total event rate used (s^-1).

sample_parameters(key, n, run_type='ordinary', smooth=True, signed=True)

Draw n glitch parameter pairs from the empirical LPF population.

Parameters:

Name Type Description Default
key
required
n int
required
run_type "ordinary" or "cold" — selects the LPF catalogue.
'ordinary'
smooth bool
   ``(log tau, log|Delta_v|)`` space (Scott's-rule bandwidth); if
   False, plain bootstrap of the catalogue's discrete values.
True
signed bool
   polarity), matching ``sampler/sample_lpf.py``.
True

Returns:

Type Description
(Deltav, tau) : two arrays of shape ``(n,)`` — velocity kick (m/s, signed if
requested) and damping time (s), clipped to the :mod:`priors` bounds.