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.
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 savedsamples.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):samples.csvPYAUTO_SKIP_CHECKS=1)PYAUTO_SKIP_CHECKSunsetconfig/output.yamlsetssamples_weight_threshold: 1.0e-10in both the workspace and the packaged PyAutoFit config.samples_above_weight_threshold_from(samples.py:481-523) keeps onlysample.weight > weight_threshold, so 299 rows withweight == 0.0should have been dropped in run B.The weight column is unambiguous —
collections.Counterover it gives exactly{'0.0': 299, '1.0': 1}.Run A is explained:
samples.py:505-506nulls the threshold underskip_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-215returns early, before the prune at line 220, whenever the summary instance raises:In this fixture the stored samples include points PyAutoGalaxy's
validate_ell_compsrejects (that is #1486), sosamples_summary.instanceplausibly raisesFitExceptionand 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_messagebeing suppressed by_disable_outputwhile the prune does run.Plan
updater.py:212-215is the path taken, e.g. by instrumenting or by constructing a fixture whose summary instance is valid while other samples are not.samples_summarywrite, or whether the early return should be narrowed.skip_checks()is false.Context worth carrying
This fixture reports
f_live=1.0000, N_eff=1— then_like_max=300cap 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.