The Result class

The Result class stores the output of a sampler run, namely a collection of samples. It contains several methods for operating on the samples, including for importance sampling, plotting, and density recovery. The full interface is documented under dingo.gw.result.Result (and its base class dingo.core.result.Result) in the API reference.

Following a sampler run, a Result can be obtained using GWComposedSampler.to_result(). Since Result inherits from DingoDataset it also possesses to_file() and to_dictionary() methods for saving samples and associated metadata (including context data, namely event data and ASDs).

Density recovery

When sampling with GNPE, there is no direct access to the probability density \(q(\theta|d)\). This is because of the Gibbs iterations: one only has access to the probability density of the entire chain, not just the final samples. The probability density is, however, needed for importance sampling, since this is the proposal distribution.

The Result class contains methods to enable recovery of the probability density for a collection of samples. The approach is as follows:

  1. Start from the samples \(\{(\theta_i, \hat\theta_i)\}_{i=1}^N\) from the final Gibbs iteration, including parameters \(\theta\) and proxy parameters \(\hat\theta\). By default these are included in the samples attribute generated by the sampler.

  2. Train an unconditional density estimator \(q(\hat\theta)\) to model the proxy parameters. This is done by (1) using parameter_subset() to produce a new Result containing just the proxies, and (2) using train_unconditional_flow() on this subset.

  3. Generate new samples \((\theta, \hat\theta) \sim q(\theta, \hat\theta | d) = q(\theta | d, \hat\theta) q(\hat\theta)\). This is accomplished using GWComposedSampler.from_singlestep_gnpe(), with the unconditional flow trained in the previous step, wrapped as a FlowFactor, as the proxy source. The resulting chain is autoregressive rather than iterative, so the density is obtained as well, and importance sampling can be performed.

Note

Density recovery can also be achieved using an unconditional density estimator for \(\theta\) (trained on samples \(\{\theta_i\}_{i=1}^N\) from GNPE). Since \(\theta\) typically comprises 14 parameters (versus 2 or 3 for \(\hat\theta\)) it is usually more straightforward to learn the proxies.

Synthetic phase

It is often challenging for Dingo to learn to model the phase parameter \(\phi_c\). For this reason, we usually marginalize over it in training by excluding it from the list of inference_parameters. The phase is, however, required for importance sampling unless using also a phase-marginalized likelihood (which is approximate except under special circumstances).

The Dingo gw.Result class includes a method sample_proposal_extensions() which, given synthetic_parameters_kwargs, produces a \(\phi_c\) sample from a \(\phi_c\)-marginalized sample. With the exact mode sum it does so by evaluating the likelihood on a \(\phi_c\)-grid and then sampling from the associated 1D distribution; with approximation_22_mode the conditional is a von Mises distribution in \(2\phi_c\), drawn exactly without a grid. The log_prob value for the sample is also corrected to reflect the sampled \(\phi_c\). Speed is ensured by caching waveform modes and evaluating the polarizations for different \(\phi_c\). For further details, see the Supplemental Material of [5].

This method should be run after recovering the density, since in particular it applies a correction to the density.

Synthetic phase and polarization angle

A network may leave out the polarization angle \(\psi\) as well as \(\phi_c\). Both can then be recovered together: \(\psi\) enters the detector strain only through the antenna patterns, which rotate with \(2\psi\), and every later projection step (time shift, calibration, whitening) is linear. The strain at any \(\psi\) is therefore \(\cos 2\psi \, h(\psi{=}0) + \sin 2\psi \, h(\psi{=}\pi/4)\), and the same single waveform evaluation per sample, projected at these two reference angles, gives the likelihood on a full \((\phi_c, \psi)\) grid. sample_proposal_extensions() uses this automatically when the samples lack psi (the SyntheticPhasePsiFactor), adding the joint proposal density to log_prob, and has the additional setting n_grid_psi. With the exact mode sum (approximation_22_mode: false) it draws \(\phi_c\) from the \(\psi\)-marginal of the grid and then \(\psi\) from the conditional at the drawn \(\phi_c\). With approximation_22_mode: true no phase grid is needed: at fixed \(\psi\) the log likelihood depends on \(\phi_c\) only through \(|z| \cos(2\phi_c + \arg z)\), with \(z = (d, h)\) at \(\phi_c = 0\), so the phase integrates out in closed form. \(\psi\) is then drawn from its marginal \(\propto e^{-(h, h)/2} I_0(|z|)\) on the \(\psi\) grid, and \(\phi_c\) exactly from the conditional, a von Mises distribution in \(2\phi_c\); n_grid_phase is not used.

Configuration

The synthetic_parameters_kwargs argument of sample_proposal_extensions() is a dict (in dingo_pipe, the synthetic_parameters entry of importance-sampling-settings). An example configuration is

approximation_22_mode: false
n_grid_phase: 5001
uniform_weight: 0.01
num_processes: 100
approximation_22_mode

Whether to assume that a phase shift multiplies the waveform by \(\exp(2 i \phi_c)\), which holds exactly when only the \((l, m) = (2, \pm 2)\) modes are present. This simplifies computations since it does not require caching of waveform modes. It is exact, not an approximation, for approximants whose co-precessing content is a single \((2, \pm 2)\) pair: IMRPhenomPv2, IMRPhenomXP and their NRTidal variants in Bilby’s spin convention (spin_conversion_phase: null, where a phase shift also rotates the in-plane spins), and aligned-spin \((2, 2)\)-only models such as IMRPhenomD in any convention. Elsewhere it is an approximation whose error grows with in-plane spin and with inclination away from face-on. If not given, the \((2, 2)\) path is taken where it is exact and the exact mode sum otherwise, for the phase alone and together with \(\psi\); dingo_pipe’s PhaseRecoveryDefault and PhasePsiRecoveryDefault leave it unset for this reason. Where neither route is exact and the mode sum is unavailable (e.g. an NRTidal network trained with spin_conversion_phase: 0.0 and no mode_list), Dingo raises and asks for approximation_22_mode: true: the proposal is then approximate, and importance sampling stays unbiased.

n_grid_phase

Number of points of the phase grid on which the likelihoods are evaluated (dingo_pipe uses 5001 in PhaseRecoveryDefault, and 512 in PhasePsiRecoveryDefault when \(\psi\) is drawn as well). Not used with approximation_22_mode: true, where the phase is drawn exactly.

n_grid_psi

Number of \(\psi\) grid points on \([0, \pi]\). Only used if the samples lack psi as well, see above (128 in PhasePsiRecoveryDefault). The grids only shape the proposal, so importance sampling is unbiased for any size, but they should resolve the likelihood peak, whose width in either angle is about 1 / SNR: for very loud events, increase them.

uniform_weight

Base probability level to add to ensure mass coverage.

num_processes

For parallelization of synthetic phase sampling. This is usually the most expensive part of importance sampling, so it is advantageous to perform calculations in parallel.

Which of the phase options to use depends on the approximant and on the spin convention the network was trained in. For a model whose co-precessing-frame content is a single \((2, \pm 2)\) pair, trained with spin_conversion_phase: null (Bilby’s convention), a phase shift multiplies the waveform by a global \(e^{2i\phi}\) factor, so approximation_22_mode: true is exact at a single waveform evaluation per sample, and its log likelihood is cached for importance sampling. With a fixed spin_conversion_phase it is approximate for precessing signals: precession mixes the inertial-frame \(m\)-components, placing a spurious phase peak at \(\phi + \pi\). The exact mode sum (approximation_22_mode: false) costs \(2\ell_{\max}+1\) evaluations per sample (5 for \(\ell_{\max} = 2\)) and needs a fixed spin_conversion_phase. For NRTidal models, which have no frequency-domain modes in LALSimulation, it requires the DFT phase decomposition with an explicit mode_list: [[2, 2], [2, -2]] in the waveform-generator settings.

Importance sampling

Once samples are in the right form—including all relevant parameters and the log probability—importance sampling is carried out using the importance_sample() method. It allows to specify options for using a marginalized likelihood. (Time and phase marginalization are separately supported; see the documentation of dingo.gw.likelihood.StationaryGaussianGWLikelihood.)

As with the synthetic phase, importance sampling allows for parallelization.

Where the phase dependence is exact, the synthetic phase also stores the log likelihood at the drawn \(\phi_c\) in the column log_likelihood_cache: either from the exact mode sum with the DFT phase decomposition, or from the \((2, 2)\) path for the models listed under approximation_22_mode above (the only exact route for the NRTidal family, for which LALSimulation implements no frequency-domain modes). For the \((2, 2)\) path the waveform is probed at the first sample before caching; if a phase shift turns out not to be a global factor, a warning is issued and the likelihood is left to importance sampling. On the mode-sum path the drawn \(\phi_c\) generally lies between grid points, so this value is evaluated exactly from the mode inner products rather than read off the grid. importance_sample() then uses these values instead of generating the waveforms again, unless a marginalized likelihood is requested.

The target may be defined on different data from the proposal (in dingo_pipe, an importance-sampling-updates duration or frequency range regenerates the event). reset_event() then makes event_metadata the event analyzed and keeps the record the samples were drawn under as importance_sampling_metadata["proposal_event_metadata"]. The data they were drawn from are not kept; they remain in the sampling-stage file.

Plotting

The plotting methods included here are intended for quick plots for evaluating results. They include

  • corner plots comparing importance sampled and proposal results;

  • weights plots to evaluate performance of importance sampling; and

  • log probability plots comparing target and proposal log probability.