|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Commands |
| 6 | + |
| 7 | +### Install |
| 8 | +```bash |
| 9 | +pip install -e ".[dev]" |
| 10 | +``` |
| 11 | + |
| 12 | +### Run Tests |
| 13 | +```bash |
| 14 | +# All tests |
| 15 | +python -m pytest test_autogalaxy/ |
| 16 | + |
| 17 | +# Single test file |
| 18 | +python -m pytest test_autogalaxy/galaxy/test_galaxy.py |
| 19 | + |
| 20 | +# Single test |
| 21 | +python -m pytest test_autogalaxy/galaxy/test_galaxy.py::TestGalaxy::test_name |
| 22 | + |
| 23 | +# With output |
| 24 | +python -m pytest test_autogalaxy/imaging/test_fit_imaging.py -s |
| 25 | +``` |
| 26 | + |
| 27 | +### Formatting |
| 28 | +```bash |
| 29 | +black autogalaxy/ |
| 30 | +``` |
| 31 | + |
| 32 | +## Architecture |
| 33 | + |
| 34 | +**PyAutoGalaxy** is a Bayesian galaxy morphology fitting library. It depends on two sibling packages: |
| 35 | +- **`autoarray`** – low-level data structures (grids, masks, arrays, imaging/interferometer datasets, inversions/pixelizations) |
| 36 | +- **`autofit`** – non-linear search / model-fitting framework (defines `af.Analysis`, `af.ModelInstance`, `af.Result`) |
| 37 | + |
| 38 | +### Core Class Hierarchy |
| 39 | + |
| 40 | +``` |
| 41 | +GeometryProfile (geometry_profiles.py) |
| 42 | +├── SphProfile |
| 43 | +└── EllProfile |
| 44 | + ├── LightProfile (profiles/light/abstract.py) + OperateImage mixin |
| 45 | + │ ├── lp.Sersic, lp.Exponential, lp.Gaussian, etc. (profiles/light/standard/) |
| 46 | + │ ├── LightProfileLinear (profiles/light/linear/) - intensity solved via inversion |
| 47 | + │ ├── LightProfileOperated (profiles/light/operated/) - PSF already applied |
| 48 | + │ └── Basis (profiles/basis.py) - collection of profiles for MGE / shapelets |
| 49 | + └── MassProfile (profiles/mass/abstract/abstract.py) + OperateDeflections mixin |
| 50 | + ├── mp.Isothermal, mp.NFW, mp.PowerLaw, etc. |
| 51 | + └── stellar, dark, total subdirectories |
| 52 | +
|
| 53 | +Galaxy (galaxy/galaxy.py) - inherits af.ModelObject, OperateImageList, OperateDeflections |
| 54 | + └── holds arbitrary kwargs: light profiles, mass profiles, pixelizations, etc. |
| 55 | +
|
| 56 | +Galaxies (galaxy/galaxies.py) - a List[Galaxy] with group operations |
| 57 | +``` |
| 58 | + |
| 59 | +### Fit Classes |
| 60 | + |
| 61 | +Each dataset type has a `Fit*` class that orchestrates the full fitting pipeline: |
| 62 | + |
| 63 | +- `FitImaging` (`imaging/fit_imaging.py`) – CCD imaging |
| 64 | +- `FitInterferometer` (`interferometer/fit_interferometer.py`) – ALMA/interferometry |
| 65 | +- `FitQuantity` (`quantity/fit_quantity.py`) – arbitrary quantity datasets |
| 66 | +- `FitEllipse` (`ellipse/fit_ellipse.py`) – isophote/ellipse fitting |
| 67 | + |
| 68 | +All inherit from `AbstractFitInversion` (`abstract_fit.py`), which handles the linear algebra inversion step when `LightProfileLinear` or pixelization-based profiles are present. |
| 69 | + |
| 70 | +### Analysis Classes (autofit integration) |
| 71 | + |
| 72 | +Each dataset type has an `Analysis*` class that implements `log_likelihood_function`: |
| 73 | + |
| 74 | +- `AnalysisImaging` (`imaging/model/analysis.py`) |
| 75 | +- `AnalysisInterferometer` (`interferometer/model/analysis.py`) |
| 76 | +- `AnalysisQuantity` (`quantity/model/analysis.py`) |
| 77 | +- `AnalysisEllipse` (`ellipse/model/analysis.py`) |
| 78 | + |
| 79 | +These inherit from `AnalysisDataset` → `Analysis` (in `analysis/analysis/`), which inherits `af.Analysis`. The `log_likelihood_function` builds a `Fit*` object from the `af.ModelInstance` and returns its `figure_of_merit`. |
| 80 | + |
| 81 | +### JAX Support |
| 82 | + |
| 83 | +JAX is integrated via the `xp` parameter pattern throughout the codebase. Fit classes accept `xp=np` (NumPy, default) or `xp=jnp` (JAX). The `AbstractFitInversion.use_jax` property tracks which backend is active. The `AnalysisImaging.__init__` has `use_jax: bool = True`. The conftest.py forces JAX backend initialization before tests run. |
| 84 | + |
| 85 | +### Linear Light Profiles & Inversions |
| 86 | + |
| 87 | +`LightProfileLinear` subclasses do not take an `intensity` parameter—it is solved via a linear inversion (provided by `autoarray`). The `GalaxiesToInversion` class (`galaxy/to_inversion.py`) handles converting galaxies with linear profiles or pixelizations into the inversion objects needed by `autoarray`. |
| 88 | + |
| 89 | +### Adapt Images (Multi-stage fitting) |
| 90 | + |
| 91 | +`AdaptImages` (`analysis/adapt_images/`) stores per-galaxy model images from a previous search. These are passed to subsequent searches to drive adaptive mesh/regularization schemes. `galaxy_name_image_dict_via_result_from` extracts adapt images from a `Result`. |
| 92 | + |
| 93 | +### Configuration |
| 94 | + |
| 95 | +Default priors, visualization settings, and general config live in `autogalaxy/config/`. Tests push a local config directory via `conf.instance.push(...)` in `test_autogalaxy/conftest.py`. |
| 96 | + |
| 97 | +### Operate Mixins |
| 98 | + |
| 99 | +- `OperateImage` (`operate/image.py`) – provides `blurred_image_2d_from`, `visibilities_from`, etc. on light objects |
| 100 | +- `OperateDeflections` (`operate/deflections.py`) – provides deflection-related operations on mass objects |
| 101 | + |
| 102 | +Both are mixin classes inherited by `LightProfile`, `MassProfile`, `Galaxy`, and `Galaxies`. |
| 103 | + |
| 104 | +### Workspace (Examples & Notebooks) |
| 105 | + |
| 106 | +The `autogalaxy_workspace` at `/mnt/c/Users/Jammy/Code/PyAutoJAX/autogalaxy_workspace` contains runnable examples and tutorials. Key locations: |
| 107 | + |
| 108 | +- `start_here.ipynb` / `start_here.py` – entry point overview of the API |
| 109 | +- `scripts/imaging/` – end-to-end scripts: `simulator.py`, `fit.py`, `modeling.py`, `likelihood_function.py`, `features/` |
| 110 | +- `scripts/interferometer/`, `scripts/ellipse/`, `scripts/multi/` – same structure for other dataset types |
| 111 | +- `scripts/howtogalaxy/` – chapter-by-chapter tutorial scripts (chapters 1–4 + optional) |
| 112 | +- `notebooks/` – Jupyter notebook equivalents of all `scripts/` |
| 113 | +- `scripts/guides/` – topic guides (e.g. linear profiles, pixelizations, chaining) |
| 114 | +- `config/` – workspace-level config that overrides package defaults when running workspace scripts |
| 115 | + |
| 116 | +### Namespace Conventions |
| 117 | + |
| 118 | +When importing `autogalaxy as ag`: |
| 119 | +- `ag.lp.*` – standard light profiles |
| 120 | +- `ag.lp_linear.*` – linear light profiles |
| 121 | +- `ag.lp_operated.*` – operated light profiles |
| 122 | +- `ag.lp_basis.*` / `ag.lp_snr.*` – basis and SNR profiles |
| 123 | +- `ag.mp.*` – mass profiles |
| 124 | +- `ag.lmp.*` – light+mass profiles |
| 125 | +- `ag.ps.*` – point sources |
| 126 | +- `ag.Galaxy`, `ag.Galaxies` |
| 127 | +- `ag.FitImaging`, `ag.AnalysisImaging`, `ag.SimulatorImaging` |
0 commit comments