Releases: PyAutoLabs/PyAutoLens
Release list
v2026.7.19.1
PyAutoLens v2026.7.19.1
📣 Major Milestones Announcement — PyAutoLens now ships an AI assistant (conversational + agentic), full JAX GPU support, and agentic-AI development via PyAutoScientist. Read the announcement →
What's New
Breaking Changes
- fix: Marquardt-scaled LM damping + zero-fill correction profiles (#626)
- Behaviour change (internal numerics): the LM damping in
al.pc.dense_util.solve_lm_step_fromis now Marquardt-scaled; identical solutions at convergence, different damping trajectories. No signatures changed.
- Behaviour change (internal numerics): the LM damping in
New Features
- feat: per-iteration evidence re-optimization for the interferometer LM engine (#628)
- feat: visibility-space iterative LM engine (interferometer phase 2a) (#625)
- feat: visibility-space potential corrections — sparse-operator route (interferometer phase 1) (#624)
- feat: xp-API dense kernels + iterative LM engine (potential correction phase 4) (#622)
- feat: potential_correction subpackage — gravitational imaging (phase 3) (#621)
- refactor: use paths.preserve_in_zip for the positions cache (#1389 phase 2) (#620)
- feat: cache solved multiple-image positions for SLaM resume fast-path (#619)
- feat: from_coolest(intermediate=True) — rebuild PEMDs as PowerLawIntermediate (#617)
- feat: COOLEST template import/export (autolens.interop.coolest) (#613)
Bug Fixes
- docs: fix stale autosummary entries breaking the docs build (#635)
- fix: interferometer LM objective double-counting + warm start (mid-tier certified) (#629)
- fix: COOLEST interop rejects relative file paths (#615)
Internal
- chore: rename PyAutoConf → PyAutoNerves in docs/prose (#637)
- refactor!: depend on and import
autonerves(renamed from autoconf) (#636) - refactor: re-export autoconf config surface from autolens (#634)
- Rename PyAutoBuild to PyAutoHands (#633)
- Add opt-in gauge_project_x0 to the imaging iterative warm start (#632)
- feat: x0 warm start for the imaging iterative engine (parity) (#630)
- Refactor: consolidate duplicated critical-curve plot helper; remove stale plan doc (#611)
Upstream Changes
PyAutoFit
- chore: rename PyAutoConf → PyAutoNerves in docs/prose (#1396)
- refactor!: depend on and import
autonerves(renamed from autoconf) (#1395) - refactor: re-export autoconf config surface from autofit (#1394)
- Rename PyAutoBuild to PyAutoHands (#1393)
- docs: pin Fitness's NaN guard contract — value-only, never gradient (#1392)
- refactor: public AbstractPaths.preserve_in_zip for post-completion artifacts (#1389) (#1390)
- fix: mark test-mode bypassed fits complete so they are resumable (#1387) (#1388)
- fix: AggregateFITS leaked one file handle per HDU per result (crash at ~500 results) (#1386)
- fix: from_dict dropped dict entries with falsy values (0.0 parameters vanish on load) (#1384)
- fix: EP projection — transform samples to base space + use log weights (#1383)
- feat: size-realistic test-mode bypass samples (PYAUTO_TEST_MODE_SAMPLES) (#1381)
- fix: sqlite database slicing + direct-write samples_summary (aggregator Phase D) (#1380)
- perf: aggregator result-loading speedups (single-scan listing, cached summaries, faster samples parse) (#1376)
- feat(search): add batch_size to the multi-start gradient searches (#1374)
PyAutoArray
- chore: rename PyAutoConf → PyAutoNerves in docs/prose (#395)
- refactor!: depend on and import
autonerves(renamed from autoconf) (#394) - refactor: re-export autoconf config surface from autoarray (#393)
- feat: opt-in gradient-safe log-det via Settings (default unchanged) (#392)
- feat: masked-grid derivative operators + mask regularizations (potential correction phase 1) (#390)
PyAutoGalaxy
- chore: rename PyAutoConf → PyAutoNerves in docs/prose (#513)
- refactor!: depend on and import
autonerves(renamed from autoconf) (#512) - refactor: re-export autoconf config surface from autogalaxy (#511)
- Rename PyAutoBuild to PyAutoHands (#510)
- feat: make Lenstool-native parameterization the default dPIE profile (#509)
- feat: zero-fill extrapolation for input pixelized mass profiles (#508)
- refactor: use paths.preserve_in_zip for the galaxy-image cache (#1389 phase 2) (#507)
- feat: input pixelized mass profiles (potential correction phase 2) (#505)
- feat: cache per-galaxy result images for SLaM resume fast-path (#502) (#504)
- feat: PowerLawIntermediate — intermediate-axis (COOLEST) Einstein radius power-law (#503)
- feat: COOLEST-standard profile parameter converters (autogalaxy.interop.coolest) (#501)
Full changelog: 2026.7.15.1...2026.7.19.1
v2026.7.15.1
PyAutoLens v2026.7.15.1
📣 Major Milestones Announcement — PyAutoLens now ships an AI assistant (conversational + agentic), full JAX GPU support, and agentic-AI development via PyAutoScientist. Read the announcement →
What's New
Breaking Changes
- docs: scaffold PyAutoLens-JAX JOSS paper (#609)
- feat: over/under-prediction policies for point-source pairing likelihoods (#586)
FitPositionsImagePairRepeatgains anunmatched_model_policyclass attribute —"magnification_filter"(new default: extra model images with |μ| <magnification_threshold=0.1 are exempt per the demagnified-central observational convention, brighter extras add distance-to-nearest-observed penalty residuals),"penalize","ignore"(the historical behaviour, now explicit) — plus ano_image_residualfinite floor when the solver returns no images and ann_unmatched_model_positionsdiagnostic.FitPositionsImagePair(Hungarian) now penalizes unmatched observed positions instead of dropping them. Behaviour change: fits where the max-likelihood model over-predicts bright images or under-predicts will report (correctly) worse likelihoods than before; equal-count well-matched fits are numerically unchanged (regression-tested).
New Features
- feat: imaging shared-state consumer — AnalysisImaging.shared_state_from + mesh preload reuse (phase 2/4) (#600)
- docs: shared PyAuto brand layer for the Furo docs (#598)
- feat: FitWeak per-galaxy sigma_crit scaling + JAX support (weak series step 10) (#591)
- feat: WeakDataset catalog IO + reduced shear (weak series step 7a) (#589)
- feat: tangential/cross shear profiles + Kaiser-Squires map (weak series step 6) (#582)
- feat: AnalysisWeak — weak lensing modeling (weak series step 4) (#580)
- feat: cluster-scale visualization — per-plane critical curves/caustics aplt helpers (#578)
Bug Fixes
- fix: dataset-scoped preloads consumption — cross-type shared state reduces to mesh view (#601)
- docs: RTD hygiene — fix nnumpydoc typo, prune conf.py, add docs CI (#597)
- docs: fix dead HowToLens Colab links + purge stale allowlist entries (#594)
Internal
- style: normalize release.sh to LF endings (HPC-safe) (#610)
- fix(interferometer): resample non-PD inversion instead of crashing the search (#607)
- chore: single-source the never-rewrite-history policy (generated block) (#605)
- test: skip jax-backed unit tests when jax is absent (Python matrix) (#604)
- docs: point AI Chat Assistant option at the ready-made prompt (#602)
- docs: document the functional plot API in plot.rst (#596)
- docs: three-ways-to-learn guide + prune stale API-doc references (#593)
- fix: mixed-dataset factor graphs crash combined visualization (#587)
- feat: cap SimulatorShearYX catalogue size under PYAUTO_SMALL_DATASETS (weak series step 9) (#584)
- docs: add dPIEMassLenstool / dPIEMassLenstoolSph to mass API autosummary (#576)
Upstream Changes
PyAutoFit
- style: normalize aggregator.py to LF endings (HPC-safe) (#1371)
- feat(search): add multi-start gradient MAP searches (Adam/ADABelief/Lion) (#1370)
- fix: respect disabled test mode in output paths (#1368)
- fix: don't register JAX-leaf types (int) as pytree nodes (shapelet vmap crash) (#1366)
- fix(graphical): EP hierarchical factor returns -inf for out-of-support scale (nightly crash) (#1364)
- chore: single-source the never-rewrite-history policy (generated block) (#1362)
- docs: drop stale [nss] gotcha reference from copilot-instructions (#1361)
- ci: remove orphaned nss_install_smoke workflow (#1360)
- test: guard blackjax NUTS tests on blackjax (Python matrix follow-up) (#1359)
- test: skip jax-backed unit tests when jax is absent (Python matrix) (#1358)
- refactor: remove the NSS nested sampler and its [nss] extra (#1357)
- fix(graphical): seed inherently-stochastic test_full_hierachical (#1352) (#1355)
- fix(graphical): EP statistics completion — F6 truncated KL + F7(b) evidence recording (#1354)
- fix(graphical): EP statistics fix batch — F1/F2/F4/F8 from #1332 (#1351)
- feat(graphical): EP diagnostics and monitoring tooling (#1349)
- fix(priors): width-modifier safety + sigma validation agreement (#1348)
- fix(plot): corner plot survives degenerate (no-dynamic-range) columns (#1347)
- fix(priors): correctness batch — crashes, log-partition, projections (#1345)
- docs: shared PyAuto brand layer for the Furo docs (#1343)
- docs: RTD hygiene — delete dead configs, converge conf.py, add docs CI (#1342)
- refactor: dispatch visualize_combined per Visualizer type in FactorGraphModel (#1340)
- docs: formal Bayesian specification of autofit.graphical (EP review phase 2) (#1334)
PyAutoArray
- fix: test-mode-gate singular/non-PD inversion crash (release tail) (#389)
- Add ticks.minus_in_math config for math minus in arcsec labels (#387)
- fix: pin tfp-nightly for JAX Matern-kernel path (tfp 0.25.0 × jax 0.10.2 crash) (#386)
- chore: single-source the never-rewrite-history policy (generated block) (#384)
- test: skip jax-backed unit tests when jax is absent (Python matrix) (#383)
- test: skip default-nufftax interferometer tests when nufftax absent (py<3.12) (#382)
- feat: PreloadsInterferometer passes mesh-geometry fields through (D5 follow-up) (#381)
- feat: PreloadsImaging + shared source-plane mesh fields (multi-exposure shared-state, phase 2/4) (#380)
- refactor: chunk the kernel-CDF forward transform (512-query blocks) (#378)
- fix: rectangular-mesh plot edges follow the mapper node convention (#375)
- feat: kernel-density CDF meshes RectangularKernelAdaptDensity/Image (#374)
- feat: NNLS solver knobs via Settings (nnls_solver_tol / nnls_max_iter), default off (#371)
- refactor: qhull-only Delaunay callback, exact JAX visibility-walk point location (#368)
- feat: catalogue-size cap for PYAUTO_SMALL_DATASETS smoke mode (#366)
- refactor: vectorize k×s segment-id construction (#365)
PyAutoGalaxy
- fix: JAX-trace Sérsic stellar-mass CSE deflection path (#499) (#500)
- chore: single-source the never-rewrite-history policy (generated block) (#498)
- test: skip jax-backed unit tests when jax is absent (Python matrix) (#497)
- docs: shared PyAuto brand layer for the Furo docs (#496)
- docs: RTD hygiene — delete dead readthedocs.yaml, prune conf.py, add docs CI (#495)
- docs: document the functional plot API in plot.rst (#494)
- docs: fix dead HowToGalaxy Colab links + purge stale allowlist entries ([#493](https://github.com/PyAutoLabs/PyAutoGalaxy/pull...
v2026.7.9.1 — 📣 Major Milestones Announcement
📣 PyAutoLens 2026.7.9.1 — Three Major Milestones
💬 Discuss this release: Announcements #603
I'm happy to announce that with the release of PyAutoLens 2026.7.9.1 we have achieved three major milestones for the software:
🤖 AI Assistant
PyAutoLens now supports two complementary AI workflows:
- Conversational AI (e.g. ChatGPT and Claude) to help you learn the API, understand concepts, debug errors, and answer lens modelling questions.
- Agentic AI (e.g. Claude Code and Codex) to inspect your data, write and execute scripts, and carry out end-to-end lens modelling workflows directly on your machine.
See the autolens_assistant for setup instructions and examples.
⚡ JAX GPU Support
Full GPU-accelerated JAX support is now available for galaxy-, group-, and cluster-scale strong lens modelling across imaging, interferometer, point-source, and datacube datasets, as well as weak gravitational lensing.
🛠️ Agentic AI Development
PyAutoLens is now developed using an agentic AI ecosystem for human-led, natural-language software development, called PyAutoScientist. If you're interested in how this works, visit https://github.com/PyAutoLabs. Documentation is still a work in progress, but we're actively expanding it.
💬 Feedback
These are significant changes to how PyAutoLens is developed and used, and we'd love your feedback. In particular, the AI tooling is evolving rapidly, so if you try the AI assistant or agentic workflows, please let us know what works well, what doesn't, and where the documentation can be improved. Your feedback will directly shape future development.
A huge thank you to everyone who has contributed to PyAutoLens over the years. We're excited to see what these new capabilities enable for the community!
PyAutoLens v2026.7.9.1
What's New
Breaking Changes
- feat: over/under-prediction policies for point-source pairing likelihoods (#586)
FitPositionsImagePairRepeatgains anunmatched_model_policyclass attribute —"magnification_filter"(new default: extra model images with |μ| <magnification_threshold=0.1 are exempt per the demagnified-central observational convention, brighter extras add distance-to-nearest-observed penalty residuals),"penalize","ignore"(the historical behaviour, now explicit) — plus ano_image_residualfinite floor when the solver returns no images and ann_unmatched_model_positionsdiagnostic.FitPositionsImagePair(Hungarian) now penalizes unmatched observed positions instead of dropping them. Behaviour change: fits where the max-likelihood model over-predicts bright images or under-predicts will report (correctly) worse likelihoods than before; equal-count well-matched fits are numerically unchanged (regression-tested).
- feat: support Kaplinghat halos in substructure arrays (#567)
- Adds support for
al.mp.KaplinghatCoredNFWSphandal.mp.KaplinghatCoredNFWMCRLudlowSphinautolens.lens.substructure_util.galaxies_to_halo_arrays. - Unsupported profile classes now raise
ValueErrorinstead of being implicitly interpreted as truncated NFW profiles.
- Adds support for
- feat: datacube shared-state for AnalysisInterferometer via curvature preloads (#566)
- Honour PYAUTO_TEST_MODE in LOSSampler to fix los_halos simulator timeouts (#559)
autolens.lens.los.negative_kappa_fromgains two optional keyword arguments,quad_limit=50andquad_epsrel=1.49e-8(both scipy's ownquaddefaults), threaded into its inner and outer integrals. Existing callers are unaffected.LOSSampler.galaxies_fromnow readsautoconf.test_mode.is_test_mode()internally; its signature is unchanged. No removals or renames. See full details below.
New Features
- feat: FitWeak per-galaxy sigma_crit scaling + JAX support (weak series step 10) (#591)
- feat: WeakDataset catalog IO + reduced shear (weak series step 7a) (#589)
- feat: tangential/cross shear profiles + Kaiser-Squires map (weak series step 6) (#582)
- feat: AnalysisWeak — weak lensing modeling (weak series step 4) (#580)
- feat: cluster-scale visualization — per-plane critical curves/caustics aplt helpers (#578)
- docs: add signpost llms.txt + consolidate agent instructions into AGENTS.md (#570)
- test: regression guard for HowToLens tutorial_3 NaN axis-limits crash (#560)
Bug Fixes
- docs: fix dead HowToLens Colab links + purge stale allowlist entries (#594)
- fix: write dataset.fits in save_attributes for aggregator (#574)
- fix(jax): defensive pytree dedup in imaging/interferometer analyses (#561)
Internal
- docs: document the functional plot API in plot.rst (#596)
- docs: three-ways-to-learn guide + prune stale API-doc references (#593)
- fix: mixed-dataset factor graphs crash combined visualization (#587)
- feat: cap SimulatorShearYX catalogue size under PYAUTO_SMALL_DATASETS (weak series step 9) (#584)
- docs: add dPIEMassLenstool / dPIEMassLenstoolSph to mass API autosummary (#576)
- feat: oversampled PSF support in SimulatorImaging.via_tracer_from (#575)
- ci: call the reusable lib-tests workflow from PyAutoHeart (not PyAutoPulse) (#573)
- main.yml → thin caller to Pulse reusable lib-tests (Stage 4 Phase A) (#572)
- Remove url_check.yml: URL hygiene centralised in PyAutoPulse (#571)
- docs: consolidate agent instructions into canonical AGENTS.md (#569)
- refactor(latent): LatentLens class + declare Analysis.Latent (Phase 2) (#568)
Upstream Changes
PyAutoFit
- refactor: dispatch visualize_combined per Visualizer type in FactorGraphModel (#1340)
- fix: LogUniform NumPy log-prior returns -inf for value<=0 (emcee NaN crash) (#1329)
- ci: pause routine scheduled (cron) workflow runs (#1325)
- ci: call the reusable lib-tests workflow from PyAutoHeart (not PyAutoPulse) (#1323)
- main.yml → thin caller to Pulse reusable lib-tests (Stage 4 Phase A) (#1322)
- Remove url_check.yml: URL hygiene centralised in PyAutoPulse (#1321)
- docs: add signpost llms.txt + consolidate agent instructions into AGENTS.md (#1320)
- docs: consolidate agent instructions into canonical AGENTS.md (#1319)
- refactor(latent): migrate af.ex.Analysis + cookbook docs to the Latent class (#1318)
- fix: skip latent computation without keys (#1317)
- refactor(latent): first-class Latent class + engine extraction (Phase 1) (#1315)
- fix: expand bypass-mode fake samples (#1314)
- test: skip NSS tests without optional dependency (#1312)
- fix(latent): degenerate latent edge cases (quantile n=1, latent exceptions, anti-correlated NaNs) (#1311)
- fix(latent): global masking in compute_latent_samples to prevent KeyError on per-batch NaN drops (#1310)
- feat: cross-Analysis shared per-evaluation state in FactorGraphModel (#1308)
- chore(deps): allow anesthetic>=2.9.0 to unblock jax>=0.7 / numpy>=2 resolution (#1306)
- fix(nss): chunked algo.init follow-up to #1303 (#1305)
- feat(nss): chunk_size kwarg for inversion-heavy A100 likelihoods (#1303)
- fix(jax): structural defense against cached_property pytree/dict leaks (#1302)
PyAutoArray
v2026.5.29.4
PyAutoLens v2026.5.29.4
What's New
Breaking Changes
- Honour PYAUTO_TEST_MODE in LOSSampler to fix los_halos simulator timeouts (#559)
autolens.lens.los.negative_kappa_fromgains two optional keyword arguments,quad_limit=50andquad_epsrel=1.49e-8(both scipy's ownquaddefaults), threaded into its inner and outer integrals. Existing callers are unaffected.LOSSampler.galaxies_fromnow readsautoconf.test_mode.is_test_mode()internally; its signature is unchanged. No removals or renames. See full details below.
- fix: effective_einstein_radius falls back to NumPy when jax_zero_contour missing (#558)
- Behaviour change (no signature change): on the JAX path (
xp is not np),effective_einstein_radiusnow detects whetherjax_zero_contouris importable. If yes — unchanged JIT path. If no — falls through to the existing NumPyeinstein_radius_from(grid)branch with a one-time-per-process warning. NumPy callers are unaffected. New private helper_jax_zero_contour_availableand module-level flag_JAX_ZERO_CONTOUR_FALLBACK_WARNED.
- Behaviour change (no signature change): on the JAX path (
- fix: raw-flux latents + soft-fail magzero-required µJy (#557)
- feat: first-class lensing latent variable API in PyAutoLens (#534)
- New public module
autolens.analysis.latentexposing the five latent functions +LATENT_FUNCTIONSregistry +latent_keys_enabled()reader.AnalysisImaginggainsLATENT_KEYS@propertyandcompute_latent_variables(parameters, model). Newautolens/config/latent.yaml(all keys defaultfalse). Helpersab_mag_via_flux_from/flux_mujy_via_ab_mag_fromare imported fromautogalaxy.imaging.model.latent(shipped in PyAutoGalaxy #441). No PyAutoFit changes. Latents take a genericfitargument and use APIs shared betweenFitImagingandFitInterferometer, so a futureAnalysisInterferometerwiring can reuse the registry without duplication.
- New public module
- fix(viz): make _compute_critical_curve_lines failures loud, not silent (#527)
_compute_critical_curve_linesis a private helper — no public API surface changes. Behavioural change: unexpected exceptions now emit aWARNINGlog with traceback before falling back to no-overlay rendering, instead of being silently swallowed.
New Features
- test: regression guard for HowToLens tutorial_3 NaN axis-limits crash (#560)
- Add placeholder subplot_fit_quick for weak lensing and combined fits (#553)
- Add subplot_fit_quick for point source quick updates (#552)
- Simplify subplot_fit_quick: use fit properties directly (#551)
- Add subplot_fit_quick for interferometer quick updates (#549)
- perf: cache expensive @Property on Fit classes (#548)
- Add subplot_fit_quick for faster quick-update rendering (#546)
- feat: SimulatorInterferometer.via_tracer_from auto-default xp from parent use_jax (#540)
- feat: SimulatorImaging.via_tracer_from auto-default xp from parent use_jax (#539)
- feat: PointSolver(use_jax=True) + autolens.jax.register_tracer_classes (#538)
Bug Fixes
- fix(jax): defensive pytree dedup in imaging/interferometer analyses (#561)
- test: lock down WeakDataset json round-trip (paired with PyAutoArray fix) (#555)
- Fix subplot_fit_quick styling: arcsecond axes, source plane, code reuse (#550)
Internal
- Fast subplot_fit_quick: sub-second rendering for quick updates (#547)
- feat: batched_simulate_substructure via jax.vmap (#545)
- feat: simulate_substructure end-to-end jittable simulator (#544)
- feat: scan-based multi-plane ray-tracing for substructure (#543)
- fix: total_source_flux_mujy wrong value for linear light profiles (#536)
- docs: add autolens_assistant prototype callout to README and docs index (#530)
- refactor(model_util): replace simulator_start_here_model_from with direct random_galaxies_for_simulation_from (#529)
- refactor: archive quantity package to autolens_workspace_developer/legacy (#528)
Upstream Changes
PyAutoFit
- chore(deps): allow anesthetic>=2.9.0 to unblock jax>=0.7 / numpy>=2 resolution (#1306)
- fix(nss): chunked algo.init follow-up to #1303 (#1305)
- feat(nss): chunk_size kwarg for inversion-heavy A100 likelihoods (#1303)
- fix(jax): structural defense against cached_property pytree/dict leaks (#1302)
- fix(jax): keep parameterization cache off ModelInstance + auto-register pytrees (#1300)
- Cache model.parameterization; try interactive matplotlib backends (#1299)
- Prefer fit_quick.png in quick-update display candidates (#1298)
- Remove use_jax_for_visualization; add visualization warmup (#1297)
- fix: skip _compute_latent_samples in PYAUTO_TEST_MODE (#1294) (#1295)
- Add live_visual_update flag for opt-in on-the-fly visualization (#1293)
- fix: PYAUTO_TEST_MODE should write to a separate output dir (#1292)
- feat(quick_update): IPython.display.update_display for live Jupyter cells (#1290)
- feat(analysis): LATENT_BATCH_MODE attribute (vmap default, jit option) (#1288)
- Fix Sample.kwargs mixed string/tuple key bug (#1287)
- nss extras: strip git+https URLs to unblock PyPI uploads (#1286)
PyAutoArray
- fix(jax): exclude cached_property descriptors from pytree flatten paths (#343)
- fix: VectorYX2DIrregular from_dict round-trip (missing values property) (#342)
- perf: cache expensive @Property on Fit classes (#341)
- fix: make Array2D.native jit-traceable for JAX simulator path (#339)
- fix: raise ValueError on xp=np + jnp-backed-grid mismatch (#337)
- feat: SimulatorInterferometer(use_jax=True) + xp-aware preprocess Gaussian noise (#336)
- feat: SimulatorImaging(use_jax=True) + xp-aware preprocess noise (#335)
- TransformerNUFFT: add chunk_size knob to cap nufftax gather buffer (#330)
- interferometer: enable sparse_operator for nufftax TransformerNUFFT (#329)
PyAutoGalaxy
- fix(jax): defensive pytree dedup in imaging/interferometer analyses (#468)
- fix(mass): convergence_func on PowerLawBroken, PowerLawMultipole, cNFW family (#467)
- fix(mass): wire convergence_func on dPIE family for MGE decomposition (#466)
- fix: soft-fail jax_zero_contour callers in lens_calc to NaN/[] (#465)
- fix: raw-flux latent + soft-fail magzero-required µJy (#463)
- perf: cache expensive @Property on Fit classes (#462)
- perf: vectorize MGE potential over components (#461)
- fix: elliptical MGE potential via deflection line integral (#460)
- fix: use xp.sqrt in NFWSph.potential_func_sph (#458)
- fix: add xp=np to convergence_func across all mass profiles (#457)
- feat: vmapped_deflections_from for batched subhalo deflections (#455)
- fix: cNFWSph deflection boundary bug and MCR validation (#451) (#454)
- docs: LaTeX docstrings for all mass profile classes (#453)
- feat: MGE/CSE fallback for zero-retu...
v2026.5.21.1
PyAutoLens v2026.5.21.1
What's New
Breaking Changes
- docs(api): sync mass.rst with full al.mp namespace + lmp / lmp_linear (#520)
- feat: redesign subplot_fit panels — add Source Plane (Mid Zoom) (#518)
-
_plot_source_plane(...)andplane_image_from(...)gain azoom_extent_scalekwarg.plane_image_fromalso gains azoom_extent_boundskwarg.
-
subplot_fitandsubplot_fit_log10produce the new 12-panel layout — same panel count, different ordering, one renamed panel ("Source Plane (Zoomed)" → "Source Plane (Max Zoom)"), one new panel ("Source Plane (Mid Zoom)"), one removed panel ("Data (Source Scale)").
-
- docs(api): sync light profile reference with PyAutoGalaxy (#516)
- fix: AnalysisPoint.init kwargs passthrough (#506)
al.AnalysisPoint.__init__gains a**kwargspassthrough — strictly additive. Any caller that previously worked is unaffected. New: callers can now passuse_jax_for_visualization=True(or any other kwarg accepted by the autofit baseAnalysis) withoutTypeError.
New Features
- feat: re-export galaxy_model_csv helpers under al.* (#526)
- feat(weak): FitWeak class + plotters (#524) (#525)
- feat(weak): aplt plotters for WeakDataset shear catalogues (#496) (#523)
- docs(api): list SersicMultipole and GaussianMultipole in autosummary (#515)
Bug Fixes
- docs: audit-driven URL fixes across docs, READMEs, and docstrings (#509)
Internal
- feat(AnalysisImaging): plumb dataset_model into adapt_images_via_instance_from (#512)
- ci: add live URL audit (weekly cron) + grandfather current broken URLs (#510)
- added maximum threshold (#505)
Upstream Changes
PyAutoFit
- nss extras: strip git+https URLs to unblock PyPI uploads (#1286)
- perf: direct-ndtr fast path for TruncatedGaussianPrior.value_for (#1285)
- fix: coerce figure_of_metric return to Python float for Drawer + JAX (#1283)
- ci: split NSS tests into parallel job (handley-lab blackjax fork ≠ mainline) (#1281)
- revert: default use_jax_for_visualization to False (reverts #1278) (#1280)
- feat: default use_jax_for_visualization to follow use_jax in Analysis.init (#1278)
- feat: autofit[nss] install extra (Phase 4 of nss_first_class_sampler) (#1277)
- feat: af.NSS checkpoint/resume + on-the-fly visualization (Phases 2-3) (#1274)
- feat: af.NSS NonLinearSearch wrapper for Nested Slice Sampling (Phase 1 of nss_first_class_sampler) (#1272)
- fix: dedupe number_of_cores in Drawer for from_dict round-trip (#1270)
- fix: log_prior_from_value sign convention — density form across Prior subclasses (#1269)
- ci: add live URL audit (weekly cron) + grandfather current broken URLs (#1268)
- fix: add quick_update kwarg to VisualizerExample.visualize_combined (#1267)
- docs: audit-driven URL fixes across docs, READMEs, and docstrings (#1265)
- Disable model.graph output by default (#1264)
- feat: JAX-native priors — xp dispatch on value_for / log_prior_from_value / vector_from_unit_vector (#1263)
- fix: exclude exclude_identifier_fields attrs from model.info (#1261)
PyAutoArray
- Pin nufftax >=0.4.0,<0.5.0 on Python 3.12+ (#328)
- feat(grids): add respect_small_datasets kwarg to Grid2D.uniform (#327)
- fix(mask): cap radius under PYAUTO_SMALL_DATASETS (#325)
- feat: add zoom_extent_scale to Mapper.extent_from for Mid Zoom panel (#324)
- feat: RectangularRotatedAdaptImage — PCA rotation fixes multi-source ghost-peak failure (#323)
- fix(inversion): make AbstractMeshGeometry picklable (xp module → _use_jax bool + property) (#321)
- Reduce critical curves and caustics overlay linewidth from 2 to 1 (#319)
- Add KNNBarycentric mesh: JAX-native Delaunay-class interpolator (#318)
- fix(interferometer): correct sparse curvature for Pmax > 1 (Delaunay) (#316)
- fix(interferometer-sparse): guard against Delaunay mappers (issue #314) (#315)
- fix(hilbert): support offset-centre circular masks (#313)
- feat(DatasetModel): add grid_rotation_angle for multi-band rotation (#312)
- feat(interferometer): from_fits accepts raise_error_dft_visibilities_limit (#311)
- ci: add live URL audit (weekly cron) + grandfather current broken URLs (#310)
- docs: audit-driven URL fixes across docs, READMEs, and docstrings (#309)
- feat: add aa.interp_2d (NumPy + JAX bilinear interpolation) (#308)
PyAutoGalaxy
- Pin jax_zero_contour >=2.0.0,<3.0.0 in [jax] extras (#432)
- fix(lens_calc): preserve evaluation_grid extent under PYAUTO_SMALL_DATASETS=1 (#431)
- fix: handle r=0 in NFWSph deflections (#430)
- fix(csv): preserve TuplePrior on af.Model built from tuple-param rows (#429)
- feat(galaxy): named-galaxy CSV reader/writer for full model round-trips (#428)
- fix: EllipseMultipoleScaled JAX-traceable via deferred derivation (#427)
- fix: Basis.image_2d_from and dPIEPotential.convergence_2d_from return wrong wrapper types (#425)
- config: add prior defaults for ExternalPotential (#423)
- feat(mass): add ExternalPotential mass profile (Powell 2022 Eq 4) (#422)
- refactor(light): split multipole module + add ag.lp_linear variants (#421)
- feat(light): add SersicMultipole and GaussianMultipole profiles (#420)
- feat(AdaptImages): rotate cached mesh grid with DatasetModel transforms (#416)
- ci: add live URL audit (weekly cron) + grandfather current broken URLs (#415)
- fix: add quick_update kwarg to VisualizerImaging.visualize_combined (#414)
- docs: audit-driven URL fixes across docs, READMEs, and docstrings (#413)
- feat: AnalysisEllipse.fit_from + JAX pytree registration (keystone) (#412)
- refactor: unify FitEllipse perimeter sampling; add JAX support (#410)
- refactor: parameterise Ellipse + EllipseMultipole math on xp (#408)
- feat: replace Ludlow16 colossus pure_callback with JAX-native impl (#403) (#406)
- fix: register DatasetModel pytree in _register_fit_quantity_pytrees (#405)
- feat: wire ag.VisualizerQuantity through fit_for_visualization (#404)
- docs(research): Ludlow16 JAX concentration feasibility study (#397) (#402)
- feat: pytree registration for FitEllipse + FitQuantity (Phase 0c) (#401)
- fix: ag.AnalysisInterferometer.init kwargs passthrough (#399)
- refactor: DatasetInterp delegates to aa.interp_2d; expose xp (#398)
Full changelog: https://github.com/PyAutoLabs/PyAutoLens/co...
v2026.5.14.2
PyAutoLens v2026.5.14.2
What's New
Breaking Changes
- fix: AnalysisPoint.init kwargs passthrough (#506)
al.AnalysisPoint.__init__gains a**kwargspassthrough — strictly additive. Any caller that previously worked is unaffected. New: callers can now passuse_jax_for_visualization=True(or any other kwarg accepted by the autofit baseAnalysis) withoutTypeError.
- feat: re-export galaxy_table CSV helpers from autogalaxy (#502)
- Three new namespace exports on
autolens, all pointing at the autogalaxy implementations from PyAutoGalaxy#392: -
al.GalaxyTable
- Three new namespace exports on
- fix: AnalysisInterferometer.init kwargs passthrough (#500)
al.AnalysisInterferometer.__init__gains a**kwargspassthrough — strictly additive. Any caller that previously worked is unaffected. New: callers can now passuse_jax_for_visualization=True(or any other kwarg accepted by the autofit baseAnalysis) withoutTypeError.
New Features
- docs: add nufftax + FINUFFT citation guidance (#503)
Bug Fixes
- fix: AnalysisImaging.log_likelihood_function CPU branch returns figure_of_merit (not log_likelihood) (#504)
Internal
- feat: re-export TransformerNUFFTPyNUFFT (legacy pynufft NUFFT) (#501)
- fix: tracer_util JAX-safe for traced subhalo redshifts (#498) (#499)
Upstream Changes
PyAutoFit
- fix: populate NUTS samples_info keys under test-mode bypass (#1260)
- fix: stop passing dataset=None to fit_cls when sensitivity Job is complete (#1259)
PyAutoArray
- feat: add aa.interp_2d (NumPy + JAX bilinear interpolation) (#308)
- perf: batched transform_mapping_matrix in TransformerNUFFT (single nufft2d2 call) (#305)
- fix(inversion): regularization_weights_mapper_dict uses correct linear_obj_list index (#304)
- feat: nufftax-backed TransformerNUFFT as default; rename pynufft variant to TransformerNUFFTPyNUFFT (#303)
- Make use_mixed_precision actually emit fp32 FFT for light profiles (#302)
- feat: honor PYAUTO_SMALL_DATASETS in Imaging.from_fits (#301)
PyAutoGalaxy
- feat: replace Ludlow16 colossus pure_callback with JAX-native impl (#403) (#406)
- fix: register DatasetModel pytree in _register_fit_quantity_pytrees (#405)
- feat: wire ag.VisualizerQuantity through fit_for_visualization (#404)
- docs(research): Ludlow16 JAX concentration feasibility study (#397) (#402)
- feat: pytree registration for FitEllipse + FitQuantity (Phase 0c) (#401)
- fix: ag.AnalysisInterferometer.init kwargs passthrough (#399)
- refactor: DatasetInterp delegates to aa.interp_2d; expose xp (#398)
- docs: add nufftax + FINUFFT citation guidance (#396)
- test: pin FitEllipse masked-points-loop behaviour (#395)
- feat: add galaxy_table CSV reader/writer for galaxy populations (#393)
- feat: re-export TransformerNUFFTPyNUFFT (legacy pynufft NUFFT) (#391)
- feat: dispatch autogalaxy visualizers via fit_for_visualization (#390)
Full changelog: 2026.5.8.2...2026.5.14.2
v2026.5.8.2
⚠️ v2026.5.8.2 is a no-op re-release of v2026.5.8.1 — same code, second release dispatched the same day to validate updated release-pipeline gates. The full set of changes shipped on 2026-05-08 follows.
PyAutoLens v2026.5.8.2
What's New
Breaking Changes
- Add VisualizerInterferometer combined plotter for datacube fits (#494)
- fix: synthetic PositionsLH under skip_checks + test_mode (#490)
- feat(weak-lensing): add WeakDataset + SimulatorShearYX (step 1) (#473)
Internal
- fix: tracer_util JAX-safe for traced subhalo redshifts (#498) (#499)
- refactor: replace os.path with pathlib (#497)
- docs: update workspace prose refs from README.rst to README.md (#493)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#492)
- Fix mapper-index lookup in source_plane_inversion_centre_from (#491)
- test: move sparse-operator parity check to autolens_workspace_test (#489)
- test: clean up jax false positives in test_autolens/ (#488)
- docs: convert prose .rst files to MyST .md (#487)
Upstream Changes
PyAutoFit
- fix: populate NUTS samples_info keys under test-mode bypass (#1260)
- fix: stop passing dataset=None to fit_cls when sensitivity Job is complete (#1259)
- refactor: replace os.path with pathlib (#1258)
- feat: add BlackJAXNUTS first-class non-linear search (#1256)
- Visualizer.visualize_combined: accept quick_update kwarg (#1254)
- Fix AnalysisFactor.visualize_combined dispatch in FactorGraph (#1253)
- Refresh cached SearchUpdater when AbstractSearch.paths is reassigned (#1252)
- docs: update workspace prose refs from README.rst to README.md (#1251)
- Support fixed Array elements through the EP fitting pipeline (#1250)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#1249)
- Add EPAnalysisFactor for cavity-message injection (#1248)
- test: delete jax-using unit tests (moved to autofit_workspace_test) (#1247)
- docs: convert prose .rst files to MyST .md (#1246)
PyAutoArray
- feat: honor PYAUTO_SMALL_DATASETS in Imaging.from_fits (#301)
- refactor: replace os.path with pathlib (#300)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#298)
- Fix subplot_of_mapper crash on interferometer data_subtracted (#297)
- fix OOB read in psf_precision_value_from causing NaN sparse-CPU log_evidence (#296)
- test: remove jax-using unit tests; assertions moved to autolens_workspace_test (#295)
- docs: convert index.rst to MyST .md (#294)
PyAutoGalaxy
- refactor: replace os.path with pathlib (#388)
- docs: update workspace prose refs from README.rst to README.md (#387)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#386)
- fix: xp-gate jax.scipy.special.factorial in shapelets/exponential.py (#385)
- test: remove jax from unit tests (moved to autogalaxy_workspace_test) (#384)
- docs: convert prose .rst files to MyST .md (#383)
Full changelog: 2026.5.1.4...2026.5.8.2
v2026.5.8.1
PyAutoLens v2026.5.8.1
What's New
Breaking Changes
- Add VisualizerInterferometer combined plotter for datacube fits (#494)
- fix: synthetic PositionsLH under skip_checks + test_mode (#490)
- feat(weak-lensing): add WeakDataset + SimulatorShearYX (step 1) (#473)
Internal
- fix: tracer_util JAX-safe for traced subhalo redshifts (#498) (#499)
- refactor: replace os.path with pathlib (#497)
- docs: update workspace prose refs from README.rst to README.md (#493)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#492)
- Fix mapper-index lookup in source_plane_inversion_centre_from (#491)
- test: move sparse-operator parity check to autolens_workspace_test (#489)
- test: clean up jax false positives in test_autolens/ (#488)
- docs: convert prose .rst files to MyST .md (#487)
Upstream Changes
PyAutoFit
- fix: populate NUTS samples_info keys under test-mode bypass (#1260)
- fix: stop passing dataset=None to fit_cls when sensitivity Job is complete (#1259)
- refactor: replace os.path with pathlib (#1258)
- feat: add BlackJAXNUTS first-class non-linear search (#1256)
- Visualizer.visualize_combined: accept quick_update kwarg (#1254)
- Fix AnalysisFactor.visualize_combined dispatch in FactorGraph (#1253)
- Refresh cached SearchUpdater when AbstractSearch.paths is reassigned (#1252)
- docs: update workspace prose refs from README.rst to README.md (#1251)
- Support fixed Array elements through the EP fitting pipeline (#1250)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#1249)
- Add EPAnalysisFactor for cavity-message injection (#1248)
- test: delete jax-using unit tests (moved to autofit_workspace_test) (#1247)
- docs: convert prose .rst files to MyST .md (#1246)
PyAutoArray
- feat: honor PYAUTO_SMALL_DATASETS in Imaging.from_fits (#301)
- refactor: replace os.path with pathlib (#300)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#298)
- Fix subplot_of_mapper crash on interferometer data_subtracted (#297)
- fix OOB read in psf_precision_value_from causing NaN sparse-CPU log_evidence (#296)
- test: remove jax-using unit tests; assertions moved to autolens_workspace_test (#295)
- docs: convert index.rst to MyST .md (#294)
PyAutoGalaxy
- refactor: replace os.path with pathlib (#388)
- docs: update workspace prose refs from README.rst to README.md (#387)
- docs: convert remaining prose .rst to MyST .md (pass 2) (#386)
- fix: xp-gate jax.scipy.special.factorial in shapelets/exponential.py (#385)
- test: remove jax from unit tests (moved to autogalaxy_workspace_test) (#384)
- docs: convert prose .rst files to MyST .md (#383)
Full changelog: 2026.5.1.4...2026.5.8.1
v2026.5.1.4
PyAutoLens v2026.5.1.4
Highlights
Python 3.9–3.13 supported, 3.12 / 3.13 recommended
This release expands supported Python versions to 3.9 through 3.13 (#486). 3.12 and 3.13 are first-class recommended; 3.9, 3.10, 3.11 are supported but emit a loud (bypassable) banner on import. Silence the banner via version.python_version_check: False in your workspace's config/general.yaml. Python 3.14 is not yet supported.
Key impacts for users:
requires-python = ">=3.9"inpyproject.toml(lower floor than before)- Classifiers now cover 3.9, 3.10, 3.11, 3.12, 3.13
- JAX is now an optional extra:
pip install autolens[jax], gated onpython_version >= '3.11'. Plainpip install autolensno longer pulls JAX as a transitive dep.
HowToLens moved to its own repo
The HowToLens lecture series now lives in its own repository at PyAutoLabs/HowToLens (#468). Existing URLs/prose in the library and workspace pointing at the previous location have been updated. Clone the new repo to follow the tutorial chapters.
Performance
- Short-circuit
set_snr_of_snr_light_profileswhen no SNR profiles are present (#471) — eliminates a redundant traversal in models that don't use SNR-tuned profiles
Internal / Cleanup
- Remove unused
pyprojrootimport (#485) - Add mask padding likelihood sanity check to test suite (#436)
- Clean up jax false positives in
test_autolens/(#488) - Move sparse-operator parity check to
autolens_workspace_test(#489) — keeps the library's unit suite numpy-only
Upstream Changes
PyAutoConf
- Support Python 3.9–3.13, first-class 3.12/3.13 (PyAutoConf#102)
- Soften Python version check with
general.yamlbypass (PyAutoConf#96)
PyAutoArray
- Support Python 3.9–3.13 (PyAutoArray#293)
- Handle off-centre masks in convolver and blurring grid padding (PyAutoArray#274)
- Fix NaN gradients from
jaxnnlsbackward pass via Jacobi preconditioning (PyAutoArray#279) - Lower
nnls_target_kappadefault to1e-11for stable NNLS gradients (PyAutoArray#283, #284)
PyAutoFit
- Support Python 3.9–3.13 (PyAutoFit#1244)
- JAX-jitted likelihoods in Dynesty via
use_jax_jit(PyAutoFit#1243) - Skip
FitExceptionsamples incompute_latent_samples(PyAutoFit#1233)
PyAutoGalaxy
- Support Python 3.9–3.13 (PyAutoGalaxy#382)
- Mark
pytree_tokenas ephemeral in light/linear profiles (PyAutoGalaxy#374) - xp-gate
jax.scipy.special.factorialinshapelets/exponential.py(PyAutoGalaxy#385)
Full changelog: 2026.4.13.6...2026.5.1.4
v2026.4.13.6
PyAutoLens v2026.4.13.6
What's New
Bug Fixes
- fix: pin autogalaxy dependency version and update homepage URL (#435)
Upstream Changes
PyAutoFit
- fix: pin autoconf dependency version and update homepage URL (#1206)
PyAutoArray
- fix: pin autoconf dependency version and update homepage URL (#273)
PyAutoGalaxy
- fix: pin autofit/autoarray dependency versions and update homepage (#348)
Full changelog: 2026.4.13.5...2026.4.13.6