Raw distance likelihood contracts

RIFT.compression.distance evaluates raw distance exports. It is separate from Posterior compression, whose reconstructed likelihood has an arbitrary event constant. Existing compression executables, INI options and pipeline defaults are unchanged. No catalog tail model is enabled by this API.

Normalization

DistanceLikelihood requires schema rift-raw-distance-v1 and quantity raw_log_likelihood. Its core predictor must return offset-restored native log likelihood, not a posterior density, normalized conditional, or the hybrid that preserves an earlier intrinsic marginal. Numerical overflow offsets must be restored before fitting. No event or intrinsic-state re-zeroing occurs.

The contract records:

  • features: the exported FEATURES tuple, in that order;

  • spin_frame, reference_frequency_hz, spin_caps and source provenance;

  • intrinsic_bounds: lower and upper eight-coordinate support arrays;

  • distance_support_mpc and distance_scale_mpc;

  • normalization: native measure, provenance, restored-offset declaration, and a noise baseline;

  • validation_status and optional tail overlap/validation provenance.

The native measure records the effective time grid, window, quadrature and nuisance-prior mass. A constant baseline uses kind = constant and explicit raw_zero_signal_log_likelihood. A state-dependent baseline uses kind = state_evaluator and evaluator_id. Supply its predictor and matching identity to the constructor. A missing baseline is an error, never a default zero. The ratio is raw_log_likelihood - native_zero_signal_log_likelihood; the raw quantity can carry an unnormalized time-quadrature volume even when the noise ratio has a unit zero-signal limit.

save_contract and load_contract round-trip JSON metadata. Backend model serialization remains backend-owned; these functions do not save predictors or deserialize executable objects. Load a matching raw core predictor explicitly. load_contract rejects experimental metadata unless allow_experimental=True; the constructor does not check the status. The status field is a producer declaration, not independent scientific certification.

Conditioning provenance

For physical exports, source_provenance must bind the native implementation name, version and source identity. Record conditioning separately for each detector: the raw PSD table hash and frequency band, data-window and PSD-window definitions, sample counts, and their evaluated mean-square factors. Record the formula and numerical factor that convert the raw table into the effective PSD used by the likelihood. Include runtime overrides, their evidence, and any unverified assumptions. Equal raw PSD hashes do not establish equal weighting.

For example, S_effective = S_raw * mean(w_data**2) differs from S_effective = S_raw. A producer that uses the ratio of data-window and PSD-window powers must record both factors. Window shape parameters alone omit finite-length and implementation differences. Resolve these quantities from the event’s deployed implementation and runtime; no package-version default is chosen by this evaluator.

Keep this record in source_provenance["conditioning"] so contract persistence and prepared snapshots retain it with the model. The validator requires source provenance but does not audit this record or certify native-likelihood parity. Raw/noise normalization controls test accounting separately from conditioning. A constant time-prior normalization cancels in normalized PE; preserve its measure when exporting absolute raw likelihoods.

Evaluation and caching

The intrinsic chart is natural log detector-frame chirp mass in solar masses, delta = (m1-m2)/(m1+m2), followed by all six Cartesian component spins. Component ordering is m1 >= m2. Spins retain the declared frame and reference frequency. The core’s ninth feature is distance_scale_mpc / dL_Mpc.

from RIFT.compression.distance import DistanceLikelihood, intrinsic_coordinates

# contract.json and raw_core belong to the same validated export/backend.
fit = DistanceLikelihood.load_contract("contract.json", raw_core,
                                      allow_experimental=True)
x = intrinsic_coordinates(m1_detector, m2_detector, cartesian_spins,
                          mass_frame="detector")
prepared = fit.prepare(x)
raw = prepared.raw_log_likelihood(distance_nodes_mpc)
ratio = prepared.log_noise_ratio(distance_nodes_mpc)

Outputs are (N,K) for N intrinsic states and a shared (K,) distance grid. Per-state (N,K) grids are also supported. A 1-D input is always a shared grid, even when K = N; pass one distance per state as (N,1). Scalars represent one distance node. Queries outside declared support are rejected. The separate raw_zero_signal_log_likelihood() returns the recorded baseline without extending accepted finite-distance support to infinity.

RF-only evaluation is the default. To enable a candidate tail, provide a predictor returning (N,degree) coefficient arrays and pass enable_tail=True. A prepared batch predicts coefficients once per unique intrinsic state, including nonadjacent duplicates, and reuses them across distance calls. Preparation snapshots metadata and captures its core predictor. Do not refit predictors in place while prepared batches remain in use; create new predictor objects and prepare new batches for a changed fit. The tail is the recorded baseline plus a zero-intercept polynomial in inverse distance. Its required tail.distance_scale_mpc binds the coefficient basis independently of the core’s distance feature scale. tail.degree declares the coefficient count, ordered from power one upward. Coefficients fitted in anchor_mpc / dL use that anchor as their tail scale; they must not be interpreted in a different inverse-distance basis. Its overlap must be explicit and inside accepted support; smoothstep blends raw log likelihood over that interval. No pilot overlap or cosmology is a framework default.

Source masses and prior integration

intrinsic_coordinates(..., mass_frame="source", redshift=z) converts source masses using explicit redshifts. Obtain these from the analysis cosmology, including an inherited compression CosmologyContext where appropriate. Scalar likelihood transformations add no density Jacobian. Integration weights must include the population/reference measure and the appropriate Jacobian.

A prepared state fixes detector-frame intrinsic coordinates. At fixed source masses, varying distance changes detector-frame masses: prepare those changed states instead of reusing one detector-frame cache. No hidden-spin reduction occurs. A reduced population likelihood must integrate the declared conditional nuisance prior and its proposal quotient; that operation is separate from distance evaluation.

For reference distance prior pi_ref, a conditional density is proportional to exp(raw) * pi_ref with its distance integral divided out. Its density measure and bounds must be explicit. Combining that conditional with an older intrinsic shape preserves the older amplitude convention; neither quantity is the raw likelihood or its noise ratio.

Validation scope

Known-polynomial tests cover baseline subtraction, the smoothstep overlap, coefficient reuse, metadata round-trip, source-mass conversion, and the metadata, support and shape guards. They do not validate finite-distance strain likelihoods or a learned tail. Grouped held-out intrinsic states, blind likelihood checks, overlap accuracy, backend round-trip and converged population integrals remain required before adopting a new fitted representation. Keep the RF fallback available.