Repository navigation
Description
Overview
The @aa.grid_dec.transform decorator reduces repeated code across ~58 profile methods but relies on implicit is_transformed kwargs and requires manual back-rotation for deflection vectors. This refactor makes the decorator less "magical" while keeping its DRY benefits, split into two phases.
Plan
- Phase 1: Move
is_transformedfrom kwargs onto a grid property, add decorator stacking validation, and update all profile methods to use the new pattern - Phase 2: Add optional automatic back-rotation for vector outputs to the transform decorator, eliminating manual
rotated_grid_from_reference_frame_fromcalls in deflection methods. Validate with direct unit tests first before rolling out across all profiles. - Update the
add_a_profile.pyworkspace guide to reflect the simplified API
Detailed implementation plan
Affected Repositories
- PyAutoArray (primary)
- PyAutoGalaxy
- autolens_workspace
Work Classification
Library (both phases), then workspace guide update
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| PyAutoArray | main | clean |
| PyAutoGalaxy | main | clean |
| autolens_workspace | main | clean |
Suggested branch: feature/transform-decorator
Worktree root: ~/Code/PyAutoLabs-wt/transform-decorator/ (created later by /start_library)
Phase 1: Explicit transform state + validation
-
Add
is_transformedproperty to grid classes (autoarray/structures/grids/)- Add boolean attribute to
Grid2D,Grid2DIrregular, and base grid classes - Ensure it's preserved through grid operations (slicing, copying)
- Add boolean attribute to
-
Update the transform decorator (
autoarray/structures/decorators/transform.py)- Read
grid.is_transformedinstead ofkwargs.get("is_transformed") - Set
is_transformed = Trueon the transformed grid copy - Keep backward compat with kwargs during transition
- Read
-
Add decorator stacking validation (
autoarray/structures/decorators/abstract.py)- Tag decorators with priority; raise
ValueErroron wrong order
- Tag decorators with priority; raise
-
Update profile methods in PyAutoGalaxy (
autogalaxy/profiles/)- Remove
is_transformedkwarg propagation where it only served this purpose - Verify all existing tests still pass
- Remove
Phase 2: Automatic back-rotation for deflection vectors
-
Write direct unit tests first against a few known profiles (e.g.
Isothermal,NFW)- Compute deflections with current manual back-rotation
- Compute deflections with new automatic back-rotation
- Assert results match to numerical precision
-
Enhance the transform decorator (
autoarray/structures/decorators/transform.py)- Add parameter to signal that output is a vector requiring back-rotation
- Implement inverse rotation using
rotated_grid_from_reference_frame_fromlogic - The
@aa.grid_dec.to_vector_yxdecorator or a new combined decorator could handle this
-
Update deflection methods (~15-20 methods across
autogalaxy/profiles/mass/)- Remove manual
rotated_grid_from_reference_frame_fromcalls - Use new decorator parameter for automatic back-rotation
- Remove manual
-
Update
add_a_profile.pyguide in autolens_workspace- Simplify the "Do I Rotate Back?" section
- Show the new pattern
Key Files
autoarray/structures/decorators/transform.py— decorator implementationautoarray/structures/decorators/to_vector_yx.py— vector output decoratorautoarray/structures/grids/— grid classes foris_transformedpropertyautogalaxy/profiles/geometry_profiles.py— transform logicautogalaxy/profiles/mass/total/isothermal.py— example profile to updateautolens_workspace/scripts/guides/advanced/add_a_profile.py— user guide
Original Prompt
Click to expand starting prompt
The transform decorator is used on nearly every mass and light profile in @PyAutoGalaxy/autogalaxy/profiles, for example: Isothermal(PowerLaw) with @aa.grid_dec.transform on deflections_yx_2d_from.
The decorator shifts the input grid to the profile centre and rotates by elliptical components. It has "magic" via is_transformed kwargs to prevent double-transforms. Users have reported not understanding where transforms are performed. The trade-off is DRY code vs readability/transparency.
Decision: keep the decorator but reduce the magic — move is_transformed to a grid property, add optional automatic back-rotation for vector outputs, and add decorator stacking validation.
Activity
Jammy2211 commentedon Apr 13, 2026
Smoke Test Results — 2026-04-13
All failures are pre-existing and unrelated to the transform-decorator changes:
autofit/cookbooks/samples.py— bypass test mode generates 2 samples, script expects 5 (IndexError)autogalaxy/imaging/start_here.py— missingmask_extra_galaxies.fitsdataset fileautogalaxy/interferometer/start_here.py— missingsma.fitsUV wavelength fileautolens/interferometer/modeling.py— same missingsma.fitsautolens_workspace_test(7 scripts) — missing dataset files and small-dataset mask/array shape mismatchesScripts that exercise the transform-decorator changes (imaging modeling/fit, galaxies guides, group/multi modeling, cookbook) all pass.
Jammy2211 commentedon Apr 13, 2026
Shipped — 2026-04-13
PRs
Summary
Refactored the
@transformdecorator to support optionalrotate_back=Truefor automatic back-rotation of vector quantities (deflection angles). Movedis_transformedfrom kwargs to a property on grid objects. Removed ~47 lines of manualrotated_grid_from_reference_frame_fromcalls across 12 mass profile files in PyAutoGalaxy, replacing them with@transform(rotate_back=True). Updated theadd_a_profile.pyworkspace guide with precise frame-convention documentation.Session Notes
rotate_back)