Skip to content

fix(csv): preserve TuplePrior on af.Model built from tuple-param rows#429

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/cluster-point-tuple-prior
May 20, 2026
Merged

fix(csv): preserve TuplePrior on af.Model built from tuple-param rows#429
Jammy2211 merged 1 commit into
mainfrom
feature/cluster-point-tuple-prior

Conversation

@Jammy2211
Copy link
Copy Markdown
Collaborator

Summary

galaxy_af_models_from_csv_tables previously built each profile's af.Model
with af.Model(cls, **params). For tuple-valued params (e.g. centre=(0.3, 0.5))
this bypassed PyAutoFit's TuplePrior auto-create path (in
autofit/mapper/prior_model/prior_model.py:144-156 the tuple branch only fires
for defaults, not kwargs) and stored centre as a raw tuple attribute. Later
overrides like model.centre_0 = af.GaussianPrior(...) then created ghost
direct attributes
alongside the raw tuple, because PriorModel.__setattr__
falls through to super().__setattr__ when no matching TuplePrior is found.
At sample time, _instance_for_arguments called
Point(centre=(0.3, 0.5), centre_0=..., centre_1=...) and the search crashed
with TypeError: Point.__init__() got an unexpected keyword argument 'centre_0'.

The fix builds af.Model(cls) with no kwargs first — this triggers the
auto-create-TuplePrior branch for tuple-defaulted ctor args — and then sets
each tuple param component-wise via setattr(model, f"{name}_{i}", component).
Scalar params are unchanged. Later prior overrides on .centre_0 / .centre_1
now delegate correctly into the existing TuplePrior.

Unblocks autolens_workspace/scripts/cluster/start_here.py and
autolens_workspace/scripts/cluster/modeling.py, which crashed on every run
after the recent cluster-CSV API adoption.

API Changes

None — internal change to the construction logic inside
galaxy_af_models_from_csv_tables. Existing callers that don't override
tuple-component priors after construction see no behaviour difference; callers
that do (the cluster modeling scripts) now succeed instead of raising
TypeError at sample time.
See full details below.

Test Plan

  • pytest test_autogalaxy/galaxy/test_galaxy_model_csv.py -v — 10/10 pass, including new regression test test__af_models__tuple_param_supports_prior_override that exercises the failing pattern end-to-end (CSV → af.Modelcentre_0/1 GaussianPrior override → instance_from_unit_vector)
  • PYAUTO_TEST_MODE=2 PYAUTO_SKIP_FIT_OUTPUT=1 PYAUTO_SKIP_VISUALIZATION=1 PYAUTO_SKIP_CHECKS=1 PYAUTO_SMALL_DATASETS=1 PYAUTO_FAST_PLOTS=1 python autolens_workspace/scripts/cluster/start_here.py — runs to completion
  • PYAUTO_TEST_MODE=2 ... python autolens_workspace/scripts/cluster/modeling.py — runs to completion
Full API Changes (for automation & release notes)

Removed

None.

Added

None.

Changed Behaviour

  • galaxy_af_models_from_csv_tables(*tables) — the returned af.Model instances now carry a TuplePrior for tuple-valued attributes (e.g. centre) rather than a raw tuple. Reading model.centre is unchanged for downstream consumers (the TuplePrior resolves to a tuple at instance construction); _0/_1 component overrides such as model.centre_0 = af.GaussianPrior(...) now delegate into the TuplePrior instead of creating ghost direct attributes alongside the raw tuple.

Migration

No migration required. The previously-broken .centre_0 = prior / .centre_1 = prior override pattern on a CSV-built model now works as the cluster scripts expect.

🤖 Generated with Claude Code

galaxy_af_models_from_csv_tables previously did af.Model(cls, **params),
which for tuple-valued params (e.g. centre=(0.3, 0.5)) bypassed PyAutoFit's
TuplePrior auto-create path and stored `centre` as a raw tuple attribute.
Later `.centre_0 = GaussianPrior(...)` overrides then created ghost direct
attributes alongside the raw tuple, so at sample time the constructor was
called as `Point(centre=(0.3, 0.5), centre_0=..., centre_1=...)` and
raised `TypeError: Point.__init__() got an unexpected keyword argument
'centre_0'`.

Build af.Model(cls) first (which triggers the TuplePrior auto-create
branch in PyAutoFit for tuple-defaulted ctor args), then setattr each
tuple param component-wise. Scalar params unchanged. Later prior
overrides on `.centre_0`/`.centre_1` now delegate into the auto-created
TuplePrior instead of producing ghost direct attributes.

Unblocks autolens_workspace/scripts/cluster/{start_here,modeling}.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label May 20, 2026
@Jammy2211 Jammy2211 merged commit 0bbfab5 into main May 20, 2026
6 checks passed
@Jammy2211 Jammy2211 deleted the feature/cluster-point-tuple-prior branch May 20, 2026 17:05
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