Inference workflow#
This page explains what happens under the hood when you run:
run_jester_inference config.yaml
The entry point is jesterTOV/inference/run_inference.py. Working through it step by step is the clearest way to understand how all the pieces connect.
1. Configuration loading#
The YAML file is parsed and validated against Pydantic models, producing an InferenceConfig object. Invalid fields (e.g., an unknown sampler type or a misspelled likelihood key) are caught here before any computation begins. Two shortcut flags are evaluated at this stage:
validate_only: true— exits immediately after successful validation.dry_run: true— continues through all setup steps (prior, transform, likelihood, sampler) but stops before callingsampler.sample(). Useful for checking that all components initialise correctly.
See the YAML Configuration Reference for a full description of all configuration options.
2. Prior setup#
The prior specification file (.prior) is parsed into a CombinePrior object. Any parameter declared with Fixed(...) is extracted into a separate fixed_params dictionary and excluded from the sampling space. Fixed parameters are still passed through the transform as constants.
If a likelihood that requires per-sample random keys is enabled (currently gw_resampled or nicer_kde), a _random_key parameter is added to the prior automatically.
For the metamodel_cse EOS, the CSE grid parameters (p_0, …, p_N) are generated programmatically based on the nb_CSE field in the config; they do not need to appear in the .prior file. The full expanded prior is printed to the log at startup.
3. Transform setup#
A JesterTransform is constructed from the EOS and TOV configuration blocks. The transform encapsulates the full EOS → TOV pipeline: it takes a parameter dictionary, builds the equation of state, solves the TOV equations, and returns a mass–radius–tidal deformability family.
After construction, the transform validates that every parameter it requires is covered by either the prior or fixed_params. A missing parameter raises an error immediately with a clear message listing what is absent. Unused prior parameters generate a warning but do not cause an error.
4. GW flow preparation#
If any gravitational wave event is configured with from_bilby_result or from_npz_file, jester trains a normalizing flow to approximate the 4D marginal posterior on (m_1, m_2, \Lambda_1, \Lambda_2) before sampling starts. The trained weights are cached under {outdir}/gw_flow_cache/{event_name}/ and reused on subsequent runs unless the flow configuration changes (checked via a SHA-256 hash) or retrain_flow: true is set.
For events that already point to a pre-trained flow directory via nf_model_dir, this step is skipped. See Analyzing a binary neutron star signal for full details on GW event configuration.
5. Likelihood setup#
All enabled likelihoods are instantiated and wrapped in a CombinedLikelihood. Each component likelihood receives equal weight (1/N). The combined log-likelihood evaluated during sampling is therefore the average of all enabled individual log-likelihoods.
6. Sampler setup#
The sampler is created from the sampler block in the config via the sampler registry. All four backends (FlowMC, SMC-RW, SMC-NUTS, NS-AW) share the same JesterSampler interface. The sampler holds references to the prior, the likelihood, and the transform; it applies the transform internally before likelihood evaluation.
Before sampling begins, jester runs a quick sanity check: it draws three prior samples, pushes them through the transform, and evaluates the likelihood. The resulting log-probabilities are printed to the log. A row of -inf values at this stage usually indicates a misconfigured likelihood or EOS parameters outside the valid physical range.
7. Sampling#
sampler.sample(jax.random.PRNGKey(seed)) is called. What happens internally depends on the sampler type — see the YAML configuration reference for sampler-specific hyperparameters. For SMC samplers, a smc_diagnostics.png plot is generated automatically at the end of sampling.
8. EOS quantity generation#
After sampling, a subset of posterior samples (controlled by n_eos_samples) is passed back through the transform to compute derived EOS quantities: the density grid, pressure, energy density, speed of sound, and the full mass–radius–tidal deformability family. These are added to the result object alongside the raw posterior samples.
This step re-runs the TOV solver in batches (batch size set by log_prob_batch_size), so it is the most expensive post-sampling operation. The batch size can be tuned to fit available memory.
9. Saving results#
Everything is saved to a single HDF5 file at {outdir}/results.h5. The file contains the posterior samples, derived EOS quantities, the original config, and sampler diagnostics. Use InferenceResult to load and work with the results.
10. Postprocessing#
If postprocessing.enabled: true, a set of diagnostic plots is generated automatically. The available plots are listed in the postprocessing block of the YAML configuration reference. Each plot is generated independently, so a failure in one (e.g., a missing LaTeX installation affecting corner plots) does not prevent the others from being produced.