Skip to content

fix: reject split regularization on rectangular meshes at construction - #417

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/api-validation-and-crash-fixes
Jul 28, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/api-validation-and-crash-fixes

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Phase 1 of the @rhayes777 API-audit campaign (epic #415, task #416). Fixes the
ConstantSplit × RectangularUniform crash reported in #332.

What was wrong

Rectangular meshes do not support split regularization — their interpolators provide no
split-cross mappings. The workspace prose already said so
(autolens_workspace/.../slam.py:18: "AdaptSplit / ConstantSplit regularization is only
valid on irregular meshes such as Delaunay"
), but nothing enforced it, so the combination
failed deep inside the inversion in two different ways:

Mesh Interpolator Before
RectangularUniform InterpolatorRectangularUniform AttributeError: ... has no attribute '_mappings_sizes_weights_split'
RectangularAdaptDensity InterpolatorRectangular IndexError: index 4 is out of bounds for axis 0 with size 4
RectangularAdaptImage InterpolatorRectangular (inherits) same IndexError

Nine combinations were affected (3 rectangular meshes × 3 split schemes —
ConstantSplit, AdaptSplit, AdaptSplitZeroth), not the one reported.

What changed

Pixelization.__init__ rejects the pairing, naming both the mesh and the regularization and
pointing at what does work. Driven by two capability flags rather than isinstance chains, so
a new mesh declares its own capability:

  • AbstractMesh.supports_split_regularization (default True; False on RectangularAdaptDensity,
    inherited by the other two)
  • AbstractRegularization.is_split_regularization (default False; True on the three split schemes)

Also removes InterpolatorRectangular._mappings_sizes_weights_split. It returned the plain
4-corner mappings, commented as "split regularization reuses the same mappings" — which is not
true. reg_split_from expects the split-cross structure, and that pass-through is what produced
the IndexError one frame later. Leaving it would invite someone to mirror it onto the uniform
class.

Why this exception type

autoarray.exc.PixelizationException is deliberately not a FitException.
autogalaxy.exc.PixelizationException is one, and fitness.py:256 converts those into
resample-rejects — so raising the wrong class would make a search silently discard every sample
instead of reporting the misconfiguration. A test pins this.

API Changes

Behavioural change, no signature change.

  • Pixelization(mesh=<rectangular>, regularization=<split>) now raises
    PixelizationException at construction instead of failing mid-inversion. This is the only
    user-visible change; every such combination already crashed, so no working code breaks.
  • New public attributes: AbstractMesh.supports_split_regularization,
    AbstractRegularization.is_split_regularization.
  • Removed: InterpolatorRectangular._mappings_sizes_weights_split (private).

Downstream impact: none. Every Pixelization(...) call site across all workspaces was
scanned — zero pair a rectangular mesh with a split regularization. Every split usage is on
Delaunay.

Testing

  • 24 new tests: all 9 rejected combinations, all 11 still-valid ones, the capability flags,
    the removed pass-through, and the not-a-FitException property.
  • PyAutoArray 930 passed · PyAutoGalaxy 1009 passed (unchanged).
  • Controls bit-identical: Delaunay + ConstantSplit log_evidence 5096.4420,
    Delaunay + Constant 5084.7513, RectangularUniform + Constant 4779.4288.

Reported by @rhayes777. Closes part of #332.

Rectangular meshes do not support split regularization -- their interpolators
provide no split-cross mappings. This was already documented in the workspace
prose ('Rectangular meshes use `Adapt`, not `AdaptSplit`') but never enforced,
so the combination failed deep inside the inversion in two different ways:

  RectangularUniform      -> AttributeError: 'InterpolatorRectangularUniform'
                             has no attribute '_mappings_sizes_weights_split'
  RectangularAdaptDensity -> IndexError: index 4 is out of bounds for axis 0
  RectangularAdaptImage      with size 4

Nine combinations were affected (3 rectangular meshes x 3 split schemes), not
the one reported.

`Pixelization` now rejects the pairing at construction, naming both the mesh
and the regularization, via two capability flags:
`AbstractMesh.supports_split_regularization` and
`AbstractRegularization.is_split_regularization`.

Also removes `InterpolatorRectangular._mappings_sizes_weights_split`, which
returned the plain 4-corner mappings on the reasoning that bilinear
interpolation already covers the neighbourhood. That was not correct --
`reg_split_from` expects the split-cross structure, which is what produced the
IndexError one frame later.

The exception is `autoarray.exc.PixelizationException`, deliberately NOT a
`FitException`: autogalaxy's same-named subclass IS one, and `fitness.py`
converts those into resample-rejects, which would make a search silently
discard every sample instead of reporting the misconfiguration.

Reported by @rhayes777 in #332. Phase 1 of #416 (epic #415).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant