sage.data.waveform.approximants.IMRPhenomXAS
Filename : IMRPhenomXAS.py Description : GPU-native batched IMRPhenomXAS aligned-spin frequency-domain
waveform model (BBH baseline, no tidal).
Implements the IMRPhenomX aligned-spin (22-mode) waveform entirely in PyTorch, following García-Quirós et al. (2020), arXiv:2001.10914. Inherits device-resident constants from PhenomConstants and adds XAS-specific QNM tables and final mass/spin fits (Jimenez-Forteza et al. 2017, arXiv:1611.00332).
This class is the BBH backbone. Do not use it directly for BNS/NSBH — use IMRPhenomXAS_NRTidalv3 instead.
0 : m1 (solar masses, m1 >= m2) 1 : m2 (solar masses) 2 : chi1z (dimensionless aligned spin of body 1) 3 : chi2z (dimensionless aligned spin of body 2) 4 : distance (Mpc) 5 : tc (s, time of coalescence) 6 : phic (rad, reference orbital phase) 7 : inclination (rad)
Created on 2026-05-27
__author__ = Narenraju Nagarajan __copyright__ = Copyright 2026, Sage __license__ = MIT Licence __version__ = 0.0.1 __maintainer__ = Narenraju Nagarajan __email__ = N/A __status__ = inProgress
References
IMRPhenomXAS : García-Quirós et al. (2020), arXiv:2001.10914 Final spin/mass: Jimenez-Forteza et al. (2017), arXiv:1611.00332 QNM tables : Berti, Cardoso & Will (2009), CQG 26, 163001; arXiv:0905.2975
Classes
GPU-native batched IMRPhenomXAS aligned-spin BBH waveform. |
Module Contents
- class IMRPhenomXAS(f, f_ref, **kwargs)[source]
Bases:
sage.data.waveform.approximants.phenom.PhenomConstantsGPU-native batched IMRPhenomXAS aligned-spin BBH waveform.
Inherits scalar constants and PhenomD QNM tables from PhenomConstants. Adds XAS-specific 1200-point QNM tables pre-interpolated to a fine uniform grid for O(1) linear-interpolation at runtime.
- Parameters:
f (torch.Tensor, shape (B, F)) – Frequency grid in Hz.
f_ref (torch.Tensor, shape (B, 1)) – Reference frequency in Hz.
**kwargs – Forwarded to PhenomConstants.
- dphase(Mf, phase_coeffs, derived=None)[source]
Evaluate the IMRPhenomXAS phase derivative dΨ₂₂/d(Mf) over the grid.
This is used by
get_hphcto compute the time-alignment shift (linb) atMf = fRING - fDAMP. The returned value is the raw derivative (not scaled by 1/η).Region definitions match
phase().
- get_hphc(theta, reproduce_lal=False)[source]
Compute FD plus and cross polarisations for a BBH parameter batch.
- Parameters:
theta (torch.Tensor, shape (B, 8+)) – Columns: [m1, m2, chi1z, chi2z, distance, tc, phic, inclination, …] Masses in solar masses, distance in Mpc, angles in radians.
reproduce_lal (bool) – If True, skip FD tapering, tc shift, and df normalisation so the output can be compared directly with raw LALSim output at the same frequency grid.
- Returns:
hp, hc – Plus and cross polarisations. The first
n_padbins (DC to f_min) are always zero.- Return type:
torch.Tensor, shape (B, n_pad + F), complex
- compute_derived_parameters(theta)[source]
Compute mass and spin derived quantities from the parameter batch.
Convention: m1 >= m2 (enforced by the parameter sampler). Mirrors IMRPhenomXSetWaveformVariables in LALSimIMRPhenomX_internals.c.
- Parameters:
theta (torch.Tensor, shape (B, 4+)) – Columns 0-3: m1, m2, chi1z, chi2z (masses in solar masses).
- Returns:
derived – ┌─────┬───────────────────────────────────────────────────────┐ │ 0 │ m1_s = m1 * GM (seconds) │ │ 1 │ m2_s = m2 * GM │ │ 2 │ M_s = (m1+m2) * GM │ │ 3 │ eta = m1*m2 / M² (symmetric mass ratio) │ │ 4 │ delta = sqrt(1 - 4*eta) (PN asymmetry) │ │ 5 │ Xa = m1/M = 0.5*(1+delta) (dimensionless) │ │ 6 │ Xb = m2/M = 0.5*(1-delta) │ │ 7 │ chiEff = Xa*chi1 + Xb*chi2 │ │ 8 │ chiPNHat (= S in all XAS fits) │ │ 9 │ STotR = (Xa²*chi1 + Xb²*chi2)/(Xa²+Xb²) │ │ 10 │ dchi = chi1 - chi2 │ │ 11 │ chi1 = chi1z (raw aligned spin, body 1) │ │ 12 │ chi2 = chi2z (raw aligned spin, body 2) │ └─────┴───────────────────────────────────────────────────────┘
- Return type:
torch.Tensor, shape (B, 13)
- static final_mass_2017(eta, S, dchi, delta)[source]
Remnant mass fraction Mfinal / M = 1 − E_rad from the 2017 fit.
Source: XLALSimIMRPhenomXFinalMass2017 in LALSimIMRPhenomXUtilities.c Reference: Jimenez-Forteza et al. (2017), arXiv:1611.00332
- static final_spin_2017(eta, S, dchi, delta)[source]
Remnant dimensionless spin a_f from the 2017 fit.
Source: XLALSimIMRPhenomXFinalSpin2017 in LALSimIMRPhenomXUtilities.c Reference: Jimenez-Forteza et al. (2017), arXiv:1611.00332
- Parameters:
- Returns:
afinal
- Return type:
(B, 1) — dimensionless remnant spin ∈ (−1, 1)
Notes
Uses the identity Xa² + Xb² = 1 − 2η to avoid recomputing individual mass fractions (verifiable from Xa = (1+δ)/2).
- static get_fRD_fdamp(af, Mfinal)[source]
Return (fRING, fDAMP) in dimensionless Mf units (f_Hz = fRING / M_s).
Uses the rational polynomial fits from LALSimIMRPhenomX_qnm.c (
evaluate_QNMfit_fring22/evaluate_QNMfit_fdamp22), which is what LAL selects at compile-time withQNMfits == 1. The fits are from Berti, Cardoso & Will (2009), CQG 26, 163001; arXiv:0905.2975.- The normalization follows LAL convention:
fRING = evaluate_QNMfit_fring22(afinal) / Mfinal
so that f_physical_Hz = fRING / M_s_total.
- Parameters:
af (torch.Tensor, shape (B, 1) — final dimensionless spin ∈ [−1, 1])
Mfinal (torch.Tensor, shape (B, 1) — remnant mass fraction from final_mass_2017)
- Returns:
fRING, fDAMP – Dimensionless frequencies; multiply by
1 / M_sto get Hz.- Return type:
torch.Tensor, shape (B, 1)
- static fMECO(eta, chiPNHat, dchi, delta)[source]
Hybrid minimum energy circular orbit (MECO) frequency (dimensionless Mf).
Source: XLALSimIMRPhenomXfMECO in LALSimIMRPhenomXUtilities.c Reference: Cabero et al., Phys.Rev.D95 (2017) 064016.
- static fISCO(afinal)[source]
Innermost stable circular orbit (ISCO) frequency (dimensionless Mf).
Source: XLALSimIMRPhenomXfISCO in LALSimIMRPhenomXUtilities.c Reference: Ori & Thorne, Phys.Rev.D62 (2000) 124022.
Returns the Kerr ISCO orbital frequency OmegaISCO / π normalised to total initial mass, i.e. f_ISCO_Hz = fISCO / M_s.
- get_amp_coeffs(derived)[source]
Compute all IMRPhenomXAS amplitude coefficients for the batch.
Mirrors
IMRPhenomXGetAmplitudeCoefficientsin LALSimIMRPhenomX_internals.c. All versions are fixed to the LAL defaults: InspiralAmpVersion=103, IntermediateAmpVersion=104, RingdownAmpVersion=103.- Parameters:
derived ((B, 13) — output of
compute_derived_parameters)- Returns:
ac – Keys (all (B, 1) tensors unless noted):
pnTTthroughpnST,rho1–rho3— inspiraldelta0–delta4— intermediategamma1,gammaR,gammaD2,gammaD13,fRING— ringdown
fAmpMatchIN,fAmpRDMin— boundaries- Return type:
- amp(f_Ms, amp_coeffs, derived)[source]
Evaluate the IMRPhenomXAS normalised amplitude A(Mf) over the grid.
- The full FD waveform amplitude is:
|h(f)| = Amp0 * Mf^{-7/6} * A(Mf)
where Amp0 = sqrt(2η/3) * π^{-1/6} and the physical prefactor M_s² / dist_s is applied in get_hphc.
- Region definitions (boundary frequencies in Mf units):
Inspiral : Mf ≤ fAmpMatchIN Intermediate: fAmpMatchIN < Mf ≤ fAmpRDMin Ringdown : Mf > fAmpRDMin
- Inspiral ansatz (Eq. 5.2 of arXiv:2001.11412):
- A_ins(Mf) = 1 + pnTT·Mf^{2/3} + pnThT·Mf + pnFoT·Mf^{4/3}
pnFiT·Mf^{5/3} + pnST·Mf²
ρ₁·Mf^{7/3} + ρ₂·Mf^{8/3} + ρ₃·Mf³
- Intermediate ansatz (Eq. 6.12):
A_int(Mf) = Mf^{7/6} / (δ₀ + δ₁·Mf + δ₂·Mf² + δ₃·Mf³ + δ₄·Mf⁴)
- Ringdown ansatz (Eq. 6.17):
- A_rd(Mf) = γ₁·fDAMP·γ₃ · exp(-(Mf-fRING)·γ₂/(fDAMP·γ₃))
/ ((Mf-fRING)² + (fDAMP·γ₃)²)
- get_phase_coeffs(derived)[source]
Compute all IMRPhenomXAS phase coefficients for the batch.
Mirrors
IMRPhenomXGetPhaseCoefficients+IMRPhenomX_Phase_22_ConnectionCoefficientsin LALSimIMRPhenomX_internals.c. Fixed to default LAL flags:IMRPhenomXInspiralPhaseVersion = 104 IMRPhenomXIntermediatePhaseVersion = 104 IMRPhenomXRingdownPhaseVersion = 105
- Parameters:
derived ((B, 13) — output of compute_derived_parameters)
- Returns:
pc –
- inspiral: phi0..phi9L (PN integrals),
sigma1..sigma5 (pseudo-PN integral coefficients), a0..a3 (pseudo-PN derivative coefficients), phiNorm, dphase0
intermediate: b0..b4 ringdown: c0, c1, c2, c4, cL, cLovfda, c4ov3 boundaries: fPhaseMatchIN, fPhaseMatchIM continuity: C1Int, C2Int, C1MRD, C2MRD
- Return type:
dict — all tensors (B, 1) unless noted:
- phase(f_Ms, phase_coeffs, derived)[source]
Evaluate the raw IMRPhenomXAS phase Ψ₂₂(Mf) over the frequency grid.
Does NOT apply the 1/η re-scaling or the tc/phic offsets — those are handled in
get_hphc. The full FD phase used to build h(f) is:phi_total = (1/η) * Ψ₂₂(Mf) + linb*Mf + phifRef
where linb is the time-alignment shift and phifRef is the reference phase (both computed in get_hphc).
- Region definitions:
Inspiral : Mf < fPhaseMatchIN Intermediate : fPhaseMatchIN ≤ Mf < fPhaseMatchIM Ringdown : Mf ≥ fPhaseMatchIM
- Inspiral ansatz integral (Eq. 7.4 of arXiv:2001.11412):
phiNorm * Mf^{-5/3} * [phi0 + phi1*Mf^{1/3} + … + sigma1*Mf^{8/3} + …]
- Intermediate ansatz integral (Eq. 7.7, case 105):
b0*Mf + b1*log(Mf) - b2/Mf - b3/(2*Mf²) - b4/(3*Mf³) + (2*cL/fDAMP)*atan((Mf-fRING)/(2*fDAMP)) + C1Int + C2Int*Mf
- Ringdown ansatz integral (Eq. 7.12):
c0*Mf + 1.5*c1*Mf^{2/3} - c2/Mf - (c4/3)*Mf^{-3} + (cL/fDAMP)*atan((Mf-fRING)/fDAMP) + C1MRD + C2MRD*Mf