Skip to content

fix: skip corner_cornerpy on a weight-degenerate sample (ESS guard) - #1542

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/nautilus-test-mode-degenerate-corner
Aug 28, 2026
Merged

fix: skip corner_cornerpy on a weight-degenerate sample (ESS guard)#1542
Jammy2211 merged 2 commits into
mainfrom
feature/nautilus-test-mode-degenerate-corner

Conversation

@Jammy2211

@Jammy2211 Jammy2211 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

autofit_workspace/scripts/plot/nautilus_plotter.py failed under PyAutoHeart's release profile (PYAUTO_TEST_MODE=1) with corner's ValueError: ... 'range' is not valid or the sample is empty. Under test mode Nautilus stops after its initial batch with exactly one non-zero weight (ESS = 1); since 8cdcff3a0 correctly forwards weights= and caller kwargs to corner, the script's range=0.999 became a weighted quantile over that single point and collapsed to a sliver excluding every row. The samples were fine (100 unique rows); the weights were degenerate, and corner_cornerpy's guard counted rows, not effective samples.

This PR adds the missing protection: corner_cornerpy skips through the existing logger.info path when the Kish effective sample size sum(w)²/sum(w²) is ≤ the parameter count, alongside the row-count check. No try/except; kwargs forwarding unchanged.

A first revision also raised the global test-mode sampler budget; that was reverted on the human's decision (it would slow every release-wave search). The workspace script instead opts out of test mode via ENV: real_search and caps the search with an explicit n_like_max — companion PR on autofit_workspace (see comment).

Corrective PR for the Heart RED reason release validation FAILED (stage integrate) — job integrate / run_scripts (3.12, autofit, plot), run 33177898708.

Side-finding for a separate prompt: the Mind prompt's premise that this "passed under smoke" was wrong — plot/ scripts are not in autofit_workspace/smoke_tests.txt, so smoke never runs them.

API Changes

corner_cornerpy now skips (logged, returns None) on a weight-degenerate sample instead of raising. No signatures change; test-mode sampler behaviour unchanged.
See full details below.

Test Plan

  • pytest test_autofit green
  • New tests in test_samples_plotters.py: ESS helper; weight-degenerate 100×3 with caller range=np.ones(3)*0.999 → logged skip, corner.corner not called; uniform weights → called
  • Release integrate autofit / plot job green with the companion workspace PR
Full API Changes (for automation & release notes)

Changed Behaviour

  • autofit.plot.corner_cornerpy — additionally skips (logged, returns None) when effective sample size ≤ number of parameters.

Added

  • autofit.non_linear.plot.samples_plotters._effective_sample_size(weight_list, sample_count) — private Kish ESS helper.

Generated by the PyAutoLabs agent workflow.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KeLmyZD5aG6BrTTdJzSmDv

…r guard

Nautilus.apply_test_mode set n_like_max = 1, so under PYAUTO_TEST_MODE=1 the
search stopped after its initial batch with exactly one non-zero weight
(ESS = 1). Since 8cdcff3 correctly forwards weights= and caller kwargs to
corner, a caller range=0.999 became a weighted quantile over that single
point and collapsed to a sliver excluding every row, so corner raised
"'range' is not valid or the sample is empty" (autofit_workspace
scripts/plot/nautilus_plotter.py under the release profile). The data was
fine (100 unique rows); the weights were degenerate, and the corner guard
counted rows, not effective samples.

- Nautilus.apply_test_mode: n_live=25, n_batch=25, n_networks=0, f_live=0.5,
  n_eff=25, n_like_max=1000 — a coarse but real posterior (measured
  825-1000 calls, ESS 29-104, 11 s on nautilus_plotter.py; autolens
  imaging/modeling.py runtime unchanged, 60.5 s vs 60.5 s interleaved).
  _fit clamps n_live >= prior_count + 5 in test mode, since nautilus
  rejects n_live <= n_dim and apply_test_mode runs before the model is known.
- Dynesty.apply_test_mode: maxcall=150, nlive/nlive_init=25 instead of
  maxcall=1. Dynesty's ESS only lifts at ~4000 calls, so this is a real
  reduced run but not a real posterior; documented, the corner guard covers it.
- corner_cornerpy: skip via the existing logged path when the Kish ESS
  (sum(w)^2 / sum(w^2)) <= parameter count, alongside the row-count check.
  No try/except, kwargs forwarding unchanged.

Closes #1541

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeLmyZD5aG6BrTTdJzSmDv
The human decided against raising the global PYAUTO_TEST_MODE=1 sampler
budget: apply_test_mode runs for every Nautilus/Dynesty search under the
release profile, so ~900 extra likelihood evaluations per search would slow
every release-wave script, not just the plotter. Nautilus n_like_max=1 and
Dynesty maxcall=1 are restored. The workspace script instead opts out of
test mode (ENV: real_search) and caps the search with an explicit
n_like_max, like other workspace examples.

The corner_cornerpy effective-sample-size guard stays: a weight-degenerate
sample now takes the logged skip path instead of crashing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeLmyZD5aG6BrTTdJzSmDv
@Jammy2211 Jammy2211 changed the title fix: give nested samplers a real test-mode posterior; ESS-based corner guard fix: skip corner_cornerpy on a weight-degenerate sample (ESS guard) Aug 28, 2026
@Jammy2211

Copy link
Copy Markdown
Collaborator Author

Workspace PR: PyAutoLabs/autofit_workspace#150

@Jammy2211
Jammy2211 merged commit 49ec201 into main Aug 28, 2026
4 checks passed
@Jammy2211
Jammy2211 deleted the feature/nautilus-test-mode-degenerate-corner branch August 28, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant