fix: test-mode bypass tolerates a single-eval FitException (resample-equivalent)#1408
Conversation
…equivalent) TEST_MODE=2's _fit_bypass_test_mode calls the likelihood once to verify it runs. If that single instance is pathological (non-PD inversion, or a degenerate Delaunay mesh yielding NaN vertices), the analysis raises FitException — the signal a real sampler absorbs by resampling. With no sampler in test mode, this hard-failed the run, making flaky pixelization scripts intermittently break CI smoke (autolens_workspace#307; interferometer Delaunay qhull "Points cannot contain NaN" via source_pix_2 -> _fit_bypass_test_mode -> log_likelihood_function). Catch FitException at the single verification eval, log the cause, and keep the existing -1.0e99 sentinel (the same effect as resample-to-reject). Only FitException is caught — genuine code errors still propagate. Central fix: benefits every analysis (imaging, interferometer, galaxy), not just this script. Tests: FitException tolerated -> fit completes with sentinel; ValueError still propagates. 108 search/result/samples tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Design validation (parity with existing autofit conventions). This isn't a bespoke workaround —
Scope is deliberately narrow (only CI: unittest 3.12 + 3.13 green, docs green. |
Summary
TEST_MODE=2's_fit_bypass_test_mode(autofit/non_linear/search/abstract_search.py) calls the likelihood once to verify the analysis runs. If that single prior-median instance is pathological — a non-positive-definite inversion, or a degenerate Delaunay mesh that yields NaN vertices — the analysis raisesaf.exc.FitException. That is exactly the signal a real non-linear search absorbs by resampling. In test mode there is no sampler, so the exception hard-failed the whole run.This made flaky pixelization scripts intermittently break CI smoke. Concretely,
autolens_workspace/scripts/interferometer/features/pixelization/delaunay.pyfails ~50% on CI py3.12 withValueError: Points cannot contain NaNfrom the Delaunay/qhull triangulation, viasource_pix_2→_fit_bypass_test_mode→log_likelihood_function→ inversion →scipy_delaunay(autolens_workspace#307, PyAutoLens#640). The same workspace commit passed on a parallel run — a true nondeterministic (CI-thread/BLAS-dependent) flake.Change
Wrap the single verification eval: on
FitException, log the cause and keep the existing-1.0e99sentinel (the same effect as a resample-to-reject). OnlyFitExceptionis caught — genuine code errors (e.g.ValueError,AttributeError) still propagate and fail test mode, so a truly broken likelihood stays loud. Central fix: benefits every analysis (imaging, interferometer, galaxy), not just this one script. Complements PyAutoLens#639 (raise_fit_exceptionpreserves the cause behind the FitException).Tests
TestBypassToleratesFitException::test__test_mode_2__fitexception_tolerated__fit_completes_with_sentinel— fit completes, sentinel log-likelihood retained....::test__test_mode_2__non_fitexception_still_propagates— aValueErrorstill raises.non_linear/{search,result,samples}tests pass; no regressions.API Changes
None. Behaviour change is confined to the
TEST_MODE=2bypass path; public API, signatures, and normal-search behaviour are unchanged. No downstream workspace migration required.Follow-ups
no_run.yamlentry + add to smoke (library-first: merge this PR first).fnnls.py:134divide-by-zero; degenerate Hilbert-mesh vertices) so the fit is not merely tolerated but correct.🤖 Generated with Claude Code