PyAutoLens: PositionsLH penalty is silently zero when positions contain inf rows (always, when chained from a result) #30
Unanswered
samlange04
asked this question in
Bugs & Errors
Replies: 1 comment
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Package: PyAutoLens (
autolens), currentmain(a1b698063). Platform: macOS, Python 3.13 (not platform specific).What happens
The multiple-image position penalty chained from a previous result does nothing when the positions contain
(inf, inf)rows, and the point solver's output always does. The SLaM pipelines inautolens_workspacechain it withfor the
source_pixandmass_totalstages.positions_likelihood_fromsolves the previous model for the images of its source centre. The solver returns a fixed-length grid padded with(inf, inf): for a real HST lens (SLACS J0008-0004, F814W) that was 2 images plus 18 inf rows.In that fit,
source_pix[1]walked to a demagnified solution with theta_E = 0.37" against 1.47" from the parametric source stage. Itspositions.infoshowed the violation plainly (threshold 0.2", max source-plane separation of the maximum-likelihood model 2.38") but the fit kept it, and every later stage inherited it.Cause
PositionsLH.log_likelihood_penalty_from(autolens/analysis/positions.py) takesxp.maxoverfurthest_separations_of_plane_positions. An inf position traces to nan, so the max is nan,nan > thresholdisFalsein both the numpy branch and thejax.lax.condbranch, and the penalty is 0 for every model.output_positions_infogoes throughmax_separation_of_plane_positions, which uses a nan-safe max, so the info file reports the true separation and hides that the likelihood saw nothing.positions_threshold_fromis also nan-safe (np.nanmax), so the threshold is correct; only the penalty is affected.Reproduced with the real positions and the fitted mass: the max is nan at theta_E 0.369" and at 1.2" alike, while the finite-only max is 2.384" and 0.857".
Any user chaining the penalty from a result, which is every SLaM pipeline with a pixelized source, is exposed.
Proposed fix
Drop non-finite rows in
PositionsLH.__init__(in numpy, at construction, so the JAX path sees a clean static grid) and raisePositionsExceptionwhen fewer than two finite positions remain, extending the existing check for exactly one position.Two alternatives I did not take, which may be worth discussing:
positions_likelihood_fromcould strip the padding before building the object, and the penalty could use a nan-safe max. A nan-safe max would also hide a real position that traces to nan, so filtering at construction seemed the narrower change.Branch: https://github.com/samlange04/PyAutoLens/tree/fix/positions-lh-non-finite, with a regression test (images at +/-1" padded with inf rows; the penalty is 0 at theta_E = 1" and fires at 0.3", red on
main).All reactions