Skip to content

Weight-threshold prune does not remove zero-weight samples with checks enabled #1487

Description

@Jammy2211

Overview

The sample weight-threshold prune does not appear to remove zero-weight samples from samples.csv, even with validation checks enabled. Found while reproducing #1486; split out because the blast radius is different — this affects every saved samples.csv, not one tutorial.

Evidence

Two local runs of autogalaxy_workspace/scripts/guides/results/_quick_fit.py (capped Nautilus, n_live=100, n_like_max=300):

run env rows in samples.csv zero-weight rows prune logged?
A smoke profile (PYAUTO_SKIP_CHECKS=1) 300 299 no
B JAX on, PYAUTO_SKIP_CHECKS unset 300 299 no

config/output.yaml sets samples_weight_threshold: 1.0e-10 in both the workspace and the packaged PyAutoFit config. samples_above_weight_threshold_from (samples.py:481-523) keeps only sample.weight > weight_threshold, so 299 rows with weight == 0.0 should have been dropped in run B.

The weight column is unambiguous — collections.Counter over it gives exactly {'0.0': 299, '1.0': 1}.

Run A is explained: samples.py:505-506 nulls the threshold under skip_checks(), which is a known and intended behaviour of the smoke profile. Run B is not explained.

The "Samples with weight less than ... removed from samples.csv." log line (samples.py:517-520) never fired in either run.

Suspect (unconfirmed)

updater.py:212-215 returns early, before the prune at line 220, whenever the summary instance raises:

try:
    instance = samples_summary.instance
except exc.FitException:
    return samples, samples_summary, None, samples   # <-- skips save_samples + prune

In this fixture the stored samples include points PyAutoGalaxy's validate_ell_comps rejects (that is #1486), so samples_summary.instance plausibly raises FitException and takes this branch — meaning an invalid sample anywhere in the list silently disables pruning for the whole run. That would make the two issues mutually reinforcing.

Not verified. Alternatives not ruled out: the final save going through a different path, or log_message being suppressed by _disable_output while the prune does run.

Plan

  • Confirm whether updater.py:212-215 is the path taken, e.g. by instrumenting or by constructing a fixture whose summary instance is valid while other samples are not.
  • If confirmed, decide whether an unreconstructable summary instance should really forfeit the prune and the samples_summary write, or whether the early return should be narrowed.
  • Add a regression test asserting that zero-weight samples are absent from the saved samples when skip_checks() is false.

Context worth carrying

This fixture reports f_live=1.0000, N_eff=1 — the n_like_max=300 cap means the sampler never converges, so the weight vector is degenerate (one-hot) by construction. Do not reason about "typical" weight distributions from it.

Split out of #1486 (fix(autofit): reconstructing a stored sample raises through ignore_assertions=True), which has the full reproduction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions